1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-03 17:56:21 +03:00

0032219: Visualization, TKService - drop dependency from OpenGL

Visual selection has been moved out from Xw_Window constructor to OpenGl_GraphicDriver::InitContext().
Default Visual is now stored within Aspect_DisplayConnection.
This commit is contained in:
kgv 2021-03-10 13:50:45 +03:00 committed by bugmaster
parent 442850c032
commit 3ae8c60b87
7 changed files with 156 additions and 180 deletions

View File

@ -16,7 +16,6 @@
#include <Aspect_DisplayConnectionDefinitionError.hxx>
#include <OSD_Environment.hxx>
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 :

View File

@ -22,6 +22,7 @@
#if !defined(_WIN32) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX)) && !defined(__ANDROID__) && !defined(__QNX__) && !defined(__EMSCRIPTEN__)
#include <InterfaceGraphic.hxx>
#include <Aspect_FBConfig.hxx>
#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<Aspect_XAtom, Atom> myAtoms;
TCollection_AsciiString myDisplayName;
Standard_Boolean myIsOwnDisplay;

View File

@ -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 <X11/Xlib.h> // XOpenDisplay()
#include <GL/glx.h>
#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 :

View File

@ -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

View File

@ -3,7 +3,6 @@ TKMath
CSF_user32
CSF_advapi32
CSF_OpenVR
CSF_OpenGlLibs
CSF_advapi32
CSF_user32
CSF_XwLibs

View File

@ -24,44 +24,6 @@
//#include <X11/XF86keysym.h>
#if defined(HAVE_EGL) || defined(HAVE_GLES2)
#include <EGL/egl.h>
#ifndef EGL_OPENGL_ES3_BIT
#define EGL_OPENGL_ES3_BIT 0x00000040
#endif
#else
#include <GL/glx.h>
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);

View File

@ -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,