diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index fe93bb44d70a..6ab050e17119 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1434,6 +1434,14 @@ public: 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: Layer(LayerManager* aManager, void* aImplData); @@ -1482,14 +1490,6 @@ protected: const gfxRect& aSnapRect, 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; ContainerLayer* mParent; Layer* mNextSibling; diff --git a/gfx/layers/client/ClientTiledThebesLayer.cpp b/gfx/layers/client/ClientTiledThebesLayer.cpp index 004c174d86e1..5220aaf74c56 100644 --- a/gfx/layers/client/ClientTiledThebesLayer.cpp +++ b/gfx/layers/client/ClientTiledThebesLayer.cpp @@ -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 low-precision valid region %s\n", this, Stringify(mLowPrecisionValidRegion).c_str()); + nsIntRegion neededRegion = mVisibleRegion; + if (neededRegion.GetNumRects() > 1 && + MayResample()) { + neededRegion = neededRegion.GetBounds(); + } + nsIntRegion invalidRegion; - invalidRegion.Sub(mVisibleRegion, mValidRegion); + invalidRegion.Sub(neededRegion, mValidRegion); if (invalidRegion.IsEmpty()) { EndPaint(); return; @@ -351,7 +357,7 @@ ClientTiledThebesLayer::RenderLayer() // In some cases we can take a fast path and just be done with it. if (UseFastPath()) { TILING_LOG("TILING %p: Taking fast-path\n", this); - mValidRegion = mVisibleRegion; + mValidRegion = neededRegion; mContentClient->mTiledBuffer.PaintThebes(mValidRegion, invalidRegion, callback, data); ClientManager()->Hold(this); 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 // critical displayport are discarded on the first update. Also make sure that we // only draw stuff inside the critical displayport on the first update. - mValidRegion.And(mValidRegion, mVisibleRegion); + mValidRegion.And(mValidRegion, neededRegion); if (!mPaintData.mCriticalDisplayPort.IsEmpty()) { mValidRegion.And(mValidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); invalidRegion.And(invalidRegion, LayerIntRect::ToUntyped(mPaintData.mCriticalDisplayPort)); @@ -387,7 +393,7 @@ ClientTiledThebesLayer::RenderLayer() if (gfxPrefs::UseLowPrecisionBuffer()) { // 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. - lowPrecisionInvalidRegion.Sub(mVisibleRegion, mLowPrecisionValidRegion); + lowPrecisionInvalidRegion.Sub(neededRegion, mLowPrecisionValidRegion); lowPrecisionInvalidRegion.Sub(lowPrecisionInvalidRegion, mValidRegion); } TILING_LOG("TILING %p: Low-precision invalid region %s\n", this, Stringify(lowPrecisionInvalidRegion).c_str()); diff --git a/gfx/layers/client/TiledContentClient.cpp b/gfx/layers/client/TiledContentClient.cpp index 964b04d36d31..56ccf397995e 100644 --- a/gfx/layers/client/TiledContentClient.cpp +++ b/gfx/layers/client/TiledContentClient.cpp @@ -327,6 +327,12 @@ ClientTiledLayerBuffer::GetContentType(SurfaceMode* aMode) const content = gfxContentType::COLOR; } #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) { diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 8f6b3cddebb0..33a2f4b16efe 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -37,14 +37,6 @@ class DataSourceSurface; namespace layers { -// Some properties of a Layer required for tiling -struct TiledLayerProperties -{ - nsIntRegion mVisibleRegion; - nsIntRegion mValidRegion; - CSSToScreenScale mEffectiveResolution; -}; - class Layer; class SurfaceDescriptor; class Compositor; @@ -121,8 +113,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr) = 0; + const nsIntRegion* aVisibleRegion = nullptr) = 0; /** * Update the content host. diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index d54ec10a4467..72d4dd7495d5 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -27,7 +27,6 @@ namespace layers { ContentHostBase::ContentHostBase(const TextureInfo& aTextureInfo) : ContentHost(aTextureInfo) - , mPaintWillResample(false) , mInitialised(false) {} @@ -41,8 +40,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const Filter& aFilter, const Rect& aClipRect, - const nsIntRegion* aVisibleRegion, - TiledLayerProperties* aLayerProperties) + const nsIntRegion* aVisibleRegion) { NS_ASSERTION(aVisibleRegion, "Requires a visible region"); diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index 40580fcea78a..e5aa7156aa9d 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -64,12 +64,16 @@ public: const nsIntRegion& aOldValidRegionBack, nsIntRegion* aUpdatedRegionBack) = 0; - virtual void SetPaintWillResample(bool aResample) { } + virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } + bool PaintWillResample() { return mPaintWillResample; } protected: ContentHost(const TextureInfo& aTextureInfo) : CompositableHost(aTextureInfo) + , mPaintWillResample(false) {} + + bool mPaintWillResample; }; /** @@ -97,10 +101,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr); - - virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } + const nsIntRegion* aVisibleRegion = nullptr); virtual NewTextureSource* GetTextureSource() = 0; virtual NewTextureSource* GetTextureSourceOnWhite() = 0; @@ -113,11 +114,9 @@ protected: return mBufferRect.TopLeft() - mBufferRotation; } - bool PaintWillResample() { return mPaintWillResample; } nsIntRect mBufferRect; nsIntPoint mBufferRotation; - bool mPaintWillResample; bool mInitialised; }; diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 2025fe0b493b..4e67991e23ec 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -65,8 +65,7 @@ ImageHost::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion, - TiledLayerProperties* aLayerProperties) + const nsIntRegion* aVisibleRegion) { if (!GetCompositor()) { // should only happen when a tab is dragged to another window and diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index 5002a00a52a7..bae8ed772072 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -50,8 +50,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr) MOZ_OVERRIDE; + const nsIntRegion* aVisibleRegion = nullptr) MOZ_OVERRIDE; virtual void UseTextureHost(TextureHost* aTexture) MOZ_OVERRIDE; diff --git a/gfx/layers/composite/ThebesLayerComposite.cpp b/gfx/layers/composite/ThebesLayerComposite.cpp index 3b4870f3f835..e47aaeb4adca 100644 --- a/gfx/layers/composite/ThebesLayerComposite.cpp +++ b/gfx/layers/composite/ThebesLayerComposite.cpp @@ -38,7 +38,6 @@ ThebesLayerComposite::ThebesLayerComposite(LayerManagerComposite *aManager) : ThebesLayer(aManager, nullptr) , LayerComposite(aManager) , mBuffer(nullptr) - , mRequiresTiledProperties(false) { MOZ_COUNT_CTOR(ThebesLayerComposite); mImplData = static_cast(this); @@ -135,13 +134,6 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect) const nsIntRegion& visibleRegion = GetEffectiveVisibleRegion(); - TiledLayerProperties tiledLayerProps; - if (mRequiresTiledProperties) { - tiledLayerProps.mVisibleRegion = visibleRegion; - tiledLayerProps.mEffectiveResolution = GetEffectiveResolution(); - tiledLayerProps.mValidRegion = mValidRegion; - } - mBuffer->SetPaintWillResample(MayResample()); mBuffer->Composite(effectChain, @@ -149,15 +141,9 @@ ThebesLayerComposite::RenderLayer(const nsIntRect& aClipRect) GetEffectiveTransform(), GetEffectFilter(), clipRect, - &visibleRegion, - mRequiresTiledProperties ? &tiledLayerProps - : nullptr); + &visibleRegion); mBuffer->BumpFlashCounter(); - if (mRequiresTiledProperties) { - mValidRegion = tiledLayerProps.mValidRegion; - } - mCompositeManager->GetCompositor()->MakeCurrent(); } diff --git a/gfx/layers/composite/ThebesLayerComposite.h b/gfx/layers/composite/ThebesLayerComposite.h index 49fbc3994222..0a09112cf82a 100644 --- a/gfx/layers/composite/ThebesLayerComposite.h +++ b/gfx/layers/composite/ThebesLayerComposite.h @@ -65,8 +65,6 @@ public: virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } - void EnsureTiled() { mRequiresTiledProperties = true; } - virtual void InvalidateRegion(const nsIntRegion& aRegion) { NS_RUNTIMEABORT("ThebesLayerComposites can't fill invalidated regions"); @@ -92,7 +90,6 @@ private: private: RefPtr mBuffer; - bool mRequiresTiledProperties; }; } /* layers */ diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index 13847958a083..6d4aee59ce5c 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -241,7 +241,6 @@ TiledContentHost::Attach(Layer* aLayer, AttachFlags aFlags /* = NO_FLAGS */) { CompositableHost::Attach(aLayer, aCompositor, aFlags); - static_cast(aLayer)->EnsureTiled(); } void @@ -324,11 +323,8 @@ TiledContentHost::Composite(EffectChain& aEffectChain, const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion /* = nullptr */, - TiledLayerProperties* aLayerProperties /* = nullptr */) + const nsIntRegion* aVisibleRegion /* = nullptr */) { - MOZ_ASSERT(aLayerProperties, "aLayerProperties required for TiledContentHost"); - if (mPendingUpload) { mTiledBuffer.SetCompositor(mCompositor); mTiledBuffer.Upload(); @@ -374,13 +370,25 @@ TiledContentHost::Composite(EffectChain& aEffectChain, (aOpacity == 1.0f && backgroundColor.a == 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. RenderLayerBuffer(mLowPrecisionTiledBuffer, lowPrecisionOpacityReduction < 1.0f ? &backgroundColor : nullptr, aEffectChain, lowPrecisionOpacityReduction * aOpacity, - aFilter, aClipRect, aLayerProperties->mVisibleRegion, aTransform); + aFilter, aClipRect, *renderRegion, aTransform); 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 // guarantee that they're no longer on the screen (and so any locks that may diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index db595e7d82f4..1c29651a4551 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -223,8 +223,7 @@ public: const gfx::Matrix4x4& aTransform, const gfx::Filter& aFilter, const gfx::Rect& aClipRect, - const nsIntRegion* aVisibleRegion = nullptr, - TiledLayerProperties* aLayerProperties = nullptr); + const nsIntRegion* aVisibleRegion = nullptr); virtual CompositableType GetType() { return CompositableType::BUFFER_TILED; }