Bug 900133 - Don't mark textures as being sent to the compositor until after we've drawn to them. r=nical
authorMatt Woodrow <mwoodrow@mozilla.com>
Tue, 20 Aug 2013 11:39:55 +1200
changeset 143164 f19e44e32c7568eeb21afc7c25fbc051716a51ed
parent 143163 de84e2d0c9c53750751052a9f74a70f3833a2356
child 143165 b8ce320d6574b5f65e83cdf55bc2ed8c5ba8bcf4
push id32642
push usermwoodrow@mozilla.com
push dateMon, 19 Aug 2013 23:40:06 +0000
treeherdermozilla-inbound@252dbb41d609 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs900133
milestone26.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 900133 - Don't mark textures as being sent to the compositor until after we've drawn to them. r=nical
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/ImageClient.cpp
gfx/layers/client/TextureClient.cpp
gfx/layers/composite/TextureHost.cpp
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -40,41 +40,46 @@ void
 CanvasClient2D::Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer)
 {
   if (mBuffer &&
       (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
     RemoveTextureClient(mBuffer);
     mBuffer = nullptr;
   }
 
+  bool bufferCreated = false;
   if (!mBuffer) {
     bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
     gfxASurface::gfxContentType contentType = isOpaque
                                                 ? gfxASurface::CONTENT_COLOR
                                                 : gfxASurface::CONTENT_COLOR_ALPHA;
     gfxASurface::gfxImageFormat format
       = gfxPlatform::GetPlatform()->OptimalFormatForContent(contentType);
     mBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
     MOZ_ASSERT(mBuffer->AsTextureClientSurface());
     mBuffer->AsTextureClientSurface()->AllocateForSurface(aSize);
 
-    AddTextureClient(mBuffer);
+    bufferCreated = true;
   }
 
   if (!mBuffer->Lock(OPEN_READ_WRITE)) {
     return;
   }
 
   nsRefPtr<gfxASurface> surface = mBuffer->AsTextureClientSurface()->GetAsSurface();
   if (surface) {
     aLayer->UpdateSurface(surface);
   }
 
   mBuffer->Unlock();
 
+  if (bufferCreated) {
+    AddTextureClient(mBuffer);
+  }
+
   if (surface) {
     GetForwarder()->UpdatedTexture(this, mBuffer, nullptr);
     GetForwarder()->UseTexture(this, mBuffer);
   }
 }
 
 TemporaryRef<BufferTextureClient>
 CanvasClient2D::CreateBufferTextureClient(gfx::SurfaceFormat aFormat)
--- a/gfx/layers/client/ImageClient.cpp
+++ b/gfx/layers/client/ImageClient.cpp
@@ -110,33 +110,38 @@ ImageClientSingle::UpdateImage(ImageCont
       return false;
     }
 
     if (mFrontBuffer && mFrontBuffer->IsImmutable()) {
       RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
+    bool bufferCreated = false;
     if (!mFrontBuffer) {
       mFrontBuffer = CreateBufferTextureClient(gfx::FORMAT_YUV);
       gfx::IntSize ySize(data->mYSize.width, data->mYSize.height);
       gfx::IntSize cbCrSize(data->mCbCrSize.width, data->mCbCrSize.height);
       if (!mFrontBuffer->AsTextureClientYCbCr()->AllocateForYCbCr(ySize, cbCrSize, data->mStereoMode)) {
         mFrontBuffer = nullptr;
         return false;
       }
-      AddTextureClient(mFrontBuffer);
+      bufferCreated = true;
     }
 
     if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
       return false;
     }
     bool status = mFrontBuffer->AsTextureClientYCbCr()->UpdateYCbCr(*data);
     mFrontBuffer->Unlock();
 
+    if (bufferCreated) {
+      AddTextureClient(mFrontBuffer);
+    }
+
     if (status) {
       GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
       GetForwarder()->UseTexture(this, mFrontBuffer);
     } else {
       MOZ_ASSERT(false);
       return false;
     }
 
@@ -147,31 +152,37 @@ ImageClientSingle::UpdateImage(ImageCont
     gfx::IntSize size = gfx::IntSize(image->GetSize().width, image->GetSize().height);
 
     if (mFrontBuffer &&
         (mFrontBuffer->IsImmutable() || mFrontBuffer->GetSize() != size)) {
       RemoveTextureClient(mFrontBuffer);
       mFrontBuffer = nullptr;
     }
 
+    bool bufferCreated = false;
     if (!mFrontBuffer) {
       gfxASurface::gfxImageFormat format
         = gfxPlatform::GetPlatform()->OptimalFormatForContent(surface->GetContentType());
       mFrontBuffer = CreateBufferTextureClient(gfx::ImageFormatToSurfaceFormat(format));
       MOZ_ASSERT(mFrontBuffer->AsTextureClientSurface());
       mFrontBuffer->AsTextureClientSurface()->AllocateForSurface(size);
 
-      AddTextureClient(mFrontBuffer);
+      bufferCreated = true;
     }
 
     if (!mFrontBuffer->Lock(OPEN_READ_WRITE)) {
       return false;
     }
     bool status = mFrontBuffer->AsTextureClientSurface()->UpdateSurface(surface);
     mFrontBuffer->Unlock();
+
+    if (bufferCreated) {
+      AddTextureClient(mFrontBuffer);
+    }
+
     if (status) {
       GetForwarder()->UpdatedTexture(this, mFrontBuffer, nullptr);
       GetForwarder()->UseTexture(this, mFrontBuffer);
     } else {
       return false;
     }
   }
 
--- a/gfx/layers/client/TextureClient.cpp
+++ b/gfx/layers/client/TextureClient.cpp
@@ -159,16 +159,17 @@ BufferTextureClient::BufferTextureClient
 
 BufferTextureClient::~BufferTextureClient()
 {}
 
 bool
 BufferTextureClient::UpdateSurface(gfxASurface* aSurface)
 {
   MOZ_ASSERT(aSurface);
+  MOZ_ASSERT(!IsImmutable());
 
   ImageDataSerializer serializer(GetBuffer());
   if (!serializer.IsValid()) {
     return false;
   }
 
   RefPtr<gfxImageSurface> surf = serializer.GetAsThebesSurface();
   if (!surf) {
--- a/gfx/layers/composite/TextureHost.cpp
+++ b/gfx/layers/composite/TextureHost.cpp
@@ -375,16 +375,19 @@ BufferTextureHost::Upload(nsIntRegion *a
     }
     ImageDataDeserializer deserializer(GetBuffer());
     if (!deserializer.IsValid()) {
       NS_WARNING("failed to open shmem surface");
       return false;
     }
 
     RefPtr<gfx::DataSourceSurface> surf = deserializer.GetAsSurface();
+    if (!surf) {
+      return false;
+    }
 
     if (!mFirstSource->Update(surf.get(), mFlags, aRegion)) {
       NS_WARNING("failed to update the DataTextureSource");
       return false;
     }
   }
   return true;
 }