VisualBench: Use first succeeding EGL API
authorkkinnunen <kkinnunen@nvidia.com>
Thu, 14 Jan 2016 17:12:01 +0000 (09:12 -0800)
committerCommit bot <commit-bot@chromium.org>
Thu, 14 Jan 2016 17:12:01 +0000 (09:12 -0800)
Fix initialization of the app window by
using the first EGL context that succeeds, not the last one.

Fixes the window creation in some cases on devices that support
OpenGL and OpenGL ES.

Also check EGL call results.

BUG=skia:4733
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1582313002

Review URL: https://codereview.chromium.org/1582313002

platform_tools/android/apps/visualbench/src/main/jni/SkOSWindow_AndroidNative.cpp

index a35742b..df1ca96 100644 (file)
@@ -50,15 +50,21 @@ bool SkOSWindow::attach(SkBackEndTypes attachType,
         },
     };
 
-    size_t apiLimit = SK_ARRAY_COUNT(kAPIs);
-
-    for (size_t api = 0; api < apiLimit; ++api) {
-        EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+    if (EGL_NO_DISPLAY == display) {
+        return false;
+    }
 
-        EGLint majorVersion;
-        EGLint minorVersion;
-        eglInitialize(display, &majorVersion, &minorVersion);
+    EGLint majorVersion;
+    EGLint minorVersion;
+    if (!eglInitialize(display, &majorVersion, &minorVersion)) {
+        return false;
+    }
 
+    for (size_t api = 0; api < SK_ARRAY_COUNT(kAPIs); ++api) {
+        if (!eglBindAPI(kAPIs[api].fAPI)) {
+            continue;
+        }
 #if 0
         SkDebugf("VENDOR: %s\n", eglQueryString(fDisplay, EGL_VENDOR));
         SkDebugf("APIS: %s\n", eglQueryString(fDisplay, EGL_CLIENT_APIS));
@@ -66,10 +72,6 @@ bool SkOSWindow::attach(SkBackEndTypes attachType,
         SkDebugf("EXTENSIONS %s\n", eglQueryString(fDisplay, EGL_EXTENSIONS));
 #endif
 
-        if (!eglBindAPI(kAPIs[api].fAPI)) {
-            continue;
-        }
-
         const EGLint configAttribs[] = {
             EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
             EGL_RENDERABLE_TYPE, kAPIs[api].fRenderableTypeBit,
@@ -89,31 +91,44 @@ bool SkOSWindow::attach(SkBackEndTypes attachType,
         /* Here, the application chooses the configuration it desires. In this
          * sample, we have a very simplified selection process, where we pick
          * the first EGLConfig that matches our criteria */
-        eglChooseConfig(display, configAttribs, &config, 1, &numConfigs);
+        if (!eglChooseConfig(display, configAttribs, &config, 1, &numConfigs) ||
+            numConfigs != 1) {
+            continue;
+        }
 
         /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is
          * guaranteed to be accepted by ANativeWindow_setBuffersGeometry().
          * As soon as we picked a EGLConfig, we can safely reconfigure the
          * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */
-        eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format);
+        if (!eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format)) {
+            continue;
+        }
 
         ANativeWindow_setBuffersGeometry(fNativeWindow, 0, 0, format);
 
         surface = eglCreateWindowSurface(display, config, fNativeWindow, nullptr);
+        if (EGL_NO_SURFACE == surface) {
+            SkDebugf("eglCreateWindowSurface failed.  EGL Error: 0x%08x\n", eglGetError());
+            continue;
+        }
         context = eglCreateContext(display, config, nullptr, kAPIs[api].fContextAttribs);
         if (EGL_NO_CONTEXT == context) {
             SkDebugf("eglCreateContext failed.  EGL Error: 0x%08x\n", eglGetError());
+            eglDestroySurface(display, surface);
             continue;
         }
 
         if (!eglMakeCurrent(display, surface, surface, context)) {
             SkDebugf("eglMakeCurrent failed.  EGL Error: 0x%08x\n", eglGetError());
+            eglDestroyContext(display, context);
+            eglDestroySurface(display, surface);
             continue;
         }
 
         fWindow.fDisplay = display;
         fWindow.fContext = context;
         fWindow.fSurface = surface;
+        break;
     }
 
     if (fWindow.fDisplay && fWindow.fContext && fWindow.fSurface) {