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
--- 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)