Bug 1048110 - Expand complex visible regions if we're going to be resampling when using tiling. r=Bas

This commit is contained in:
Matt Woodrow 2014-08-04 15:29:55 +12:00
Родитель dc910067d7
Коммит 2434f004e1
12 изменённых файлов: 51 добавлений и 63 удалений

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

@ -1434,6 +1434,14 @@ public:
virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); } virtual int32_t GetMaxLayerSize() { return Manager()->GetMaxTextureSize(); }
/**
* Returns true if this layer's effective transform is not just
* a translation by integers, or if this layer or some ancestor layer
* is marked as having a transform that may change without a full layer
* transaction.
*/
bool MayResample();
protected: protected:
Layer(LayerManager* aManager, void* aImplData); Layer(LayerManager* aManager, void* aImplData);
@ -1482,14 +1490,6 @@ protected:
const gfxRect& aSnapRect, const gfxRect& aSnapRect,
gfx::Matrix* aResidualTransform); gfx::Matrix* aResidualTransform);
/**
* Returns true if this layer's effective transform is not just
* a translation by integers, or if this layer or some ancestor layer
* is marked as having a transform that may change without a full layer
* transaction.
*/
bool MayResample();
LayerManager* mManager; LayerManager* mManager;
ContainerLayer* mParent; ContainerLayer* mParent;
Layer* mNextSibling; Layer* mNextSibling;

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

