Esempio n. 1
0
//---------------------------------------------------------------------------
// init
//---------------------------------------------------------------------------
void Pipe::configInit( const uint128_t& initID, const uint32_t frameNumber )
{
    EQASSERT( _state == STATE_STOPPED );
    _state = STATE_INITIALIZING;

    EQLOG( LOG_INIT ) << "Create pipe" << std::endl;
    NodeCreatePipePacket createPipePacket;
    createPipePacket.objectID = getNode()->getID();
    createPipePacket.pipeID   = getID();
    createPipePacket.threaded = getIAttribute( IATTR_HINT_THREAD );
    getNode()->send( createPipePacket );

    EQLOG( LOG_INIT ) << "Init pipe" << std::endl;
    PipeConfigInitPacket packet;
    packet.initID = initID;
    packet.frameNumber = frameNumber;
    send( packet );
}
Esempio n. 2
0
bool Config::_cmdUpdate( co::ICommand& cmd )
{
    co::ObjectICommand command( cmd );

    LBVERB << "handle config update " << command << std::endl;

    const uint32_t versionID = command.read< uint32_t >();
    const uint32_t finishID = command.read< uint32_t >();

    sync();
    commit();

    co::NodePtr node = command.getRemoteNode();
    if( !_needsFinish )
    {
        send( node, fabric::CMD_CONFIG_UPDATE_VERSION )
                << getVersion() << versionID << finishID << LB_UNDEFINED_UINT32;
        return true;
    }

    co::LocalNodePtr localNode = getLocalNode();
    lunchbox::Request< void > request = localNode->registerRequest< void >();

    send( node, fabric::CMD_CONFIG_UPDATE_VERSION )
        << getVersion() << versionID << finishID << request;

    _flushAllFrames();
    _finishedFrame.waitEQ( _currentFrame ); // wait for render clients idle
    request.wait(); // wait for app sync
    _needsFinish = false;

    const bool canFail = (getIAttribute( IATTR_ROBUSTNESS ) != OFF);
    const bool result = _updateRunning( canFail );
    if( !result && !canFail )
    {
        LBWARN << "Config update failed, exiting config" << std::endl;
        exit();
    }

    const uint128_t version = commit();
    send( command.getRemoteNode(), fabric::CMD_CONFIG_UPDATE_REPLY )
            << version << command.read< uint32_t >() << result;
    return true;
}
Esempio n. 3
0
void Node::frameStart( const uint128_t&, const uint32_t frameNumber )
{
    startFrame( frameNumber ); // unlock pipe threads
    
    switch( getIAttribute( IATTR_THREAD_MODEL ))
    {
        case ASYNC:
            // Don't wait for pipes to release frame locally, sync not needed
            releaseFrameLocal( frameNumber );
            break;

        case DRAW_SYNC:  // Sync and release in frameDrawFinish
        case LOCAL_SYNC: // Sync and release in frameTasksFinish
            break;

        default:
            LBUNIMPLEMENTED;
    }
}
Esempio n. 4
0
bool Node::configInit( const eq::uint128_t& initId )
{
    // All render data is static or multi-buffered, we can run asynchronously
    if( getIAttribute( IATTR_THREAD_MODEL ) == eq::UNDEFINED )
        setIAttribute( IATTR_THREAD_MODEL, eq::ASYNC );

    if( !eq::Node::configInit( initId ))
        return false;

    livre::Client* client = static_cast<livre::Client*>( getClient( ).get());
    client->setIdleFunction( std::bind( &detail::Node::updateAndSendFrameRange,
                                        _impl));

    if( !isApplicationNode( ))
    {
        Config *config = static_cast< Config *>( getConfig() );
        config->mapFrameData( initId );
    }

    return _impl->configInit();
}
Esempio n. 5
0
void Node::_setAffinity()
{
    const int32_t affinity = getIAttribute( IATTR_HINT_AFFINITY );
    switch( affinity )
    {
        case OFF:
            break;

        case AUTO:
            // TODO
            LBVERB << "No automatic thread placement for node threads "
                   << std::endl;
            break;

        default:
            co::LocalNodePtr node = getLocalNode();
            send( node, fabric::CMD_NODE_SET_AFFINITY ) << affinity;

            node->setAffinity( affinity );
            break;
    }
}
Esempio n. 6
0
void Node::_setAffinity()
{
    const int32_t affinity = getIAttribute( IATTR_HINT_AFFINITY );
    switch( affinity )
    {
        case OFF:
            break;

        case AUTO:
            LBINFO << "No automatic thread placement for node threads "
                   << std::endl;
            break;

        default:
            NodeAffinityPacket packet;
            packet.affinity = affinity;
            co::LocalNodePtr node = getLocalNode();
            send( node, packet );

            node->setAffinity( affinity );
            break;
    }
}
Esempio n. 7
0
bool Window::processEvent( const Event& event )
{
    // see comment in _updateEvent
    _updateEvent( const_cast< Event& >( event ));

    switch( event.type )
    {
        case Event::WINDOW_HIDE:
            setPixelViewport( PixelViewport( 0, 0, 0, 0 ));
            break;

        case Event::WINDOW_SHOW:
        case Event::WINDOW_RESIZE:
            setPixelViewport( PixelViewport( event.resize.x, event.resize.y,
                                             event.resize.w, event.resize.h ));
            break;

        case Event::KEY_PRESS:
        case Event::KEY_RELEASE:
            if( event.key.key == KC_VOID )
                return true; // ignore
            // else fall through
        case Event::WINDOW_EXPOSE:
        case Event::WINDOW_CLOSE:
        case Event::STATISTIC:
        case Event::MAGELLAN_AXIS:
        case Event::MAGELLAN_BUTTON:
            break;

        case Event::WINDOW_POINTER_GRAB:
            _grabbedChannels = _getEventChannels( event.pointer );
            break;
        case Event::WINDOW_POINTER_UNGRAB:
            _grabbedChannels.clear();
            break;

        case Event::WINDOW_POINTER_MOTION:
        case Event::WINDOW_POINTER_BUTTON_PRESS:
        case Event::WINDOW_POINTER_BUTTON_RELEASE:
        case Event::WINDOW_POINTER_WHEEL:
        {
            const Channels& channels = _getEventChannels( event.pointer );
            for( Channels::const_iterator i = channels.begin();
                 i != channels.end(); ++i )
            {
                Channel* channel = *i;
                Event channelEvent = event;
                switch( event.type )
                {
                  case Event::WINDOW_POINTER_MOTION:
                    channelEvent.type = Event::CHANNEL_POINTER_MOTION;
                    break;
                  case Event::WINDOW_POINTER_BUTTON_PRESS:
                    channelEvent.type = Event::CHANNEL_POINTER_BUTTON_PRESS;
                    break;
                  case Event::WINDOW_POINTER_BUTTON_RELEASE:
                    channelEvent.type = Event::CHANNEL_POINTER_BUTTON_RELEASE;
                    break;
                  case Event::WINDOW_POINTER_WHEEL:
                    channelEvent.type = Event::CHANNEL_POINTER_WHEEL;
                    break;
                  default:
                    LBWARN << "Unhandled window event of type " << event.type
                           << std::endl;
                    LBUNIMPLEMENTED;
                }

                // convert y to GL notation (Channel PVP uses GL coordinates)
                const PixelViewport& pvp = getPixelViewport();
                const int32_t y = pvp.h - event.pointer.y;
                const PixelViewport& channelPVP =
                    channel->getNativePixelViewport();

                channelEvent.originator = channel->getID();
                channelEvent.serial = channel->getSerial();
                channelEvent.pointer.x -= channelPVP.x;
                channelEvent.pointer.y = channelPVP.h - y + channelPVP.y;
                channel->processEvent( channelEvent );
            }
            break;
        }

        case Event::WINDOW_SCREENSAVER:
            switch( getIAttribute( WindowSettings::IATTR_HINT_SCREENSAVER ))
            {
                case OFF:
                    return true; // screen saver stays inactive
                case ON:
                    return false; // screen saver becomes active
                default: // AUTO
                    if( getDrawableConfig().doublebuffered &&
                        getIAttribute( WindowSettings::IATTR_HINT_DRAWABLE ) == WINDOW )
                    {
                        return true; // screen saver stays inactive
                    }
                    return false;
            }

        case Event::UNKNOWN:
            // unknown window-system native event, which was not handled
            return false;

        default:
            LBWARN << "Unhandled window event of type " << event.type
                   << std::endl;
            LBUNIMPLEMENTED;
    }

    Config* config = getConfig();
    ConfigEvent configEvent;
    configEvent.data = event;
    config->sendEvent( configEvent );
    return true;
}
Esempio n. 8
0
uint32_t Global::getTimeout()
{
    return getIAttribute( IATTR_ROBUSTNESS ) ?
           getIAttribute( IATTR_TIMEOUT_DEFAULT ) : LB_TIMEOUT_INDEFINITE;
}
Esempio n. 9
0
bool Window::configInitAGLWindow()
{
    AGLContext context = getAGLContext();
    if( !context )
    {
        sendError( ERROR_AGLWINDOW_NO_CONTEXT );
        return false;
    }

    // window
    const bool decoration =
        getIAttribute(WindowSettings::IATTR_HINT_DECORATION) != OFF;
    WindowAttributes winAttributes = ( decoration ?
                                       kWindowStandardDocumentAttributes :
                                       kWindowNoTitleBarAttribute |
                                       kWindowNoShadowAttribute   |
                                       kWindowResizableAttribute  ) |
                                     kWindowStandardHandlerAttribute | kWindowInWindowMenuAttribute;

    // top, left, bottom, right
    const PixelViewport& pvp = getPixelViewport();
    const int32_t menuHeight = decoration ? EQ_AGL_MENUBARHEIGHT : 0 ;
    Rect windowRect = { short( pvp.y + menuHeight ), short( pvp.x ),
                        short( pvp.getYEnd() + menuHeight ),
                        short( pvp.getXEnd( ))
                      };
    WindowRef windowRef;

    Global::enterCarbon();
    const OSStatus status = CreateNewWindow( kDocumentWindowClass,
                            winAttributes,
                            &windowRect, &windowRef );
    if( status != noErr )
    {
        sendError( ERROR_AGLWINDOW_CREATEWINDOW_FAILED )
                << lexical_cast< std::string >( status );
        Global::leaveCarbon();
        return false;
    }

    // window title
    const std::string& name = getName();
    std::stringstream windowTitle;

    if( name.empty( ))
    {
        windowTitle << "Equalizer";
#ifndef NDEBUG
        windowTitle << " (" << getpid() << ")";
#endif
    }
    else
        windowTitle << name;

    CFStringRef title = CFStringCreateWithCString( kCFAllocatorDefault,
                        windowTitle.str().c_str(),
                        kCFStringEncodingMacRoman );
    SetWindowTitleWithCFString( windowRef, title );
    CFRelease( title );

    if( !aglSetWindowRef( context, windowRef ))
    {
        sendError( ERROR_AGLWINDOW_SETWINDOW_FAILED ) << aglError();
        Global::leaveCarbon();
        return false;
    }

    // show
    ShowWindow( windowRef );

    // Do focus hell
    ProcessSerialNumber selfProcess = { 0, kCurrentProcess };
    SetFrontProcess( &selfProcess );

    Global::leaveCarbon();
    setCarbonWindow( windowRef );

    return true;
}
Esempio n. 10
0
AGLPixelFormat Window::chooseAGLPixelFormat()
{
    Global::enterCarbon();

    CGOpenGLDisplayMask glDisplayMask =
        CGDisplayIDToOpenGLDisplayMask( _impl->cgDisplayID );

    // build attribute list
    std::vector<GLint> attributes;

    attributes.push_back( AGL_RGBA );
    attributes.push_back( GL_TRUE );
    attributes.push_back( AGL_ACCELERATED );
    attributes.push_back( GL_TRUE );

    if( getIAttribute( WindowSettings::IATTR_HINT_FULLSCREEN ) == ON )
        attributes.push_back( AGL_FULLSCREEN );

    attributes.push_back( AGL_DISPLAY_MASK );
    attributes.push_back( glDisplayMask );

    GLint colorSize = getIAttribute( WindowSettings::IATTR_PLANES_COLOR );
    if( colorSize != OFF )
    {
        switch( colorSize )
        {
        case RGBA16F:
            attributes.push_back( AGL_COLOR_FLOAT );
            colorSize = 16;
            break;
        case RGBA32F:
            attributes.push_back( AGL_COLOR_FLOAT );
            colorSize = 32;
            break;
        case AUTO:
            colorSize = 8;
            break;
        default:
            break;
        }

        attributes.push_back( AGL_RED_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( AGL_GREEN_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( AGL_BLUE_SIZE );
        attributes.push_back( colorSize );

        const int alphaSize = getIAttribute( WindowSettings::IATTR_PLANES_ALPHA );
        if( alphaSize > 0 || alphaSize == AUTO )
        {
            attributes.push_back( AGL_ALPHA_SIZE );
            attributes.push_back( alphaSize > 0 ? alphaSize : colorSize );
        }
    }

    const int depthSize = getIAttribute( WindowSettings::IATTR_PLANES_DEPTH );
    if( depthSize > 0 || depthSize == AUTO )
    {
        attributes.push_back( AGL_DEPTH_SIZE );
        attributes.push_back( depthSize>0 ? depthSize : 24 );
    }
    const int stencilSize = getIAttribute( WindowSettings::IATTR_PLANES_STENCIL );
    if( stencilSize > 0 || stencilSize == AUTO )
    {
        attributes.push_back( AGL_STENCIL_SIZE );
        attributes.push_back( stencilSize>0 ? stencilSize : 1 );
    }
    const int accumSize  = getIAttribute( WindowSettings::IATTR_PLANES_ACCUM );
    const int accumAlpha = getIAttribute( WindowSettings::IATTR_PLANES_ACCUM_ALPHA );
    if( accumSize >= 0 )
    {
        attributes.push_back( AGL_ACCUM_RED_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_GREEN_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_BLUE_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( AGL_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha >= 0 ? accumAlpha : accumSize );
    }
    else if( accumAlpha >= 0 )
    {
        attributes.push_back( AGL_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha );
    }

    const int samplesSize  = getIAttribute( WindowSettings::IATTR_PLANES_SAMPLES );
    if( samplesSize >= 0 )
    {
        attributes.push_back( AGL_SAMPLE_BUFFERS_ARB );
        attributes.push_back( 1 );
        attributes.push_back( AGL_SAMPLES_ARB );
        attributes.push_back( samplesSize );
    }

    if( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == ON ||
            ( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
              getIAttribute( WindowSettings::IATTR_HINT_DRAWABLE )     == WINDOW ))
    {
        attributes.push_back( AGL_DOUBLEBUFFER );
        attributes.push_back( GL_TRUE );
    }
    if( getIAttribute( WindowSettings::IATTR_HINT_STEREO ) == ON )
    {
        attributes.push_back( AGL_STEREO );
        attributes.push_back( GL_TRUE );
    }

    attributes.push_back( AGL_NONE );

    // build backoff list, least important attribute last
    std::vector<int> backoffAttributes;
    if( getIAttribute( WindowSettings::IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
            getIAttribute( WindowSettings::IATTR_HINT_DRAWABLE )     == WINDOW  )

        backoffAttributes.push_back( AGL_DOUBLEBUFFER );

    if( stencilSize == AUTO )
        backoffAttributes.push_back( AGL_STENCIL_SIZE );

    // choose pixel format
    AGLPixelFormat pixelFormat = 0;
    while( true )
    {
        pixelFormat = aglCreatePixelFormat( &attributes.front( ));

        if( pixelFormat ||              // found one or
                backoffAttributes.empty( )) // nothing else to try

            break;

        // Gradually remove backoff attributes
        const GLint attribute = backoffAttributes.back();
        backoffAttributes.pop_back();

        std::vector<GLint>::iterator iter = find( attributes.begin(),
                                            attributes.end(), attribute );
        LBASSERT( iter != attributes.end( ));

        attributes.erase( iter, iter+2 ); // remove two item (attr, value)
    }

    if( !pixelFormat )
        sendError( ERROR_SYSTEMWINDOW_PIXELFORMAT_NOTFOUND );

    Global::leaveCarbon();
    return pixelFormat;
}
Esempio n. 11
0
void Window::setXDrawable( XID drawable )
{
    LBASSERT( _impl->xDisplay );

    if( _impl->xDrawable == drawable )
        return;

    if( _impl->xDrawable )
        exitEventHandler();

    _impl->xDrawable = drawable;

    if( !drawable )
        return;

    const int32_t drawableType = getIAttribute( IATTR_HINT_DRAWABLE );
    if( drawableType != OFF )
        initEventHandler();

    // query pixel viewport of window
    switch( drawableType )
    {
        case PBUFFER:
        {
            unsigned width = 0;
            unsigned height = 0;
            glXQueryDrawable( _impl->xDisplay, drawable, GLX_WIDTH,  &width );
            glXQueryDrawable( _impl->xDisplay, drawable, GLX_HEIGHT, &height );

            setPixelViewport(
                PixelViewport( 0, 0, int32_t( width ), int32_t( height )));
            break;
        }
        case WINDOW:
        case AUTO:
        case UNDEFINED:
        {
            XWindowAttributes wa;
            XGetWindowAttributes( _impl->xDisplay, drawable, &wa );

            // position is relative to parent: translate to absolute coords
            ::Window root, parent, *children;
            unsigned nChildren;

            XQueryTree( _impl->xDisplay, drawable, &root, &parent, &children,
                        &nChildren );
            if( children != 0 )
                XFree( children );

            int x,y;
            ::Window childReturn;
            XTranslateCoordinates( _impl->xDisplay, parent, root, wa.x, wa.y,
                                   &x, &y, &childReturn );

            setPixelViewport( PixelViewport( x, y, wa.width, wa.height ));
            break;
        }
        default:
            LBERROR << "Unknown drawable type " << drawableType << std::endl;
            LBUNIMPLEMENTED;
        case OFF:
        case FBO:
            LBASSERT( getPixelViewport().hasArea( ));
    }
}
Esempio n. 12
0
XID Window::_createGLXWindow( GLXFBConfig* fbConfig, const PixelViewport& pvp )
{
    LBASSERT( getIAttribute( IATTR_HINT_DRAWABLE ) != PBUFFER );

    if( !_impl->xDisplay )
    {
        sendError( ERROR_GLXWINDOW_NO_DISPLAY );
        return 0;
    }
    if( !fbConfig )
    {
        sendError( ERROR_SYSTEMWINDOW_NO_PIXELFORMAT );
        return 0;
    }

    XVisualInfo* visInfo = GLXEW_VERSION_1_3 ?
        glXGetVisualFromFBConfig( _impl->xDisplay, fbConfig[0] ) :
        glXGetVisualFromFBConfigSGIX( _impl->xDisplay, fbConfig[0]);
    if( !visInfo )
    {
        sendError( ERROR_GLXWINDOW_NO_VISUAL );
        return 0;
    }

    const int screen = DefaultScreen( _impl->xDisplay );
    XID parent = RootWindow( _impl->xDisplay, screen );
    XSetWindowAttributes wa;
    wa.colormap = XCreateColormap( _impl->xDisplay, parent, visInfo->visual,
                                   AllocNone );
    wa.background_pixmap = None;
    wa.border_pixel = 0;
    wa.event_mask = StructureNotifyMask | VisibilityChangeMask | ExposureMask |
                    KeyPressMask | KeyReleaseMask | PointerMotionMask |
                    ButtonPressMask | ButtonReleaseMask;

    switch( getIAttribute( IATTR_HINT_DECORATION ))
    {
      case ON:
          wa.override_redirect = False;
          break;

      case OFF:
          wa.override_redirect = True;
          break;

      case AUTO:
      default:
          wa.override_redirect =
              getIAttribute( IATTR_HINT_FULLSCREEN ) == ON ?
              True : False;
          break;
    }

    XID drawable = XCreateWindow( _impl->xDisplay, parent,
                                  pvp.x, pvp.y, pvp.w, pvp.h,
                                  0, visInfo->depth, InputOutput,
                                  visInfo->visual,
                                  CWBackPixmap | CWBorderPixel | CWEventMask |
                                  CWColormap | CWOverrideRedirect, &wa );
    XFree( visInfo );
    if( !drawable )
    {
        sendError( ERROR_GLXWINDOW_CREATEWINDOW_FAILED );
        return 0;
    }

    std::stringstream windowTitle;
    const std::string& name = getName();

    if( name.empty( ))
    {
        windowTitle << "Equalizer";
#ifndef NDEBUG
        windowTitle << " (" << getpid() << ")";
#endif
    }
    else
        windowTitle << name;

    XStoreName( _impl->xDisplay, drawable, windowTitle.str().c_str( ));

    // Register for close window request from the window manager
    Atom deleteAtom = XInternAtom( _impl->xDisplay, "WM_DELETE_WINDOW", False );
    XSetWMProtocols( _impl->xDisplay, drawable, &deleteAtom, 1 );

    return drawable;
}
Esempio n. 13
0
GLXContext Window::createGLXContext( GLXFBConfig* fbConfig )
{
    if( !_impl->xDisplay )
    {
        sendError( ERROR_GLXWINDOW_NO_DISPLAY );
        return 0;
    }
    if( !fbConfig )
    {
        sendError( ERROR_SYSTEMWINDOW_NO_PIXELFORMAT );
        return 0;
    }

    GLXContext shCtx = 0;
    const SystemWindow* shareWindow = getSharedContextWindow();
    if( shareWindow )
    {
        const WindowIF* shareGLXWindow =
                                 dynamic_cast< const WindowIF* >( shareWindow );
        if( shareGLXWindow )
            shCtx = shareGLXWindow->getGLXContext();
#ifdef EQUALIZER_USE_QT5WIDGETS
        else if( dynamic_cast< const qt::WindowIF* >( shareWindow ))
        {
            // allows sharing with Qt window
            shareWindow->makeCurrent();
            shCtx = glXGetCurrentContext();
        }
#endif
    }

    int type = GLX_RGBA_TYPE;
    if( getIAttribute( IATTR_HINT_DRAWABLE ) == PBUFFER &&
        ( getIAttribute( IATTR_PLANES_COLOR ) == RGBA16F ||
          getIAttribute( IATTR_PLANES_COLOR ) == RGBA32F ))
    {
        type = GLX_RGBA_FLOAT_TYPE;
    }

    GLXContext context = 0;
    if( glXCreateContextAttribsARB &&
        getIAttribute( IATTR_HINT_CORE_PROFILE ) == ON )
    {
        int attribList[] = {
            GLX_CONTEXT_MAJOR_VERSION_ARB,
            getIAttribute( IATTR_HINT_OPENGL_MAJOR ),
            GLX_CONTEXT_MINOR_VERSION_ARB,
            getIAttribute( IATTR_HINT_OPENGL_MINOR ),
            GLX_RENDER_TYPE, type,
            GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
            None
        };

        context = glXCreateContextAttribsARB( _impl->xDisplay, fbConfig[0],
                                              shCtx, True, attribList );
    }
    else
    {
        if( GLXEW_VERSION_1_3 )
            context = glXCreateNewContext( _impl->xDisplay, fbConfig[0], type,
                                           shCtx, True );
        else
            context = glXCreateContextWithConfigSGIX( _impl->xDisplay,
                                               fbConfig[0], type, shCtx, True );
    }

#ifdef Darwin
    // WAR http://xquartz.macosforge.org/trac/ticket/466
    if( !context )
    {
        XVisualInfo* visInfo = GLXEW_VERSION_1_3 ?
            glXGetVisualFromFBConfig( _impl->xDisplay, fbConfig[0] ) :
            glXGetVisualFromFBConfigSGIX( _impl->xDisplay, fbConfig[0] );
        if( !visInfo )
        {
            std::vector<int> attributes;
            attributes.push_back( GLX_RGBA );
            attributes.push_back( GLX_RED_SIZE );
            attributes.push_back( 1 );
            attributes.push_back( GLX_ALPHA_SIZE );
            attributes.push_back( 1 );
            attributes.push_back( GLX_DEPTH_SIZE );
            attributes.push_back( 1 );
            attributes.push_back( GLX_DOUBLEBUFFER );
            attributes.push_back( None );

            const int screen = DefaultScreen( _impl->xDisplay );
            visInfo = glXChooseVisual( _impl->xDisplay, screen,
                                       &attributes.front( ));
            if( !visInfo )
            {
                sendError( ERROR_GLXWINDOW_NO_VISUAL );
                return 0;
            }
        }

        context = glXCreateContext( _impl->xDisplay, visInfo, shCtx, True );
        XFree( visInfo );
    }
#endif

    if( !context )
    {
        sendError( ERROR_GLXWINDOW_CREATECONTEXT_FAILED );
        return 0;
    }
    return context;
}
Esempio n. 14
0
GLXFBConfig* Window::chooseGLXFBConfig()
{
    if( !_impl->xDisplay )
    {
        sendError( ERROR_GLXWINDOW_NO_DISPLAY );
        return 0;
    }
    if( !GLXEW_VERSION_1_3 && !GLXEW_SGIX_fbconfig )
    {
        sendError( ERROR_GLXWINDOW_FBCONFIG_REQUIRED );
        return 0;
    }

    // build attribute list
    std::vector< int > attributes;
    const int32_t drawableHint = getIAttribute( IATTR_HINT_DRAWABLE );
    switch( drawableHint )
    {
      case PBUFFER:
        attributes.push_back ( GLX_DRAWABLE_TYPE );
        attributes.push_back ( GLX_PBUFFER_BIT );
        break;

      default:
        LBWARN << "Unknown drawable type " << drawableHint << ", using window"
               << std::endl;
        // no break;
      case UNDEFINED:
      case OFF: // needs fbConfig with visual for dummy window
      case FBO: // No typo - FBO needs fbConfig with visual for dummy window
      case WINDOW:
        attributes.push_back( GLX_X_RENDERABLE );
        attributes.push_back( True );
    }

    int colorSize = getIAttribute( IATTR_PLANES_COLOR );
    if( colorSize != OFF )
    {
        if( drawableHint == FBO || drawableHint == OFF )
            colorSize = 8; // Create FBO dummy window with 8bpp
        else switch( colorSize )
        {
          case RGBA16F:
          case RGBA32F:
            if( !GLXEW_ARB_fbconfig_float )
            {
                sendError( ERROR_SYSTEMWINDOW_ARB_FLOAT_FB_REQUIRED );
                return 0;
            }
            attributes.push_back( GLX_RENDER_TYPE );
            attributes.push_back( GLX_RGBA_FLOAT_BIT );
            colorSize = colorSize == RGBA16F ? 16 : 32;
            break;

          case AUTO:
          case ON:
            colorSize = 8;
            break;
          default:
            break;
        }

        LBASSERT( colorSize > 0 );
        attributes.push_back( GLX_RED_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( GLX_GREEN_SIZE );
        attributes.push_back( colorSize );
        attributes.push_back( GLX_BLUE_SIZE );
        attributes.push_back( colorSize );

        const int alphaSize = getIAttribute( IATTR_PLANES_ALPHA );
        switch( alphaSize )
        {
          case AUTO:
          case UNDEFINED:
          case ON:
            attributes.push_back( GLX_ALPHA_SIZE );
            attributes.push_back( colorSize );
            break;

          case OFF:
              break;

          default:
            LBASSERT( alphaSize > 0 );
            attributes.push_back( GLX_ALPHA_SIZE );
            attributes.push_back( alphaSize > 0 ? alphaSize : colorSize );
        }
    }
    const int depthSize = getIAttribute( IATTR_PLANES_DEPTH );
    if( depthSize > 0  || depthSize == AUTO )
    {
        attributes.push_back( GLX_DEPTH_SIZE );
        attributes.push_back( depthSize > 0 ? depthSize : 1 );
    }
    const int stencilSize = getIAttribute( IATTR_PLANES_STENCIL );
    if( stencilSize > 0 || stencilSize == AUTO )
    {
        attributes.push_back( GLX_STENCIL_SIZE );
        attributes.push_back( stencilSize>0 ? stencilSize : 1 );
    }
    const int accumSize = getIAttribute( IATTR_PLANES_ACCUM );
    const int accumAlpha = getIAttribute( IATTR_PLANES_ACCUM_ALPHA );
    if( accumSize >= 0 )
    {
        attributes.push_back( GLX_ACCUM_RED_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( GLX_ACCUM_GREEN_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( GLX_ACCUM_BLUE_SIZE );
        attributes.push_back( accumSize );
        attributes.push_back( GLX_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha >= 0 ? accumAlpha : accumSize );
    }
    else if( accumAlpha >= 0 )
    {
        attributes.push_back( GLX_ACCUM_ALPHA_SIZE );
        attributes.push_back( accumAlpha );
    }

    const int samplesSize  = getIAttribute( IATTR_PLANES_SAMPLES );
    if( samplesSize >= 0 && drawableHint != FBO )
    {
        attributes.push_back( GLX_SAMPLE_BUFFERS );
        attributes.push_back( 1 );
        attributes.push_back( GLX_SAMPLES );
        attributes.push_back( samplesSize );
    }

#ifdef Darwin
    // WAR: glDrawBuffer( GL_BACK ) renders only to the left back buffer on a
    // stereo visual on Darwin which creates ugly flickering on mono configs
    if( getIAttribute( IATTR_HINT_STEREO ) == ON )
    {
        attributes.push_back( GLX_STEREO );
        attributes.push_back( true );
    }
#else
    if( getIAttribute( IATTR_HINT_STEREO ) == ON ||
        ( getIAttribute( IATTR_HINT_STEREO )   == AUTO &&
          getIAttribute( IATTR_HINT_DRAWABLE ) == WINDOW ))
    {
        attributes.push_back( GLX_STEREO );
        attributes.push_back( true );
    }
#endif
    if( getIAttribute( IATTR_HINT_DOUBLEBUFFER ) == ON ||
        ( getIAttribute( IATTR_HINT_DOUBLEBUFFER ) == AUTO &&
          getIAttribute( IATTR_HINT_DRAWABLE )     == WINDOW ))
    {
        attributes.push_back( GLX_DOUBLEBUFFER );
        attributes.push_back( true );
    }
    attributes.push_back( None );

    // build backoff list, least important attribute last
    std::vector<int> backoffAttributes;
    if( getIAttribute( IATTR_HINT_DRAWABLE ) == WINDOW )
    {
        if( getIAttribute( IATTR_HINT_DOUBLEBUFFER ) == AUTO )
            backoffAttributes.push_back( GLX_DOUBLEBUFFER );

#ifndef Darwin
        if( getIAttribute( IATTR_HINT_STEREO ) == AUTO )
            backoffAttributes.push_back( GLX_STEREO );
#endif
    }

    if( stencilSize == AUTO )
        backoffAttributes.push_back( GLX_STENCIL_SIZE );

    PFNGLXCHOOSEFBCONFIGSGIXPROC chooseFBConfig = GLXEW_VERSION_1_3 ?
        glXChooseFBConfig : glXChooseFBConfigSGIX;

    const int screen = DefaultScreen( _impl->xDisplay );
    int nConfigs = 0;
    GLXFBConfig* configs = chooseFBConfig( _impl->xDisplay, screen,
                                           &attributes[0], &nConfigs );

    while(( nConfigs == 0 || !configs ) && !backoffAttributes.empty( ))
    {
        // Gradually remove backoff attributes
        const int attribute = backoffAttributes.back();
        backoffAttributes.pop_back();

        std::vector<int>::iterator iter = find( attributes.begin(),
                                                attributes.end(), attribute );
        LBASSERT( iter != attributes.end( ));
        attributes.erase( iter, iter+2 );
        configs = chooseFBConfig( _impl->xDisplay, screen, &attributes[0],
                                  &nConfigs );
    }

    return configs;
}
Esempio n. 15
0
bool Window::configInitGL( const eq::uint128_t& initID )
{
LBINFO << "-----> Window::configInitGL(" << initID <<
    ", " << getPixelViewport( ) <<
    ", " << getViewport( ) << ")" << std::endl;

    bool init = false;

    LBASSERT( !_window.valid( ));

    if( !eq::Window::configInitGL( initID ))
        goto out;

    {
        const eq::PixelViewport& pvp = getPixelViewport( );
        const eq::DrawableConfig& dc = getDrawableConfig( );

        osg::ref_ptr< osg::GraphicsContext::Traits > traits =
            new osg::GraphicsContext::Traits( );
        traits->x = pvp.x;
        traits->y = pvp.y;
        traits->width = pvp.w;
        traits->height = pvp.h;
        traits->red = traits->blue = traits->green = dc.colorBits;
        traits->alpha = dc.alphaBits;
        traits->stencil = dc.stencilBits;
        traits->doubleBuffer = dc.doublebuffered;
#if 0
        traits->pbuffer =
            ( getIAttribute( IATTR_HINT_DRAWABLE ) == eq::PBUFFER );
#endif
        std::ostringstream version;
        version << dc.glVersion;
        traits->glContextVersion = version.str( );

#if 0
        Window* sharedWindow =
            static_cast< Window* >( getSharedContextWindow( ));
        if( sharedWindow && ( sharedWindow != this ))
            traits->sharedContext = sharedWindow->getGraphicsContext( );
#endif

        _window = new osgViewer::GraphicsWindowEmbedded( traits );

        static_cast< Node* >( getNode( ))->addGraphicsContext( _window );

        const unsigned int maxTexturePoolSize =
            osg::DisplaySettings::instance( )->getMaxTexturePoolSize( );
        const unsigned int maxBufferObjectPoolSize =
            osg::DisplaySettings::instance( )->getMaxBufferObjectPoolSize( );

        if( maxTexturePoolSize > 0 )
            getState( )->setMaxTexturePoolSize( maxTexturePoolSize );
        if( maxBufferObjectPoolSize > 0 )
            getState( )->setMaxBufferObjectPoolSize( maxBufferObjectPoolSize );

        initCapabilities( _window );
    }

    init = true;

out:
    if( !init )
        cleanup( );

LBINFO << "<----- Window::configInitGL(" << initID << ")" << std::endl;

    return init;
}