Commit fd08a959 by Corentin Wallez Committed by Commit Bot

DisplayGLX: make the Mesa context creation workaround Mesa specific.

BUG=598902 Change-Id: Ib2ca69fb3573dbd0df3dafb4caec0500c7a8aa3b Reviewed-on: https://chromium-review.googlesource.com/347071Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
parent 00ed7a1f
......@@ -18,7 +18,7 @@ struct Optional
mValue(T())
{}
explicit Optional(const T &valueIn)
Optional(const T &valueIn)
: mValid(true),
mValue(valueIn)
{}
......
......@@ -23,6 +23,8 @@ struct Version
GLuint minor;
};
bool operator==(const Version &a, const Version &b);
bool operator!=(const Version &a, const Version &b);
bool operator>=(const Version &a, const Version &b);
bool operator<(const Version &a, const Version &b);
......
......@@ -20,6 +20,16 @@ inline Version::Version(GLuint major_, GLuint minor_)
minor = minor_;
}
inline bool operator==(const Version &a, const Version &b)
{
return a.major == b.major && a.minor == b.minor;
}
inline bool operator!=(const Version &a, const Version &b)
{
return !(a == b);
}
inline bool operator>=(const Version &a, const Version &b)
{
return a.major > b.major || (a.major == b.major && a.minor >= b.minor);
......
......@@ -161,6 +161,9 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
mHasARBCreateContextProfile = mGLX.hasExtension("GLX_ARB_create_context_profile");
mHasEXTCreateContextES2Profile = mGLX.hasExtension("GLX_EXT_create_context_es2_profile");
std::string clientVendor = mGLX.getClientString(GLX_VENDOR);
mIsMesa = clientVendor.find("Mesa") != std::string::npos;
// Choose the swap_control extension to use, if any.
// The EXT version is better as it allows glXSwapInterval to be called per
// window, while we'll potentially need to change the swap interval on each
......@@ -351,13 +354,6 @@ egl::Error DisplayGLX::initialize(egl::Display *display)
syncXCommands();
std::string rendererString =
reinterpret_cast<const char*>(mFunctionsGL->getString(GL_RENDERER));
mIsMesa = rendererString.find("Mesa") != std::string::npos;
std::string version;
getDriverVersion(&version);
return DisplayGL::initialize(display);
}
......@@ -472,74 +468,82 @@ egl::Error DisplayGLX::initializeContext(glx::FBConfig config,
// It is commonly assumed that glXCreateContextAttrib will create a context
// of the highest version possible but it is not specified in the spec and
// is not true on the Mesa drivers. Instead we try to create a context per
// GL version until we succeed, starting from newer version. When the default
// platform is selected, if no desktop context can be created, we fallback to
// an ES context.
// clang-format off
const gl::Version desktopVersionsFrom3_2[] = {
gl::Version(4, 5),
gl::Version(4, 4),
gl::Version(4, 3),
gl::Version(4, 2),
gl::Version(4, 1),
gl::Version(4, 0),
gl::Version(3, 3),
gl::Version(3, 2),
// is not true on the Mesa drivers. On Mesa, Instead we try to create a
// context per GL version until we succeed, starting from newer version.
// On both Mesa and other drivers we try to create a desktop context and fall
// back to ES context.
// The code could be simpler if the Mesa code path was used for all drivers,
// however the cost of failing a context creation can be high (3 milliseconds
// for the NVIDIA driver). The good thing is that failed context creation only
// takes 0.1 milliseconds on Mesa.
struct ContextCreationInfo
{
EGLint displayType;
int profileFlag;
Optional<gl::Version> version;
};
const gl::Version desktopVersionsPre3_2[] = {
gl::Version(3, 1),
gl::Version(3, 0),
gl::Version(2, 0),
gl::Version(1, 5),
gl::Version(1, 4),
gl::Version(1, 3),
gl::Version(1, 2),
gl::Version(1, 1),
gl::Version(1, 0),
// clang-format off
// For regular drivers we try to create a core, compatibility, then ES context.
// Without requiring any specific version (the Optional version is undefined).
const ContextCreationInfo contextsToTry[] = {
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, {} },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, {} },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, {} },
};
const gl::Version esVersionsFrom2_0[] = {
gl::Version(3, 2),
gl::Version(3, 1),
gl::Version(3, 0),
gl::Version(2, 0),
// On Mesa we try to create a core context, except for versions below 3.2
// where it is not applicable. (and fallback to ES as well)
const ContextCreationInfo mesaContextsToTry[] = {
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 5) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 4) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 3) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 2) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 1) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(4, 0) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(3, 3) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { gl::Version(3, 2) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(3, 1) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(3, 0) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(2, 0) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 5) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 4) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 3) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 2) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 1) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, 0, { gl::Version(1, 0) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 2) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 1) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(3, 0) } },
{ EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { gl::Version(2, 0) } },
};
// clang-format on
const ContextCreationInfo *toTry = contextsToTry;
size_t toTryLength = ArraySize(contextsToTry);
if (mIsMesa)
{
toTry = mesaContextsToTry;
toTryLength = ArraySize(mesaContextsToTry);
}
// NOTE: below we return as soon as we're able to create a context so the
// "error" variable is EGL_SUCCESS when returned contrary to the common idiom
// of returning "error" when there is an actual error.
if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE)
for (size_t i = 0; i < toTryLength; ++i)
{
for (auto &version : desktopVersionsFrom3_2)
const ContextCreationInfo &info = toTry[i];
if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE &&
requestedDisplayType != info.displayType)
{
egl::Error error =
createContextAttribs(config, version, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, context);
if (!error.isError())
{
return error;
}
}
for (auto &version : desktopVersionsPre3_2)
{
egl::Error error = createContextAttribs(config, version, 0, context);
if (!error.isError())
{
return error;
}
continue;
}
}
if (requestedDisplayType != EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE)
{
for (auto &version : esVersionsFrom2_0)
egl::Error error = createContextAttribs(config, info.version, info.profileFlag, context);
if (!error.isError())
{
egl::Error error =
createContextAttribs(config, version, GLX_CONTEXT_ES2_PROFILE_BIT_EXT, context);
if (!error.isError())
{
return error;
}
return error;
}
}
......@@ -903,16 +907,20 @@ int DisplayGLX::getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const
}
egl::Error DisplayGLX::createContextAttribs(glx::FBConfig,
gl::Version version,
const Optional<gl::Version> &version,
int profileMask,
glx::Context *context) const
{
std::vector<int> attribs;
attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
attribs.push_back(version.major);
attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
attribs.push_back(version.minor);
if (version.valid())
{
attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
attribs.push_back(version.value().major);
attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
attribs.push_back(version.value().minor);
}
if (profileMask != 0 && mHasARBCreateContextProfile)
{
......
......@@ -12,6 +12,7 @@
#include <string>
#include <vector>
#include "common/Optional.h"
#include "libANGLE/renderer/gl/DisplayGL.h"
#include "libANGLE/renderer/gl/glx/FunctionsGLX.h"
......@@ -104,7 +105,7 @@ class DisplayGLX : public DisplayGL
int getGLXFBConfigAttrib(glx::FBConfig config, int attrib) const;
egl::Error createContextAttribs(glx::FBConfig,
gl::Version version,
const Optional<gl::Version> &version,
int profileMask,
glx::Context *context) const;
......
......@@ -45,6 +45,7 @@ struct FunctionsGLX::GLXFunctionTable
getCurrentDrawablePtr(nullptr),
waitXPtr(nullptr),
waitGLPtr(nullptr),
getClientStringPtr(nullptr),
queryExtensionsStringPtr(nullptr),
getFBConfigsPtr(nullptr),
chooseFBConfigPtr(nullptr),
......@@ -75,6 +76,7 @@ struct FunctionsGLX::GLXFunctionTable
PFNGLXWAITGLPROC waitGLPtr;
// GLX 1.1
PFNGLXGETCLIENTSTRINGPROC getClientStringPtr;
PFNGLXQUERYEXTENSIONSSTRINGPROC queryExtensionsStringPtr;
//GLX 1.3
......@@ -175,6 +177,7 @@ bool FunctionsGLX::initialize(Display *xDisplay, int screen, std::string *errorS
GET_FNPTR_OR_ERROR(&mFnPtrs->waitGLPtr, glXWaitGL);
// GLX 1.1
GET_FNPTR_OR_ERROR(&mFnPtrs->getClientStringPtr, glXGetClientString);
GET_FNPTR_OR_ERROR(&mFnPtrs->queryExtensionsStringPtr, glXQueryExtensionsString);
// Check we have a working GLX
......@@ -314,6 +317,11 @@ void FunctionsGLX::waitGL() const
}
// GLX 1.1
const char *FunctionsGLX::getClientString(int name) const
{
return mFnPtrs->getClientStringPtr(mXDisplay, name);
}
const char *FunctionsGLX::queryExtensionsString() const
{
return mFnPtrs->queryExtensionsStringPtr(mXDisplay, mXScreen);
......
......@@ -49,6 +49,7 @@ class FunctionsGLX
void waitGL() const;
// GLX 1.1
const char *getClientString(int name) const;
const char *queryExtensionsString() const;
// GLX 1.3
......
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