Bug 1465590 - Don't clear a tile if we are painting opaque content. r?nical
MozReview-Commit-ID: IKayyoo19eG
--- a/gfx/layers/client/MultiTiledContentClient.cpp
+++ b/gfx/layers/client/MultiTiledContentClient.cpp
@@ -437,16 +437,18 @@ ClientMultiTiledLayerBuffer::ValidateTil
// Add the region we copied from the front buffer into the painted region
extraPainted.MoveBy(aTileOrigin);
extraPainted.And(extraPainted, mNewValidRegion);
if (!backBuffer) {
return false;
}
+ // Get the targets to draw into, and create a dual target
+ // if we are using component alpha
RefPtr<DrawTarget> dt = backBuffer->BorrowDrawTarget();
RefPtr<DrawTarget> dtOnWhite;
if (backBufferOnWhite) {
dtOnWhite = backBufferOnWhite->BorrowDrawTarget();
}
if (!dt || (backBufferOnWhite && !dtOnWhite)) {
aTile.DiscardBuffers();
@@ -455,49 +457,59 @@ ClientMultiTiledLayerBuffer::ValidateTil
RefPtr<DrawTarget> drawTarget;
if (dtOnWhite) {
drawTarget = Factory::CreateDualDrawTarget(dt, dtOnWhite);
} else {
drawTarget = dt;
}
- auto clear = CapturedTiledPaintState::Clear{
- dt,
- dtOnWhite,
- tileDirtyRegion
- };
+ // We need to clear the dirty region of the tile before painting
+ // if we are painting non-opaque content
+ Maybe<CapturedTiledPaintState::Clear> clear = Nothing();
+ if (mode != SurfaceMode::SURFACE_OPAQUE) {
+ clear = Some(CapturedTiledPaintState::Clear{
+ dt,
+ dtOnWhite,
+ tileDirtyRegion
+ });
+ }
+ // Queue or execute the paint operation
gfx::Tile paintTile;
paintTile.mTileOrigin = gfx::IntPoint(aTileOrigin.x, aTileOrigin.y);
if (aFlags & TilePaintFlags::Async) {
RefPtr<CapturedTiledPaintState> asyncPaint = new CapturedTiledPaintState();
RefPtr<DrawTargetCapture> captureDT =
Factory::CreateCaptureDrawTarget(drawTarget->GetBackendType(),
drawTarget->GetSize(),
drawTarget->GetFormat());
paintTile.mDrawTarget = captureDT;
asyncPaint->mTarget = drawTarget;
asyncPaint->mCapture = captureDT;
asyncPaint->mCopies = std::move(asyncPaintCopies);
- asyncPaint->mClears.push_back(clear);
+ if (clear) {
+ asyncPaint->mClears.push_back(*clear);
+ }
asyncPaint->mClients = std::move(asyncPaintClients);
asyncPaint->mClients.push_back(backBuffer);
if (backBufferOnWhite) {
asyncPaint->mClients.push_back(backBufferOnWhite);
}
mPaintStates.push_back(asyncPaint);
} else {
paintTile.mDrawTarget = drawTarget;
- clear.ClearBuffer();
+ if (clear) {
+ clear->ClearBuffer();
+ }
}
mPaintTiles.push_back(paintTile);
mTilingOrigin.x = std::min(mTilingOrigin.x, paintTile.mTileOrigin.x);
mTilingOrigin.y = std::min(mTilingOrigin.y, paintTile.mTileOrigin.y);
// The new buffer is now validated, remove the dirty region from it.