mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 907926 - Don't ignore the composition operator in the Azure paths through ThebesLayerBuffer. r=roc
This commit is contained in:
parent
795eeb8c27
commit
130f818a0b
@ -161,6 +161,7 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
|
|||||||
XSide aXSide, YSide aYSide,
|
XSide aXSide, YSide aYSide,
|
||||||
ContextSource aSource,
|
ContextSource aSource,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
|
gfx::CompositionOp aOperator,
|
||||||
gfx::SourceSurface* aMask,
|
gfx::SourceSurface* aMask,
|
||||||
const gfx::Matrix* aMaskTransform) const
|
const gfx::Matrix* aMaskTransform) const
|
||||||
{
|
{
|
||||||
@ -193,14 +194,26 @@ RotatedBuffer::DrawBufferQuadrant(gfx::DrawTarget* aTarget,
|
|||||||
SurfacePattern source(snapshot, EXTEND_CLAMP, transform);
|
SurfacePattern source(snapshot, EXTEND_CLAMP, transform);
|
||||||
#endif
|
#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) {
|
if (aMask) {
|
||||||
SurfacePattern mask(aMask, EXTEND_CLAMP, *aMaskTransform);
|
SurfacePattern mask(aMask, EXTEND_CLAMP, *aMaskTransform);
|
||||||
|
|
||||||
aTarget->Mask(source, mask, DrawOptions(aOpacity));
|
aTarget->Mask(source, mask, DrawOptions(aOpacity, aOperator));
|
||||||
} else {
|
} else {
|
||||||
aTarget->FillRect(gfx::Rect(fillRect.x, fillRect.y,
|
aTarget->FillRect(gfx::Rect(fillRect.x, fillRect.y,
|
||||||
fillRect.width, fillRect.height),
|
fillRect.width, fillRect.height),
|
||||||
source, DrawOptions(aOpacity));
|
source, DrawOptions(aOpacity, aOperator));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aOperator == OP_SOURCE) {
|
||||||
|
aTarget->PopClip();
|
||||||
}
|
}
|
||||||
|
|
||||||
aTarget->Flush();
|
aTarget->Flush();
|
||||||
@ -224,6 +237,7 @@ RotatedBuffer::DrawBufferWithRotation(gfxContext* aTarget, ContextSource aSource
|
|||||||
void
|
void
|
||||||
RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
|
RotatedBuffer::DrawBufferWithRotation(gfx::DrawTarget *aTarget, ContextSource aSource,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
|
gfx::CompositionOp aOperator,
|
||||||
gfx::SourceSurface* aMask,
|
gfx::SourceSurface* aMask,
|
||||||
const gfx::Matrix* aMaskTransform) const
|
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
|
// 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
|
// though! Particularly on D2D Repeat should be a lot faster, need to look
|
||||||
// into that. TODO[Bas]
|
// into that. TODO[Bas]
|
||||||
DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aMask, aMaskTransform);
|
DrawBufferQuadrant(aTarget, LEFT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
|
||||||
DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aMask, aMaskTransform);
|
DrawBufferQuadrant(aTarget, RIGHT, TOP, aSource, aOpacity, aOperator, aMask, aMaskTransform);
|
||||||
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
|
DrawBufferQuadrant(aTarget, LEFT, BOTTOM, aSource, aOpacity, aOperator, aMask, aMaskTransform);
|
||||||
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aMask, aMaskTransform);
|
DrawBufferQuadrant(aTarget, RIGHT, BOTTOM, aSource, aOpacity, aOperator,aMask, aMaskTransform);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
@ -306,7 +320,8 @@ ThebesLayerBuffer::DrawTo(ThebesLayer* aLayer,
|
|||||||
maskTransform = ToMatrix(*aMaskTransform);
|
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) {
|
if (clipped) {
|
||||||
dt->PopClip();
|
dt->PopClip();
|
||||||
}
|
}
|
||||||
@ -727,7 +742,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
|||||||
destDTBuffer->SetTransform(mat);
|
destDTBuffer->SetTransform(mat);
|
||||||
EnsureBuffer();
|
EnsureBuffer();
|
||||||
MOZ_ASSERT(mDTBuffer, "Have we got a Thebes buffer for some reason?");
|
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());
|
destDTBuffer->SetTransform(Matrix());
|
||||||
|
|
||||||
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
|
||||||
@ -735,7 +750,7 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
|
|||||||
destDTBufferOnWhite->SetTransform(mat);
|
destDTBufferOnWhite->SetTransform(mat);
|
||||||
EnsureBufferOnWhite();
|
EnsureBufferOnWhite();
|
||||||
MOZ_ASSERT(destDTBufferOnWhite, "Have we got a Thebes buffer for some reason?");
|
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());
|
destDTBufferOnWhite->SetTransform(Matrix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,6 +87,7 @@ public:
|
|||||||
|
|
||||||
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
|
void DrawBufferWithRotation(gfx::DrawTarget* aTarget, ContextSource aSource,
|
||||||
float aOpacity = 1.0,
|
float aOpacity = 1.0,
|
||||||
|
gfx::CompositionOp aOperator = gfx::OP_OVER,
|
||||||
gfx::SourceSurface* aMask = nullptr,
|
gfx::SourceSurface* aMask = nullptr,
|
||||||
const gfx::Matrix* aMaskTransform = nullptr) const;
|
const gfx::Matrix* aMaskTransform = nullptr) const;
|
||||||
|
|
||||||
@ -124,6 +125,7 @@ protected:
|
|||||||
void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
|
void DrawBufferQuadrant(gfx::DrawTarget* aTarget, XSide aXSide, YSide aYSide,
|
||||||
ContextSource aSource,
|
ContextSource aSource,
|
||||||
float aOpacity,
|
float aOpacity,
|
||||||
|
gfx::CompositionOp aOperator,
|
||||||
gfx::SourceSurface* aMask,
|
gfx::SourceSurface* aMask,
|
||||||
const gfx::Matrix* aMaskTransform) const;
|
const gfx::Matrix* aMaskTransform) const;
|
||||||
|
|
||||||
|
@ -537,11 +537,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
|||||||
|
|
||||||
if (SupportsAzureContent()) {
|
if (SupportsAzureContent()) {
|
||||||
MOZ_ASSERT(!destCtx->IsCairo());
|
MOZ_ASSERT(!destCtx->IsCairo());
|
||||||
|
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK, 1.0, OP_SOURCE);
|
||||||
if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) {
|
|
||||||
destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height));
|
|
||||||
}
|
|
||||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_BLACK);
|
|
||||||
} else {
|
} else {
|
||||||
aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
|
aSource.DrawBufferWithRotation(destCtx, BUFFER_BLACK);
|
||||||
}
|
}
|
||||||
@ -559,11 +555,7 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
|||||||
|
|
||||||
if (SupportsAzureContent()) {
|
if (SupportsAzureContent()) {
|
||||||
MOZ_ASSERT(!destCtx->IsCairo());
|
MOZ_ASSERT(!destCtx->IsCairo());
|
||||||
|
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE, 1.0, OP_SOURCE);
|
||||||
if (destCtx->GetDrawTarget()->GetFormat() == FORMAT_B8G8R8A8) {
|
|
||||||
destCtx->GetDrawTarget()->ClearRect(Rect(0, 0, mFrontBufferRect.width, mFrontBufferRect.height));
|
|
||||||
}
|
|
||||||
aSource.DrawBufferWithRotation(destCtx->GetDrawTarget(), BUFFER_WHITE);
|
|
||||||
} else {
|
} else {
|
||||||
aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
|
aSource.DrawBufferWithRotation(destCtx, BUFFER_WHITE);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user