Bug 1178376 - Optionally fade in new progressively painted tiles r=nical

This commit is contained in:
James Willcox 2015-09-08 09:24:16 -05:00
parent 55d33074aa
commit fd1ffff272
10 changed files with 112 additions and 11 deletions

View File

@ -1593,7 +1593,7 @@ public:
* Returns the current area of the layer (in layer-space coordinates)
* marked as needed to be recomposited.
*/
const nsIntRegion& GetInvalidRegion() { return mInvalidRegion; }
const virtual nsIntRegion GetInvalidRegion() { return mInvalidRegion; }
const void SetInvalidRegion(const nsIntRegion& aRect) { mInvalidRegion = aRect; }
/**

View File

@ -497,7 +497,7 @@ TileClient::PrivateProtector::Set(TileClient * const aContainer, TextureClient*
// Placeholder
TileClient::TileClient()
: mCompositableClient(nullptr)
: mCompositableClient(nullptr), mWasPlaceholder(false)
{
}
@ -518,6 +518,7 @@ TileClient::TileClient(const TileClient& o)
mBackLock = o.mBackLock;
mFrontLock = o.mFrontLock;
mCompositableClient = o.mCompositableClient;
mWasPlaceholder = o.mWasPlaceholder;
mUpdateRect = o.mUpdateRect;
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
mLastUpdate = o.mLastUpdate;
@ -539,6 +540,7 @@ TileClient::operator=(const TileClient& o)
mBackLock = o.mBackLock;
mFrontLock = o.mFrontLock;
mCompositableClient = o.mCompositableClient;
mWasPlaceholder = o.mWasPlaceholder;
mUpdateRect = o.mUpdateRect;
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
mLastUpdate = o.mLastUpdate;
@ -842,9 +844,12 @@ TileDescriptor
TileClient::GetTileDescriptor()
{
if (IsPlaceholderTile()) {
mWasPlaceholder = true;
return PlaceholderTileDescriptor();
}
MOZ_ASSERT(mFrontLock);
bool wasPlaceholder = mWasPlaceholder;
mWasPlaceholder = false;
if (mFrontLock->GetType() == gfxSharedReadLock::TYPE_MEMORY) {
// AddRef here and Release when receiving on the host side to make sure the
// reference count doesn't go to zero before the host receives the message.
@ -856,13 +861,15 @@ TileClient::GetTileDescriptor()
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
mUpdateRect,
TileLock(uintptr_t(mFrontLock.get())));
TileLock(uintptr_t(mFrontLock.get())),
wasPlaceholder);
} else {
gfxShmSharedReadLock *lock = static_cast<gfxShmSharedReadLock*>(mFrontLock.get());
return TexturedTileDescriptor(nullptr, mFrontBuffer->GetIPDLActor(),
mFrontBufferOnWhite ? MaybeTexture(mFrontBufferOnWhite->GetIPDLActor()) : MaybeTexture(null_t()),
mUpdateRect,
TileLock(lock->GetShmemSection()));
TileLock(lock->GetShmemSection()),
wasPlaceholder);
}
}
@ -889,12 +896,7 @@ ClientMultiTiledLayerBuffer::GetSurfaceDescriptorTiles()
InfallibleTArray<TileDescriptor> tiles;
for (TileClient& tile : mRetainedTiles) {
TileDescriptor tileDesc;
if (tile.IsPlaceholderTile()) {
tileDesc = PlaceholderTileDescriptor();
} else {
tileDesc = tile.GetTileDescriptor();
}
TileDescriptor tileDesc = tile.GetTileDescriptor();
tiles.AppendElement(tileDesc);
// Reset the update rect
tile.mUpdateRect = IntRect();

View File

@ -275,6 +275,7 @@ struct TileClient
RefPtr<TextureClientAllocator> mAllocator;
gfx::IntRect mUpdateRect;
CompositableClient* mCompositableClient;
bool mWasPlaceholder;
#ifdef GFX_TILEDLAYER_DEBUG_OVERLAY
TimeStamp mLastUpdate;
#endif

View File

@ -61,6 +61,8 @@ public:
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
bool PaintWillResample() { return mPaintWillResample; }
virtual void InvalidateForAnimation(nsIntRegion& aRegion) { }
protected:
explicit ContentHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)

View File

@ -179,5 +179,16 @@ PaintedLayerComposite::PrintInfo(std::stringstream& aStream, const char* aPrefix
}
}
const nsIntRegion
PaintedLayerComposite::GetInvalidRegion()
{
nsIntRegion region = mInvalidRegion;
if (mBuffer) {
mBuffer->InvalidateForAnimation(region);
}
return region;
}
} // namespace layers
} // namespace mozilla

View File

@ -73,6 +73,8 @@ public:
Mutated();
}
const virtual nsIntRegion GetInvalidRegion() override;
MOZ_LAYER_DECL_NAME("PaintedLayerComposite", TYPE_PAINTED)
protected:

View File

@ -10,6 +10,7 @@
#include "mozilla/gfx/Matrix.h" // for Matrix4x4
#include "mozilla/gfx/Point.h" // for IntSize
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorParent.h" // for CompositorParent
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
@ -28,6 +29,26 @@ namespace layers {
class Layer;
float
TileHost::GetFadeInOpacity(float aOpacity)
{
TimeStamp now = TimeStamp::Now();
if (!gfxPrefs::LayerTileFadeInEnabled() ||
mFadeStart.IsNull() ||
now < mFadeStart)
{
return aOpacity;
}
float duration = gfxPrefs::LayerTileFadeInDuration();
float elapsed = (now - mFadeStart).ToMilliseconds();
if (elapsed > duration) {
mFadeStart = TimeStamp();
return aOpacity;
}
return aOpacity * (elapsed / duration);
}
TiledLayerBufferComposite::TiledLayerBufferComposite()
: mFrameResolution()
{}
@ -56,6 +77,21 @@ TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor)
}
}
void
TiledLayerBufferComposite::InvalidateForAnimation(nsIntRegion& aRegion)
{
// We need to invalidate rects where we have a tile that is in the
// process of fading in.
for (size_t i = 0; i < mRetainedTiles.Length(); i++) {
if (!mRetainedTiles[i].mFadeStart.IsNull()) {
TileIntPoint position = mTiles.TilePosition(i);
IntPoint offset = GetTileOffset(position);
nsIntRegion tileRegion = IntRect(offset, GetScaledTileSize());
aRegion.OrWith(tileRegion);
}
}
}
TiledContentHost::TiledContentHost(const TextureInfo& aTextureInfo)
: ContentHost(aTextureInfo)
, mTiledBuffer(TiledLayerBufferComposite())
@ -233,6 +269,14 @@ public:
}
}
void RecycleTileFading(TileHost& aTile) {
for (size_t i = 0; i < mTiles.Length(); i++) {
if (mTiles[i].mTextureHost == aTile.mTextureHost) {
aTile.mFadeStart = mTiles[i].mFadeStart;
}
}
}
protected:
nsTArray<TileHost> mTiles;
size_t mFirstPossibility;
@ -310,6 +354,20 @@ TiledLayerBufferComposite::UseTiles(const SurfaceDescriptorTiles& aTiles,
// If this same tile texture existed in the old tile set then this will move the texture
// source into our new tile.
oldRetainedTiles.RecycleTextureSourceForTile(tile);
// If this tile is in the process of fading, we need to keep that going
oldRetainedTiles.RecycleTileFading(tile);
if (aTiles.isProgressive() &&
texturedDesc.wasPlaceholder())
{
// This is a progressive paint, and the tile used to be a placeholder.
// We need to begin fading it in (if enabled via layers.tiles.fade-in.enabled)
tile.mFadeStart = TimeStamp::Now();
aCompositor->CompositeUntil(tile.mFadeStart +
TimeDuration::FromMilliseconds(gfxPrefs::LayerTileFadeInDuration()));
}
}
// Step 3, attempt to recycle unused texture sources from the old tile set into new tiles.
@ -487,6 +545,8 @@ TiledContentHost::RenderTile(TileHost& aTile,
return;
}
float opacity = aTile.GetFadeInOpacity(aOpacity);
aEffectChain.mPrimaryEffect = effect;
nsIntRegionRectIterator it(aScreenRegion);
@ -499,7 +559,7 @@ TiledContentHost::RenderTile(TileHost& aTile,
textureRect.y / aTextureBounds.height,
textureRect.width / aTextureBounds.width,
textureRect.height / aTextureBounds.height);
mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, aOpacity, aTransform, aVisibleRect);
mCompositor->DrawQuad(graphicsRect, aClipRect, aEffectChain, opacity, aTransform, aVisibleRect);
}
DiagnosticFlags flags = DiagnosticFlags::CONTENT | DiagnosticFlags::TILE;
if (aTile.mTextureHostOnWhite) {
@ -634,5 +694,12 @@ TiledContentHost::Dump(std::stringstream& aStream,
mTiledBuffer.Dump(aStream, aPrefix, aDumpHtml);
}
void
TiledContentHost::InvalidateForAnimation(nsIntRegion& aRegion)
{
return mTiledBuffer.InvalidateForAnimation(aRegion);
}
} // namespace layers
} // namespace mozilla

View File

@ -113,6 +113,14 @@ public:
CompositableHost::DumpTextureHost(aStream, mTextureHost);
}
/**
* This does a linear tween of the passed opacity (which is assumed
* to be between 0.0 and 1.0). The duration of the fade is controlled
* by the 'layers.tiles.fade-in.duration-ms' preference. It is enabled
* via 'layers.tiles.fade-in.enabled'
*/
float GetFadeInOpacity(float aOpacity);
RefPtr<gfxSharedReadLock> mSharedLock;
CompositableTextureHostRef mTextureHost;
CompositableTextureHostRef mTextureHostOnWhite;
@ -120,6 +128,7 @@ public:
mutable CompositableTextureSourceRef mTextureSourceOnWhite;
// This is not strictly necessary but makes debugging whole lot easier.
TileIntPoint mTilePosition;
TimeStamp mFadeStart;
};
class TiledLayerBufferComposite
@ -152,6 +161,8 @@ public:
// Used when TiledContentClient is present in client side.
static void RecycleCallback(TextureHost* textureHost, void* aClosure);
void InvalidateForAnimation(nsIntRegion& aRegion);
protected:
CSSToParentLayerScale2D mFrameResolution;
@ -267,6 +278,8 @@ public:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
virtual void InvalidateForAnimation(nsIntRegion& aRegion) override;
private:
void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,

View File

@ -319,6 +319,7 @@ struct TexturedTileDescriptor {
MaybeTexture textureOnWhite;
IntRect updateRect;
TileLock sharedLock;
bool wasPlaceholder;
};
struct PlaceholderTileDescriptor {

View File

@ -352,6 +352,8 @@ private:
DECL_GFX_PREF(Once, "layers.tiled-drawtarget.enabled", TiledDrawTargetEnabled, bool, false);
DECL_GFX_PREF(Once, "layers.tiles.adjust", LayersTilesAdjust, bool, true);
DECL_GFX_PREF(Once, "layers.tiles.edge-padding", TileEdgePaddingEnabled, bool, true);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.enabled", LayerTileFadeInEnabled, bool, false);
DECL_GFX_PREF(Live, "layers.tiles.fade-in.duration-ms", LayerTileFadeInDuration, uint32_t, 100);
DECL_GFX_PREF(Live, "layers.transaction.warning-ms", LayerTransactionWarning, uint32_t, 200);
DECL_GFX_PREF(Once, "layers.uniformity-info", UniformityInfo, bool, false);
DECL_GFX_PREF(Once, "layers.use-image-offscreen-surfaces", UseImageOffscreenSurfaces, bool, false);