Fix ES2 composition on some devices

- turns out fragment shaders don't have default precision by default
- GLES 1.x extensions that became core in GLES 2.0 don't always work
  as extensions in GLES 2.0 (!)

Bug: 8679321
Change-Id: I5a4a93e158247910399325a965af5d2e3bbece9b
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
index 428cdb8..19f17df 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.cpp
@@ -15,12 +15,12 @@
  */
 
 #include <GLES/gl.h>
+#include <GLES/glext.h>
 
 #include <utils/String8.h>
 #include <cutils/compiler.h>
 
 #include "GLES11RenderEngine.h"
-#include "GLExtensions.h"
 #include "Mesh.h"
 
 // ---------------------------------------------------------------------------
@@ -183,6 +183,31 @@
     glDisable(GL_BLEND);
 }
 
+void GLES11RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
+        uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+    GLuint tname, name;
+    // turn our EGLImage into a texture
+    glGenTextures(1, &tname);
+    glBindTexture(GL_TEXTURE_2D, tname);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+    // create a Framebuffer Object to render into
+    glGenFramebuffersOES(1, &name);
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
+    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
+            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
+
+    *status = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+    *texName = tname;
+    *fbName = name;
+}
+
+void GLES11RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
+    glDeleteFramebuffersOES(1, &fbName);
+    glDeleteTextures(1, &texName);
+}
+
 void GLES11RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
     glColor4f(r, g, b, a);
     glDisable(GL_TEXTURE_EXTERNAL_OES);
@@ -219,14 +244,13 @@
 }
 
 void GLES11RenderEngine::dump(String8& result) {
-    const GLExtensions& extensions(GLExtensions::getInstance());
-    result.appendFormat("GLES: %s, %s, %s\n",
-            extensions.getVendor(),
-            extensions.getRenderer(),
-            extensions.getVersion());
-    result.appendFormat("%s\n", extensions.getExtension());
+    RenderEngine::dump(result);
 }
 
 // ---------------------------------------------------------------------------
 }; // namespace android
 // ---------------------------------------------------------------------------
+
+#if defined(__gl2_h_)
+#error "don't include gl2/gl2.h in this file"
+#endif
diff --git a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
index 8bb7ed1..d20ff1c 100644
--- a/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES11RenderEngine.h
@@ -37,6 +37,10 @@
     GLint mMaxViewportDims[2];
     GLint mMaxTextureSize;
 
+    virtual void bindImageAsFramebuffer(EGLImageKHR image,
+            uint32_t* texName, uint32_t* fbName, uint32_t* status);
+    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+
 public:
     GLES11RenderEngine();
 
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 9be12bf..4add66b 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -17,6 +17,7 @@
 #define ATRACE_TAG ATRACE_TAG_GRAPHICS
 
 #include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
 
 #include <utils/String8.h>
 #include <utils/Trace.h>
@@ -24,7 +25,6 @@
 #include <cutils/compiler.h>
 
 #include "GLES20RenderEngine.h"
-#include "GLExtensions.h"
 #include "Program.h"
 #include "ProgramCache.h"
 #include "Description.h"
@@ -157,6 +157,32 @@
     glDisable(GL_BLEND);
 }
 
+
+void GLES20RenderEngine::bindImageAsFramebuffer(EGLImageKHR image,
+        uint32_t* texName, uint32_t* fbName, uint32_t* status) {
+    GLuint tname, name;
+    // turn our EGLImage into a texture
+    glGenTextures(1, &tname);
+    glBindTexture(GL_TEXTURE_2D, tname);
+    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
+
+    // create a Framebuffer Object to render into
+    glGenFramebuffers(1, &name);
+    glBindFramebuffer(GL_FRAMEBUFFER, name);
+    glFramebufferTexture2D(GL_FRAMEBUFFER,
+            GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, tname, 0);
+
+    *status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    *texName = tname;
+    *fbName = name;
+}
+
+void GLES20RenderEngine::unbindFramebuffer(uint32_t texName, uint32_t fbName) {
+    glBindFramebuffer(GL_FRAMEBUFFER, 0);
+    glDeleteFramebuffers(1, &fbName);
+    glDeleteTextures(1, &texName);
+}
+
 void GLES20RenderEngine::fillWithColor(const Mesh& mesh, float r, float g, float b, float a) {
     mState.setColor(r, g, b, a);
     disableTexturing();
@@ -200,14 +226,13 @@
 }
 
 void GLES20RenderEngine::dump(String8& result) {
-    const GLExtensions& extensions(GLExtensions::getInstance());
-    result.appendFormat("GLES: %s, %s, %s\n",
-            extensions.getVendor(),
-            extensions.getRenderer(),
-            extensions.getVersion());
-    result.appendFormat("%s\n", extensions.getExtension());
+    RenderEngine::dump(result);
 }
 
 // ---------------------------------------------------------------------------
 }; // namespace android
 // ---------------------------------------------------------------------------
