Add a RemoteRotatedBuffer. (bug 1409871 part 4, r=nical) draft
authorRyan Hunt <rhunt@eqrion.net>
Wed, 11 Oct 2017 14:34:41 -0400
changeset 684126 5a3030b14c133cbbe7b3002061e7873c0109d3b9
parent 684125 452a8c19e7a8b931638935af492b395cc73830cc
child 684127 9a369bc08fe994fd7e722931631085e9aa3dad80
push id85567
push userbmo:rhunt@eqrion.net
push dateFri, 20 Oct 2017 22:13:22 +0000
reviewersnical
bugs1409871
milestone58.0a1
Add a RemoteRotatedBuffer. (bug 1409871 part 4, r=nical) This adds a new implementation of rotated buffer, which is backed by texture clients. This will be the rotated buffer that remote content clients use. MozReview-Commit-ID: 3Y776uk5mFG
gfx/layers/RotatedBuffer.cpp
gfx/layers/RotatedBuffer.h
--- a/gfx/layers/RotatedBuffer.cpp
+++ b/gfx/layers/RotatedBuffer.cpp
@@ -342,16 +342,88 @@ RotatedBuffer::BorrowDrawTargetForQuadra
     MOZ_ASSERT(aOutMatrix);
     *aOutMatrix = Matrix::Translation(-quadrantRect.x, -quadrantRect.y);
     mSetTransform = false;
   }
 
   return mLoanedDrawTarget;
 }
 
+bool
+RemoteRotatedBuffer::Lock(OpenMode aMode)
+{
+  MOZ_ASSERT(!mTarget);
+  MOZ_ASSERT(!mTargetOnWhite);
+
+  bool locked = mClient->Lock(aMode) &&
+                (!mClientOnWhite || mClientOnWhite->Lock(aMode));
+  if (!locked) {
+    Unlock();
+    return false;
+  }
+
+  mTarget = mClient->BorrowDrawTarget();
+  if (!mTarget || !mTarget->IsValid()) {
+    gfxCriticalNote << "Invalid draw target " << hexa(mTarget)
+                    << "in RemoteRotatedBuffer::Lock";
+    Unlock();
+    return false;
+  }
+
+  if (mClientOnWhite) {
+    mTargetOnWhite = mClientOnWhite->BorrowDrawTarget();
+    if (!mTargetOnWhite || !mTargetOnWhite->IsValid()) {
+      gfxCriticalNote << "Invalid draw target(s) " << hexa(mTarget)
+                      << " and " << hexa(mTargetOnWhite)
+                      << "in RemoteRotatedBuffer::Lock";
+      Unlock();
+      return false;
+    }
+  }
+
+  return true;
+}
+
+void
+RemoteRotatedBuffer::Unlock()
+{
+  mTarget = nullptr;
+  mTargetOnWhite = nullptr;
+
+  if (mClient->IsLocked()) {
+    mClient->Unlock();
+  }
+  if (mClientOnWhite && mClientOnWhite->IsLocked()) {
+    mClientOnWhite->Unlock();
+  }
+}
+
+already_AddRefed<gfx::SourceSurface>
+RemoteRotatedBuffer::GetSourceSurface(ContextSource aSource) const
+{
+  if (aSource == ContextSource::BUFFER_BLACK) {
+    return mTarget->Snapshot();
+  } else {
+    MOZ_ASSERT(aSource == ContextSource::BUFFER_WHITE);
+    return mTargetOnWhite->Snapshot();
+  }
+}
+
+gfx::DrawTarget*
+RemoteRotatedBuffer::GetDTBuffer() const
+{
+  return mTarget;
+}
+
+gfx::DrawTarget*
+RemoteRotatedBuffer::GetDTBufferOnWhite() const
+{
+  return mTargetOnWhite;
+}
+
 already_AddRefed<SourceSurface>
 SourceRotatedBuffer::GetSourceSurface(ContextSource aSource) const
 {
   RefPtr<SourceSurface> surf;
   if (aSource == BUFFER_BLACK) {
     surf = mSource;
   } else {
     MOZ_ASSERT(aSource == BUFFER_WHITE);
--- a/gfx/layers/RotatedBuffer.h
+++ b/gfx/layers/RotatedBuffer.h
@@ -7,31 +7,31 @@
 #define ROTATEDBUFFER_H_
 
 #include "gfxTypes.h"
 #include <stdint.h>                     // for uint32_t
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc
 #include "mozilla/RefPtr.h"             // for RefPtr, already_AddRefed
 #include "mozilla/gfx/2D.h"             // for DrawTarget, etc
 #include "mozilla/gfx/MatrixFwd.h"      // for Matrix
+#include "mozilla/layers/TextureClient.h" // for TextureClient
 #include "mozilla/mozalloc.h"           // for operator delete
 #include "nsCOMPtr.h"                   // for already_AddRefed
 #include "nsDebug.h"                    // for NS_RUNTIMEABORT
 #include "nsISupportsImpl.h"            // for MOZ_COUNT_CTOR, etc
 #include "nsRegion.h"                   // for nsIntRegion
 #include "LayersTypes.h"
 
 namespace mozilla {
 namespace layers {
 
 class CapturedPaintState;
 
 typedef bool (*PrepDrawTargetForPaintingCallback)(CapturedPaintState*);
 
-class TextureClient;
 class PaintedLayer;
 
 // Mixin class for classes which need logic for loaning out a draw target.
 // See comments on BorrowDrawTargetForQuadrantUpdate.
 class BorrowDrawTarget
 {
 protected:
   void ReturnDrawTarget(gfx::DrawTarget*& aReturned);
@@ -195,16 +195,47 @@ protected:
    * buffer at the other end, not 2D rotation!
    */
   gfx::IntPoint            mBufferRotation;
   // When this is true it means that all pixels have moved inside the buffer.
   // It's not possible to sync with another buffer without a full copy.
   bool                  mDidSelfCopy;
 };
 
+class RemoteRotatedBuffer : public RotatedBuffer
+{
+public:
+  RemoteRotatedBuffer(TextureClient* aClient, TextureClient* aClientOnWhite,
+                      const gfx::IntRect& aBufferRect,
+                      const gfx::IntPoint& aBufferRotation)
+    : RotatedBuffer(aBufferRect, aBufferRotation)
+    , mClient(aClient)
+    , mClientOnWhite(aClientOnWhite)
+  { }
+
+  bool Lock(OpenMode aMode);
+  void Unlock();
+
+  virtual bool HaveBuffer() const override { return !!mClient; }
+  virtual bool HaveBufferOnWhite() const override { return !!mClientOnWhite; }
+
+  virtual already_AddRefed<gfx::SourceSurface> GetSourceSurface(ContextSource aSource) const override;
+
+protected:
+  virtual gfx::DrawTarget* GetDTBuffer() const override;
+  virtual gfx::DrawTarget* GetDTBufferOnWhite() const override;
+
+private:
+  RefPtr<TextureClient> mClient;
+  RefPtr<TextureClient> mClientOnWhite;
+
+  RefPtr<gfx::DrawTarget> mTarget;
+  RefPtr<gfx::DrawTarget> mTargetOnWhite;
+};
+
 class SourceRotatedBuffer : public RotatedBuffer
 {
 public:
   SourceRotatedBuffer(gfx::SourceSurface* aSource, gfx::SourceSurface* aSourceOnWhite,
                       const gfx::IntRect& aBufferRect,
                       const gfx::IntPoint& aBufferRotation)
     : RotatedBuffer(aBufferRect, aBufferRotation)
     , mSource(aSource)