Bug 1444447 - Implement AsyncReadbackBuffer Compositor APIs for BasicCompositor r=mstange
authorMarkus Stange <mstange@themasta.com>
Fri, 18 Jan 2019 03:50:45 +0000
changeset 514739 28e336f7b9da63ef319650a7bd698289574a4f11
parent 514738 a115176a8faa34bb59da329fc5d458f5ab7f9267
child 514740 a70ed4f3086ae9e117c3e46f99fd40122bc07dc6
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1444447
milestone66.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 1444447 - Implement AsyncReadbackBuffer Compositor APIs for BasicCompositor r=mstange Depends on D14874 Differential Revision: https://phabricator.services.mozilla.com/D14875
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/basic/BasicCompositor.h
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -9,16 +9,17 @@
 #include "GeckoProfiler.h"
 #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 "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "YCbCrUtils.h"
 #include <algorithm>
@@ -174,16 +175,47 @@ class WrappingTextureSourceYCbCrBasic : 
 
  public:
   BufferTextureHost* mTexture;
   const gfx::IntSize mSize;
   RefPtr<gfx::DataSourceSurface> mSurface;
   bool mNeedsUpdate;
 };
 
+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);
+
+  return SwizzleData(sourceMap.GetData(), sourceMap.GetStride(),
+                     mSurface->GetFormat(), destMap.GetData(),
+                     destMap.GetStride(), aSurface->GetFormat(), aReadSize);
+}
+
 BasicCompositor::BasicCompositor(CompositorBridgeParent* aParent,
                                  widget::CompositorWidget* aWidget)
     : Compositor(aWidget, aParent),
       mIsPendingEndRemoteDrawing(false),
       mFullWindowRenderTarget(nullptr) {
   MOZ_COUNT_CTOR(BasicCompositor);
 
   mMaxTextureSize = Factory::GetMaxSurfaceSize(gfxVars::ContentBackend());
@@ -816,16 +848,30 @@ void BasicCompositor::DrawGeometry(
 void BasicCompositor::ClearRect(const gfx::Rect& aRect) {
   mRenderTarget->mDrawTarget->ClearRect(aRect);
 
   if (mFullWindowRenderTarget) {
     mFullWindowRenderTarget->mDrawTarget->ClearRect(aRect);
   }
 }
 
+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::BeginFrame(
     const nsIntRegion& aInvalidRegion, const gfx::IntRect* aClipRectIn,
     const gfx::IntRect& aRenderBounds, const nsIntRegion& aOpaqueRegion,
     gfx::IntRect* aClipRectOut /* = nullptr */,
     gfx::IntRect* aRenderBoundsOut /* = nullptr */) {
   if (mIsPendingEndRemoteDrawing) {
     // Force to end previous remote drawing.
     TryToEndRemoteDrawing(/* aForceToEnd */ true);
--- a/gfx/layers/basic/BasicCompositor.h
+++ b/gfx/layers/basic/BasicCompositor.h
@@ -78,16 +78,22 @@ class BasicCompositor : public Composito
 
   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* GetWindowRenderTarget() const override {
     return mFullWindowRenderTarget;
   }