+
+#if defined(__gl_h_)
+#error "don't include gl/gl.h in this file"
+#endif
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index 873a643..2998874 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -41,6 +41,10 @@
 
     Description mState;
 
+    virtual void bindImageAsFramebuffer(EGLImageKHR image,
+            uint32_t* texName, uint32_t* fbName, uint32_t* status);
+    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName);
+
 public:
     GLES20RenderEngine();
 
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index f378713..db64a16 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -122,6 +122,10 @@
     if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
         fs << "#extension GL_OES_EGL_image_external : require";
     }
+
+    // default precision is required-ish in fragment shaders
+    fs << "precision mediump float;";
+
     if (needs.getTextureTarget() == Key::TEXTURE_EXT) {
         fs << "uniform samplerExternalOES sampler;"
            << "varying vec2 outTexCoords;";
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index dc9cf4c..063be2e 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -42,7 +42,7 @@
             EGL_NONE, EGL_NONE
     };
 
-    EGLContext ctxt = EGL_NO_CONTEXT; // eglCreateContext(display, config, NULL, contextAttributes);
+    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");
@@ -190,34 +190,29 @@
     glDeleteTextures(count, names);
 }
 
+void RenderEngine::dump(String8& result) {
+    const GLExtensions& extensions(GLExtensions::getInstance());
+    result.appendFormat("GLES: %s, %s, %s\n",
+            extensions.getVendor(),
+            extensions.getRenderer(),
+            extensions.getVersion());
+    result.appendFormat("%s\n", extensions.getExtension());
+}
+
 // ---------------------------------------------------------------------------
 
 RenderEngine::BindImageAsFramebuffer::BindImageAsFramebuffer(
         RenderEngine& engine, EGLImageKHR image) : mEngine(engine)
 {
-    GLuint tname, name;
-    // turn our EGLImage into a texture
-    glGenTextures(1, &tname);
-    glBindTexture(GL_TEXTURE_2D, tname);
-    glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, (GLeglImageOES)image);
-    // create a Framebuffer Object to render into
-    glGenFramebuffersOES(1, &name);
-    glBindFramebufferOES(GL_FRAMEBUFFER_OES, name);
-    glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES,
-            GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, tname, 0);
-    mStatus = glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
+    mEngine.bindImageAsFramebuffer(image, &mTexName, &mFbName, &mStatus);
+
     ALOGE_IF(mStatus != GL_FRAMEBUFFER_COMPLETE_OES,
             "glCheckFramebufferStatusOES error %d", mStatus);
-    mTexName = tname;
-    mFbName = name;
 }
 
 RenderEngine::BindImageAsFramebuffer::~BindImageAsFramebuffer() {
     // back to main framebuffer
-    glBindFramebufferOES(GL_FRAMEBUFFER_OES, 0);
-    glDeleteFramebuffersOES(1, &mFbName);
-    glDeleteTextures(1, &mTexName);
-
+    mEngine.unbindFramebuffer(mTexName, mFbName);
 }
 
 status_t RenderEngine::BindImageAsFramebuffer::getStatus() const {
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index f4fa30b..3c2b2ea 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -45,6 +45,9 @@
     EGLContext mEGLContext;
     void setEGLContext(EGLContext ctxt);
 
+    virtual void bindImageAsFramebuffer(EGLImageKHR image, uint32_t* texName, uint32_t* fbName, uint32_t* status) = 0;
+    virtual void unbindFramebuffer(uint32_t texName, uint32_t fbName) = 0;
+
 protected:
     RenderEngine();
     virtual ~RenderEngine() = 0;
@@ -52,6 +55,9 @@
 public:
     static RenderEngine* create(EGLDisplay display, EGLConfig config);
 
+    // dump the extension strings. always call the base class.
+    virtual void dump(String8& result);
+
     // helpers
     void clearWithColor(float red, float green, float blue, float alpha);
     void fillRegionWithColor(const Region& region, uint32_t height,
@@ -65,8 +71,8 @@
 
     class BindImageAsFramebuffer {
         RenderEngine& mEngine;
-        unsigned int mTexName, mFbName;
-        unsigned int mStatus;
+        uint32_t mTexName, mFbName;
+        uint32_t mStatus;
     public:
         BindImageAsFramebuffer(RenderEngine& engine, EGLImageKHR image);
         ~BindImageAsFramebuffer();
@@ -75,7 +81,6 @@
 
     // set-up
     virtual void checkErrors() const;
-    virtual void dump(String8& result) = 0;
     virtual void setViewportAndProjection(size_t vpw, size_t vph, size_t w, size_t h, bool yswap) = 0;
     virtual void setupLayerBlending(bool premultipliedAlpha, bool opaque, int alpha) = 0;
     virtual void setupDimLayerBlending(int alpha) = 0;