mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 992486 - Part 5: Fix copying the front buffer to back buffer. r=roc
This commit is contained in:
parent
bf1ea57aff
commit
15c07b67c1
@ -228,8 +228,32 @@ RotatedContentBuffer::DrawTo(ThebesLayer* aLayer,
|
||||
|
||||
DrawTarget*
|
||||
RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
ContextSource aSource)
|
||||
ContextSource aSource,
|
||||
DrawIterator* aIter)
|
||||
{
|
||||
nsIntRect bounds = aBounds;
|
||||
if (aIter) {
|
||||
// If an iterator was provided, then BeginPaint must have been run with
|
||||
// PAINT_CAN_DRAW_ROTATED, and the draw region might cover multiple quadrants.
|
||||
// Iterate over each of them, and return an appropriate buffer each time we find
|
||||
// one that intersects the draw region. The iterator mCount value tracks which
|
||||
// quadrants we have considered across multiple calls to this function.
|
||||
aIter->mDrawRegion.SetEmpty();
|
||||
while (aIter->mCount < 4) {
|
||||
nsIntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT,
|
||||
(aIter->mCount & 2) ? TOP : BOTTOM);
|
||||
aIter->mDrawRegion.And(aBounds, quadrant);
|
||||
aIter->mCount++;
|
||||
if (!aIter->mDrawRegion.IsEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aIter->mDrawRegion.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
bounds = aIter->mDrawRegion.GetBounds();
|
||||
}
|
||||
|
||||
if (!EnsureBuffer()) {
|
||||
return nullptr;
|
||||
}
|
||||
@ -254,10 +278,10 @@ RotatedContentBuffer::BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds
|
||||
// Figure out which quadrant to draw in
|
||||
int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
|
||||
int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
|
||||
XSide sideX = aBounds.XMost() <= xBoundary ? RIGHT : LEFT;
|
||||
YSide sideY = aBounds.YMost() <= yBoundary ? BOTTOM : TOP;
|
||||
XSide sideX = bounds.XMost() <= xBoundary ? RIGHT : LEFT;
|
||||
YSide sideY = bounds.YMost() <= yBoundary ? BOTTOM : TOP;
|
||||
nsIntRect quadrantRect = GetQuadrantRectangle(sideX, sideY);
|
||||
NS_ASSERTION(quadrantRect.Contains(aBounds), "Messed up quadrants");
|
||||
NS_ASSERTION(quadrantRect.Contains(bounds), "Messed up quadrants");
|
||||
|
||||
mLoanedTransform = mLoanedDrawTarget->GetTransform();
|
||||
mLoanedTransform.Translate(-quadrantRect.x, -quadrantRect.y);
|
||||
@ -673,33 +697,18 @@ RotatedContentBuffer::BorrowDrawTargetForPainting(const PaintState& aPaintState,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const nsIntRegion* drawPtr;
|
||||
if (aIter) {
|
||||
// If an iterator was provided, then BeginPaint must have been run with
|
||||
// PAINT_CAN_DRAW_ROTATED, and the draw region might cover multiple quadrants.
|
||||
// Iterate over each of them, and return an appropriate buffer each time we find
|
||||
// one that intersects the draw region. The iterator mCount value tracks which
|
||||
// quadrants we have considered across multiple calls to this function.
|
||||
aIter->mDrawRegion.SetEmpty();
|
||||
while (aIter->mCount < 4) {
|
||||
nsIntRect quadrant = GetQuadrantRectangle((aIter->mCount & 1) ? LEFT : RIGHT,
|
||||
(aIter->mCount & 2) ? TOP : BOTTOM);
|
||||
aIter->mDrawRegion.And(aPaintState.mRegionToDraw, quadrant);
|
||||
aIter->mCount++;
|
||||
if (!aIter->mDrawRegion.IsEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (aIter->mDrawRegion.IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
drawPtr = &aIter->mDrawRegion;
|
||||
} else {
|
||||
drawPtr = &aPaintState.mRegionToDraw;
|
||||
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(aPaintState.mRegionToDraw.GetBounds(),
|
||||
BUFFER_BOTH, aIter);
|
||||
if (!result) {
|
||||
return nullptr;
|
||||
}
|
||||
const nsIntRegion* drawPtr = &aPaintState.mRegionToDraw;
|
||||
if (aIter) {
|
||||
// The iterators draw region currently only contains the bounds of the region,
|
||||
// this makes it the precise region.
|
||||
aIter->mDrawRegion.And(aIter->mDrawRegion, aPaintState.mRegionToDraw);
|
||||
drawPtr = &aIter->mDrawRegion;
|
||||
}
|
||||
|
||||
DrawTarget* result = BorrowDrawTargetForQuadrantUpdate(drawPtr->GetBounds(),
|
||||
BUFFER_BOTH);
|
||||
|
||||
if (aPaintState.mMode == SurfaceMode::SURFACE_COMPONENT_ALPHA) {
|
||||
MOZ_ASSERT(mDTBuffer && mDTBufferOnWhite);
|
||||
|
@ -358,7 +358,8 @@ protected:
|
||||
*/
|
||||
gfx::DrawTarget*
|
||||
BorrowDrawTargetForQuadrantUpdate(const nsIntRect& aBounds,
|
||||
ContextSource aSource);
|
||||
ContextSource aSource,
|
||||
DrawIterator* aIter);
|
||||
|
||||
static bool IsClippingCheap(gfx::DrawTarget* aTarget, const nsIntRegion& aRegion);
|
||||
|
||||
|
@ -499,39 +499,15 @@ void
|
||||
ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
const nsIntRegion& aUpdateRegion)
|
||||
{
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK);
|
||||
if (!destDT) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, CompositionOp::OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
// Flush the destination before the sources become inaccessible (Unlock).
|
||||
destDT->Flush();
|
||||
ReturnDrawTargetToBuffer(destDT);
|
||||
|
||||
if (aSource.HaveBufferOnWhite()) {
|
||||
MOZ_ASSERT(HaveBufferOnWhite());
|
||||
DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE);
|
||||
if (!destDT) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool isClippingCheap = IsClippingCheap(destDT, aUpdateRegion);
|
||||
DrawIterator iter;
|
||||
while (DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_BLACK, &iter)) {
|
||||
bool isClippingCheap = IsClippingCheap(destDT, iter.mDrawRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destDT, aUpdateRegion);
|
||||
gfxUtils::ClipToRegion(destDT, iter.mDrawRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, CompositionOp::OP_SOURCE);
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_BLACK, 1.0, CompositionOp::OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
@ -539,6 +515,26 @@ ContentClientDoubleBuffered::UpdateDestinationFrom(const RotatedBuffer& aSource,
|
||||
destDT->Flush();
|
||||
ReturnDrawTargetToBuffer(destDT);
|
||||
}
|
||||
|
||||
if (aSource.HaveBufferOnWhite()) {
|
||||
MOZ_ASSERT(HaveBufferOnWhite());
|
||||
DrawIterator whiteIter;
|
||||
while (DrawTarget* destDT =
|
||||
BorrowDrawTargetForQuadrantUpdate(aUpdateRegion.GetBounds(), BUFFER_WHITE, &whiteIter)) {
|
||||
bool isClippingCheap = IsClippingCheap(destDT, whiteIter.mDrawRegion);
|
||||
if (isClippingCheap) {
|
||||
gfxUtils::ClipToRegion(destDT, whiteIter.mDrawRegion);
|
||||
}
|
||||
|
||||
aSource.DrawBufferWithRotation(destDT, BUFFER_WHITE, 1.0, CompositionOp::OP_SOURCE);
|
||||
if (isClippingCheap) {
|
||||
destDT->PopClip();
|
||||
}
|
||||
// Flush the destination before the sources become inaccessible (Unlock).
|
||||
destDT->Flush();
|
||||
ReturnDrawTargetToBuffer(destDT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user