Bug 907926 - Don't ignore the composition operator in the Azure paths through ThebesLayerBuffer. r=roc

This commit is contained in:
Matt Woodrow 2013-09-11 17:08:53 +12:00
parent 795eeb8c27
commit 130f818a0b
3 changed files with 28 additions and 19 deletions

View File

@ -161,6 +161,7 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
XSide aXSide, YSide aYSide,
ContextSource aSource,
float aOpacity,
gfx::CompositionOp aOperator,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) const
{
@ -193,14 +194,26 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
SurfacePattern source(snapshot, EXTEND_CLAMP, transform);
#endif
if (aOperator == OP_SOURCE) {
// OP_SOURCE is unbounded in Azure, and we really don't want that behaviour here.
// We also can't do a ClearRect+FillRect since we need the drawing to happen
// as an atomic operation (to prevent flickering).
aTarget->PushClipRect(gfx::Rect(fillRect.x, fillRect.y,
fillRect.width, fillRect.height));
}
if (aMask) {
SurfacePattern mask(aMask, EXTEND_CLAMP, *aMaskTransform);
aTarget->Mask(source, mask, DrawOptions(aOpacity));
aTarget->Mask(source, mask, DrawOptions(aOpacity, aOperator));
} else {
aTarget->FillRect(gfx::Rect(fillRect.x, fillRect.y,
fillRect.width, fillRect.height),
source, DrawOptions(aOpacity));
source, DrawOptions(aOpacity, aOperator));
}
if (aOperator == OP_SOURCE) {
aTarget->PopClip();
}
aTarget->Flush();
@ -224,6 +237,7 @@ RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource
void
RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
float aOpacity,
gfx::CompositionOp aOperator,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) const
{
@ -231,10 +245,10 @@ RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aS
// See above, in Azure Repeat should always be a safe, even faster choice
// though! Particularly on D2D Repeat should be a lot faster, need to look
// into that. TODO[Bas]
DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aOperator, aMask, aMaskTransform);
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aOperator,aMask, aMaskTransform);
}
/* static */ bool
@ -306,7 +320,8 @@ ThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
maskTransform = ToMatrix(*aMaskTransform);
}
DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, mask, &maskTransform);
CompositionOp op = CompositionOpForOp(aTarget->CurrentOperator());
DrawBufferWithRotation(dt, BUFFER_BLACK, aOpacity, op, mask, &maskTransform);
if (clipped) {
dt->PopClip();
}
@ -727,7 +742,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
destDTBuffer->SetTransform(mat);
EnsureBuffer();
MOZ_ASSERT(mDTBuffer, "Have we got a Thebes buffer for some reason?");
DrawBufferWithRotation(destDTBuffer, BUFFER_BLACK);
DrawBufferWithRotation(destDTBuffer, BUFFER_BLACK, 1.0, OP_SOURCE);
destDTBuffer->SetTransform(Matrix());
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
@ -735,7 +750,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
destDTBufferOnWhite->SetTransform(mat);
EnsureBufferOnWhite();
MOZ_ASSERT(destDTBufferOnWhite, "Have we got a Thebes buffer for some reason?");
DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE);
DrawBufferWithRotation(destDTBufferOnWhite, BUFFER_WHITE, 1.0, OP_SOURCE);
destDTBufferOnWhite->SetTransform(Matrix());
}
}

View File

@ -87,6 +87,7 @@ public:
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
float aOpacity = 1.0,
gfx::CompositionOp aOperator = gfx::OP_OVER,
gfx::SourceSurface* aMask = nullptr,
const gfx::Matrix* aMaskTransform = nullptr) const;
@ -124,6 +125,7 @@ protected:
void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
ContextSource aSource,
float aOpacity,
gfx::CompositionOp aOperator,
gfx::SourceSurface* aMask,
const gfx::Matrix* aMaskTransform) const;

View File

@ -537,11 +537,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
if (SupportsAzureContent()) {
MOZ_ASSERT(!destCtx->IsCairo());
if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) {
destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height));
}
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK);
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
} else {
aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
}
@ -559,11 +555,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
if (SupportsAzureContent()) {
MOZ_ASSERT(!destCtx->IsCairo());
if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) {
destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height));
}
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE);
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
} else {
aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
}