From 1e627276c55f1627bef3afa0051685d99443ab1f Mon Sep 17 00:00:00 2001 From: "commit-bot@chromium.org" Date: Fri, 6 Sep 2013 18:57:14 +0000 Subject: Fallback to GLES context when GL context setup fails at any stage. R=robertphillips@google.com Author: bsalomon@google.com Review URL: https://chromiumcodereview.appspot.com/23902015 git-svn-id: http://skia.googlecode.com/svn/trunk@11135 2bbb7eff-a529-9590-31e7-b0007b416f81 --- src/gpu/gl/android/SkNativeGLContext_android.cpp | 142 ++++++++++++++--------- 1 file changed, 84 insertions(+), 58 deletions(-) (limited to 'src/gpu/gl/android') diff --git a/src/gpu/gl/android/SkNativeGLContext_android.cpp b/src/gpu/gl/android/SkNativeGLContext_android.cpp index 4b8612c521..8811ddae9d 100644 --- a/src/gpu/gl/android/SkNativeGLContext_android.cpp +++ b/src/gpu/gl/android/SkNativeGLContext_android.cpp @@ -61,74 +61,100 @@ const GrGLInterface* SkNativeGLContext::createGLContext() { EGL_NONE }; - // Try first for OpenGL, then fall back to OpenGL ES. - EGLint renderableTypeBit = EGL_OPENGL_BIT; - const EGLint* contextAttribs = kEGLContextAttribsForOpenGL; - EGLBoolean apiBound = eglBindAPI(EGL_OPENGL_API); - - if (!apiBound) { - apiBound = eglBindAPI(EGL_OPENGL_ES_API); - renderableTypeBit = EGL_OPENGL_ES2_BIT; - contextAttribs = kEGLContextAttribsForOpenGLES; - } + static const struct { + const EGLint* fContextAttribs; + EGLenum fAPI; + EGLint fRenderableTypeBit; + GrGLBinding fBinding; + } kAPIs[] = { + { // OpenGL + kEGLContextAttribsForOpenGL, + EGL_OPENGL_API, + EGL_OPENGL_BIT, + kDesktop_GrGLBinding + }, + { // OpenGL ES. This seems to work for both ES2 and 3 (when available). + kEGLContextAttribsForOpenGLES, + EGL_OPENGL_ES_API, + EGL_OPENGL_ES2_BIT, + kES_GrGLBinding + }, + }; - if (!apiBound) { - return NULL; - } + const GrGLInterface* interface = NULL; - fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); + for (size_t api = 0; NULL == interface && api < SK_ARRAY_COUNT(kAPIs); ++api) { + fDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); - EGLint majorVersion; - EGLint minorVersion; - eglInitialize(fDisplay, &majorVersion, &minorVersion); + EGLint majorVersion; + EGLint minorVersion; + eglInitialize(fDisplay, &majorVersion, &minorVersion); - EGLint numConfigs; - const EGLint configAttribs[] = { - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_RENDERABLE_TYPE, renderableTypeBit, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_NONE - }; +#if 0 + SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR)); + SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS)); + SkDebugf("VERSION: %s\n", eglQueryString(fDisplay, EGL_VERSION)); + SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS)); +#endif - EGLConfig surfaceConfig; - if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { - SkDebugf("eglChooseConfig failed.\n"); - return NULL; - } + if (!eglBindAPI(kAPIs[api].fAPI)) { + continue; + } - fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, contextAttribs); - if (EGL_NO_CONTEXT == fContext) { - SkDebugf("eglCreateContext failed.\n"); - return NULL; - } + EGLint numConfigs; + const EGLint configAttribs[] = { + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_NONE + }; + + EGLConfig surfaceConfig; + if (!eglChooseConfig(fDisplay, configAttribs, &surfaceConfig, 1, &numConfigs)) { + SkDebugf("eglChooseConfig failed. EGL Error: 0x%08x\n", eglGetError()); + continue; + } - static const EGLint kSurfaceAttribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; + fContext = eglCreateContext(fDisplay, surfaceConfig, NULL, kAPIs[api].fContextAttribs); + if (EGL_NO_CONTEXT == fContext) { + SkDebugf("eglCreateContext failed. EGL Error: 0x%08x\n", eglGetError()); + continue; + } - fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs); - if (EGL_NO_SURFACE == fSurface) { - SkDebugf("eglCreatePbufferSurface failed.\n"); - this->destroyGLContext(); - return NULL; - } + static const EGLint kSurfaceAttribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + + fSurface = eglCreatePbufferSurface(fDisplay, surfaceConfig, kSurfaceAttribs); + if (EGL_NO_SURFACE == fSurface) { + SkDebugf("eglCreatePbufferSurface failed. EGL Error: 0x%08x\n", eglGetError()); + this->destroyGLContext(); + continue; + } - if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { - SkDebugf("eglMakeCurrent failed.\n"); - this->destroyGLContext(); - return NULL; - } + if (!eglMakeCurrent(fDisplay, fSurface, fSurface, fContext)) { + SkDebugf("eglMakeCurrent failed. EGL Error: 0x%08x\n", eglGetError()); + this->destroyGLContext(); + continue; + } - const GrGLInterface* interface = GrGLCreateNativeInterface(); - if (!interface) { - SkDebugf("Failed to create gl interface.\n"); - this->destroyGLContext(); - return NULL; + interface = GrGLCreateNativeInterface(); + if (NULL == interface) { + SkDebugf("Failed to create gl interface.\n"); + this->destroyGLContext(); + continue; + } + + if (!interface->validate(kAPIs[api].fBinding)) { + interface->unref(); + interface = NULL; + this->destroyGLContext(); + } } return interface; -- cgit v1.2.3