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

This commit is contained in:
James Willcox 2016-04-26 09:05:14 -05:00
Родитель e05e837ec0
Коммит 94ec972fe7
10 изменённых файлов: 112 добавлений и 11 удалений

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

@ -1676,7 +1676,7 @@ public:
* Returns the current area of the layer (in layer-space coordinates)
* marked as needed to be recomposited.
*/
const gfx::TiledIntRegion& GetInvalidRegion() { return mInvalidRegion; }
const virtual gfx::TiledIntRegion& GetInvalidRegion() { return mInvalidRegion; }
void AddInvalidRegion(const nsIntRegion& aRegion) {
mInvalidRegion.Add(aRegion);
}

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

@ -506,7 +506,7 @@ TileClient::PrivateProtector::Set(TileClient * const aContainer, TextureClient*
// Placeholder
TileClient::TileClient()
: mCompositableClient(nullptr)
: mCompositableClient(nullptr), mWasPlaceholder(false)
{
}
@ -527,6 +527,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;
@ -548,6 +549,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;
@ -832,9 +834,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.
@ -846,13 +851,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);
}
}
@ -879,12 +886,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();

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

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

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

@ -59,6 +59,10 @@ public:
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
bool PaintWillResample() { return mPaintWillResample; }
// We use this to allow TiledContentHost to invalidate regions where
// tiles are fading in.
virtual void AddAnimationInvalidation(nsIntRegion& aRegion) { }
protected:
explicit ContentHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo)

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

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

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

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

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

@ -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/CompositorBridgeParent.h" // for CompositorBridgeParent
#include "mozilla/layers/Effects.h" // for TexturedEffect, Effect, etc
#include "mozilla/layers/LayerMetricsWrapper.h" // for LayerMetricsWrapper
#include "mozilla/layers/TextureHostOGL.h" // for TextureHostOGL
@ -26,6 +27,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()
{}
@ -48,6 +69,21 @@ TiledLayerBufferComposite::SetCompositor(Compositor* aCompositor)
}
}
void
TiledLayerBufferComposite::AddAnimationInvalidation(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())
@ -246,6 +282,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;
@ -323,6 +367,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.
@ -500,6 +558,7 @@ TiledContentHost::RenderTile(TileHost& aTile,
return;
}
float opacity = aTile.GetFadeInOpacity(aOpacity);
aEffectChain.mPrimaryEffect = effect;
for (auto iter = aScreenRegion.RectIter(); !iter.Done(); iter.Next()) {
@ -512,7 +571,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) {
@ -648,5 +707,12 @@ TiledContentHost::Dump(std::stringstream& aStream,
TextureDumpMode::DoNotCompress /* compression not supported on host side */);
}
void
TiledContentHost::AddAnimationInvalidation(nsIntRegion& aRegion)
{
return mTiledBuffer.AddAnimationInvalidation(aRegion);
}
} // namespace layers
} // namespace mozilla

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

@ -111,6 +111,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;
@ -118,6 +126,7 @@ public:
mutable CompositableTextureSourceRef mTextureSourceOnWhite;
// This is not strictly necessary but makes debugging whole lot easier.
TileIntPoint mTilePosition;
TimeStamp mFadeStart;
};
class TiledLayerBufferComposite
@ -146,6 +155,7 @@ public:
void SetCompositor(Compositor* aCompositor);
void AddAnimationInvalidation(nsIntRegion& aRegion);
protected:
CSSToParentLayerScale2D mFrameResolution;
@ -263,6 +273,8 @@ public:
virtual void PrintInfo(std::stringstream& aStream, const char* aPrefix) override;
virtual void AddAnimationInvalidation(nsIntRegion& aRegion) override;
private:
void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,

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

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

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

@ -394,6 +394,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, 250);
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, true);