From d7d2f8b642ff87019a708bb3c585dfc02d7b7e66 Mon Sep 17 00:00:00 2001 From: Ryan Hunt Date: Wed, 11 Oct 2017 14:34:41 -0400 Subject: [PATCH] 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 --HG-- extra : rebase_source : 40acce3f4150c5f6f51bf73f0b3c7e974ed8fd72 --- gfx/layers/RotatedBuffer.cpp | 72 ++++++++++++++++++++++++++++++++++++ gfx/layers/RotatedBuffer.h | 33 ++++++++++++++++- 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/gfx/layers/RotatedBuffer.cpp b/gfx/layers/RotatedBuffer.cpp index 32542a7d747b..7cb5c6bd5c08 100644 --- a/gfx/layers/RotatedBuffer.cpp +++ b/gfx/layers/RotatedBuffer.cpp @@ -347,6 +347,78 @@ RotatedBuffer::BorrowDrawTargetForQuadrantUpdate(const IntRect& aBounds, 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 +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 SourceRotatedBuffer::GetSourceSurface(ContextSource aSource) const { diff --git a/gfx/layers/RotatedBuffer.h b/gfx/layers/RotatedBuffer.h index e9a5f22da9b8..37f004fe207e 100644 --- a/gfx/layers/RotatedBuffer.h +++ b/gfx/layers/RotatedBuffer.h @@ -12,6 +12,7 @@ #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 @@ -26,7 +27,6 @@ class CapturedPaintState; typedef bool (*PrepDrawTargetForPaintingCallback)(CapturedPaintState*); -class TextureClient; class PaintedLayer; // Mixin class for classes which need logic for loaning out a draw target. @@ -200,6 +200,37 @@ protected: 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 GetSourceSurface(ContextSource aSource) const override; + +protected: + virtual gfx::DrawTarget* GetDTBuffer() const override; + virtual gfx::DrawTarget* GetDTBufferOnWhite() const override; + +private: + RefPtr mClient; + RefPtr mClientOnWhite; + + RefPtr mTarget; + RefPtr mTargetOnWhite; +}; + class SourceRotatedBuffer : public RotatedBuffer { public: