Move buffer clearing after all copies in SingleTiledContentClient (bug 1422392, r=nical)

CaptureTiledPaintState will execute all buffer copy operations first,
followed by all buffer clears. This works for MultiTiledContentClient
as it does those operations in that order. SingleTiledContentClient
can do copies, followed by a clear, followed by some copies.

If the clears are hoisted after the copies, graphical corruption can
happen. I think the easiest way to fix this is to move the clear
after the copies and sub out the region that has been successfully
copied.

MozReview-Commit-ID: EfMVmCzyy8w

--HG--
extra : rebase_source : aa9dfa0e38b0173100da99d7111a8c412c628c60
This commit is contained in:
Ryan Hunt 2017-12-06 12:28:37 -06:00
Родитель 919893286a
Коммит 3405de8af3
1 изменённых файлов: 24 добавлений и 15 удалений

Просмотреть файл

@ -186,24 +186,12 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
dtOnWhite = backBufferOnWhite->BorrowDrawTarget(); dtOnWhite = backBufferOnWhite->BorrowDrawTarget();
} }
if (mode != SurfaceMode::SURFACE_OPAQUE) {
auto clear = CapturedTiledPaintState::Clear{
dt,
dtOnWhite,
tileDirtyRegion,
};
if (asyncPaint) {
paintClears.push_back(clear);
} else {
clear.ClearBuffer();
}
}
// If the old frontbuffer was discarded then attempt to copy what we // If the old frontbuffer was discarded then attempt to copy what we
// can from it to the new backbuffer. // can from it to the new backbuffer.
bool copiedFromDiscarded = false;
nsIntRegion copyableRegion;
if (discardedFrontBuffer) { if (discardedFrontBuffer) {
nsIntRegion copyableRegion;
copyableRegion.And(aNewValidRegion, discardedValidRegion); copyableRegion.And(aNewValidRegion, discardedValidRegion);
copyableRegion.SubOut(aDirtyRegion); copyableRegion.SubOut(aDirtyRegion);
@ -266,10 +254,31 @@ ClientSingleTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
// We don't need to repaint valid content that was just copied. // We don't need to repaint valid content that was just copied.
paintRegion.SubOut(copyableRegion); paintRegion.SubOut(copyableRegion);
copiedFromDiscarded = true;
} }
} }
} }
if (mode != SurfaceMode::SURFACE_OPAQUE) {
nsIntRegion regionToClear = tileDirtyRegion;
if (copiedFromDiscarded) {
copyableRegion.MoveBy(-mTilingOrigin);
regionToClear.SubOut(copyableRegion);
}
auto clear = CapturedTiledPaintState::Clear{
dt,
dtOnWhite,
regionToClear,
};
if (asyncPaint) {
paintClears.push_back(clear);
} else {
clear.ClearBuffer();
}
}
if (dtOnWhite) { if (dtOnWhite) {
dt = gfx::Factory::CreateDualDrawTarget(dt, dtOnWhite); dt = gfx::Factory::CreateDualDrawTarget(dt, dtOnWhite);
dtOnWhite = nullptr; dtOnWhite = nullptr;