Bug 948406 - Append some zeros to EGL attrib lists to work around a bug in Android/B2G emulator. r=vladv, a=lsblakk
authorBenoit Jacob <bjacob@mozilla.com>
Fri, 13 Dec 2013 15:15:07 -0500
changeset 167778 abcbe0e114e3e6f2956169f39e8fe19e1d0d99a9
parent 167775 53889e96edd9298a89eb2ad767c32663c1db2861
child 167779 6c0aa15ef904c790406cccc89a57bbacf0e71a43
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvladv, lsblakk
bugs948406
milestone27.0
Bug 948406 - Append some zeros to EGL attrib lists to work around a bug in Android/B2G emulator. r=vladv, a=lsblakk
gfx/gl/GLContextProviderEGL.cpp
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -130,26 +130,36 @@ namespace gl {
 #ifndef MOZ_ANDROID_OMTC
 static EGLSurface
 CreateSurfaceForWindow(nsIWidget *aWidget, EGLConfig config);
 #endif
 
 static bool
 CreateConfig(EGLConfig* aConfig);
 
+// append three zeros at the end of attribs list to work around
+// EGL implementation bugs that iterate until they find 0, instead of
+// EGL_NONE. See bug 948406.
+#define EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS \
+     LOCAL_EGL_NONE, 0, 0, 0
+
+static EGLint gTerminationAttribs[] = {
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
+};
+
 static EGLint gContextAttribs[] = {
     LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static EGLint gContextAttribsRobustness[] = {
     LOCAL_EGL_CONTEXT_CLIENT_VERSION, 2,
     //LOCAL_EGL_CONTEXT_ROBUST_ACCESS_EXT, LOCAL_EGL_TRUE,
     LOCAL_EGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_EXT, LOCAL_EGL_LOSE_CONTEXT_ON_RESET_EXT,
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static int
 next_power_of_two(int v)
 {
     v--;
     v |= v >> 1;
     v |= v >> 2;
@@ -621,17 +631,19 @@ protected:
         if (bindToTextureFormat != LOCAL_EGL_NONE) {
             pbattrs.AppendElement(LOCAL_EGL_TEXTURE_TARGET);
             pbattrs.AppendElement(LOCAL_EGL_TEXTURE_2D);
 
             pbattrs.AppendElement(LOCAL_EGL_TEXTURE_FORMAT);
             pbattrs.AppendElement(bindToTextureFormat);
         }
 
-        pbattrs.AppendElement(LOCAL_EGL_NONE);
+        for (size_t i = 0; i < MOZ_ARRAY_LENGTH(gTerminationAttribs); i++) {
+          pbattrs.AppendElement(gTerminationAttribs[i]);
+        }
 
         surface = sEGLLibrary.fCreatePbufferSurface(EGL_DISPLAY(), config, &pbattrs[0]);
         if (!surface) {
             if (!is_power_of_two(pbsize.width) ||
                 !is_power_of_two(pbsize.height))
             {
                 if (!is_power_of_two(pbsize.width))
                     pbsize.width = next_power_of_two(pbsize.width);
@@ -1004,50 +1016,50 @@ GLContextEGL::TileGenFunc(const nsIntSiz
   fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
   return teximage.forget();
 }
 
 static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_PBUFFER_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static const EGLint kEGLConfigAttribsRGB16[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        5,
     LOCAL_EGL_GREEN_SIZE,      6,
     LOCAL_EGL_BLUE_SIZE,       5,
     LOCAL_EGL_ALPHA_SIZE,      0,
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static const EGLint kEGLConfigAttribsRGB24[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        8,
     LOCAL_EGL_GREEN_SIZE,      8,
     LOCAL_EGL_BLUE_SIZE,       8,
     LOCAL_EGL_ALPHA_SIZE,      0,
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static const EGLint kEGLConfigAttribsRGBA32[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_RED_SIZE,        8,
     LOCAL_EGL_GREEN_SIZE,      8,
     LOCAL_EGL_BLUE_SIZE,       8,
     LOCAL_EGL_ALPHA_SIZE,      8,
 #if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 17
     LOCAL_EGL_FRAMEBUFFER_TARGET_ANDROID, LOCAL_EGL_TRUE,
 #endif
-    LOCAL_EGL_NONE
+    EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS
 };
 
 static bool
 CreateConfig(EGLConfig* aConfig, int32_t depth)
 {
     EGLConfig configs[64];
     const EGLint* attribs;
     EGLint ncfg = ArrayLength(configs);
@@ -1341,8 +1353,9 @@ GLContextProviderEGL::GetGlobalContext(c
 void
 GLContextProviderEGL::Shutdown()
 {
 }
 
 } /* namespace gl */
 } /* namespace mozilla */
 
+#undef EGL_ATTRIBS_LIST_SAFE_TERMINATION_WORKING_AROUND_BUGS