Bug 784244: We really, seriously, can only let the BufferTracker take care of our required AutoOpenSurfaces. r=roc
authorChris Jones <jones.chris.g@gmail.com>
Mon, 24 Sep 2012 14:54:01 -0700
changeset 108056 beed670216f6a941e5225f45b549252416461afd
parent 108055 780a4b8551e61eb945c759c44598c40b4e51bb7f
child 108057 8bd13443d0bc3ab59bf8191e5460c4233daf0a54
push id82
push usershu@rfrn.org
push dateFri, 05 Oct 2012 13:20:22 +0000
reviewersroc
bugs784244
milestone18.0a1
Bug 784244: We really, seriously, can only let the BufferTracker take care of our required AutoOpenSurfaces. r=roc
gfx/layers/basic/BasicThebesLayer.cpp
gfx/layers/basic/BasicThebesLayer.h
--- a/gfx/layers/basic/BasicThebesLayer.cpp
+++ b/gfx/layers/basic/BasicThebesLayer.cpp
@@ -254,25 +254,27 @@ struct NS_STACK_CLASS AutoBufferTracker 
 
   ~AutoBufferTracker() {
     mLayer->mBufferTracker = nullptr;
     mLayer->mBuffer.RevokeBuffer();
     // mInitialBuffer and mNewBuffer will clean up after themselves if
     // they were constructed.
   }
 
+  gfxASurface* GetInitialBuffer() { return mInitialBuffer.ref().Get(); }
+
   gfxASurface*
   CreatedBuffer(const SurfaceDescriptor& aDescriptor) {
     Maybe<AutoOpenSurface>* surface = mNewBuffers.AppendElement();
     surface->construct(OPEN_READ_WRITE, aDescriptor);
     return surface->ref().Get();
   }
 
   Maybe<AutoOpenSurface> mInitialBuffer;
-  nsAutoTArray<Maybe<AutoOpenSurface>, 2> mNewBuffers;
+  nsAutoTArray<Maybe<AutoOpenSurface>, 3> mNewBuffers;
   BasicShadowableThebesLayer* mLayer;
 
 private:
   AutoBufferTracker(const AutoBufferTracker&) MOZ_DELETE;
   AutoBufferTracker& operator=(const AutoBufferTracker&) MOZ_DELETE;
 };
 
 void
@@ -323,30 +325,28 @@ BasicShadowableThebesLayer::SyncFrontBuf
     return;
   }
 
   // We temporarily map our back buffer here in order to copy from the
   // front buffer.  We need a live buffer tracker in order to unmap
   // that buffer when appropriate.
   MOZ_ASSERT(mBufferTracker);
 
-  gfxASurface* backBuffer = mBuffer.GetBuffer();
+  nsRefPtr<gfxASurface> backBuffer = mBuffer.GetBuffer();
   if (!IsSurfaceDescriptorValid(mBackBuffer)) {
     MOZ_ASSERT(!backBuffer);
     MOZ_ASSERT(mROFrontBuffer.type() == OptionalThebesBuffer::TThebesBuffer);
     const ThebesBuffer roFront = mROFrontBuffer.get_ThebesBuffer();
     AutoOpenSurface roFrontBuffer(OPEN_READ_ONLY, roFront.buffer());
-    AllocBackBuffer(roFrontBuffer.ContentType(), roFrontBuffer.Size());
+    backBuffer = CreateBuffer(roFrontBuffer.ContentType(), roFrontBuffer.Size());
   }
   mFrontAndBackBufferDiffer = false;
 
