mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 933549. Change PaintState to use a DrawTarget instead of a gfxContext. r=mattwoodrow
This commit is contained in:
parent
a44e014503
commit
100d053c89
@ -11,10 +11,8 @@
|
||||
#include "BufferUnrotate.h" // for BufferUnrotate
|
||||
#include "GeckoProfiler.h" // for PROFILER_LABEL
|
||||
#include "Layers.h" // for ThebesLayer, Layer, etc
|
||||
#include "gfxContext.h" // for gfxContext, etc
|
||||
#include "gfxMatrix.h" // for gfxMatrix
|
||||
#include "gfxPlatform.h" // for gfxPlatform
|
||||
#include "gfxPoint.h" // for gfxPoint
|
||||
#include "gfxUtils.h" // for gfxUtils
|
||||
#include "mozilla/ArrayUtils.h" // for ArrayLength
|
||||
#include "mozilla/gfx/BasePoint.h" // for BasePoint
|
||||
@ -178,18 +176,19 @@ RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aS
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
RotatedContentBuffer::IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion)
|
||||
RotatedContentBuffer::IsClippingCheap(DrawTarget* aTarget, const nsIntRegion& aRegion)
|
||||
{
|
||||
// Assume clipping is cheap if the context just has an integer
|
||||
// Assume clipping is cheap if the draw target just has an integer
|
||||
// translation, and the visible region is simple.
|
||||
return !aTarget->CurrentMatrix().HasNonIntegerTranslation() &&
|
||||
return !aTarget->GetTransform().HasNonIntegerTranslation() &&
|
||||
aRegion.GetNumRects() <= 1;
|
||||
}
|
||||
|
||||
void
|
||||
RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
gfxContext* aTarget,
|
||||
DrawTarget* aTarget,
|
||||
float aOpacity,
|
||||
CompositionOp aOp,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform)
|
||||
{
|
||||
@ -197,8 +196,6 @@ RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt = aTarget->GetDrawTarget();
|
||||
MOZ_ASSERT(dt, "Did you pass a non-Azure gfxContext?");
|
||||
bool clipped = false;
|
||||
|
||||
// If the entire buffer is valid, we can just draw the whole thing,
|
||||
@ -214,13 +211,13 @@ RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
// Bug 599189 if there is a non-integer-translation transform in aTarget,
|
||||
// we might sample pixels outside GetEffectiveVisibleRegion(), which is wrong
|
||||
// and may cause gray lines.
|
||||
gfxUtils::ClipToRegionSnapped(dt, aLayer->GetEffectiveVisibleRegion());
|
||||
gfxUtils::ClipToRegionSnapped(aTarget, aLayer->GetEffectiveVisibleRegion());
|
||||
clipped = true;
|
||||
}
|
||||
|
||||
RefPtr<gfx::SourceSurface> mask;
|
||||
if (aMask) {
|
||||
mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(dt, aMask);
|
||||
mask = gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTarget, aMask);
|
||||
}
|
||||
|
||||
Matrix maskTransform;
|
||||
@ -228,38 +225,35 @@ RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
maskTransform = ToMatrix(*aMaskTransform);
|
||||
}
|
||||
|
||||
CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
|
||||
DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
|
||||
DrawBufferWithRotation(aTarget, BUFFER_BLACK, aOpacity, aOp, mask, &maskTransform);
|
||||
if (clipped) {
|
||||
dt->PopClip();
|
||||
aTarget->PopClip();
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<gfxContext>
|
||||
RotatedContentBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
ContextSource aSource,
|
||||
nsIntPoint *aTopLeft)
|
||||
DrawTarget*
|
||||
RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
ContextSource aSource)
|
||||
{
|
||||
if (!EnsureBuffer()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<gfxContext> ctx;
|
||||
MOZ_ASSERT(!mLoanedDrawTarget, "draw target has been borrowed and not returned");
|
||||
if (aSource == BUFFER_BOTH && HaveBufferOnWhite()) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return nullptr;
|
||||
}
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
RefPtr<DrawTarget> dualDT = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
|
||||
ctx = new gfxContext(dualDT);
|
||||
mLoanedDrawTarget = Factory::CreateDualDrawTarget(mDTBuffer, mDTBufferOnWhite);
|
||||
} else if (aSource == BUFFER_WHITE) {
|
||||
if (!EnsureBufferOnWhite()) {
|
||||
return nullptr;
|
||||
}
|
||||
ctx = new gfxContext(mDTBufferOnWhite);
|
||||
mLoanedDrawTarget = mDTBufferOnWhite;
|
||||
} else {
|
||||
// BUFFER_BLACK, or BUFFER_BOTH with a single buffer.
|
||||
ctx = new gfxContext(mDTBuffer);
|
||||
mLoanedDrawTarget = mDTBuffer;
|
||||
}
|
||||
|
||||
// Figure out which quadrant to draw in
|
||||
@ -269,13 +263,22 @@ RotatedContentBuffer::GetContextForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
YSide sideY = aBounds.YMost() <= yBoundary ? BOTTOM : TOP;
|
||||
nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
|
||||
NS_ASSERTION(quadrantRect.Contains(aBounds), "Messed up quadrants");
|
||||
ctx->Translate(-gfxPoint(quadrantRect.x, quadrantRect.y));
|
||||
|
||||
if (aTopLeft) {
|
||||
*aTopLeft = nsIntPoint(quadrantRect.x, quadrantRect.y);
|
||||
}
|
||||
mLoanedTransform = mLoanedDrawTarget->GetTransform();
|
||||
mLoanedTransform.Translate(-quadrantRect.x, -quadrantRect.y);
|
||||
mLoanedDrawTarget->SetTransform(mLoanedTransform);
|
||||
mLoanedTransform.Translate(quadrantRect.x, quadrantRect.y);
|
||||
|
||||
return ctx.forget();
|
||||
return mLoanedDrawTarget;
|
||||
}
|
||||
|
||||
void
|
||||
BorrowDrawTarget::ReturnDrawTarget(gfx::DrawTarget*& aReturned)
|
||||
{
|
||||
MOZ_ASSERT(aReturned == mLoanedDrawTarget);
|
||||
mLoanedDrawTarget->SetTransform(mLoanedTransform);
|
||||
mLoanedDrawTarget = nullptr;
|
||||
aReturned = nullptr;
|
||||
}
|
||||
|
||||
gfxContentType
|
||||
@ -309,6 +312,7 @@ RotatedContentBuffer::BufferSizeOkFor(const nsIntSize& aSize)
|
||||
bool
|
||||
RotatedContentBuffer::EnsureBuffer()
|
||||
{
|
||||
NS_ASSERTION(!mLoanedDrawTarget, "Loaned draw target must be returned");
|
||||
if (!mDTBuffer) {
|
||||
if (mDeprecatedBufferProvider) {
|
||||
mDTBuffer = mDeprecatedBufferProvider->LockDrawTarget();
|
||||
@ -324,6 +328,7 @@ RotatedContentBuffer::EnsureBuffer()
|
||||
bool
|
||||
RotatedContentBuffer::EnsureBufferOnWhite()
|
||||
{
|
||||
NS_ASSERTION(!mLoanedDrawTarget, "Loaned draw target must be returned");
|
||||
if (!mDTBufferOnWhite) {
|
||||
if (mDeprecatedBufferProviderOnWhite) {
|
||||
mDTBufferOnWhite = mDeprecatedBufferProviderOnWhite->LockDrawTarget();
|
||||
@ -644,8 +649,7 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
|
||||
result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
|
||||
|
||||
nsIntPoint topLeft;
|
||||
result.mContext = GetContextForQuadrantUpdate(drawBounds, BUFFER_BOTH, &topLeft);
|
||||
result.mTarget = BorrowDrawTargetForQuadrantUpdate(drawBounds, BUFFER_BOTH);
|
||||
result.mClip = CLIP_DRAW_SNAPPED;
|
||||
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
@ -662,7 +666,7 @@ RotatedContentBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
||||
nsIntRegionRectIterator iter(result.mRegionToDraw);
|
||||
const nsIntRect *iterRect;
|
||||
while ((iterRect = iter.Next())) {
|
||||
result.mContext->GetDrawTarget()->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
result.mTarget->ClearRect(Rect(iterRect->x, iterRect->y, iterRect->width, iterRect->height));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@
|
||||
|
||||
#include <stdint.h> // for uint32_t
|
||||
#include "gfxASurface.h" // for gfxASurface, etc
|
||||
#include "gfxContext.h" // for gfxContext
|
||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||
#include "mozilla/RefPtr.h" // for RefPtr, TemporaryRef
|
||||
#include "mozilla/gfx/2D.h" // for DrawTarget, etc
|
||||
@ -137,11 +136,27 @@ protected:
|
||||
bool mDidSelfCopy;
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
// The draw target loaned by BorrowDrawTargetForQuadrantUpdate. It should not
|
||||
// be used, we just keep a reference to ensure it is kept alive and so we can
|
||||
// correctly restore state when it is returned.
|
||||
RefPtr<gfx::DrawTarget> mLoanedDrawTarget;
|
||||
gfx::Matrix mLoanedTransform;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class encapsulates the buffer used to retain ThebesLayer contents,
|
||||
* i.e., the contents of the layer's GetVisibleRegion().
|
||||
*/
|
||||
class RotatedContentBuffer : public RotatedBuffer {
|
||||
class RotatedContentBuffer : public RotatedBuffer
|
||||
, public BorrowDrawTarget
|
||||
{
|
||||
public:
|
||||
typedef gfxContentType ContentType;
|
||||
|
||||
@ -187,7 +202,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* This is returned by BeginPaint. The caller should draw into mContext.
|
||||
* This is returned by BeginPaint. The caller should draw into mTarget.
|
||||
* mRegionToDraw must be drawn. mRegionToInvalidate has been invalidated
|
||||
* by RotatedContentBuffer and must be redrawn on the screen.
|
||||
* mRegionToInvalidate is set when the buffer has changed from
|
||||
@ -197,14 +212,15 @@ public:
|
||||
*/
|
||||
struct PaintState {
|
||||
PaintState()
|
||||
: mDidSelfCopy(false)
|
||||
: mTarget(nullptr)
|
||||
, mDidSelfCopy(false)
|
||||
{}
|
||||
|
||||
nsRefPtr<gfxContext> mContext;
|
||||
gfx::DrawTarget* mTarget;
|
||||
nsIntRegion mRegionToDraw;
|
||||
nsIntRegion mRegionToInvalidate;
|
||||
bool mDidSelfCopy;
|
||||
DrawRegionClip mClip;
|
||||
bool mDidSelfCopy;
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -215,7 +231,7 @@ public:
|
||||
* Start a drawing operation. This returns a PaintState describing what
|
||||
* needs to be drawn to bring the buffer up to date in the visible region.
|
||||
* This queries aLayer to get the currently valid and visible regions.
|
||||
* The returned mContext may be null if mRegionToDraw is empty.
|
||||
* The returned mTarget may be null if mRegionToDraw is empty.
|
||||
* Otherwise it must not be null.
|
||||
* mRegionToInvalidate will contain mRegionToDraw.
|
||||
* @param aFlags when PAINT_WILL_RESAMPLE is passed, this indicates that
|
||||
@ -260,8 +276,12 @@ public:
|
||||
* drawn before this is called. The contents of the buffer are drawn
|
||||
* to aTarget.
|
||||
*/
|
||||
void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
|
||||
gfxASurface* aMask, const gfxMatrix* aMaskTransform);
|
||||
void DrawTo(ThebesLayer* aLayer,
|
||||
gfx::DrawTarget* aTarget,
|
||||
float aOpacity,
|
||||
gfx::CompositionOp aOp,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform);
|
||||
|
||||
protected:
|
||||
TemporaryRef<gfx::DrawTarget>
|
||||
@ -345,15 +365,24 @@ protected:
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a context at the specified resolution for updating |aBounds|,
|
||||
* Get a draw target at the specified resolution for updating |aBounds|,
|
||||
* which must be contained within a single quadrant.
|
||||
*
|
||||
* Optionally returns the TopLeft coordinate of the quadrant being drawn to.
|
||||
* The result should only be held temporarily by the caller (it will be kept
|
||||
* alive by this). Once used it should be returned using ReturnDrawTarget.
|
||||
* BorrowDrawTargetForQuadrantUpdate may not be called more than once without
|
||||
* first calling ReturnDrawTarget.
|
||||
*
|
||||
* ReturnDrawTarget will restore the transform on the draw target. But it is
|
||||
* the callers responsibility to restore the clip. The caller should flush the
|
||||
* draw target, if necessary.
|
||||
*/
|
||||
already_AddRefed<gfxContext>
|
||||
GetContextForQuadrantUpdate(const nsIntRect& aBounds, ContextSource aSource, nsIntPoint* aTopLeft = nullptr);
|
||||
gfx::DrawTarget*
|
||||
BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
ContextSource aSource);
|
||||
void ReturnDrawTarget(gfx::DrawTarget* aReturned);
|
||||
|
||||
static bool IsClippingCheap(gfxContext* aTarget, const nsIntRegion& aRegion);
|
||||
static bool IsClippingCheap(gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
|
||||
|
||||
protected:
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "nsTArray.h" // for nsTArray, nsTArray_Impl
|
||||
#include "AutoMaskData.h"
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
struct gfxMatrix;
|
||||
|
||||
@ -132,8 +133,9 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
}
|
||||
|
||||
if (!IsHidden() && !clipExtents.IsEmpty()) {
|
||||
AutoSetOperator setOperator(aContext, GetOperator());
|
||||
mContentClient->DrawTo(this, aContext, opacity, maskSurface, maskTransform);
|
||||
mContentClient->DrawTo(this, aContext->GetDrawTarget(), opacity,
|
||||
CompositionOpForOp(GetOperator()),
|
||||
maskSurface, maskTransform);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < readbackUpdates.Length(); ++i) {
|
||||
@ -145,7 +147,9 @@ BasicThebesLayer::PaintThebes(gfxContext* aContext,
|
||||
if (ctx) {
|
||||
NS_ASSERTION(opacity == 1.0, "Should only read back opaque layers");
|
||||
ctx->Translate(gfxPoint(offset.x, offset.y));
|
||||
mContentClient->DrawTo(this, ctx, 1.0, maskSurface, maskTransform);
|
||||
mContentClient->DrawTo(this, ctx->GetDrawTarget(), 1.0,
|
||||
CompositionOpForOp(ctx->CurrentOperator()),
|
||||
maskSurface, maskTransform);
|
||||
update.mLayer->GetSink()->EndUpdate(ctx, update.mUpdateRect + offset);
|
||||
}
|
||||
}
|
||||
@ -188,7 +192,7 @@ BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
mContentClient->BeginPaintBuffer(this, contentType, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (state.mContext) {
|
||||
if (state.mTarget) {
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
@ -196,17 +200,20 @@ BasicThebesLayer::Validate(LayerManager::DrawThebesLayerCallback aCallback,
|
||||
state.mRegionToInvalidate.And(state.mRegionToInvalidate,
|
||||
GetEffectiveVisibleRegion());
|
||||
nsIntRegion extendedDrawRegion = state.mRegionToDraw;
|
||||
SetAntialiasingFlags(this, state.mContext);
|
||||
SetAntialiasingFlags(this, state.mTarget);
|
||||
|
||||
RenderTraceInvalidateStart(this, "FFFF00", state.mRegionToDraw.GetBounds());
|
||||
|
||||
PaintBuffer(state.mContext,
|
||||
nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(state.mTarget);
|
||||
PaintBuffer(ctx,
|
||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||
state.mDidSelfCopy,
|
||||
state.mClip,
|
||||
aCallback, aCallbackData);
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||
Mutated();
|
||||
ctx = nullptr;
|
||||
mContentClient->ReturnDrawTarget(state.mTarget);
|
||||
|
||||
RenderTraceInvalidateEnd(this, "FFFF00");
|
||||
} else {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsCOMPtr.h" // for already_AddRefed
|
||||
#include "nsISupportsImpl.h" // for Layer::AddRef, etc
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "gfx2DGlue.h"
|
||||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
@ -61,7 +62,7 @@ ClientThebesLayer::PaintThebes()
|
||||
mContentClient->BeginPaintBuffer(this, contentType, flags);
|
||||
mValidRegion.Sub(mValidRegion, state.mRegionToInvalidate);
|
||||
|
||||
if (state.mContext) {
|
||||
if (state.mTarget) {
|
||||
// The area that became invalid and is visible needs to be repainted
|
||||
// (this could be the whole visible area if our buffer switched
|
||||
// from RGB to RGBA, because we might need to repaint with
|
||||
@ -69,13 +70,16 @@ ClientThebesLayer::PaintThebes()
|
||||
state.mRegionToInvalidate.And(state.mRegionToInvalidate,
|
||||
GetEffectiveVisibleRegion());
|
||||
nsIntRegion extendedDrawRegion = state.mRegionToDraw;
|
||||
SetAntialiasingFlags(this, state.mContext);
|
||||
SetAntialiasingFlags(this, state.mTarget);
|
||||
|
||||
PaintBuffer(state.mContext,
|
||||
nsRefPtr<gfxContext> ctx = gfxContext::ContextForDrawTarget(state.mTarget);
|
||||
PaintBuffer(ctx,
|
||||
state.mRegionToDraw, extendedDrawRegion, state.mRegionToInvalidate,
|
||||
state.mDidSelfCopy, state.mClip);
|
||||
MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) PaintThebes", this));
|
||||
Mutated();
|
||||
ctx = nullptr;
|
||||
mContentClient->ReturnDrawTarget(state.mTarget);
|
||||
} else {
|
||||
// It's possible that state.mRegionToInvalidate is nonempty here,
|
||||
// if we are shrinking the valid region to nothing. So use mRegionToDraw
|
||||
|
@ -608,29 +608,35 @@ void
|
||||
ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
const nsIntRegion& aUpdateRegion)
|
||||
{
|
||||
nsRefPtr<gfxContext> destCtx =
|
||||
GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
|
||||
destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
ReturnDrawTarget(destDT);
|
||||
|
||||
if (aSource.HaveBufferOnWhite()) {
|
||||
MOZ_ASSERT(HaveBufferOnWhite());
|
||||
nsRefPtr<gfxContext> destCtx =
|
||||
GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
|
||||
destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
ReturnDrawTarget(destDT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -817,32 +823,38 @@ void
|
||||
DeprecatedContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
const nsIntRegion& aUpdateRegion)
|
||||
{
|
||||
nsRefPtr<gfxContext> destCtx =
|
||||
GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
|
||||
if (!destCtx) {
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
|
||||
if (!destDT) {
|
||||
return;
|
||||
}
|
||||
destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
ReturnDrawTarget(destDT);
|
||||
|
||||
if (aSource.HaveBufferOnWhite()) {
|
||||
MOZ_ASSERT(HaveBufferOnWhite());
|
||||
nsRefPtr<gfxContext> destCtx =
|
||||
GetContextForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
|
||||
destCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destCtx, aUpdateRegion);
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destCtx, aUpdateRegion);
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
ReturnDrawTarget(destDT);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1135,6 +1147,8 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
invalidate.Sub(aLayer->GetValidRegion(), destBufferRect);
|
||||
result.mRegionToInvalidate.Or(result.mRegionToInvalidate, invalidate);
|
||||
|
||||
MOZ_ASSERT(!mLoanedDrawTarget);
|
||||
|
||||
// BeginUpdate is allowed to modify the given region,
|
||||
// if it wants more to be repainted than we request.
|
||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||
@ -1149,22 +1163,25 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
|
||||
RefPtr<DrawTarget> onBlackDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onBlack, onBlack->GetSize().ToIntSize());
|
||||
RefPtr<DrawTarget> onWhiteDT = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(onWhite, onWhite->GetSize().ToIntSize());
|
||||
RefPtr<DrawTarget> dt = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
|
||||
result.mContext = new gfxContext(dt);
|
||||
mLoanedDrawTarget = Factory::CreateDualDrawTarget(onBlackDT, onWhiteDT);
|
||||
} else {
|
||||
result.mContext = nullptr;
|
||||
mLoanedDrawTarget = nullptr;
|
||||
}
|
||||
} else {
|
||||
nsRefPtr<gfxASurface> surf = GetUpdateSurface(BUFFER_BLACK, result.mRegionToDraw);
|
||||
MOZ_ASSERT(gfxPlatform::GetPlatform()->SupportsAzureContent());
|
||||
RefPtr<DrawTarget> dt = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize().ToIntSize());
|
||||
result.mContext = new gfxContext(dt);
|
||||
mLoanedDrawTarget = gfxPlatform::GetPlatform()->CreateDrawTargetForUpdateSurface(surf, surf->GetSize());
|
||||
}
|
||||
if (!result.mContext) {
|
||||
if (!mLoanedDrawTarget) {
|
||||
NS_WARNING("unable to get context for update");
|
||||
return result;
|
||||
}
|
||||
result.mContext->Translate(-gfxPoint(drawBounds.x, drawBounds.y));
|
||||
|
||||
result.mTarget = mLoanedDrawTarget;
|
||||
mLoanedTransform = mLoanedDrawTarget->GetTransform();
|
||||
mLoanedTransform.Translate(-drawBounds.x, -drawBounds.y);
|
||||
result.mTarget->SetTransform(mLoanedTransform);
|
||||
mLoanedTransform.Translate(drawBounds.x, drawBounds.y);
|
||||
|
||||
// If we do partial updates, we have to clip drawing to the regionToDraw.
|
||||
// If we don't clip, background images will be fillrect'd to the region correctly,
|
||||
@ -1176,11 +1193,9 @@ ContentClientIncremental::BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
result.mClip = CLIP_DRAW;
|
||||
|
||||
if (mContentType == GFX_CONTENT_COLOR_ALPHA) {
|
||||
result.mContext->Save();
|
||||
gfxUtils::ClipToRegion(result.mContext, result.mRegionToDraw);
|
||||
result.mContext->SetOperator(gfxContext::OPERATOR_CLEAR);
|
||||
result.mContext->Paint();
|
||||
result.mContext->Restore();
|
||||
gfxUtils::ClipToRegion(result.mTarget, result.mRegionToDraw);
|
||||
nsIntRect bounds = result.mRegionToDraw.GetBounds();
|
||||
result.mTarget->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height));
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -97,6 +97,7 @@ public:
|
||||
virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
RotatedContentBuffer::ContentType aContentType,
|
||||
uint32_t aFlags) = 0;
|
||||
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) = 0;
|
||||
|
||||
// Sync front/back buffers content
|
||||
// After executing, the new back buffer has the same (interesting) pixels as
|
||||
@ -140,16 +141,25 @@ public:
|
||||
typedef RotatedContentBuffer::ContentType ContentType;
|
||||
|
||||
virtual void Clear() { RotatedContentBuffer::Clear(); }
|
||||
PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags)
|
||||
virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags) MOZ_OVERRIDE
|
||||
{
|
||||
return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
|
||||
}
|
||||
|
||||
void DrawTo(ThebesLayer* aLayer, gfxContext* aTarget, float aOpacity,
|
||||
gfxASurface* aMask, const gfxMatrix* aMaskTransform)
|
||||
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aMask, aMaskTransform);
|
||||
BorrowDrawTarget::ReturnDrawTarget(aReturned);
|
||||
}
|
||||
|
||||
void DrawTo(ThebesLayer* aLayer,
|
||||
gfx::DrawTarget* aTarget,
|
||||
float aOpacity,
|
||||
gfx::CompositionOp aOp,
|
||||
gfxASurface* aMask,
|
||||
const gfxMatrix* aMaskTransform)
|
||||
{
|
||||
RotatedContentBuffer::DrawTo(aLayer, aTarget, aOpacity, aOp,
|
||||
aMask, aMaskTransform);
|
||||
}
|
||||
|
||||
virtual void CreateBuffer(ContentType aType, const nsIntRect& aRect, uint32_t aFlags,
|
||||
@ -195,11 +205,16 @@ public:
|
||||
typedef RotatedContentBuffer::ContentType ContentType;
|
||||
|
||||
virtual void Clear() { RotatedContentBuffer::Clear(); }
|
||||
PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags)
|
||||
|
||||
virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags) MOZ_OVERRIDE
|
||||
{
|
||||
return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
|
||||
}
|
||||
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
BorrowDrawTarget::ReturnDrawTarget(aReturned);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin/End Paint map a gfxASurface from the texture client
|
||||
@ -295,11 +310,16 @@ public:
|
||||
typedef RotatedContentBuffer::ContentType ContentType;
|
||||
|
||||
virtual void Clear() { RotatedContentBuffer::Clear(); }
|
||||
PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags)
|
||||
|
||||
virtual PaintState BeginPaintBuffer(ThebesLayer* aLayer, ContentType aContentType,
|
||||
uint32_t aFlags) MOZ_OVERRIDE
|
||||
{
|
||||
return RotatedContentBuffer::BeginPaint(aLayer, aContentType, aFlags);
|
||||
}
|
||||
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
BorrowDrawTarget::ReturnDrawTarget(aReturned);
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin/End Paint map a gfxASurface from the texture client
|
||||
@ -496,6 +516,7 @@ protected:
|
||||
* new ones each frame.
|
||||
*/
|
||||
class ContentClientIncremental : public ContentClientRemote
|
||||
, public BorrowDrawTarget
|
||||
{
|
||||
public:
|
||||
ContentClientIncremental(CompositableForwarder* aFwd)
|
||||
@ -521,9 +542,14 @@ public:
|
||||
mHasBuffer = false;
|
||||
mHasBufferOnWhite = false;
|
||||
}
|
||||
|
||||
virtual RotatedContentBuffer::PaintState BeginPaintBuffer(ThebesLayer* aLayer,
|
||||
RotatedContentBuffer::ContentType aContentType,
|
||||
uint32_t aFlags);
|
||||
uint32_t aFlags) MOZ_OVERRIDE;
|
||||
virtual void ReturnDrawTarget(gfx::DrawTarget* aReturned) MOZ_OVERRIDE
|
||||
{
|
||||
BorrowDrawTarget::ReturnDrawTarget(aReturned);
|
||||
}
|
||||
|
||||
virtual void Updated(const nsIntRegion& aRegionToDraw,
|
||||
const nsIntRegion& aVisibleRegion,
|
||||
|
@ -115,6 +115,15 @@ gfxContext::gfxContext(DrawTarget *aTarget)
|
||||
mDT->SetTransform(Matrix());
|
||||
}
|
||||
|
||||
/* static */ already_AddRefed<gfxContext>
|
||||
gfxContext::ContextForDrawTarget(DrawTarget* aTarget)
|
||||
{
|
||||
Matrix transform = aTarget->GetTransform();
|
||||
nsRefPtr<gfxContext> result = new gfxContext(aTarget);
|
||||
result->SetMatrix(ThebesMatrix(transform));
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
gfxContext::~gfxContext()
|
||||
{
|
||||
if (mCairo) {
|
||||
|
@ -48,11 +48,20 @@ public:
|
||||
|
||||
/**
|
||||
* Initialize this context from a DrawTarget.
|
||||
* Strips any transform from aTarget.
|
||||
* aTarget will be flushed in the gfxContext's destructor.
|
||||
*/
|
||||
gfxContext(mozilla::gfx::DrawTarget *aTarget);
|
||||
|
||||
~gfxContext();
|
||||
|
||||
/**
|
||||
* Create a new gfxContext wrapping aTarget and preserving aTarget's
|
||||
* transform. Note that the transform is moved from aTarget to the resulting
|
||||
* gfxContext, aTarget will no longer have its transform.
|
||||
*/
|
||||
static already_AddRefed<gfxContext> ContextForDrawTarget(mozilla::gfx::DrawTarget* aTarget);
|
||||
|
||||
/**
|
||||
* Return the surface that this gfxContext was created with
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user