Bug 1444447 - Implement AsyncReadbackBuffer Compositor APIs for BasicCompositor. r?jrmuizel draft
authorMarkus Stange <mstange@themasta.com>
Wed, 28 Mar 2018 17:06:42 -0400
changeset 781373 874c6e2141d0ff84a01ece3cc90c96b199fa7885
parent 781372 de143eb84a04884ef0303dc77edfa684467c9134
child 781374 a728958c1390f55342e301b79f1fd2a0bd7cd8f8
push id106284
push userbmo:mstange@themasta.com
push dateThu, 12 Apr 2018 21:31:17 +0000
reviewersjrmuizel
bugs1444447
milestone61.0a1
Bug 1444447 - Implement AsyncReadbackBuffer Compositor APIs for BasicCompositor. r?jrmuizel MozReview-Commit-ID: CQf7Vy8GaY4
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -8,16 +8,17 @@
 #include "BasicLayersImpl.h"            // for FillRectWithMask
 #include "TextureHostBasic.h"
 #include "mozilla/layers/Effects.h"
 #include "nsIWidget.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/gfx/Helpers.h"
+#include "mozilla/gfx/Swizzle.h"
 #include "mozilla/gfx/Tools.h"
 #include "mozilla/gfx/ssse3-scaler.h"
 #include "mozilla/layers/ImageDataSerializer.h"
 #include "mozilla/SSE.h"
 #include "gfxUtils.h"
 #include "YCbCrUtils.h"
 #include <algorithm>
 #include "ImageContainer.h"
@@ -875,16 +876,71 @@ BasicCompositor::DrawGeometry(const Geom
     } else {
       buffer->Draw3DTransformedSurface(destSnapshot, new3DTransform);
     }
   }
 
   buffer->PopClip();
 }
 
+class BasicAsyncReadbackBuffer final : public AsyncReadbackBuffer
+{
+public:
+  explicit BasicAsyncReadbackBuffer(const IntSize& aSize)
+    : AsyncReadbackBuffer(aSize)
+  {
+  }
+
+  bool MapAndCopyInto(DataSourceSurface* aSurface,
+                      const IntSize& aReadSize) const override;
+
+  void TakeSurface(SourceSurface* aSurface)
+  {
+    mSurface = aSurface;
+  }
+
+private:
+  RefPtr<SourceSurface> mSurface;
+};
+
+bool
+BasicAsyncReadbackBuffer::MapAndCopyInto(DataSourceSurface* aSurface,
+                                         const IntSize& aReadSize) const
+{
+  if (!mSurface) {
+    return false;
+  }
+
+  MOZ_RELEASE_ASSERT(aReadSize <= aSurface->GetSize());
+  RefPtr<DataSourceSurface> source = mSurface->GetDataSurface();
+
+  DataSourceSurface::ScopedMap sourceMap(source, DataSourceSurface::READ);
+  DataSourceSurface::ScopedMap destMap(aSurface, DataSourceSurface::WRITE);
+  SwizzleData(sourceMap.GetData(), sourceMap.GetStride(), mSurface->GetFormat(),
+              destMap.GetData(), destMap.GetStride(), aSurface->GetFormat(),
+              aReadSize);
+  return true;
+}
+
+bool
+BasicCompositor::ReadbackRenderTarget(CompositingRenderTarget* aSource,
+                                      AsyncReadbackBuffer* aDest)
+{
+  RefPtr<SourceSurface> snapshot =
+    static_cast<BasicCompositingRenderTarget*>(aSource)->mDrawTarget->Snapshot();
+  static_cast<BasicAsyncReadbackBuffer*>(aDest)->TakeSurface(snapshot);
+  return true;
+}
+
+already_AddRefed<AsyncReadbackBuffer>
+BasicCompositor::CreateAsyncReadbackBuffer(const gfx::IntSize& aSize)
+{
+  return MakeAndAddRef<BasicAsyncReadbackBuffer>(aSize);
+}
+
 void
 BasicCompositor::ClearRect(const gfx::Rect& aRect)
 {
   mRenderTarget->mDrawTarget->ClearRect(aRect);
 }
 
 void
 BasicCompositor::BeginFrame(const nsIntRegion& aInvalidRegion,
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -81,16 +81,23 @@ public:
 
   virtual already_AddRefed<DataTextureSource>
   CreateDataTextureSourceAroundYCbCr(TextureHost* aTexture) override;
 
   virtual bool SupportsEffect(EffectTypes aEffect) override;
 
   bool SupportsLayerGeometry() const override;
 
+  virtual bool
+  ReadbackRenderTarget(CompositingRenderTarget* aSource,
+                       AsyncReadbackBuffer* aDest) override;
+
+  virtual already_AddRefed<AsyncReadbackBuffer>
+  CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override;
+
   virtual void SetRenderTarget(CompositingRenderTarget *aSource) override
   {
     mRenderTarget = static_cast<BasicCompositingRenderTarget*>(aSource);
     mRenderTarget->BindRenderTarget();
   }
   virtual CompositingRenderTarget* GetCurrentRenderTarget() const override
   {
     return mRenderTarget;