Bug 695406 - Reset IPC double buffers if the ContentType has changed. r=cjones
☠☠ backed out by 97437826246d ☠ ☠
authorOleg Romashin <romaxa@gmail.com>, Matt Woodrow <mwoodrow@mozilla.com>
Fri, 21 Oct 2011 14:29:09 +1300
changeset 79040 73dc291f89748f97c974f70aec7680a05dcba584
parent 79039 049ba0a8823f57a2b983a679821adb8d68288b33
child 79041 564144b09c4b39a7b72183459cfe18742a321eba
push id2823
push usermwoodrow@mozilla.com
push dateFri, 21 Oct 2011 01:30:04 +0000
treeherdermozilla-inbound@73dc291f8974 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerscjones
bugs695406
milestone10.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
Bug 695406 - Reset IPC double buffers if the ContentType has changed. r=cjones
gfx/layers/basic/BasicLayers.cpp
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
--- a/gfx/layers/basic/BasicLayers.cpp
+++ b/gfx/layers/basic/BasicLayers.cpp
@@ -2384,17 +2384,18 @@ BasicShadowableThebesLayer::CreateBuffer
 }
 
 
 class BasicShadowableImageLayer : public BasicImageLayer,
                                   public BasicShadowableLayer
 {
 public:
   BasicShadowableImageLayer(BasicShadowLayerManager* aManager) :
-    BasicImageLayer(aManager)
+    BasicImageLayer(aManager),
+    mBufferIsOpaque(false)
   {
     MOZ_COUNT_CTOR(BasicShadowableImageLayer);
   }
   virtual ~BasicShadowableImageLayer()
   {
     DestroyBackBuffer();
     MOZ_COUNT_DTOR(BasicShadowableImageLayer);
   }
@@ -2446,16 +2447,17 @@ private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
   // For YUV Images these are the 3 planes (Y, Cb and Cr),
   // for RGB images only mBackSurface is used.
   SurfaceDescriptor mBackBuffer;
+  bool mBufferIsOpaque;
   nsRefPtr<gfxSharedImageSurface> mBackBufferY;
   nsRefPtr<gfxSharedImageSurface> mBackBufferU;
   nsRefPtr<gfxSharedImageSurface> mBackBufferV;
   gfxIntSize mCbCrSize;
 };
  
 void
 BasicShadowableImageLayer::Paint(gfxContext* aContext)
@@ -2513,22 +2515,26 @@ BasicShadowableImageLayer::Paint(gfxCont
     return;
   }
 
   gfxIntSize oldSize = mSize;
   nsRefPtr<gfxPattern> pat = GetAndPaintCurrentImage(aContext, GetEffectiveOpacity());
   if (!pat || !HasShadow())
     return;
 
