Bug 801176 - part7-v1: Don't remove TextureClient until the frame update is done. r=roc
authorvincentliu <vliu@mozilla.com>
Fri, 04 Mar 2016 15:24:19 +0800
changeset 323107 a2a7b1c4dc5bde72d8c288211f4075a8d74f3253
parent 323106 e210473d793ce93f41642780fc66b56e97972eee
child 323108 624fb8512ba55b2011fafe4f6b0d3399b76ac707
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs801176
milestone47.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 801176 - part7-v1: Don't remove TextureClient until the frame update is done. r=roc --- gfx/layers/client/CanvasClient.cpp | 10 ++++++++-- gfx/layers/client/CanvasClient.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-)
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -82,28 +82,27 @@ CanvasClient2D::UpdateAsync(AsyncCanvasR
   Renderer renderer;
   renderer.construct<AsyncCanvasRenderer*>(aRenderer);
   UpdateRenderer(aRenderer->GetSize(), renderer);
 }
 
 void
 CanvasClient2D::UpdateRenderer(gfx::IntSize aSize, Renderer& aRenderer)
 {
-  AutoRemoveTexture autoRemove(this);
   ClientCanvasLayer* layer = nullptr;
   AsyncCanvasRenderer* asyncRenderer = nullptr;
   if (aRenderer.constructed<ClientCanvasLayer*>()) {
     layer = aRenderer.ref<ClientCanvasLayer*>();
   } else {
     asyncRenderer = aRenderer.ref<AsyncCanvasRenderer*>();
   }
 
   if (mBuffer &&
       (mBuffer->IsImmutable() || mBuffer->GetSize() != aSize)) {
-    autoRemove.mTexture = mBuffer;
+    mPrevBuffer = mBuffer;
     mBuffer = nullptr;
   }
 
   mBufferCreated = false;
   if (!mBuffer) {
     bool isOpaque;
     gfxContentType contentType;
     if (layer) {
@@ -150,16 +149,23 @@ CanvasClient2D::UpdateRenderer(gfx::IntS
     }
     mUpdated = true;
   }
 }
 
 void
 CanvasClient2D::Updated()
 {
+  AutoRemoveTexture autoRemove(this);
+
+  if (mPrevBuffer) {
+    autoRemove.mTexture = mPrevBuffer;
+    mPrevBuffer = nullptr;
+  }
+
   if (mBufferCreated && !AddTextureClient(mBuffer)) {
     mBuffer = nullptr;
     return;
   }
 
   if (mUpdated) {
     AutoTArray<CompositableForwarder::TimedTextureClient,1> textures;
     CompositableForwarder::TimedTextureClient* t = textures.AppendElement();
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -84,16 +84,17 @@ protected:
 
 // Used for 2D canvases and WebGL canvas on non-GL systems where readback is requried.
 class CanvasClient2D : public CanvasClient
 {
 public:
   CanvasClient2D(CompositableForwarder* aLayerForwarder,
                  TextureFlags aFlags)
     : CanvasClient(aLayerForwarder, aFlags),
+      mPrevBuffer(nullptr),
       mBufferCreated(false),
       mUpdated(false)
   {
   }
 
   TextureInfo GetTextureInfo() const override
   {
     return TextureInfo(CompositableType::IMAGE, mTextureFlags);
@@ -123,16 +124,17 @@ public:
 
 private:
   already_AddRefed<TextureClient>
     CreateTextureClientForCanvas(gfx::SurfaceFormat aFormat,
                                  gfx::IntSize aSize,
                                  TextureFlags aFlags,
                                  ClientCanvasLayer* aLayer);
 
+  RefPtr<TextureClient> mPrevBuffer;
   RefPtr<TextureClient> mBuffer;
   bool mBufferCreated;
   bool mUpdated;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
 class CanvasClientSharedSurface : public CanvasClient