Bug 863223 - Make canvas updates asynchronous once again r=nrc
authorJames Willcox <snorp@snorp.net>
Wed, 01 May 2013 19:24:27 -0400
changeset 141508 29aa0fd47707864bf9307ca51e5e06b523e128ca
parent 141507 9b1b9e61db7b18f51b5113866cf42a25bf577a02
child 141509 cdfa3301b1725d0545fd1cfa7f82b84eb46d48ae
push id2579
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 18:52:47 +0000
treeherdermozilla-beta@b69b7de8a05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnrc
bugs863223
milestone23.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 863223 - Make canvas updates asynchronous once again r=nrc
gfx/layers/client/CanvasClient.cpp
gfx/layers/client/CanvasClient.h
gfx/layers/ipc/CompositableForwarder.h
gfx/layers/ipc/ImageBridgeChild.cpp
gfx/layers/ipc/ImageBridgeChild.h
gfx/layers/ipc/ShadowLayers.cpp
gfx/layers/ipc/ShadowLayers.h
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -62,16 +62,23 @@ CanvasClient2D::Update(gfx::IntSize aSiz
                                               : gfxASurface::CONTENT_COLOR_ALPHA;
   mTextureClient->EnsureAllocated(aSize, contentType);
 
   gfxASurface* surface = mTextureClient->LockSurface();
   aLayer->UpdateSurface(surface);
   mTextureClient->Unlock();
 }
 
+void
+CanvasClient2D::Updated()
+{
+  mForwarder->UpdateTextureNoSwap(this, 1, mTextureClient->GetDescriptor());
+}
+
+
 CanvasClientWebGL::CanvasClientWebGL(CompositableForwarder* aFwd,
                                      TextureFlags aFlags)
 : CanvasClient(aFwd, aFlags)
 {
   mTextureInfo.mCompositableType = BUFFER_IMAGE_BUFFERED;
 }
 
 void
--- a/gfx/layers/client/CanvasClient.h
+++ b/gfx/layers/client/CanvasClient.h
@@ -60,16 +60,18 @@ public:
                  TextureFlags aFlags);
 
   TextureInfo GetTextureInfo() const MOZ_OVERRIDE
   {
     return mTextureInfo;
   }
 
   virtual void Update(gfx::IntSize aSize, ClientCanvasLayer* aLayer);
+
+  virtual void Updated() MOZ_OVERRIDE;
 };
 
 // Used for GL canvases where we don't need to do any readback, i.e., with a
 // GL backend.
 class CanvasClientWebGL : public CanvasClient
 {
 public:
   CanvasClientWebGL(CompositableForwarder* aFwd,
--- a/gfx/layers/ipc/CompositableForwarder.h
+++ b/gfx/layers/ipc/CompositableForwarder.h
@@ -80,16 +80,23 @@ public:
    * Communicate to the compositor that the texture identified by aCompositable
    * and aTextureId has been updated to aImage.
    */
   virtual void UpdateTexture(CompositableClient* aCompositable,
                              TextureIdentifier aTextureId,
                              SurfaceDescriptor* aDescriptor) = 0;
 
   /**
+   * Same as UpdateTexture, but performs an asynchronous layer transaction (if possible)
+   */
+  virtual void UpdateTextureNoSwap(CompositableClient* aCompositable,
+                                   TextureIdentifier aTextureId,
+                                   SurfaceDescriptor* aDescriptor) = 0;
+
+  /**
    * Communicate to the compositor that aRegion in the texture identified by
    * aCompositable and aIdentifier has been updated to aThebesBuffer.
    */
   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
                                    const ThebesBufferData& aThebesBufferData,
                                    const nsIntRegion& aUpdatedRegion) = 0;
 
   /**
--- a/gfx/layers/ipc/ImageBridgeChild.cpp
+++ b/gfx/layers/ipc/ImageBridgeChild.cpp
@@ -90,16 +90,33 @@ ImageBridgeChild::UpdateTexture(Composit
                   SurfaceDescriptor(*aDescriptor)));
     *aDescriptor = SurfaceDescriptor();
   } else {
     NS_WARNING("Trying to send a null SurfaceDescriptor.");
   }
 }
 
 void
+ImageBridgeChild::UpdateTextureNoSwap(CompositableClient* aCompositable,
+                                      TextureIdentifier aTextureId,
+                                      SurfaceDescriptor* aDescriptor)
+{
+  if (aDescriptor->type() != SurfaceDescriptor::T__None &&
+      aDescriptor->type() != SurfaceDescriptor::Tnull_t) {
+    MOZ_ASSERT(aCompositable);
+    MOZ_ASSERT(aCompositable->GetIPDLActor());
+    mTxn->AddNoSwapEdit(OpPaintTexture(nullptr, aCompositable->GetIPDLActor(), 1,
+                                       SurfaceDescriptor(*aDescriptor)));
+    *aDescriptor = SurfaceDescriptor();
+  } else {
+    NS_WARNING("Trying to send a null SurfaceDescriptor.");
+  }
+}
+
+void
 ImageBridgeChild::UpdatePictureRect(CompositableClient* aCompositable,
                                     const nsIntRect& aRect)
 {
   mTxn->AddNoSwapEdit(OpUpdatePictureRect(nullptr, aCompositable->GetIPDLActor(), aRect));
 }
 
 // Singleton
 static ImageBridgeChild *sImageBridgeChildSingleton = nullptr;
--- a/gfx/layers/ipc/ImageBridgeChild.h
+++ b/gfx/layers/ipc/ImageBridgeChild.h
@@ -239,16 +239,20 @@ public:
   /**
    * Communicate to the compositor that the texture identified by aCompositable
    * and aTextureId has been updated to aDescriptor.
    */
   virtual void UpdateTexture(CompositableClient* aCompositable,
                              TextureIdentifier aTextureId,
                              SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
 
+  virtual void UpdateTextureNoSwap(CompositableClient* aCompositable,
+                                   TextureIdentifier aTextureId,
+                                   SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
+
   /**
    * Communicate the picture rect of a YUV image in aLayer to the compositor
    */
   virtual void UpdatePictureRect(CompositableClient* aCompositable,
                                  const nsIntRect& aRect) MOZ_OVERRIDE;
 
 
   // at the moment we don't need to implement these. They are only used for
--- a/gfx/layers/ipc/ShadowLayers.cpp
+++ b/gfx/layers/ipc/ShadowLayers.cpp
@@ -312,16 +312,33 @@ ShadowLayerForwarder::UpdateTexture(Comp
                                   SurfaceDescriptor(*aDescriptor)));
     *aDescriptor = SurfaceDescriptor();
   } else {
     NS_WARNING("Trying to send a null SurfaceDescriptor.");
   }
 }
 
 void
