Bug 593175, part 1: Request backing buffers with gfxContentType rather than gfxImageFormat. r=karl a=blocking-fennec
authorChris Jones <jones.chris.g@gmail.com>
Thu, 16 Sep 2010 16:24:17 -0500
changeset 54285 abc747783d430dcc3c5df7837b6cbdad9a5f5eed
parent 54284 bb22acd87a0202f79696692e08be75d760ef5196
child 54286 4746a5bf666200f889fc609f053cc6dd7ee336b5
push idunknown
push userunknown
push dateunknown
reviewerskarl, blocking-fennec
bugs593175
milestone2.0b7pre
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
Bug 593175, part 1: Request backing buffers with gfxContentType rather than gfxImageFormat. r=karl a=blocking-fennec
gfx/layers/basic/BasicLayers.cpp
gfx/layers/ipc/ShadowLayerUtilsX11.cpp
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -1554,17 +1554,19 @@ BasicShadowableImageLayer::Paint(gfxCont
       mBackSurface = nsnull;
 
       BasicManager()->DestroyedImageBuffer(BasicManager()->Hold(this));
     }
 
     nsRefPtr<gfxSharedImageSurface> tmpFrontSurface;
     // XXX error handling?
     if (!BasicManager()->AllocDoubleBuffer(
-          mSize, gfxASurface::ImageFormatARGB32,
+          mSize,
+          (GetContentFlags() & CONTENT_OPAQUE) ?
+            gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
           getter_AddRefs(tmpFrontSurface), getter_AddRefs(mBackSurface)))
       NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
 
     BasicManager()->CreatedImageBuffer(BasicManager()->Hold(this),
                                        nsIntSize(mSize.width, mSize.height),
                                        tmpFrontSurface);
   }
 
@@ -1670,17 +1672,18 @@ BasicShadowableCanvasLayer::Initialize(c
 
     BasicManager()->DestroyedCanvasBuffer(BasicManager()->Hold(this));
   }
 
   nsRefPtr<gfxSharedImageSurface> tmpFrontBuffer;
   // XXX error handling?
   if (!BasicManager()->AllocDoubleBuffer(
         gfxIntSize(aData.mSize.width, aData.mSize.height),
-        gfxASurface::ImageFormatARGB32,
+        (GetContentFlags() & CONTENT_OPAQUE) ?
+          gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
         getter_AddRefs(tmpFrontBuffer), getter_AddRefs(mBackBuffer)))
     NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!");
 
   BasicManager()->CreatedCanvasBuffer(BasicManager()->Hold(this),
                                       aData.mSize,
                                       tmpFrontBuffer);
 }
 
--- a/gfx/layers/ipc/ShadowLayerUtilsX11.cpp
+++ b/gfx/layers/ipc/ShadowLayerUtilsX11.cpp
@@ -75,24 +75,28 @@ CreateSimilar(gfxXlibSurface* aReference
     // Couldn't use aReference's directly.  Use a standard format then.
     gfxASurface::gfxImageFormat format;
     switch (aType) {
     case gfxASurface::CONTENT_COLOR:
       // FIXME/bug 593175: investigate 16bpp
       format = gfxASurface::ImageFormatRGB24; break;
     case gfxASurface::CONTENT_ALPHA:
       format = gfxASurface::ImageFormatA8; break;
+    default:
+      NS_NOTREACHED("unknown gfxContentType");
     case gfxASurface::CONTENT_COLOR_ALPHA:
       format = gfxASurface::ImageFormatARGB32; break;
-    default:
-      NS_NOTREACHED("unknown gfxContentType");
     }
     xrenderFormat = gfxXlibSurface::FindRenderFormat(display, format);
   }
-  NS_ABORT_IF_FALSE(xrenderFormat, "should have a render format by now");
+
+  if (!xrenderformat) {
+    NS_WARNING("couldn't find suitable render format");
+    return nsnull;
+  }
 
   return gfxXlibSurface::Create(aReference->XScreen(), xrenderFormat,
                                 aSize, aReference->XDrawable());
 }
 
 static PRBool
 TakeAndDestroyXlibSurface(SurfaceDescriptor* aSurface)
 {
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -353,28 +353,46 @@ ShadowLayerForwarder::EndTransaction(nsT
     MOZ_LAYERS_LOG(("[LayersForwarder] WARNING: sending transaction failed!"));
     return PR_FALSE;
   }
 
   MOZ_LAYERS_LOG(("[LayersForwarder] ... done"));
   return PR_TRUE;
 }
 
