Commit 50ff85e5 by Corentin Wallez

DisplayGLX: add support for complete lack of extensions

We thought we could rely on GLX_create_context_attrib being present but this is not the case with VM drivers. Instead we fallback to creating contexts with glXCreateContext that doesn't offer control on which version and profile the context will have. Likewise we may not always be able to use the multisample but we can safely assume that the number of samples and sample buffers are zero in this case. BUG=angleproject:1206 Change-Id: I888c69e609764994baf86386c9683b3edeb320f7 Reviewed-on: https://chromium-review.googlesource.com/312230Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Tested-by: 's avatarCorentin Wallez <cwallez@chromium.org>
parent a37c6137
...@@ -62,6 +62,8 @@ DisplayGLX::DisplayGLX() ...@@ -62,6 +62,8 @@ DisplayGLX::DisplayGLX()
mDummyPbuffer(0), mDummyPbuffer(0),
mUsesNewXDisplay(false), mUsesNewXDisplay(false),
mIsMesa(false), mIsMesa(false),
mHasMultisample(false),
mHasARBCreateContext(false),
mSwapControl(SwapControl::Absent), mSwapControl(SwapControl::Absent),
mMinSwapInterval(0), mMinSwapInterval(0),
mMaxSwapInterval(0), mMaxSwapInterval(0),
...@@ -98,20 +100,8 @@ egl::Error DisplayGLX::initialize(egl::Display *display) ...@@ -98,20 +100,8 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
return egl::Error(EGL_NOT_INITIALIZED, glxInitError.c_str()); return egl::Error(EGL_NOT_INITIALIZED, glxInitError.c_str());
} }
// Check we have the needed extensions mHasMultisample = mGLX.minorVersion > 3 || mGLX.hasExtension("GLX_ARB_multisample");
{ mHasARBCreateContext = mGLX.hasExtension("GLX_ARB_create_context");
if (mGLX.minorVersion == 3 && !mGLX.hasExtension("GLX_ARB_multisample"))
{
return egl::Error(EGL_NOT_INITIALIZED, "GLX doesn't support ARB_multisample.");
}
// Require ARB_create_context which has been supported since Mesa 9 unconditionnaly
// and is present in Mesa 8 in an almost always on compile flag. Also assume proprietary
// drivers have it.
if (!mGLX.hasExtension("GLX_ARB_create_context"))
{
return egl::Error(EGL_NOT_INITIALIZED, "GLX doesn't support ARB_create_context.");
}
}
// Choose the swap_control extension to use, if any. // Choose the swap_control extension to use, if any.
// The EXT version is better as it allows glXSwapInterval to be called per // The EXT version is better as it allows glXSwapInterval to be called per
...@@ -188,7 +178,27 @@ egl::Error DisplayGLX::initialize(egl::Display *display) ...@@ -188,7 +178,27 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
XFree(candidates); XFree(candidates);
} }
mContext = initializeContext(mContextConfig, display->getAttributeMap()); if (mHasARBCreateContext)
{
mContext = initializeContext(mContextConfig, display->getAttributeMap());
}
else
{
XVisualInfo visualTemplate;
visualTemplate.visualid = getGLXFBConfigAttrib(mContextConfig, GLX_VISUAL_ID);
int numVisuals = 0;
XVisualInfo *visuals = XGetVisualInfo(xDisplay, VisualIDMask, &visualTemplate, &numVisuals);
if (numVisuals <= 0)
{
return egl::Error(EGL_NOT_INITIALIZED,
"Could not get the visual info from the fb config");
}
ASSERT(numVisuals == 1);
mContext = mGLX.createContext(&visuals[0], nullptr, true);
XFree(visuals);
}
if (!mContext) if (!mContext)
{ {
return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context."); return egl::Error(EGL_NOT_INITIALIZED, "Could not create GL context.");
...@@ -383,8 +393,6 @@ egl::ConfigSet DisplayGLX::generateConfigs() const ...@@ -383,8 +393,6 @@ egl::ConfigSet DisplayGLX::generateConfigs() const
egl::ConfigSet configs; egl::ConfigSet configs;
configIdToGLXConfig.clear(); configIdToGLXConfig.clear();
bool hasSwapControl = mGLX.hasExtension("GLX_EXT_swap_control");
const gl::Version &maxVersion = getMaxSupportedESVersion(); const gl::Version &maxVersion = getMaxSupportedESVersion();
ASSERT(maxVersion >= gl::Version(2, 0)); ASSERT(maxVersion >= gl::Version(2, 0));
bool supportsES3 = maxVersion >= gl::Version(3, 0); bool supportsES3 = maxVersion >= gl::Version(3, 0);
...@@ -397,8 +405,9 @@ egl::ConfigSet DisplayGLX::generateConfigs() const ...@@ -397,8 +405,9 @@ egl::ConfigSet DisplayGLX::generateConfigs() const
int contextDepthSize = getGLXFBConfigAttrib(mContextConfig, GLX_DEPTH_SIZE); int contextDepthSize = getGLXFBConfigAttrib(mContextConfig, GLX_DEPTH_SIZE);
int contextStencilSize = getGLXFBConfigAttrib(mContextConfig, GLX_STENCIL_SIZE); int contextStencilSize = getGLXFBConfigAttrib(mContextConfig, GLX_STENCIL_SIZE);
int contextSamples = getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLES); int contextSamples = mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLES) : 0;
int contextSampleBuffers = getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLE_BUFFERS); int contextSampleBuffers =
mHasMultisample ? getGLXFBConfigAttrib(mContextConfig, GLX_SAMPLE_BUFFERS) : 0;
int contextAccumRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_RED_SIZE); int contextAccumRedSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_RED_SIZE);
int contextAccumGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_GREEN_SIZE); int contextAccumGreenSize = getGLXFBConfigAttrib(mContextConfig, GLX_ACCUM_GREEN_SIZE);
...@@ -459,8 +468,9 @@ egl::ConfigSet DisplayGLX::generateConfigs() const ...@@ -459,8 +468,9 @@ egl::ConfigSet DisplayGLX::generateConfigs() const
config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize; config.bufferSize = config.redSize + config.greenSize + config.blueSize + config.alphaSize;
// Multisample and accumulation buffers // Multisample and accumulation buffers
int samples = getGLXFBConfigAttrib(glxConfig, GLX_SAMPLES); int samples = mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLES) : 0;
int sampleBuffers = getGLXFBConfigAttrib(glxConfig, GLX_SAMPLE_BUFFERS); int sampleBuffers =
mHasMultisample ? getGLXFBConfigAttrib(glxConfig, GLX_SAMPLE_BUFFERS) : 0;
int accumRedSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_RED_SIZE); int accumRedSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_RED_SIZE);
int accumGreenSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_GREEN_SIZE); int accumGreenSize = getGLXFBConfigAttrib(glxConfig, GLX_ACCUM_GREEN_SIZE);
......
...@@ -102,6 +102,8 @@ class DisplayGLX : public DisplayGL ...@@ -102,6 +102,8 @@ class DisplayGLX : public DisplayGL
bool mUsesNewXDisplay; bool mUsesNewXDisplay;
bool mIsMesa; bool mIsMesa;
bool mHasMultisample;
bool mHasARBCreateContext;
enum class SwapControl enum class SwapControl
{ {
......
...@@ -35,33 +35,35 @@ static bool GetProc(PFNGETPROCPROC getProc, T *member, const char *name) ...@@ -35,33 +35,35 @@ static bool GetProc(PFNGETPROCPROC getProc, T *member, const char *name)
struct FunctionsGLX::GLXFunctionTable struct FunctionsGLX::GLXFunctionTable
{ {
GLXFunctionTable() GLXFunctionTable()
: destroyContextPtr(nullptr), : createContextPtr(nullptr),
makeCurrentPtr(nullptr), destroyContextPtr(nullptr),
swapBuffersPtr(nullptr), makeCurrentPtr(nullptr),
queryExtensionPtr(nullptr), swapBuffersPtr(nullptr),
queryVersionPtr(nullptr), queryExtensionPtr(nullptr),
getCurrentContextPtr(nullptr), queryVersionPtr(nullptr),
getCurrentDrawablePtr(nullptr), getCurrentContextPtr(nullptr),
waitXPtr(nullptr), getCurrentDrawablePtr(nullptr),
waitGLPtr(nullptr), waitXPtr(nullptr),
queryExtensionsStringPtr(nullptr), waitGLPtr(nullptr),
getFBConfigsPtr(nullptr), queryExtensionsStringPtr(nullptr),
chooseFBConfigPtr(nullptr), getFBConfigsPtr(nullptr),
getFBConfigAttribPtr(nullptr), chooseFBConfigPtr(nullptr),
getVisualFromFBConfigPtr(nullptr), getFBConfigAttribPtr(nullptr),
createWindowPtr(nullptr), getVisualFromFBConfigPtr(nullptr),
destroyWindowPtr(nullptr), createWindowPtr(nullptr),
createPbufferPtr(nullptr), destroyWindowPtr(nullptr),
destroyPbufferPtr(nullptr), createPbufferPtr(nullptr),
queryDrawablePtr(nullptr), destroyPbufferPtr(nullptr),
createContextAttribsARBPtr(nullptr), queryDrawablePtr(nullptr),
swapIntervalEXTPtr(nullptr), createContextAttribsARBPtr(nullptr),
swapIntervalMESAPtr(nullptr), swapIntervalEXTPtr(nullptr),
swapIntervalSGIPtr(nullptr) swapIntervalMESAPtr(nullptr),
swapIntervalSGIPtr(nullptr)
{ {
} }
// GLX 1.0 // GLX 1.0
PFNGLXCREATECONTEXTPROC createContextPtr;
PFNGLXDESTROYCONTEXTPROC destroyContextPtr; PFNGLXDESTROYCONTEXTPROC destroyContextPtr;
PFNGLXMAKECURRENTPROC makeCurrentPtr; PFNGLXMAKECURRENTPROC makeCurrentPtr;
PFNGLXSWAPBUFFERSPROC swapBuffersPtr; PFNGLXSWAPBUFFERSPROC swapBuffersPtr;
...@@ -161,6 +163,7 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS ...@@ -161,6 +163,7 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS
#endif #endif
// GLX 1.0 // GLX 1.0
GET_FNPTR_OR_ERROR(&mFnPtrs->createContextPtr, glXCreateContext);
GET_FNPTR_OR_ERROR(&mFnPtrs->destroyContextPtr, glXDestroyContext); GET_FNPTR_OR_ERROR(&mFnPtrs->destroyContextPtr, glXDestroyContext);
GET_FNPTR_OR_ERROR(&mFnPtrs->makeCurrentPtr, glXMakeCurrent); GET_FNPTR_OR_ERROR(&mFnPtrs->makeCurrentPtr, glXMakeCurrent);
GET_FNPTR_OR_ERROR(&mFnPtrs->swapBuffersPtr, glXSwapBuffers); GET_FNPTR_OR_ERROR(&mFnPtrs->swapBuffersPtr, glXSwapBuffers);
...@@ -263,6 +266,12 @@ int FunctionsGLX::getScreen() const ...@@ -263,6 +266,12 @@ int FunctionsGLX::getScreen() const
// GLX functions // GLX functions
// GLX 1.0 // GLX 1.0
glx::Context FunctionsGLX::createContext(XVisualInfo *visual, glx::Context share, bool direct) const
{
GLXContext shareCtx = reinterpret_cast<GLXContext>(share);
GLXContext context = mFnPtrs->createContextPtr(mXDisplay, visual, shareCtx, direct);
return reinterpret_cast<glx::Context>(context);
}
void FunctionsGLX::destroyContext(glx::Context context) const void FunctionsGLX::destroyContext(glx::Context context) const
{ {
GLXContext ctx = reinterpret_cast<GLXContext>(context); GLXContext ctx = reinterpret_cast<GLXContext>(context);
......
...@@ -37,6 +37,7 @@ class FunctionsGLX ...@@ -37,6 +37,7 @@ class FunctionsGLX
PFNGETPROCPROC getProc; PFNGETPROCPROC getProc;
// GLX 1.0 // GLX 1.0
glx::Context createContext(XVisualInfo *visual, glx::Context share, bool direct) const;
void destroyContext(glx::Context context) const; void destroyContext(glx::Context context) const;
Bool makeCurrent(glx::Drawable drawable, glx::Context context) const; Bool makeCurrent(glx::Drawable drawable, glx::Context context) const;
void swapBuffers(glx::Drawable drawable) const; void swapBuffers(glx::Drawable drawable) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment