Bug 1108164 - Remove per-tile drawing. r=Bas

This commit is contained in:
Nicolas Silva 2014-12-17 17:32:29 +01:00
Родитель 5ec594bb99
Коммит cabb056a02
3 изменённых файлов: 57 добавлений и 121 удалений

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

@ -883,20 +883,7 @@ ClientTiledLayerBuffer::PaintThebes(const nsIntRegion& aNewValidRegion,
// If this region is empty XMost() - 1 will give us a negative value.
NS_ASSERTION(!aPaintRegion.GetBounds().IsEmpty(), "Empty paint region\n");
bool useSinglePaintBuffer = UseSinglePaintBuffer();
// XXX The single-tile case doesn't work at the moment, see bug 850396
/*
if (useSinglePaintBuffer) {
// Check if the paint only spans a single tile. If that's
// the case there's no point in using a single paint buffer.
nsIntRect paintBounds = aPaintRegion.GetBounds();
useSinglePaintBuffer = GetTileStart(paintBounds.x) !=
GetTileStart(paintBounds.XMost() - 1) ||
GetTileStart(paintBounds.y) !=
GetTileStart(paintBounds.YMost() - 1);
}
*/
if (useSinglePaintBuffer && !gfxPrefs::TiledDrawTargetEnabled()) {
if (!gfxPrefs::TiledDrawTargetEnabled()) {
nsRefPtr<gfxContext> ctxt;
const nsIntRect bounds = aPaintRegion.GetBounds();
@ -1118,7 +1105,9 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
nsIntRegion offsetScaledDirtyRegion = aDirtyRegion.MovedBy(-aTileOrigin);
offsetScaledDirtyRegion.ScaleRoundOut(mResolution, mResolution);
bool usingSinglePaintBuffer = !!mSinglePaintDrawTarget;
bool usingTiledDrawTarget = gfxPrefs::TiledDrawTargetEnabled();
MOZ_ASSERT(usingTiledDrawTarget || !!mSinglePaintDrawTarget);
SurfaceMode mode;
gfxContentType content = GetContentType(&mode);
nsIntRegion extraPainted;
@ -1127,7 +1116,7 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
aTile.GetBackBuffer(offsetScaledDirtyRegion,
content, mode,
&createdTextureClient, extraPainted,
!usingSinglePaintBuffer && !gfxPrefs::TiledDrawTargetEnabled(),
usingTiledDrawTarget,
&backBufferOnWhite);
extraPainted.MoveBy(aTileOrigin);
@ -1160,7 +1149,7 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
}
}
if (gfxPrefs::TiledDrawTargetEnabled()) {
if (usingTiledDrawTarget) {
aTile.Flip();
if (createdTextureClient) {
@ -1222,11 +1211,17 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
}
}
// The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidFront.Sub(nsIntRect(0, 0, GetTileSize().width, GetTileSize().height),
offsetScaledDirtyRegion);
return aTile;
} else {
MOZ_ASSERT(!backBufferOnWhite, "Component alpha only supported with TiledDrawTarget");
}
// Single paint buffer case:
MOZ_ASSERT(!backBufferOnWhite, "Component alpha only supported with TiledDrawTarget");
// We must not keep a reference to the DrawTarget after it has been unlocked,
// make sure these are null'd before unlocking as destruction of the context
// may cause the target to be flushed.
@ -1235,107 +1230,55 @@ ClientTiledLayerBuffer::ValidateTile(TileClient aTile,
RefPtr<gfxContext> ctxt = new gfxContext(drawTarget);
if (usingSinglePaintBuffer) {
// XXX Perhaps we should just copy the bounding rectangle here?
RefPtr<gfx::SourceSurface> source = mSinglePaintDrawTarget->Snapshot();
nsIntRegionRectIterator it(aDirtyRegion);
for (const nsIntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
// XXX Perhaps we should just copy the bounding rectangle here?
RefPtr<gfx::SourceSurface> source = mSinglePaintDrawTarget->Snapshot();
nsIntRegionRectIterator it(aDirtyRegion);
for (const nsIntRect* dirtyRect = it.Next(); dirtyRect != nullptr; dirtyRect = it.Next()) {
#ifdef GFX_TILEDLAYER_PREF_WARNINGS
printf_stderr(" break into subdirtyRect %i, %i, %i, %i\n",
dirtyRect->x, dirtyRect->y, dirtyRect->width, dirtyRect->height);
printf_stderr(" break into subdirtyRect %i, %i, %i, %i\n",
dirtyRect->x, dirtyRect->y, dirtyRect->width, dirtyRect->height);
#endif
gfx::Rect drawRect(dirtyRect->x - aTileOrigin.x,
dirtyRect->y - aTileOrigin.y,
dirtyRect->width,
dirtyRect->height);
drawRect.Scale(mResolution);
gfx::Rect drawRect(dirtyRect->x - aTileOrigin.x,
dirtyRect->y - aTileOrigin.y,
dirtyRect->width,
dirtyRect->height);
drawRect.Scale(mResolution);
gfx::IntRect copyRect(NS_roundf((dirtyRect->x - mSinglePaintBufferOffset.x) * mResolution),
NS_roundf((dirtyRect->y - mSinglePaintBufferOffset.y) * mResolution),
drawRect.width,
drawRect.height);
gfx::IntPoint copyTarget(NS_roundf(drawRect.x), NS_roundf(drawRect.y));
drawTarget->CopySurface(source, copyRect, copyTarget);
// Mark the newly updated area as invalid in the front buffer
aTile.mInvalidFront.Or(aTile.mInvalidFront, nsIntRect(copyTarget.x, copyTarget.y, copyRect.width, copyRect.height));
}
// only worry about padding when not doing low-res
// because it simplifies the math and the artifacts
// won't be noticable
if (mResolution == 1) {
nsIntRect unscaledTile = nsIntRect(aTileOrigin.x,
aTileOrigin.y,
GetTileSize().width,
GetTileSize().height);
nsIntRegion tileValidRegion = GetValidRegion();
tileValidRegion.Or(tileValidRegion, aDirtyRegion);
// We only need to pad out if the tile has area that's not valid
if (!tileValidRegion.Contains(unscaledTile)) {
tileValidRegion = tileValidRegion.Intersect(unscaledTile);
// translate the region into tile space and pad
tileValidRegion.MoveBy(-nsIntPoint(unscaledTile.x, unscaledTile.y));
PadDrawTargetOutFromRegion(drawTarget, tileValidRegion);
}
}
// The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidBack.Sub(nsIntRect(0, 0, GetTileSize().width, GetTileSize().height),
offsetScaledDirtyRegion);
} else {
// Area of the full tile...
nsIntRegion tileRegion =
nsIntRect(aTileOrigin.x, aTileOrigin.y,
GetScaledTileSize().width, GetScaledTileSize().height);
// Intersect this area with the portion that's dirty.
tileRegion = tileRegion.Intersect(aDirtyRegion);
// Add the resolution scale to store the dirty region.
nsIntPoint unscaledTileOrigin = nsIntPoint(aTileOrigin.x * mResolution,
aTileOrigin.y * mResolution);
nsIntRegion unscaledTileRegion(tileRegion);
unscaledTileRegion.ScaleRoundOut(mResolution, mResolution);
// Move invalid areas into scaled layer space.
aTile.mInvalidFront.MoveBy(unscaledTileOrigin);
aTile.mInvalidBack.MoveBy(unscaledTileOrigin);
// Add the area that's going to be redrawn to the invalid area of the
// front region.
aTile.mInvalidFront.Or(aTile.mInvalidFront, unscaledTileRegion);
// Add invalid areas of the backbuffer to the area to redraw.
tileRegion.Or(tileRegion, aTile.mInvalidBack);
// Move invalid areas back into tile space.
aTile.mInvalidFront.MoveBy(-unscaledTileOrigin);
// This will be validated now.
aTile.mInvalidBack.SetEmpty();
nsIntRect bounds = tileRegion.GetBounds();
bounds.MoveBy(-aTileOrigin);
if (GetContentType() != gfxContentType::COLOR) {
drawTarget->ClearRect(Rect(bounds.x, bounds.y, bounds.width, bounds.height));
}
ctxt->NewPath();
ctxt->Clip(gfxRect(bounds.x, bounds.y, bounds.width, bounds.height));
ctxt->SetMatrix(
ctxt->CurrentMatrix().Translate(-unscaledTileOrigin.x,
-unscaledTileOrigin.y).
Scale(mResolution, mResolution));
mCallback(mPaintedLayer, ctxt,
tileRegion.GetBounds(),
DrawRegionClip::NONE,
nsIntRegion(), mCallbackData);
gfx::IntRect copyRect(NS_roundf((dirtyRect->x - mSinglePaintBufferOffset.x) * mResolution),
NS_roundf((dirtyRect->y - mSinglePaintBufferOffset.y) * mResolution),
drawRect.width,
drawRect.height);
gfx::IntPoint copyTarget(NS_roundf(drawRect.x), NS_roundf(drawRect.y));
drawTarget->CopySurface(source, copyRect, copyTarget);
// Mark the newly updated area as invalid in the front buffer
aTile.mInvalidFront.Or(aTile.mInvalidFront, nsIntRect(copyTarget.x, copyTarget.y, copyRect.width, copyRect.height));
}
// only worry about padding when not doing low-res
// because it simplifies the math and the artifacts
// won't be noticable
if (mResolution == 1) {
nsIntRect unscaledTile = nsIntRect(aTileOrigin.x,
aTileOrigin.y,
GetTileSize().width,
GetTileSize().height);
nsIntRegion tileValidRegion = GetValidRegion();
tileValidRegion.Or(tileValidRegion, aDirtyRegion);
// We only need to pad out if the tile has area that's not valid
if (!tileValidRegion.Contains(unscaledTile)) {
tileValidRegion = tileValidRegion.Intersect(unscaledTile);
// translate the region into tile space and pad
tileValidRegion.MoveBy(-nsIntPoint(unscaledTile.x, unscaledTile.y));
PadDrawTargetOutFromRegion(drawTarget, tileValidRegion);
}
}
// The new buffer is now validated, remove the dirty region from it.
aTile.mInvalidBack.Sub(nsIntRect(0, 0, GetTileSize().width, GetTileSize().height),
offsetScaledDirtyRegion);
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
DrawDebugOverlay(drawTarget, aTileOrigin.x * mResolution,
aTileOrigin.y * mPresShellResolution, GetTileLength(), GetTileLength());

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

@ -445,12 +445,6 @@ protected:
void UnlockTile(TileClient aTile);
// If this returns true, we perform the paint operation into a single large
// buffer and copy it out to the tiles instead of calling PaintThebes() on
// each tile individually. Somewhat surprisingly, this turns out to be faster
// on Android.
bool UseSinglePaintBuffer() { return !gfxPrefs::PerTileDrawing(); }
void ReleaseTile(TileClient aTile) { aTile.Release(); }
void SwapTiles(TileClient& aTileA, TileClient& aTileB) { std::swap(aTileA, aTileB); }

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

@ -280,7 +280,6 @@ private:
DECL_GFX_PREF(Once, "layers.enable-tiles", LayersTilesEnabledDoNotUseDirectly, bool, false);
DECL_GFX_PREF(Once, "layers.force-enable-tiles", LayersTilesForceEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.force-per-tile-drawing", PerTileDrawing, bool, false);
DECL_GFX_PREF(Once, "layers.tiled-drawtarget.enabled", TiledDrawTargetEnabled, bool, false);
// We allow for configurable and rectangular tile size to avoid wasting memory on devices whose
// screen size does not align nicely to the default tile size. Although layers can be any size,