+ShadowLayerForwarder::UpdateTextureNoSwap(CompositableClient* aCompositable,
+                                          TextureIdentifier aTextureId,
+                                          SurfaceDescriptor* aDescriptor)
+{
+  if (aDescriptor->type() != SurfaceDescriptor::T__None &&
+      aDescriptor->type() != SurfaceDescriptor::Tnull_t) {
+    MOZ_ASSERT(aCompositable);
+    MOZ_ASSERT(aCompositable->GetIPDLActor());
+    mTxn->AddNoSwapPaint(OpPaintTexture(nullptr, aCompositable->GetIPDLActor(), 1,
+                                        SurfaceDescriptor(*aDescriptor)));
+    *aDescriptor = SurfaceDescriptor();
+  } else {
+    NS_WARNING("Trying to send a null SurfaceDescriptor.");
+  }
+}
+
+void
 ShadowLayerForwarder::UpdateTextureRegion(CompositableClient* aCompositable,
                                           const ThebesBufferData& aThebesBufferData,
                                           const nsIntRegion& aUpdatedRegion)
 {
   MOZ_ASSERT(aCompositable);
   MOZ_ASSERT(aCompositable->GetIPDLActor());
   mTxn->AddPaint(OpPaintTextureRegion(nullptr, aCompositable->GetIPDLActor(),
                                       aThebesBufferData,
--- a/gfx/layers/ipc/ShadowLayers.h
+++ b/gfx/layers/ipc/ShadowLayers.h
@@ -269,16 +269,23 @@ public:
    * Communicate to the compositor that the texture identified by aLayer
    * and aIdentifier has been updated to aImage.
    */
   virtual void UpdateTexture(CompositableClient* aCompositable,
                              TextureIdentifier aTextureId,
                              SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
 
   /**
+   * Same as above, but performs an asynchronous layer transaction
+   */
+  virtual void UpdateTextureNoSwap(CompositableClient* aCompositable,
+                                   TextureIdentifier aTextureId,
+                                   SurfaceDescriptor* aDescriptor) MOZ_OVERRIDE;
+
+  /**
    * Communicate to the compositor that aRegion in the texture identified by aLayer
    * and aIdentifier has been updated to aThebesBuffer.
    */
   virtual void UpdateTextureRegion(CompositableClient* aCompositable,
                                    const ThebesBufferData& aThebesBufferData,
                                    const nsIntRegion& aUpdatedRegion) MOZ_OVERRIDE;
 
   /**