Fix GLES context version selection

Explicitly selects an ES 2.0 config first, then an ES 1.x config,
before attempting the fallback path for the emulator.

Bug: 10820214
Change-Id: Ia8cc084c02a0e3de910def024da8a08d02bbd89d
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 46f628d..c36fcde 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -30,9 +30,25 @@
 // ---------------------------------------------------------------------------
 
 RenderEngine* RenderEngine::create(EGLDisplay display, EGLConfig config) {
+    EGLint renderableType = 0;
+    EGLint contextClientVersion = 0;
+
+    // query the renderable type, setting the EGL_CONTEXT_CLIENT_VERSION accordingly
+    if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, &renderableType)) {
+        LOG_ALWAYS_FATAL("can't query EGLConfig RENDERABLE_TYPE");
+    }
+
+    if (renderableType & EGL_OPENGL_ES2_BIT) {
+        contextClientVersion = 2;
+    } else if (renderableType & EGL_OPENGL_ES_BIT) {
+        contextClientVersion = 1;
+    } else {
+        LOG_ALWAYS_FATAL("no supported EGL_RENDERABLE_TYPEs");
+    }
+
     // Also create our EGLContext
     EGLint contextAttributes[] = {
-            EGL_CONTEXT_CLIENT_VERSION, 2,      // MUST be first
+            EGL_CONTEXT_CLIENT_VERSION, contextClientVersion,      // MUST be first
 #ifdef EGL_IMG_context_priority
 #ifdef HAS_CONTEXT_PRIORITY
 #warning "using EGL_IMG_context_priority"
@@ -41,13 +57,7 @@
 #endif
             EGL_NONE, EGL_NONE
     };
-
     EGLContext ctxt = eglCreateContext(display, config, NULL, contextAttributes);
-    if (ctxt == EGL_NO_CONTEXT) {
-        // maybe ES 2.x is not supported
-        ALOGW("can't create an ES 2.x context, trying 1.x");
-        ctxt = eglCreateContext(display, config, NULL, contextAttributes + 2);
-    }
 
     // if can't create a GL context, we can only abort.
     LOG_ALWAYS_FATAL_IF(ctxt==EGL_NO_CONTEXT, "EGLContext creation failed");
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index def4618..02aef2b 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -366,43 +366,40 @@
     operator EGLint const* () const { return &mList.keyAt(0).v; }
 };
 
-EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId) {
+EGLConfig SurfaceFlinger::selectEGLConfig(EGLDisplay display, EGLint nativeVisualId,
+    EGLint renderableType) {
     // select our EGLConfig. It must support EGL_RECORDABLE_ANDROID if
     // it is to be used with WIFI displays
     EGLConfig config;
     EGLint dummy;
     status_t err;
+    EGLint wantedAttribute;
+    EGLint wantedAttributeValue;
 
     EGLAttributeVector attribs;
-    // TODO: enable ES2
-    //attribs[EGL_RENDERABLE_TYPE]            = EGL_OPENGL_ES_BIT | EGL_OPENGL_ES2_BIT;
-    attribs[EGL_SURFACE_TYPE]               = EGL_WINDOW_BIT | EGL_PBUFFER_BIT;
-    attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
-    attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
-    attribs[EGL_RED_SIZE]                   = 8;
-    attribs[EGL_GREEN_SIZE]                 = 8;
-    attribs[EGL_BLUE_SIZE]                  = 8;
+    if (renderableType) {
+        attribs[EGL_RENDERABLE_TYPE]            = renderableType;
+        attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
+        attribs[EGL_SURFACE_TYPE]               = EGL_WINDOW_BIT|EGL_PBUFFER_BIT;
+        attribs[EGL_FRAMEBUFFER_TARGET_ANDROID] = EGL_TRUE;
+        attribs[EGL_RED_SIZE]                   = 8;
+        attribs[EGL_GREEN_SIZE]                 = 8;
+        attribs[EGL_BLUE_SIZE]                  = 8;
+        wantedAttribute                         = EGL_NONE;
+        wantedAttributeValue                    = EGL_NONE;
 
-    err = selectConfigForAttribute(display, attribs, EGL_NONE, EGL_NONE, &config);
+    } else {
+        // if no renderable type specified, fallback to a simplified query
+        attribs[EGL_RECORDABLE_ANDROID]         = EGL_TRUE;
+        wantedAttribute                         = EGL_NATIVE_VISUAL_ID;
+        wantedAttributeValue                    = nativeVisualId;
+    }
+
+    err = selectConfigForAttribute(display, attribs, wantedAttribute,
+        wantedAttributeValue, &config);
     if (!err)
         goto success;
 
-    // this didn't work, probably because we're on the emulator...
-    // try a simplified query
-    ALOGW("no suitable EGLConfig found, trying a simpler query");
-    attribs.remove(EGL_RENDERABLE_TYPE);
-    attribs.remove(EGL_FRAMEBUFFER_TARGET_ANDROID);
-    attribs.remove(EGL_RECORDABLE_ANDROID);
-    attribs.remove(EGL_RED_SIZE);
-    attribs.remove(EGL_GREEN_SIZE);
-    attribs.remove(EGL_BLUE_SIZE);
-    err = selectConfigForAttribute(display, attribs,
-            EGL_NATIVE_VISUAL_ID, nativeVisualId, &config);
-    if (!err)
-        goto success;
-
-    // this EGL is too lame for Android
-    LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
     return 0;
 
 success:
@@ -427,8 +424,25 @@
     mHwc = new HWComposer(this,
             *static_cast<HWComposer::EventHandler *>(this));
 
-    // initialize the config and context (can't fail)
-    mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID());
+    // First try to get an ES2 config
+    mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES2_BIT);
+
+    if (!mEGLConfig) {
+        // If ES2 fails, try ES1
+        mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), EGL_OPENGL_ES_BIT);
+    }
+
+    if (!mEGLConfig) {
+        // still didn't work, probably because we're on the emulator...
+        // try a simplified query
+        ALOGW("no suitable EGLConfig found, trying a simpler query");
+        mEGLConfig = selectEGLConfig(mEGLDisplay, mHwc->getVisualID(), 0);
+    }
+
+    if (!mEGLConfig) {
+        // this EGL is too lame for android
+        LOG_ALWAYS_FATAL("no suitable EGLConfig found, giving up");
+    }
 
     // print some debugging info
     EGLint r,g,b,a;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 347e3e3..0cfc600 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -317,7 +317,8 @@
      */
     static status_t selectConfigForAttribute(EGLDisplay dpy,
         EGLint const* attrs, EGLint attribute, EGLint value, EGLConfig* outConfig);
-    static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId);
+    static EGLConfig selectEGLConfig(EGLDisplay disp, EGLint visualId,
+		EGLint renderableType);
     size_t getMaxTextureSize() const;
     size_t getMaxViewportDims() const;