diff --git a/src/Aspect/Aspect_DisplayConnection.cxx b/src/Aspect/Aspect_DisplayConnection.cxx index d6643b32e6..53a7d3a161 100755 --- a/src/Aspect/Aspect_DisplayConnection.cxx +++ b/src/Aspect/Aspect_DisplayConnection.cxx @@ -16,7 +16,6 @@ #include #include - IMPLEMENT_STANDARD_RTTIEXT(Aspect_DisplayConnection,Standard_Transient) // ======================================================================= @@ -27,6 +26,8 @@ Aspect_DisplayConnection::Aspect_DisplayConnection() { #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) myDisplay = NULL; + myDefVisualInfo = NULL; + myDefFBConfig = NULL; myIsOwnDisplay = false; OSD_Environment anEnv ("DISPLAY"); myDisplayName = anEnv.Value(); @@ -41,6 +42,10 @@ Aspect_DisplayConnection::Aspect_DisplayConnection() Aspect_DisplayConnection::~Aspect_DisplayConnection() { #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) + if (myDefVisualInfo != NULL) + { + XFree (myDefVisualInfo); + } if (myDisplay != NULL && myIsOwnDisplay) { @@ -56,6 +61,8 @@ Aspect_DisplayConnection::~Aspect_DisplayConnection() // ======================================================================= Aspect_DisplayConnection::Aspect_DisplayConnection (const TCollection_AsciiString& theDisplayName) : myDisplay (NULL), + myDefVisualInfo (NULL), + myDefFBConfig (NULL), myIsOwnDisplay (false) { myDisplayName = theDisplayName; @@ -68,11 +75,28 @@ Aspect_DisplayConnection::Aspect_DisplayConnection (const TCollection_AsciiStrin // ======================================================================= Aspect_DisplayConnection::Aspect_DisplayConnection (Display* theDisplay) : myDisplay (NULL), + myDefVisualInfo (NULL), + myDefFBConfig (NULL), myIsOwnDisplay (false) { Init (theDisplay); } +// ======================================================================= +// function : SetDefaultVisualInfo +// purpose : +// ======================================================================= +void Aspect_DisplayConnection::SetDefaultVisualInfo (XVisualInfo* theVisual, + Aspect_FBConfig theFBConfig) +{ + if (myDefVisualInfo != NULL) + { + XFree (myDefVisualInfo); + } + myDefVisualInfo = theVisual; + myDefFBConfig = theFBConfig; +} + // ======================================================================= // function : Init // purpose : diff --git a/src/Aspect/Aspect_DisplayConnection.hxx b/src/Aspect/Aspect_DisplayConnection.hxx index e31f0f2cf4..2cfba3d422 100755 --- a/src/Aspect/Aspect_DisplayConnection.hxx +++ b/src/Aspect/Aspect_DisplayConnection.hxx @@ -22,6 +22,7 @@ #if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) #include + #include #endif //! This class creates and provides connection with X server. @@ -72,9 +73,21 @@ public: //! @param theDisplay external pointer to allocated Display, or NULL if new connection should be created void Init (Display* theDisplay); + //! Return default window visual or NULL when undefined. + XVisualInfo* GetDefaultVisualInfo() const { return myDefVisualInfo; } + + //! @return native Window FB config (GLXFBConfig on Xlib) + Aspect_FBConfig GetDefaultFBConfig() const { return myDefFBConfig; } + + //! Set default window visual; the visual will be deallocated using XFree(). + Standard_EXPORT void SetDefaultVisualInfo (XVisualInfo* theVisual, + Aspect_FBConfig theFBConfig); + private: Display* myDisplay; + XVisualInfo* myDefVisualInfo; + Aspect_FBConfig myDefFBConfig; NCollection_DataMap myAtoms; TCollection_AsciiString myDisplayName; Standard_Boolean myIsOwnDisplay; diff --git a/src/OpenGl/OpenGl_GraphicDriver.cxx b/src/OpenGl/OpenGl_GraphicDriver.cxx index 71b7796344..3c1f511a75 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.cxx +++ b/src/OpenGl/OpenGl_GraphicDriver.cxx @@ -46,6 +46,7 @@ IMPLEMENT_STANDARD_RTTIEXT(OpenGl_GraphicDriver,Graphic3d_GraphicDriver) #if !defined(_WIN32) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) #include // XOpenDisplay() + #include #endif #if defined(HAVE_EGL) || defined(HAVE_GLES2) || defined(OCCT_UWP) || defined(__ANDROID__) || defined(__QNX__) || defined(__EMSCRIPTEN__) @@ -109,7 +110,31 @@ namespace } return aCfg; } +#elif !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) + //! Search for RGBA double-buffered visual with stencil buffer. + static int TheDoubleBuffVisual[] = + { + GLX_RGBA, + GLX_DEPTH_SIZE, 16, + GLX_STENCIL_SIZE, 1, + GLX_DOUBLEBUFFER, + None + }; + + //! Search for RGBA double-buffered visual with stencil buffer. + static int TheDoubleBuffFBConfig[] = + { + GLX_X_RENDERABLE, True, + GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, + GLX_RENDER_TYPE, GLX_RGBA_BIT, + GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, + GLX_DEPTH_SIZE, 16, + GLX_STENCIL_SIZE, 1, + GLX_DOUBLEBUFFER, True, + None + }; #endif + } // ======================================================================= @@ -140,15 +165,6 @@ OpenGl_GraphicDriver::OpenGl_GraphicDriver (const Handle(Aspect_DisplayConnectio Bool toSync = ::getenv ("CSF_GraphicSync") != NULL || ::getenv ("CALL_SYNCHRO_X") != NULL; XSynchronize (aDisplay, toSync); - -#if !defined(HAVE_EGL) && !defined(HAVE_GLES2) - // does the server know about OpenGL & GLX? - int aDummy; - if (!XQueryExtension (aDisplay, "GLX", &aDummy, &aDummy, &aDummy)) - { - ::Message::SendWarning ("OpenGl_GraphicDriver, this system doesn't appear to support OpenGL"); - } -#endif #endif if (theToInitialize && !InitContext()) @@ -333,6 +349,7 @@ Standard_Boolean OpenGl_GraphicDriver::InitContext() // return Standard_False; //} #endif + chooseVisualInfo(); myIsOwnContext = Standard_True; return Standard_True; } @@ -371,10 +388,91 @@ Standard_Boolean OpenGl_GraphicDriver::InitEglContext (Aspect_Display t return Standard_False; } } + chooseVisualInfo(); return Standard_True; } #endif +// ======================================================================= +// function : chooseVisualInfo +// purpose : +// ======================================================================= +void OpenGl_GraphicDriver::chooseVisualInfo() +{ + if (myDisplayConnection.IsNull()) + { + return; + } + +#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__) + Display* aDisp = myDisplayConnection->GetDisplay(); + + XVisualInfo* aVisInfo = NULL; + Aspect_FBConfig anFBConfig = NULL; +#if defined(HAVE_EGL) || defined(HAVE_GLES2) + XVisualInfo aVisInfoTmp; + memset (&aVisInfoTmp, 0, sizeof(aVisInfoTmp)); + aVisInfoTmp.screen = DefaultScreen (aDisp); + if (myEglDisplay != EGL_NO_DISPLAY + && myEglConfig != NULL + && eglGetConfigAttrib ((EGLDisplay )myEglDisplay, myEglConfig, EGL_NATIVE_VISUAL_ID, (EGLint* )&aVisInfoTmp.visualid) == EGL_TRUE) + { + int aNbVisuals = 0; + aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbVisuals); + } +#else + int aScreen = DefaultScreen(aDisp); + int aDummy = 0; + if (!XQueryExtension (aDisp, "GLX", &aDummy, &aDummy, &aDummy) + || !glXQueryExtension (aDisp, &aDummy, &aDummy)) + { + Message::SendFail ("Error: OpenGl_GraphicDriver, GLX extension is unavailable"); + } + + // FBConfigs were added in GLX version 1.3 + int aGlxMajor = 0, aGlxMinor = 0; + const bool hasFBCfg = glXQueryVersion (aDisp, &aGlxMajor, &aGlxMinor) + && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1)); + if (hasFBCfg) + { + int aFBCount = 0; + GLXFBConfig* aFBCfgList = NULL; + if (hasFBCfg) + { + aFBCfgList = glXChooseFBConfig (aDisp, aScreen, TheDoubleBuffFBConfig, &aFBCount); + } + if(aFBCfgList != NULL + && aFBCount >= 1) + { + anFBConfig = aFBCfgList[0]; + aVisInfo = glXGetVisualFromFBConfig (aDisp, anFBConfig); + + /*int aDepthSize = 0, aStencilSize = 0; + glXGetFBConfigAttrib (aDisp, anFBConfig, GLX_DEPTH_SIZE, &aDepthSize); + glXGetFBConfigAttrib (aDisp, anFBConfig, GLX_STENCIL_SIZE, &aStencilSize); + Message::SendInfo() << "GLX FBConfig:" + << "\n DepthSize= " << aDepthSize + << "\n StencilSize= " << aStencilSize;*/ + } + XFree (aFBCfgList); + } + + if (aVisInfo == NULL) + { + aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuffVisual); + } +#endif + if (aVisInfo != NULL) + { + myDisplayConnection->SetDefaultVisualInfo (aVisInfo, anFBConfig); + } + else + { + Message::SendWarning ("OpenGl_GraphicDriver, couldn't find compatible Visual (RGBA, double-buffered)"); + } +#endif +} + // ======================================================================= // function : InquireLimit // purpose : diff --git a/src/OpenGl/OpenGl_GraphicDriver.hxx b/src/OpenGl/OpenGl_GraphicDriver.hxx index 09e8438e16..1c91d0b088 100644 --- a/src/OpenGl/OpenGl_GraphicDriver.hxx +++ b/src/OpenGl/OpenGl_GraphicDriver.hxx @@ -185,6 +185,11 @@ public: //! Returns unique ID for primitive arrays. Standard_Size GetNextPrimitiveArrayUID() const { return myUIDGenerator.Increment(); } +protected: + + //! Choose default visual for new windows created by Aspect_DisplayConnection. + Standard_EXPORT void chooseVisualInfo(); + protected: Standard_Boolean myIsOwnContext; //!< indicates that shared context has been created within OpenGl_GraphicDriver diff --git a/src/TKService/EXTERNLIB b/src/TKService/EXTERNLIB index 5bb0ceebaa..765caf7f93 100755 --- a/src/TKService/EXTERNLIB +++ b/src/TKService/EXTERNLIB @@ -3,7 +3,6 @@ TKMath CSF_user32 CSF_advapi32 CSF_OpenVR -CSF_OpenGlLibs CSF_advapi32 CSF_user32 CSF_XwLibs diff --git a/src/Xw/Xw_Window.cxx b/src/Xw/Xw_Window.cxx index 709af9e92c..c3d9de7016 100644 --- a/src/Xw/Xw_Window.cxx +++ b/src/Xw/Xw_Window.cxx @@ -24,44 +24,6 @@ //#include -#if defined(HAVE_EGL) || defined(HAVE_GLES2) - #include - #ifndef EGL_OPENGL_ES3_BIT - #define EGL_OPENGL_ES3_BIT 0x00000040 - #endif -#else - #include - -namespace -{ - - //! Search for RGBA double-buffered visual with stencil buffer. - static int TheDoubleBuffVisual[] = - { - GLX_RGBA, - GLX_DEPTH_SIZE, 16, - GLX_STENCIL_SIZE, 1, - GLX_DOUBLEBUFFER, - None - }; - - //! Search for RGBA double-buffered visual with stencil buffer. - static int TheDoubleBuffFBConfig[] = - { - GLX_X_RENDERABLE, True, - GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, - GLX_RENDER_TYPE, GLX_RGBA_BIT, - GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR, - GLX_DEPTH_SIZE, 16, - GLX_STENCIL_SIZE, 1, - GLX_DOUBLEBUFFER, True, - None - }; - -} - -#endif - IMPLEMENT_STANDARD_RTTIEXT(Xw_Window, Aspect_Window) // ======================================================================= @@ -73,12 +35,11 @@ Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay, const Standard_Integer thePxLeft, const Standard_Integer thePxTop, const Standard_Integer thePxWidth, - const Standard_Integer thePxHeight, - const Aspect_FBConfig theFBConfig) + const Standard_Integer thePxHeight) : Aspect_Window(), myDisplay (theXDisplay), myXWindow (0), - myFBConfig (theFBConfig), + myFBConfig (NULL), myXLeft (thePxLeft), myYTop (thePxTop), myXRight (thePxLeft + thePxWidth), @@ -92,120 +53,15 @@ Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay, else if (theXDisplay.IsNull()) { throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined"); - return; } + myFBConfig = theXDisplay->GetDefaultFBConfig(); + XVisualInfo* aVisInfo = theXDisplay->GetDefaultVisualInfo(); + Display* aDisp = myDisplay->GetDisplay(); int aScreen = DefaultScreen(aDisp); Window aParent = RootWindow (aDisp, aScreen); - XVisualInfo* aVisInfo = NULL; -#if defined(HAVE_EGL) || defined(HAVE_GLES2) - EGLDisplay anEglDisplay = eglGetDisplay (aDisp); - EGLint aVerMajor = 0; EGLint aVerMinor = 0; - XVisualInfo aVisInfoTmp; memset (&aVisInfoTmp, 0, sizeof(aVisInfoTmp)); - if (anEglDisplay != EGL_NO_DISPLAY - && eglInitialize (anEglDisplay, &aVerMajor, &aVerMinor) == EGL_TRUE) - { - EGLint aConfigAttribs[] = - { - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 0, - EGL_DEPTH_SIZE, 24, - EGL_STENCIL_SIZE, 8, - #if defined(HAVE_GLES2) - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - #else - EGL_RENDERABLE_TYPE, EGL_OPENGL_BIT, - #endif - EGL_NONE - }; - - EGLint aNbConfigs = 0; - void* anEglConfig = NULL; - for (Standard_Integer aGlesVer = 3; aGlesVer >= 2; --aGlesVer) - { - #if defined(GL_ES_VERSION_2_0) - aConfigAttribs[6 * 2 + 1] = aGlesVer == 3 ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_ES2_BIT; - #else - if (aGlesVer == 2) - { - break; - } - #endif - - if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) == EGL_TRUE - && anEglConfig != NULL) - { - break; - } - eglGetError(); - - aConfigAttribs[4 * 2 + 1] = 16; // try config with smaller depth buffer - if (eglChooseConfig (anEglDisplay, aConfigAttribs, &anEglConfig, 1, &aNbConfigs) == EGL_TRUE - && anEglConfig != NULL) - { - break; - } - eglGetError(); - } - - if (anEglConfig != NULL - && eglGetConfigAttrib (anEglDisplay, anEglConfig, EGL_NATIVE_VISUAL_ID, (EGLint* )&aVisInfoTmp.visualid) == EGL_TRUE) - { - int aNbVisuals = 0; - aVisInfoTmp.screen = DefaultScreen (aDisp); - aVisInfo = XGetVisualInfo (aDisp, VisualIDMask | VisualScreenMask, &aVisInfoTmp, &aNbVisuals); - } - } - if (aVisInfo == NULL) - { - Message::SendWarning ("Warning: cannot choose Visual using EGL while creating Xw_Window"); - } -#else - int aDummy = 0; - if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy)) - { - throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable"); - return; - } - if (myFBConfig == NULL) - { - // FBConfigs were added in GLX version 1.3 - int aGlxMajor = 0; - int aGlxMinor = 0; - const bool hasFBCfg = glXQueryVersion (aDisp, &aGlxMajor, &aGlxMinor) - && ((aGlxMajor == 1 && aGlxMinor >= 3) || (aGlxMajor > 1)); - if (hasFBCfg) - { - int aFBCount = 0; - GLXFBConfig* aFBCfgList = NULL; - if (hasFBCfg) - { - aFBCfgList = glXChooseFBConfig (aDisp, aScreen, TheDoubleBuffFBConfig, &aFBCount); - } - if(aFBCfgList != NULL - && aFBCount >= 1) - { - myFBConfig = aFBCfgList[0]; - aVisInfo = glXGetVisualFromFBConfig (aDisp, myFBConfig); - } - XFree (aFBCfgList); - } - } - - if (aVisInfo == NULL) - { - aVisInfo = glXChooseVisual (aDisp, aScreen, TheDoubleBuffVisual); - } - if (aVisInfo == NULL) - { - throw Aspect_WindowDefinitionError("Xw_Window, couldn't find compatible Visual (RGBA, double-buffered)"); - return; - } -#endif unsigned long aMask = 0; XSetWindowAttributes aWinAttr; @@ -225,15 +81,9 @@ Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay, InputOutput, aVisInfo != NULL ? aVisInfo->visual : CopyFromParent, CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, &aWinAttr); - if (aVisInfo != NULL) - { - XFree (aVisInfo); - aVisInfo = NULL; - } if (myXWindow == 0) { throw Aspect_WindowDefinitionError("Xw_Window, Unable to create window"); - return; } // if parent - desktop @@ -277,22 +127,11 @@ Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay, if (theXWin == 0) { throw Aspect_WindowDefinitionError("Xw_Window, given invalid X window"); - return; } else if (theXDisplay.IsNull()) { throw Aspect_WindowDefinitionError("Xw_Window, X Display connection is undefined"); - return; } -#if !defined(HAVE_EGL) && !defined(HAVE_GLES2) - int aDummy = 0; - if (!glXQueryExtension (myDisplay->GetDisplay(), &aDummy, &aDummy)) - { - myXWindow = 0; - throw Aspect_WindowDefinitionError("Xw_Window, GLX extension is unavailable"); - return; - } -#endif Display* aDisp = myDisplay->GetDisplay(); @@ -306,7 +145,6 @@ Xw_Window::Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay, if (aVisInfo == NULL) { throw Aspect_WindowDefinitionError("Xw_Window, Visual is unavailable"); - return; } XFree (aVisInfo); diff --git a/src/Xw/Xw_Window.hxx b/src/Xw/Xw_Window.hxx index 6b21974f6c..0ba84ddddd 100644 --- a/src/Xw/Xw_Window.hxx +++ b/src/Xw/Xw_Window.hxx @@ -53,8 +53,7 @@ public: const Standard_Integer thePxLeft, const Standard_Integer thePxTop, const Standard_Integer thePxWidth, - const Standard_Integer thePxHeight, - const Aspect_FBConfig theFBConfig = NULL); + const Standard_Integer thePxHeight); //! Creates a wrapper over existing Window handle Standard_EXPORT Xw_Window (const Handle(Aspect_DisplayConnection)& theXDisplay,