зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1108164 - Remove per-tile drawing. r=Bas
This commit is contained in:
Родитель
5ec594bb99
Коммит
cabb056a02
|
@ -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,
|
||||
|
|
Загрузка…
Ссылка в новой задаче