-  Maybe<AutoOpenSurface> autoBackBuffer;
   if (!backBuffer) {
-    autoBackBuffer.construct(OPEN_READ_WRITE, mBackBuffer);
-    backBuffer = autoBackBuffer.ref().Get();
+    backBuffer = mBufferTracker->GetInitialBuffer();
   }
 
   if (OptionalThebesBuffer::Tnull_t == mROFrontBuffer.type()) {
     // We didn't get back a read-only ref to our old back buffer (the
     // parent's new front buffer).  If the parent is pushing updates
     // to a texture it owns, then we probably got back the same buffer
     // we pushed in the update and all is well.  If not, ...
     mValidRegion = mFrontValidRegion;
@@ -411,33 +411,16 @@ BasicShadowableThebesLayer::PaintBuffer(
                     "should have a back buffer by now");
   BasicManager()->PaintedThebesBuffer(BasicManager()->Hold(this),
                                       updatedRegion,
                                       mBuffer.BufferRect(),
                                       mBuffer.BufferRotation(),
                                       mBackBuffer);
 }
 
-void
-BasicShadowableThebesLayer::AllocBackBuffer(Buffer::ContentType aType,
-                                            const nsIntSize& aSize)
-{
-  // This function may *not* open the buffer it allocates.
-  if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
-                                   aType,
-                                   &mBackBuffer)) {
-    enum { buflen = 256 };
-    char buf[buflen];
-    PR_snprintf(buf, buflen,
-                "creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
-                aSize.width, aSize.height, int(aType));
-    NS_RUNTIMEABORT(buf);
-  }
-}
-
 already_AddRefed<gfxASurface>
 BasicShadowableThebesLayer::CreateBuffer(Buffer::ContentType aType,
                                          const nsIntSize& aSize)
 {
   if (!HasShadow()) {
     return BasicThebesLayer::CreateBuffer(aType, aSize);
   }
 
@@ -446,17 +429,26 @@ BasicShadowableThebesLayer::CreateBuffer
                   aSize.width, aSize.height));
 
   if (IsSurfaceDescriptorValid(mBackBuffer)) {
     BasicManager()->DestroyedThebesBuffer(BasicManager()->Hold(this),
                                           mBackBuffer);
     mBackBuffer = SurfaceDescriptor();
   }
 
-  AllocBackBuffer(aType, aSize);
+  if (!BasicManager()->AllocBuffer(gfxIntSize(aSize.width, aSize.height),
+                                   aType,
+                                   &mBackBuffer)) {
+    enum { buflen = 256 };
+    char buf[buflen];
+    PR_snprintf(buf, buflen,
+                "creating ThebesLayer 'back buffer' failed! width=%d, height=%d, type=%x",
+                aSize.width, aSize.height, int(aType));
+    NS_RUNTIMEABORT(buf);
+  }
 
   NS_ABORT_IF_FALSE(!mIsNewBuffer,
                     "Bad! Did we create a buffer twice without painting?");
 
   mIsNewBuffer = true;
 
   nsRefPtr<gfxASurface> buffer = mBufferTracker->CreatedBuffer(mBackBuffer);
   return buffer.forget();
--- a/gfx/layers/basic/BasicThebesLayer.h
+++ b/gfx/layers/basic/BasicThebesLayer.h
@@ -162,20 +162,16 @@ private:
   PaintBuffer(gfxContext* aContext,
               const nsIntRegion& aRegionToDraw,
               const nsIntRegion& aExtendedRegionToDraw,
               const nsIntRegion& aRegionToInvalidate,
               bool aDidSelfCopy,
               LayerManager::DrawThebesLayerCallback aCallback,
               void* aCallbackData) MOZ_OVERRIDE;
 
-  // This function may *not* open the buffer it allocates.
-  void
-  AllocBackBuffer(Buffer::ContentType aType, const nsIntSize& aSize);
-
   virtual already_AddRefed<gfxASurface>
   CreateBuffer(Buffer::ContentType aType, const nsIntSize& aSize) MOZ_OVERRIDE;
 
   void DestroyBackBuffer()
   {
     if (IsSurfaceDescriptorValid(mBackBuffer)) {
       BasicManager()->ShadowLayerForwarder::DestroySharedSurface(&mBackBuffer);
     }