@ -335,8 +335,14 @@ ClientTiledThebesLayer::RenderLayer()
TILING_LOG("TILING %p: Initial valid region %s\n", this, Stringify(mValidRegion).c_str()); TILING_LOG("TILING %p: Initial valid region %s\n", this, Stringify(mValidRegion).c_str());
TILING_LOG("TILING %p: Initial low-precision valid region %s\n", this, Stringify(mLowPrecisionValidRegion).c_str()); TILING_LOG("TILING %p: Initial low-precision valid region %s\n", this, Stringify(mLowPrecisionValidRegion).c_str());
nsIntRegion neededRegion = mVisibleRegion;
if (neededRegion.GetNumRects() > 1 &&
MayResample()) {
neededRegion = neededRegion.GetBounds();
}
nsIntRegion invalidRegion; nsIntRegion invalidRegion;
invalidRegion.Sub(mVisibleRegion, mValidRegion); invalidRegion.Sub(neededRegion, mValidRegion);
if (invalidRegion.IsEmpty()) { if (invalidRegion.IsEmpty()) {
EndPaint(); EndPaint();
return; return;
@ -351,7 +357,7 @@ ClientTiledThebesLayer::RenderLayer()
// In some cases we can take a fast path and just be done with it. // In some cases we can take a fast path and just be done with it.
if (UseFastPath()) { if (UseFastPath()) {
TILING_LOG("TILING %p: Taking fast-path\n", this); TILING_LOG("TILING %p: Taking fast-path\n", this);
mValidRegion = mVisibleRegion; mValidRegion = neededRegion;
mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion, callback, data); mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion, callback, data);
ClientManager()->Hold(this); ClientManager()->Hold(this);
mContentClient->UseTiledLayerBuffer(TiledContentClient::TILED_BUFFER); mContentClient->UseTiledLayerBuffer(TiledContentClient::TILED_BUFFER);
@ -368,7 +374,7 @@ ClientTiledThebesLayer::RenderLayer()
// Make sure that tiles that fall outside of the visible region or outside of the // Make sure that tiles that fall outside of the visible region or outside of the
// critical displayport are discarded on the first update. Also make sure that we // critical displayport are discarded on the first update. Also make sure that we
// only draw stuff inside the critical displayport on the first update. // only draw stuff inside the critical displayport on the first update.
mValidRegion.And(mValidRegion, mVisibleRegion); mValidRegion.And(mValidRegion, neededRegion);
if (!mPaintData.mCriticalDisplayPort.IsEmpty()) { if (!mPaintData.mCriticalDisplayPort.IsEmpty()) {
mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort));
invalidRegion.And(invalidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); invalidRegion.And(invalidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort));
@ -387,7 +393,7 @@ ClientTiledThebesLayer::RenderLayer()
if (gfxPrefs::UseLowPrecisionBuffer()) { if (gfxPrefs::UseLowPrecisionBuffer()) {
// Calculate the invalid region for the low precision buffer. Make sure // Calculate the invalid region for the low precision buffer. Make sure
// to remove the valid high-precision area so we don't double-paint it. // to remove the valid high-precision area so we don't double-paint it.
lowPrecisionInvalidRegion.Sub(mVisibleRegion, mLowPrecisionValidRegion); lowPrecisionInvalidRegion.Sub(neededRegion, mLowPrecisionValidRegion);
lowPrecisionInvalidRegion.Sub(lowPrecisionInvalidRegion, mValidRegion); lowPrecisionInvalidRegion.Sub(lowPrecisionInvalidRegion, mValidRegion);
} }
TILING_LOG("TILING %p: Low-precision invalid region %s\n", this, Stringify(lowPrecisionInvalidRegion).c_str()); TILING_LOG("TILING %p: Low-precision invalid region %s\n", this, Stringify(lowPrecisionInvalidRegion).c_str());

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

@ -327,6 +327,12 @@ ClientTiledLayerBuffer::GetContentType(SurfaceMode* aMode) const
content = gfxContentType::COLOR; content = gfxContentType::COLOR;
} }
#endif #endif
} else if (mode == SurfaceMode::SURFACE_OPAQUE) {
if (mThebesLayer->GetVisibleRegion().GetNumRects() > 1 &&
mThebesLayer->MayResample()) {
mode = SurfaceMode::SURFACE_SINGLE_CHANNEL_ALPHA;
content = gfxContentType::COLOR_ALPHA;
}
} }
if (aMode) { if (aMode) {

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

@ -37,14 +37,6 @@ class DataSourceSurface;
namespace layers { namespace layers {
// Some properties of a Layer required for tiling
struct TiledLayerProperties
{
nsIntRegion mVisibleRegion;
nsIntRegion mValidRegion;
CSSToScreenScale mEffectiveResolution;
};
class Layer; class Layer;
class SurfaceDescriptor; class SurfaceDescriptor;
class Compositor; class Compositor;
@ -121,8 +113,7 @@ public:
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr, const nsIntRegion* aVisibleRegion = nullptr) = 0;
TiledLayerProperties* aLayerProperties = nullptr) = 0;
/** /**
* Update the content host. * Update the content host.

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

@ -27,7 +27,6 @@ namespace layers {
ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo) ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo)
: ContentHost(aTextureInfo) : ContentHost(aTextureInfo)
, mPaintWillResample(false)
, mInitialised(false) , mInitialised(false)
{} {}
@ -41,8 +40,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain,
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const Filter& aFilter, const Filter& aFilter,
const Rect& aClipRect, const Rect& aClipRect,
const nsIntRegion* aVisibleRegion, const nsIntRegion* aVisibleRegion)
TiledLayerProperties* aLayerProperties)
{ {
NS_ASSERTION(aVisibleRegion, "Requires a visible region"); NS_ASSERTION(aVisibleRegion, "Requires a visible region");

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

@ -64,12 +64,16 @@ public:
const nsIntRegion& aOldValidRegionBack, const nsIntRegion& aOldValidRegionBack,
nsIntRegion* aUpdatedRegionBack) = 0; nsIntRegion* aUpdatedRegionBack) = 0;
virtual void SetPaintWillResample(bool aResample) { } virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
bool PaintWillResample() { return mPaintWillResample; }
protected: protected:
ContentHost(const TextureInfo& aTextureInfo) ContentHost(const TextureInfo& aTextureInfo)
: CompositableHost(aTextureInfo) : CompositableHost(aTextureInfo)
, mPaintWillResample(false)
{} {}
bool mPaintWillResample;
}; };
/** /**
@ -97,10 +101,7 @@ public:
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr, const nsIntRegion* aVisibleRegion = nullptr);
TiledLayerProperties* aLayerProperties = nullptr);
virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; }
virtual NewTextureSource* GetTextureSource() = 0; virtual NewTextureSource* GetTextureSource() = 0;
virtual NewTextureSource* GetTextureSourceOnWhite() = 0; virtual NewTextureSource* GetTextureSourceOnWhite() = 0;
@ -113,11 +114,9 @@ protected:
return mBufferRect.TopLeft() - mBufferRotation; return mBufferRect.TopLeft() - mBufferRotation;
} }
bool PaintWillResample() { return mPaintWillResample; }
nsIntRect mBufferRect; nsIntRect mBufferRect;
nsIntPoint mBufferRotation; nsIntPoint mBufferRotation;
bool mPaintWillResample;
bool mInitialised; bool mInitialised;
}; };

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

@ -65,8 +65,7 @@ ImageHost::Composite(EffectChain& aEffectChain,
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion, const nsIntRegion* aVisibleRegion)
TiledLayerProperties* aLayerProperties)
{ {
if (!GetCompositor()) { if (!GetCompositor()) {
// should only happen when a tab is dragged to another window and // should only happen when a tab is dragged to another window and

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

@ -50,8 +50,7 @@ public:
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr, const nsIntRegion* aVisibleRegion = nullptr) MOZ_OVERRIDE;
TiledLayerProperties* aLayerProperties = nullptr) MOZ_OVERRIDE;
virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE; virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE;

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

@ -38,7 +38,6 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager)
: ThebesLayer(aManager, nullptr) : ThebesLayer(aManager, nullptr)
, LayerComposite(aManager) , LayerComposite(aManager)
, mBuffer(nullptr) , mBuffer(nullptr)
, mRequiresTiledProperties(false)
{ {
MOZ_COUNT_CTOR(ThebesLayerComposite); MOZ_COUNT_CTOR(ThebesLayerComposite);
mImplData = static_cast<LayerComposite*>(this); mImplData = static_cast<LayerComposite*>(this);
@ -135,13 +134,6 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect)
const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion();
TiledLayerProperties tiledLayerProps;
if (mRequiresTiledProperties) {
tiledLayerProps.mVisibleRegion = visibleRegion;
tiledLayerProps.mEffectiveResolution = GetEffectiveResolution();
tiledLayerProps.mValidRegion = mValidRegion;
}
mBuffer->SetPaintWillResample(MayResample()); mBuffer->SetPaintWillResample(MayResample());
mBuffer->Composite(effectChain, mBuffer->Composite(effectChain,
@ -149,15 +141,9 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect)
GetEffectiveTransform(), GetEffectiveTransform(),
GetEffectFilter(), GetEffectFilter(),
clipRect, clipRect,
&visibleRegion, &visibleRegion);
mRequiresTiledProperties ? &tiledLayerProps
: nullptr);
mBuffer->BumpFlashCounter(); mBuffer->BumpFlashCounter();
if (mRequiresTiledProperties) {
mValidRegion = tiledLayerProps.mValidRegion;
}
mCompositeManager->GetCompositor()->MakeCurrent(); mCompositeManager->GetCompositor()->MakeCurrent();
} }

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

@ -65,8 +65,6 @@ public:
virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; }
void EnsureTiled() { mRequiresTiledProperties = true; }
virtual void InvalidateRegion(const nsIntRegion& aRegion) virtual void InvalidateRegion(const nsIntRegion& aRegion)
{ {
NS_RUNTIMEABORT("ThebesLayerComposites can't fill invalidated regions"); NS_RUNTIMEABORT("ThebesLayerComposites can't fill invalidated regions");
@ -92,7 +90,6 @@ private:
private: private:
RefPtr<ContentHost> mBuffer; RefPtr<ContentHost> mBuffer;
bool mRequiresTiledProperties;
}; };
} /* layers */ } /* layers */

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

@ -241,7 +241,6 @@ TiledContentHost::Attach(Layer* aLayer,
AttachFlags aFlags /* = NO_FLAGS */) AttachFlags aFlags /* = NO_FLAGS */)
{ {
CompositableHost::Attach(aLayer, aCompositor, aFlags); CompositableHost::Attach(aLayer, aCompositor, aFlags);
static_cast<ThebesLayerComposite*>(aLayer)->EnsureTiled();
} }
void void
@ -324,11 +323,8 @@ TiledContentHost::Composite(EffectChain& aEffectChain,
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion /* = nullptr */, const nsIntRegion* aVisibleRegion /* = nullptr */)
TiledLayerProperties* aLayerProperties /* = nullptr */)
{ {
MOZ_ASSERT(aLayerProperties, "aLayerProperties required for TiledContentHost");
if (mPendingUpload) { if (mPendingUpload) {
mTiledBuffer.SetCompositor(mCompositor); mTiledBuffer.SetCompositor(mCompositor);
mTiledBuffer.Upload(); mTiledBuffer.Upload();
@ -374,13 +370,25 @@ TiledContentHost::Composite(EffectChain& aEffectChain,
(aOpacity == 1.0f && backgroundColor.a == 1.0f) (aOpacity == 1.0f && backgroundColor.a == 1.0f)
? gfxPrefs::LowPrecisionOpacity() : 1.0f; ? gfxPrefs::LowPrecisionOpacity() : 1.0f;
nsIntRegion tmpRegion;
const nsIntRegion* renderRegion;
if (PaintWillResample()) {
// If we're resampling, then the texture image will contain exactly the
// entire visible region's bounds, and we should draw it all in one quad
// to avoid unexpected aliasing.
tmpRegion = aVisibleRegion->GetBounds();
renderRegion = &tmpRegion;
} else {
renderRegion = aVisibleRegion;
}
// Render the low and high precision buffers. // Render the low and high precision buffers.
RenderLayerBuffer(mLowPrecisionTiledBuffer, RenderLayerBuffer(mLowPrecisionTiledBuffer,
lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr, lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr,
aEffectChain, lowPrecisionOpacityReduction * aOpacity, aEffectChain, lowPrecisionOpacityReduction * aOpacity,
aFilter, aClipRect, aLayerProperties->mVisibleRegion, aTransform); aFilter, aClipRect, *renderRegion, aTransform);
RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aFilter, RenderLayerBuffer(mTiledBuffer, nullptr, aEffectChain, aOpacity, aFilter,
aClipRect, aLayerProperties->mVisibleRegion, aTransform); aClipRect, *renderRegion, aTransform);
// Now release the old buffer if it had double-buffered tiles, as we can // Now release the old buffer if it had double-buffered tiles, as we can
// guarantee that they're no longer on the screen (and so any locks that may // guarantee that they're no longer on the screen (and so any locks that may

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

@ -223,8 +223,7 @@ public:
const gfx::Matrix4x4& aTransform, const gfx::Matrix4x4& aTransform,
const gfx::Filter& aFilter, const gfx::Filter& aFilter,
const gfx::Rect& aClipRect, const gfx::Rect& aClipRect,
const nsIntRegion* aVisibleRegion = nullptr, const nsIntRegion* aVisibleRegion = nullptr);
TiledLayerProperties* aLayerProperties = nullptr);
virtual CompositableType GetType() { return CompositableType::BUFFER_TILED; } virtual CompositableType GetType() { return CompositableType::BUFFER_TILED; }