-  if (oldSize != mSize || !IsSurfaceDescriptorValid(mBackBuffer)) {
+  bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
+  if (oldSize != mSize || 
+      !IsSurfaceDescriptorValid(mBackBuffer) ||
+      isOpaque != mBufferIsOpaque) {
     DestroyBackBuffer();
+    mBufferIsOpaque = isOpaque;
 
     if (!BasicManager()->AllocBuffer(
           mSize,
-          (GetContentFlags() & CONTENT_OPAQUE) ?
+          isOpaque ?
             gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
           &mBackBuffer))
       NS_RUNTIMEABORT("creating ImageLayer 'front buffer' failed!");
   }
 
   nsRefPtr<gfxASurface> backSurface =
     BasicManager()->OpenDescriptor(mBackBuffer);
   nsRefPtr<gfxContext> tmpCtx = new gfxContext(backSurface);
@@ -2570,17 +2576,18 @@ public:
   }
 };
 
 class BasicShadowableCanvasLayer : public BasicCanvasLayer,
                                    public BasicShadowableLayer
 {
 public:
   BasicShadowableCanvasLayer(BasicShadowLayerManager* aManager) :
-    BasicCanvasLayer(aManager)
+    BasicCanvasLayer(aManager),
+    mBufferIsOpaque(false)
   {
     MOZ_COUNT_CTOR(BasicShadowableCanvasLayer);
   }
   virtual ~BasicShadowableCanvasLayer()
   {
     DestroyBackBuffer();
     MOZ_COUNT_DTOR(BasicShadowableCanvasLayer);
   }
@@ -2617,16 +2624,17 @@ public:
 
 private:
   BasicShadowLayerManager* BasicManager()
   {
     return static_cast<BasicShadowLayerManager*>(mManager);
   }
 
   SurfaceDescriptor mBackBuffer;
+  bool mBufferIsOpaque;
 };
 
 void
 BasicShadowableCanvasLayer::Initialize(const Data& aData)
 {
   BasicCanvasLayer::Initialize(aData);
   if (!HasShadow())
       return;
@@ -2646,20 +2654,24 @@ BasicShadowableCanvasLayer::Initialize(c
 void
 BasicShadowableCanvasLayer::Paint(gfxContext* aContext)
 {
   if (!HasShadow()) {
     BasicCanvasLayer::Paint(aContext);
     return;
   }
 
-  if (!IsSurfaceDescriptorValid(mBackBuffer)) {
+  bool isOpaque = (GetContentFlags() & CONTENT_OPAQUE);
+  if (!IsSurfaceDescriptorValid(mBackBuffer) ||
+      isOpaque != mBufferIsOpaque) {
+    DestroyBackBuffer();
+    mBufferIsOpaque = isOpaque;
     if (!BasicManager()->AllocBuffer(
         gfxIntSize(mBounds.width, mBounds.height),
-        (GetContentFlags() & CONTENT_OPAQUE) ?
+        isOpaque ?
           gfxASurface::CONTENT_COLOR : gfxASurface::CONTENT_COLOR_ALPHA,
         &mBackBuffer))
     NS_RUNTIMEABORT("creating CanvasLayer back buffer failed!");
   }
 
   nsRefPtr<gfxASurface> backSurface =
     BasicManager()->OpenDescriptor(mBackBuffer);
 
@@ -2938,17 +2950,23 @@ protected:
 
 void
 BasicShadowImageLayer::Swap(const SharedImage& aNewFront,
                             SharedImage* aNewBack)
 {
   nsRefPtr<gfxASurface> surface =
     BasicManager()->OpenDescriptor(aNewFront);
   // Destroy mFrontBuffer if size different
-  if (surface->GetSize() != mSize) {
+  bool needDrop = false;
+  if (IsSurfaceDescriptorValid(mFrontBuffer)) {
+    nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontBuffer);
+    needDrop = surface->GetSize() != mSize ||
+               surface->GetContentType() != front->GetContentType();
+  }
+  if (needDrop) {
     DestroyFrontBuffer();
     mSize = surface->GetSize();
   }
 
   // If mFrontBuffer
   if (IsSurfaceDescriptorValid(mFrontBuffer)) {
     *aNewBack = mFrontBuffer;
   } else {
@@ -3054,17 +3072,23 @@ BasicShadowCanvasLayer::Initialize(const
 void
 BasicShadowCanvasLayer::Swap(const CanvasSurface& aNewFront, bool needYFlip,
                              CanvasSurface* aNewBack)
 {
   nsRefPtr<gfxASurface> surface =
     BasicManager()->OpenDescriptor(aNewFront);
   // Destroy mFrontBuffer if size different
   gfxIntSize sz = surface->GetSize();
-  if (sz != gfxIntSize(mBounds.width, mBounds.height)) {
+  bool needDrop = false;
+  if (IsSurfaceDescriptorValid(mFrontSurface)) {
+    nsRefPtr<gfxASurface> front = BasicManager()->OpenDescriptor(mFrontSurface);
+    needDrop = sz != gfxIntSize(mBounds.width, mBounds.height) ||
+               surface->GetContentType() != front->GetContentType();
+  }
+  if (needDrop) {
     DestroyFrontBuffer();
     mBounds.SetRect(0, 0, sz.width, sz.height);
   }
 
   mNeedsYFlip = needYFlip;
   // If mFrontBuffer
   if (IsSurfaceDescriptorValid(mFrontSurface)) {
     *aNewBack = mFrontSurface;
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -319,17 +319,18 @@ ShadowCanvasLayerOGL::Init(const CanvasS
 void
 ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
                            bool needYFlip,
                            CanvasSurface* aNewBack)
 {
   if (!mDestroyed) {
     nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
     gfxIntSize sz = surf->GetSize();
-    if (!mTexImage || mTexImage->GetSize() != sz) {
+    if (!mTexImage || mTexImage->GetSize() != sz ||
+        mTexImage->GetContentType() != surf->GetContentType()) {
       Init(aNewFront, needYFlip);
     }
     nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
     mTexImage->DirectUpdate(surf, updateRegion);
   }
 
   *aNewBack = aNewFront;
 }
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -880,17 +880,18 @@ void
 ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
                           SharedImage* aNewBack)
 {
   if (!mDestroyed) {
     if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
       nsRefPtr<gfxASurface> surf =
         ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor());
       gfxIntSize size = surf->GetSize();
-      if (mSize != size || !mTexImage) {
+      if (mSize != size || !mTexImage ||
+          mTexImage->GetContentType() != surf->GetContentType()) {
         Init(aNewFront);
       }
       // XXX this is always just ridiculously slow
       nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
       mTexImage->DirectUpdate(surf, updateRegion);
     } else {
       const YUVImage& yuv = aNewFront.get_YUVImage();