//--------------------------------------------------------------------------- // 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 ); }
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; }
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; } }
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(); }
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; } }
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; } }
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; }
uint32_t Global::getTimeout() { return getIAttribute( IATTR_ROBUSTNESS ) ? getIAttribute( IATTR_TIMEOUT_DEFAULT ) : LB_TIMEOUT_INDEFINITE; }
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; }
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; }
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( )); } }
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; }
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; }
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; }
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; }