+static gfxASurface::gfxImageFormat
+OptimalFormatFor(gfxASurface::gfxContentType aContent)
+{
+  switch (aContent) {
+  case gfxASurface::CONTENT_COLOR:
+    // FIXME/bug 593175: investigate 16bpp
+    return gfxASurface::ImageFormatRGB24;
+  case gfxASurface::CONTENT_ALPHA:
+    return gfxASurface::ImageFormatA8;
+  case gfxASurface::CONTENT_COLOR_ALPHA:
+    return gfxASurface::ImageFormatARGB32;
+  default:
+    NS_NOTREACHED("unknown gfxContentType");
+    return gfxASurface::ImageFormatARGB32;
+  }
+}
+
 PRBool
 ShadowLayerForwarder::AllocDoubleBuffer(const gfxIntSize& aSize,
-                                        gfxASurface::gfxImageFormat aFormat,
+                                        gfxASurface::gfxContentType aContent,
                                         gfxSharedImageSurface** aFrontBuffer,
                                         gfxSharedImageSurface** aBackBuffer)
 {
   NS_ABORT_IF_FALSE(HasShadowManager(), "no manager to forward to");
 
+  gfxASurface::gfxImageFormat format = OptimalFormatFor(aContent);
   nsRefPtr<gfxSharedImageSurface> front = new gfxSharedImageSurface();
   nsRefPtr<gfxSharedImageSurface> back = new gfxSharedImageSurface();
-  if (!front->Init(mShadowManager, aSize, aFormat) ||
-      !back->Init(mShadowManager, aSize, aFormat))
+  if (!front->Init(mShadowManager, aSize, format) ||
+      !back->Init(mShadowManager, aSize, format))
     return PR_FALSE;
 
   *aFrontBuffer = NULL;       *aBackBuffer = NULL;
   front.swap(*aFrontBuffer);  back.swap(*aBackBuffer);
   return PR_TRUE;
 }
 
 void
@@ -393,22 +411,19 @@ ShadowLayerForwarder::AllocDoubleBuffer(
 #ifdef DEBUG
   tryPlatformSurface = !PR_GetEnv("MOZ_LAYERS_FORCE_SHMEM_SURFACES");
 #endif
   if (tryPlatformSurface &&
       PlatformAllocDoubleBuffer(aSize, aContent, aFrontBuffer, aBackBuffer)) {
     return PR_TRUE;
   }
 
-  gfxASurface::gfxImageFormat format = (aContent == gfxASurface::CONTENT_COLOR) ?
-                                       gfxASurface::ImageFormatRGB24 : 
-                                       gfxASurface::ImageFormatARGB32;
   nsRefPtr<gfxSharedImageSurface> front;
   nsRefPtr<gfxSharedImageSurface> back;
-  if (!AllocDoubleBuffer(aSize, format,
+  if (!AllocDoubleBuffer(aSize, aContent,
                          getter_AddRefs(front), getter_AddRefs(back))) {
     return PR_FALSE;
   }
 
   *aFrontBuffer = front->GetShmem();
   *aBackBuffer = back->GetShmem();
   return PR_TRUE;
 }
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -269,17 +269,17 @@ public:
   /**
    * Shmem (gfxSharedImageSurface) buffers are available on all
    * platforms, but they may not be optimal.
    *
    * NB: this interface is being deprecated in favor of the
    * SurfaceDescriptor variant below.
    */
   PRBool AllocDoubleBuffer(const gfxIntSize& aSize,
-                           gfxASurface::gfxImageFormat aFormat,
+                           gfxASurface::gfxContentType aContent,
                            gfxSharedImageSurface** aFrontBuffer,
                            gfxSharedImageSurface** aBackBuffer);
   void DestroySharedSurface(gfxSharedImageSurface* aSurface);
 
   /**
    * In the absence of platform-specific buffers these fall back to
    * Shmem/gfxSharedImageSurface.
    */