aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools/gpu/gl
diff options
context:
space:
mode:
authorGravatar martina.kollarova <martina.kollarova@intel.com>2016-08-09 01:41:55 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-08-09 01:41:55 -0700
commitfc3ea41cebb8272c3f683f9cf585ff780b18f09b (patch)
tree0cd1e3f26c7707e45fc26576dc15db4fcdec4e32 /tools/gpu/gl
parent643ede69216c073c2dd497c382577dc9fde36b3e (diff)
Check more GLES versions when creating context
Unifies the context creation for GL and GLES into a single loop. BUG=skia:5403 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2201033003 Review-Url: https://codereview.chromium.org/2201033003
Diffstat (limited to 'tools/gpu/gl')
-rw-r--r--tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp166
1 files changed, 76 insertions, 90 deletions
diff --git a/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp b/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp
index a3069dc028..c483fecabe 100644
--- a/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp
+++ b/tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2011 Google Inc.
*
@@ -11,12 +10,15 @@
#include <GL/glx.h>
#include <GL/glu.h>
+#include <vector>
+#include <utility>
+
namespace {
/* Note: Skia requires glx 1.3 or newer */
/* This struct is taken from a mesa demo. Please update as required */
-static const struct { int major, minor; } gl_versions[] = {
+static const std::vector<std::pair<int, int>> gl_versions = {
{1, 0},
{1, 1},
{1, 2},
@@ -34,9 +36,12 @@ static const struct { int major, minor; } gl_versions[] = {
{4, 2},
{4, 3},
{4, 4},
- {0, 0} /* end of list */
};
-#define NUM_GL_VERSIONS SK_ARRAY_COUNT(gl_versions)
+
+static const std::vector<std::pair<int, int>> gles_versions = {
+ {2, 0},
+ {3, 0},
+};
static bool ctxErrorOccurred = false;
static int ctxErrorHandler(Display *dpy, XErrorEvent *ev) {
@@ -51,6 +56,8 @@ public:
private:
void destroyGLContext();
+ static GLXContext CreateBestContext(bool isES, Display* display, GLXFBConfig bestFbc,
+ GLXContext glxSharedContext);
void onPlatformMakeCurrent() const override;
void onPlatformSwapBuffers() const override;
@@ -149,25 +156,10 @@ GLXGLTestContext::GLXGLTestContext(GrGLStandard forcedGpuAPI, GLXGLTestContext*
// Done with the visual info data
XFree(vi);
- // Create the context
-
- // Install an X error handler so the application won't exit if GL 3.0
- // context allocation fails.
- //
- // Note this error handler is global.
- // All display connections in all threads of a process use the same
- // error handler, so be sure to guard against other threads issuing
- // X commands while this code is running.
- ctxErrorOccurred = false;
- int (*oldHandler)(Display*, XErrorEvent*) =
- XSetErrorHandler(&ctxErrorHandler);
-
// Get the default screen's GLX extension list
const char *glxExts = glXQueryExtensionsString(
fDisplay, DefaultScreen(fDisplay)
);
-
-
// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
if (!gluCheckExtension(reinterpret_cast<const GLubyte*>("GLX_ARB_create_context"),
@@ -176,85 +168,17 @@ GLXGLTestContext::GLXGLTestContext(GrGLStandard forcedGpuAPI, GLXGLTestContext*
fContext = glXCreateNewContext(fDisplay, bestFbc, GLX_RGBA_TYPE, 0, True);
}
} else {
- //SkDebugf("Creating context.\n");
- PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribsARB =
- (PFNGLXCREATECONTEXTATTRIBSARBPROC) glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
-
if (kGLES_GrGLStandard == forcedGpuAPI) {
if (gluCheckExtension(
reinterpret_cast<const GLubyte*>("GLX_EXT_create_context_es2_profile"),
reinterpret_cast<const GLubyte*>(glxExts))) {
- const int context_attribs_gles[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
- GLX_CONTEXT_MINOR_VERSION_ARB, 0,
- GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_ES2_PROFILE_BIT_EXT,
- None
- };
- fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
- context_attribs_gles);
+ fContext = CreateBestContext(true, fDisplay, bestFbc, glxShareContext);
}
} else {
- // Well, unfortunately GLX will not just give us the highest context so instead we have
- // to do this nastiness
- for (i = NUM_GL_VERSIONS - 2; i > 0 ; i--) {
- /* don't bother below GL 3.0 */
- if (gl_versions[i].major < 3) {
- break;
- }
- // On Nvidia GPUs, to use Nv Path rendering we need a compatibility profile for the
- // time being.
- // TODO when Nvidia implements NVPR on Core profiles, we should start requesting
- // core here
- // Warning: This array should not be set to static. The
- // glXCreateContextAttribsARB call writes to it upon failure and
- // the next call would fail too.
- const int context_attribs_gl[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, gl_versions[i].major,
- GLX_CONTEXT_MINOR_VERSION_ARB, gl_versions[i].minor,
- GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB,
- None
- };
- fContext =
- glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
- context_attribs_gl);
-
- // Sync to ensure any errors generated are processed.
- XSync(fDisplay, False);
-
- if (!ctxErrorOccurred && fContext) {
- break;
- }
- // try again
- ctxErrorOccurred = false;
- }
-
- // Couldn't create GL 3.0 context.
- // Fall back to old-style 2.x context.
- // When a context version below 3.0 is requested,
- // implementations will return the newest context version
- // compatible with OpenGL versions less than version 3.0.
- if (ctxErrorOccurred || !fContext) {
- const int context_attribs_gl_fallback[] = {
- GLX_CONTEXT_MAJOR_VERSION_ARB, 1,
- GLX_CONTEXT_MINOR_VERSION_ARB, 0,
- None
- };
-
- ctxErrorOccurred = false;
-
- fContext = glXCreateContextAttribsARB(fDisplay, bestFbc, glxShareContext, True,
- context_attribs_gl_fallback);
- }
+ fContext = CreateBestContext(false, fDisplay, bestFbc, glxShareContext);
}
}
-
- // Sync to ensure any errors generated are processed.
- XSync(fDisplay, False);
-
- // Restore the original error handler
- XSetErrorHandler(oldHandler);
-
- if (ctxErrorOccurred || !fContext) {
+ if (!fContext) {
SkDebugf("Failed to create an OpenGL context.\n");
this->destroyGLContext();
return;
@@ -320,6 +244,68 @@ void GLXGLTestContext::destroyGLContext() {
}
}
+/* Create a context with the highest possible version.
+ *
+ * Disable Xlib errors for the duration of this function (by default they abort
+ * the program) and try to get a context starting from the highest version
+ * number - there is no way to just directly ask what the highest supported
+ * version is.
+ *
+ * Returns the correct context or NULL on failure.
+ */
+GLXContext GLXGLTestContext::CreateBestContext(bool isES, Display* display, GLXFBConfig bestFbc,
+ GLXContext glxShareContext) {
+ auto glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)
+ glXGetProcAddressARB((GrGLubyte*)"glXCreateContextAttribsARB");
+ if (!glXCreateContextAttribsARB) {
+ SkDebugf("Failed to get address of glXCreateContextAttribsARB");
+ return nullptr;
+ }
+ GLXContext context = nullptr;
+ // Install Xlib error handler that will set ctxErrorOccurred.
+ // WARNING: It is global for all threads.
+ ctxErrorOccurred = false;
+ int (*oldHandler)(Display*, XErrorEvent*) = XSetErrorHandler(&ctxErrorHandler);
+
+ auto versions = isES ? gles_versions : gl_versions;
+ // Well, unfortunately GLX will not just give us the highest context so
+ // instead we have to do this nastiness
+ for (int i = versions.size() - 1; i >= 0 ; i--) {
+ // WARNING: Don't try to optimize this and make this array static. The
+ // glXCreateContextAttribsARB call writes to it upon failure and the
+ // next call would fail too.
+ std::vector<int> flags = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, versions[i].first,
+ GLX_CONTEXT_MINOR_VERSION_ARB, versions[i].second,
+ };
+ if (isES) {
+ flags.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
+ // the ES2 flag should work even for higher versions
+ flags.push_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT);
+ } else if (versions[i].first > 2) {
+ flags.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
+ // TODO When Nvidia implements NVPR on Core profiles, we should start
+ // requesting core here - currently Nv Path rendering on Nvidia
+ // requires a compatibility profile.
+ flags.push_back(GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB);
+ }
+ flags.push_back(0);
+ context = glXCreateContextAttribsARB(display, bestFbc, glxShareContext, true,
+ &flags[0]);
+ // Sync to ensure any errors generated are processed.
+ XSync(display, False);
+
+ if (!ctxErrorOccurred && context) {
+ break;
+ }
+ // try again
+ ctxErrorOccurred = false;
+ }
+ // Restore the original error handler.
+ XSetErrorHandler(oldHandler);
+ return context;
+}
+
void GLXGLTestContext::onPlatformMakeCurrent() const {
if (!glXMakeCurrent(fDisplay, fGlxPixmap, fContext)) {
SkDebugf("Could not set the context.\n");