b=767064; use 4444/565 GL context format for WebGL on mobile; r=jgilbert,r=bjacob
authorVladimir Vukicevic <vladimir@pobox.com>
Fri, 06 Jul 2012 09:19:27 -0400
changeset 99616 41eb4e7896e556cf21a2db1276e8eaad2f455dd1
parent 99615 a0e708ee19528559cef4b5f6bdbea262fc17eecb
child 99617 b2def0ae47bbaadfd504c0e4c5bb17fa40a316da
push id23140
push useremorley@mozilla.com
push dateWed, 18 Jul 2012 12:33:13 +0000
treeherdermozilla-central@134e66224b04 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert, bjacob
bugs767064
milestone17.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
b=767064; use 4444/565 GL context format for WebGL on mobile; r=jgilbert,r=bjacob
content/canvas/src/WebGLContext.cpp
gfx/gl/GLContext.cpp
gfx/thebes/gfxPlatform.cpp
modules/libpref/src/init/all.js
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -283,25 +283,33 @@ GetBoolFromPropertyBag(nsIPropertyBag *b
 }
 
 NS_IMETHODIMP
 WebGLContext::SetContextOptions(nsIPropertyBag *aOptions)
 {
     if (!aOptions)
         return NS_OK;
 
+    bool defaultNoAlpha =
+        Preferences::GetBool("webgl.default-no-alpha", false);
+
     WebGLContextOptions newOpts;
 
     GetBoolFromPropertyBag(aOptions, "stencil", &newOpts.stencil);
     GetBoolFromPropertyBag(aOptions, "depth", &newOpts.depth);
-    GetBoolFromPropertyBag(aOptions, "alpha", &newOpts.alpha);
     GetBoolFromPropertyBag(aOptions, "premultipliedAlpha", &newOpts.premultipliedAlpha);
     GetBoolFromPropertyBag(aOptions, "antialias", &newOpts.antialias);
     GetBoolFromPropertyBag(aOptions, "preserveDrawingBuffer", &newOpts.preserveDrawingBuffer);
 
+    // alpha defaults to true as per the spec, but we want to evaluate
+    // what will happen if it were to default to false based on a pref
+    if (!GetBoolFromPropertyBag(aOptions, "alpha", &newOpts.alpha) && defaultNoAlpha) {
+        newOpts.alpha = false;
+    }
+
     // enforce that if stencil is specified, we also give back depth
     newOpts.depth |= newOpts.stencil;
 
 #if 0
     GenerateWarning("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d preserve: %d\n",
                newOpts.antialias ? 1 : 0,
                newOpts.stencil ? 1 : 0,
                newOpts.depth ? 1 : 0,
@@ -373,16 +381,18 @@ WebGLContext::SetDimensions(PRInt32 widt
         Preferences::GetBool("webgl.prefer-native-gl", false);
 #endif
     bool forceEnabled =
         Preferences::GetBool("webgl.force-enabled", false);
     bool useMesaLlvmPipe =
         Preferences::GetBool("gfx.prefer-mesa-llvmpipe", false);
     bool disabled =
         Preferences::GetBool("webgl.disabled", false);
+    bool prefer16bit =
+        Preferences::GetBool("webgl.prefer-16bpp", false);
 
     ScopedGfxFeatureReporter reporter("WebGL", forceEnabled);
 
     if (disabled)
         return NS_ERROR_FAILURE;
 
     // We're going to create an entirely new context.  If our
     // generation is not 0 right now (that is, if this isn't the first
@@ -402,26 +412,42 @@ WebGLContext::SetDimensions(PRInt32 widt
     }
 
     if (mOptions.stencil) {
         format.stencil = 8;
         format.minStencil = 8;
     }
 
     if (!mOptions.alpha) {
-        // Select 565; we won't/shouldn't hit this on the desktop,
-        // but let mobile know we're ok with it.
-        format.red = 5;
-        format.green = 6;
-        format.blue = 5;
-
         format.alpha = 0;
         format.minAlpha = 0;
     }
 
+    // we should really have this behind a
+    // |gfxPlatform::GetPlatform()->GetScreenDepth() == 16| check, but
+    // for now it's just behind a pref for testing/evaluation.
+    if (prefer16bit) {
+        // Select 4444 or 565 on 16-bit displays; we won't/shouldn't
+        // hit this on the desktop, but let mobile know we're ok with
+        // it.  Note that we don't just set this to 4440 if no alpha,
+        // because that might cause us to choose 4444 anyway and we
+        // don't want that.
+        if (mOptions.alpha) {
+            format.red = 4;
+            format.green = 4;
+            format.blue = 4;
+            format.alpha = 4;
+        } else {
+            format.red = 5;
+            format.green = 6;
+            format.blue = 5;
+            format.alpha = 0;
+        }
+    }
+
     bool forceMSAA =
         Preferences::GetBool("webgl.msaa-force", false);
 
     PRInt32 status;
     nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
     if (mOptions.antialias &&
         gfxInfo &&
         NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_WEBGL_MSAA, &status))) {
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1272,45 +1272,63 @@ PRUint32 TiledTextureImage::GetTileCount
     return mImages.Length();
 }
 
 GLContext::GLFormats
 GLContext::ChooseGLFormats(ContextFormat& aCF, ColorByteOrder aByteOrder)
 {
     GLFormats formats;
 
-    if (aCF.alpha) {
-        if (mIsGLES2 && IsExtensionSupported(EXT_texture_format_BGRA8888) && aByteOrder != ForceRGBA) {
-            formats.texColor = LOCAL_GL_BGRA;
-        } else {
+    // If we're on ES2 hardware and we have an explicit request for 16 bits of color or less
+    // OR we don't support full 8-bit color, return a 4444 or 565 format.
+    if (mIsGLES2 && (aCF.colorBits() <= 16 || !IsExtensionSupported(OES_rgb8_rgba8))) {
+        if (aCF.alpha) {
             formats.texColor = LOCAL_GL_RGBA;
-        }
-
-        if (mIsGLES2 && !IsExtensionSupported(OES_rgb8_rgba8)) {
+            formats.texColorType = LOCAL_GL_UNSIGNED_SHORT_4_4_4_4;
             formats.rbColor = LOCAL_GL_RGBA4;
+
             aCF.red = aCF.green = aCF.blue = aCF.alpha = 4;
         } else {
-            formats.rbColor = LOCAL_GL_RGBA8;
-            aCF.red = aCF.green = aCF.blue = aCF.alpha = 8;
-        }
-    } else {
-        formats.texColor = LOCAL_GL_RGB;
-        if (mIsGLES2 && !IsExtensionSupported(OES_rgb8_rgba8)) {
+            formats.texColor = LOCAL_GL_RGB;
+            formats.texColorType = LOCAL_GL_UNSIGNED_SHORT_5_6_5;
             formats.rbColor = LOCAL_GL_RGB565;
+
             aCF.red = 5;
             aCF.green = 6;
             aCF.blue = 5;
+            aCF.alpha = 0;
+        }   
+    } else {
+        formats.texColorType = LOCAL_GL_UNSIGNED_BYTE;
+
+        if (aCF.alpha) {
+            // Prefer BGRA8888 on ES2 hardware; if the extension is supported, it
+            // should be faster.  There are some cases where we don't want this --
+            // specifically, CopyTex*Image doesn't seem to understand how to deal
+            // with a BGRA source going to a RGB/RGBA destination on some drivers.
+            if (mIsGLES2 &&
+                IsExtensionSupported(EXT_texture_format_BGRA8888) &&
+                aByteOrder != ForceRGBA)
+            {
+                formats.texColor = LOCAL_GL_BGRA;
+            } else {
+                formats.texColor = LOCAL_GL_RGBA;
+            }
+
+            formats.rbColor = LOCAL_GL_RGBA8;
+
+            aCF.red = aCF.green = aCF.blue = aCF.alpha = 8;
         } else {
+            formats.texColor = LOCAL_GL_RGB;
             formats.rbColor = LOCAL_GL_RGB8;
+
             aCF.red = aCF.green = aCF.blue = 8;
+            aCF.alpha = 0;
         }
-        aCF.alpha = 0;
     }
-    formats.texColorType = LOCAL_GL_UNSIGNED_BYTE;
-
 
     GLsizei samples = aCF.samples;
 
     GLsizei maxSamples = 0;
     if (SupportsFramebufferMultisample())
         fGetIntegerv(LOCAL_GL_MAX_SAMPLES, (GLint*)&maxSamples);
     samples = NS_MIN(samples, maxSamples);
 
--- a/gfx/thebes/gfxPlatform.cpp
+++ b/gfx/thebes/gfxPlatform.cpp
@@ -1486,17 +1486,17 @@ gfxPlatform::GetLog(eGfxLog aWhichLog)
 #else
     return nsnull;
 #endif
 }
 
 int
 gfxPlatform::GetScreenDepth() const
 {
-    MOZ_ASSERT(false, "Not implemented on this platform");
+    NS_WARNING("GetScreenDepth not implemented on this platform -- returning 0!");
     return 0;
 }
 
 mozilla::gfx::SurfaceFormat
 gfxPlatform::Optimal2DFormatForContent(gfxASurface::gfxContentType aContent)
 {
   switch (aContent) {
   case gfxASurface::CONTENT_COLOR:
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -3477,16 +3477,18 @@ pref("webgl.disabled", false);
 pref("webgl.shader_validator", true);
 pref("webgl.force_osmesa", false);
 pref("webgl.osmesalib", "");
 pref("webgl.prefer-native-gl", false);
 pref("webgl.min_capability_mode", false);
 pref("webgl.disable-extensions", false);
 pref("webgl.msaa-level", 2);
 pref("webgl.msaa-force", false);
+pref("webgl.prefer-16bpp", false);
+pref("webgl.default-no-alpha", false);
 
 #ifdef XP_WIN
 // The default TCP send window on Windows is too small, and autotuning only occurs on receive
 pref("network.tcp.sendbuffer", 131072);
 #endif
 
 // Asynchonous video compositing using the ImageBridge IPDL protocol.
 // requires off-main-thread compositing.