From 65756dd40d21d7bd446eeccf52cd1b3248d7ed5b Mon Sep 17 00:00:00 2001 From: Boris Chiou Date: Mon, 19 May 2014 12:00:04 +0800 Subject: [PATCH] Bug 975346 - Part 1: General functions for EffectChains 1. Support GenEffectChain() for LayerComposite. 2. Support GenEffect() for CompositableHost. 3. Move AutoLock to compositeHost. --- gfx/layers/composite/CanvasLayerComposite.cpp | 22 +++++++++ gfx/layers/composite/CanvasLayerComposite.h | 2 + gfx/layers/composite/ColorLayerComposite.cpp | 12 +++++ gfx/layers/composite/ColorLayerComposite.h | 2 + gfx/layers/composite/CompositableHost.h | 32 +++++++++++++ gfx/layers/composite/ContentHost.cpp | 39 +++++++-------- gfx/layers/composite/ContentHost.h | 21 ++++----- gfx/layers/composite/ImageHost.cpp | 47 ++++++++++++++++++- gfx/layers/composite/ImageHost.h | 9 ++++ gfx/layers/composite/ImageLayerComposite.cpp | 11 +++++ gfx/layers/composite/ImageLayerComposite.h | 2 + gfx/layers/composite/LayerManagerComposite.h | 6 ++- gfx/layers/composite/ThebesLayerComposite.cpp | 11 +++++ gfx/layers/composite/ThebesLayerComposite.h | 2 + gfx/layers/composite/TiledContentHost.cpp | 5 ++ gfx/layers/composite/TiledContentHost.h | 2 +- 16 files changed, 187 insertions(+), 38 deletions(-) diff --git a/gfx/layers/composite/CanvasLayerComposite.cpp b/gfx/layers/composite/CanvasLayerComposite.cpp index f6465ce804345..2cc790e2c9f5c 100644 --- a/gfx/layers/composite/CanvasLayerComposite.cpp +++ b/gfx/layers/composite/CanvasLayerComposite.cpp @@ -132,6 +132,28 @@ CanvasLayerComposite::CleanupResources() mImageHost = nullptr; } +void +CanvasLayerComposite::GenEffectChain(EffectChain& aEffect, + CompositableHost* aHost) +{ + // Add layerRef + aEffect.mLayerRef = this; + + // Add primary effect + GraphicsFilter filter = mFilter; +#ifdef ANDROID + // Bug 691354 + // Using the LINEAR filter we get unexplained artifacts. + // Use NEAREST when no scaling is required. + Matrix matrix; + bool is2D = GetEffectiveTransform().Is2D(&matrix); + if (is2D && !ThebesMatrix(matrix).HasNonTranslationOrFlip()) { + filter = GraphicsFilter::FILTER_NEAREST; + } +#endif + aEffect.mPrimaryEffect = aHost->GenEffect(gfx::ToFilter(filter)); +} + nsACString& CanvasLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix) { diff --git a/gfx/layers/composite/CanvasLayerComposite.h b/gfx/layers/composite/CanvasLayerComposite.h index 2964dcf43b7fc..f2791357d0829 100644 --- a/gfx/layers/composite/CanvasLayerComposite.h +++ b/gfx/layers/composite/CanvasLayerComposite.h @@ -52,6 +52,8 @@ class CanvasLayerComposite : public CanvasLayer, virtual void CleanupResources() MOZ_OVERRIDE; + virtual void GenEffectChain(EffectChain& aEffect, CompositableHost* aHost) MOZ_OVERRIDE; + CompositableHost* GetCompositableHost() MOZ_OVERRIDE; virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/composite/ColorLayerComposite.cpp b/gfx/layers/composite/ColorLayerComposite.cpp index 6aeeb785b344a..f50159d81e426 100644 --- a/gfx/layers/composite/ColorLayerComposite.cpp +++ b/gfx/layers/composite/ColorLayerComposite.cpp @@ -50,5 +50,17 @@ ColorLayerComposite::RenderLayer(const nsIntRect& aClipRect) transform); } +void +ColorLayerComposite::GenEffectChain(EffectChain& aEffect, + CompositableHost* aHost) +{ + aEffect.mLayerRef = this; + gfxRGBA color = GetColor(); + aEffect.mPrimaryEffect = new EffectSolidColor(gfx::Color(color.r, + color.g, + color.b, + color.a)); +} + } /* layers */ } /* mozilla */ diff --git a/gfx/layers/composite/ColorLayerComposite.h b/gfx/layers/composite/ColorLayerComposite.h index 8252ea49c1338..10a92f9386765 100644 --- a/gfx/layers/composite/ColorLayerComposite.h +++ b/gfx/layers/composite/ColorLayerComposite.h @@ -44,6 +44,8 @@ class ColorLayerComposite : public ColorLayer, virtual void RenderLayer(const nsIntRect& aClipRect) MOZ_OVERRIDE; virtual void CleanupResources() MOZ_OVERRIDE {}; + virtual void GenEffectChain(EffectChain& aEffect, CompositableHost* aHost) MOZ_OVERRIDE; + CompositableHost* GetCompositableHost() MOZ_OVERRIDE { return nullptr; } virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/composite/CompositableHost.h b/gfx/layers/composite/CompositableHost.h index 76c173192caec..338bdb34a8d38 100644 --- a/gfx/layers/composite/CompositableHost.h +++ b/gfx/layers/composite/CompositableHost.h @@ -17,6 +17,7 @@ #include "mozilla/gfx/Types.h" // for Filter #include "mozilla/ipc/ProtocolUtils.h" #include "mozilla/layers/CompositorTypes.h" // for TextureInfo, etc +#include "mozilla/layers/Effects.h" // for Texture Effect #include "mozilla/layers/LayersTypes.h" // for LayerRenderState, etc #include "mozilla/layers/TextureHost.h" // for TextureHost #include "mozilla/mozalloc.h" // for operator delete @@ -289,6 +290,14 @@ class CompositableHost void SetAsyncID(uint64_t aID) { mAsyncID = aID; } + virtual bool Lock() { return false; } + + virtual void Unlock() { } + + virtual TemporaryRef GenEffect(const gfx::Filter& aFilter) { + return nullptr; + } + protected: TextureInfo mTextureInfo; uint64_t mAsyncID; @@ -301,6 +310,29 @@ class CompositableHost bool mKeepAttached; }; +class AutoLockCompositableHost MOZ_FINAL +{ +public: + AutoLockCompositableHost(CompositableHost* aHost) + : mHost(aHost) + { + mSucceeded = mHost->Lock(); + } + + ~AutoLockCompositableHost() + { + if (mSucceeded) { + mHost->Unlock(); + } + } + + bool Failed() const { return !mSucceeded; } + +private: + RefPtr mHost; + bool mSucceeded; +}; + /** * Global CompositableMap, to use in the compositor thread only. * diff --git a/gfx/layers/composite/ContentHost.cpp b/gfx/layers/composite/ContentHost.cpp index 31f3b8e63d501..043e05f251d76 100644 --- a/gfx/layers/composite/ContentHost.cpp +++ b/gfx/layers/composite/ContentHost.cpp @@ -35,27 +35,6 @@ ContentHostBase::~ContentHostBase() { } -struct AutoLockContentHost -{ - AutoLockContentHost(ContentHostBase* aHost) - : mHost(aHost) - { - mSucceeded = mHost->Lock(); - } - - ~AutoLockContentHost() - { - if (mSucceeded) { - mHost->Unlock(); - } - } - - bool Failed() { return !mSucceeded; } - - ContentHostBase* mHost; - bool mSucceeded; -}; - void ContentHostBase::Composite(EffectChain& aEffectChain, float aOpacity, @@ -67,7 +46,7 @@ ContentHostBase::Composite(EffectChain& aEffectChain, { NS_ASSERTION(aVisibleRegion, "Requires a visible region"); - AutoLockContentHost lock(this); + AutoLockCompositableHost lock(this); if (lock.Failed()) { return; } @@ -288,6 +267,22 @@ ContentHostTexture::Dump(FILE* aFile, } #endif +TemporaryRef +ContentHostBase::GenEffect(const gfx::Filter& aFilter) +{ + RefPtr source = GetTextureSource(); + RefPtr sourceOnWhite = GetTextureSourceOnWhite(); + if (!source) { + return nullptr; + } + RefPtr effect = + CreateTexturedEffect(source, sourceOnWhite, aFilter); + if (!effect) { + return nullptr; + } + return effect; +} + static inline void AddWrappedRegion(const nsIntRegion& aInput, nsIntRegion& aOutput, const nsIntSize& aSize, const nsIntPoint& aShift) diff --git a/gfx/layers/composite/ContentHost.h b/gfx/layers/composite/ContentHost.h index 915bc2801b7e6..92ddb04587665 100644 --- a/gfx/layers/composite/ContentHost.h +++ b/gfx/layers/composite/ContentHost.h @@ -102,12 +102,11 @@ class ContentHostBase : public ContentHost virtual void SetPaintWillResample(bool aResample) { mPaintWillResample = aResample; } - virtual bool Lock() = 0; - virtual void Unlock() = 0; - virtual NewTextureSource* GetTextureSource() = 0; virtual NewTextureSource* GetTextureSourceOnWhite() = 0; + virtual TemporaryRef GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE; + protected: virtual nsIntPoint GetOriginOffset() { @@ -150,7 +149,7 @@ class ContentHostTexture : public ContentHostBase virtual void UseComponentAlphaTextures(TextureHost* aTextureOnBlack, TextureHost* aTextureOnWhite) MOZ_OVERRIDE; - virtual bool Lock() { + virtual bool Lock() MOZ_OVERRIDE { MOZ_ASSERT(!mLocked); if (!mTextureHost) { return false; @@ -166,7 +165,7 @@ class ContentHostTexture : public ContentHostBase mLocked = true; return true; } - virtual void Unlock() { + virtual void Unlock() MOZ_OVERRIDE { MOZ_ASSERT(mLocked); mTextureHost->Unlock(); if (mTextureHostOnWhite) { @@ -175,11 +174,11 @@ class ContentHostTexture : public ContentHostBase mLocked = false; } - virtual NewTextureSource* GetTextureSource() { + virtual NewTextureSource* GetTextureSource() MOZ_OVERRIDE { MOZ_ASSERT(mLocked); return mTextureHost->GetTextureSources(); } - virtual NewTextureSource* GetTextureSourceOnWhite() { + virtual NewTextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE { MOZ_ASSERT(mLocked); if (mTextureHostOnWhite) { return mTextureHostOnWhite->GetTextureSources(); @@ -281,20 +280,20 @@ class ContentHostIncremental : public ContentHostBase virtual void PrintInfo(nsACString& aTo, const char* aPrefix) MOZ_OVERRIDE; - virtual bool Lock() { + virtual bool Lock() MOZ_OVERRIDE { MOZ_ASSERT(!mLocked); ProcessTextureUpdates(); mLocked = true; return true; } - virtual void Unlock() { + virtual void Unlock() MOZ_OVERRIDE { MOZ_ASSERT(mLocked); mLocked = false; } - virtual NewTextureSource* GetTextureSource(); - virtual NewTextureSource* GetTextureSourceOnWhite(); + virtual NewTextureSource* GetTextureSource() MOZ_OVERRIDE; + virtual NewTextureSource* GetTextureSourceOnWhite() MOZ_OVERRIDE; private: diff --git a/gfx/layers/composite/ImageHost.cpp b/gfx/layers/composite/ImageHost.cpp index 5ee051e9623cc..cdc2000d5ba31 100644 --- a/gfx/layers/composite/ImageHost.cpp +++ b/gfx/layers/composite/ImageHost.cpp @@ -31,6 +31,7 @@ ImageHost::ImageHost(const TextureInfo& aTextureInfo) : CompositableHost(aTextureInfo) , mFrontBuffer(nullptr) , mHasPictureRect(false) + , mLocked(false) {} ImageHost::~ImageHost() {} @@ -81,12 +82,12 @@ ImageHost::Composite(EffectChain& aEffectChain, mFrontBuffer->SetCompositor(GetCompositor()); mFrontBuffer->SetCompositableBackendSpecificData(GetCompositableBackendSpecificData()); - AutoLockTextureHost autoLock(mFrontBuffer); + AutoLockCompositableHost autoLock(this); if (autoLock.Failed()) { NS_WARNING("failed to lock front buffer"); return; } - RefPtr source = mFrontBuffer->GetTextureSources(); + RefPtr source = GetTextureSource(); if (!source) { return; } @@ -240,5 +241,47 @@ ImageHost::GetAsSurface() } #endif +bool +ImageHost::Lock() +{ + MOZ_ASSERT(!mLocked); + if (!mFrontBuffer->Lock()) { + return false; + } + mLocked = true; + return true; +} + +void +ImageHost::Unlock() +{ + MOZ_ASSERT(mLocked); + mFrontBuffer->Unlock(); + mLocked = false; +} + +TemporaryRef +ImageHost::GetTextureSource() +{ + MOZ_ASSERT(mLocked); + return mFrontBuffer->GetTextureSources(); +} + +TemporaryRef +ImageHost::GenEffect(const gfx::Filter& aFilter) +{ + RefPtr source = GetTextureSource(); + if (!source) { + return nullptr; + } + RefPtr effect = CreateTexturedEffect(mFrontBuffer->GetFormat(), + source, + aFilter); + if (!effect) { + return nullptr; + } + return effect; +} + } } diff --git a/gfx/layers/composite/ImageHost.h b/gfx/layers/composite/ImageHost.h index 5dde7374aec79..0418bb99a1b2c 100644 --- a/gfx/layers/composite/ImageHost.h +++ b/gfx/layers/composite/ImageHost.h @@ -79,11 +79,20 @@ class ImageHost : public CompositableHost virtual TemporaryRef GetAsSurface() MOZ_OVERRIDE; #endif + virtual bool Lock() MOZ_OVERRIDE; + + virtual void Unlock() MOZ_OVERRIDE; + + virtual TemporaryRef GetTextureSource(); + + virtual TemporaryRef GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE; + protected: RefPtr mFrontBuffer; nsIntRect mPictureRect; bool mHasPictureRect; + bool mLocked; }; } diff --git a/gfx/layers/composite/ImageLayerComposite.cpp b/gfx/layers/composite/ImageLayerComposite.cpp index e2e5d0a15c349..f46a143f2cc97 100644 --- a/gfx/layers/composite/ImageLayerComposite.cpp +++ b/gfx/layers/composite/ImageLayerComposite.cpp @@ -161,6 +161,17 @@ ImageLayerComposite::CleanupResources() mImageHost = nullptr; } +void +ImageLayerComposite::GenEffectChain(EffectChain& aEffect, + CompositableHost* aHost) +{ + // Add layerRef + aEffect.mLayerRef = this; + + // Add primary effect, if the buffer in aHost is locked. + aEffect.mPrimaryEffect = aHost->GenEffect(gfx::ToFilter(mFilter)); +} + nsACString& ImageLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix) { diff --git a/gfx/layers/composite/ImageLayerComposite.h b/gfx/layers/composite/ImageLayerComposite.h index 2563fb0a097b9..7b851e0c2b53b 100644 --- a/gfx/layers/composite/ImageLayerComposite.h +++ b/gfx/layers/composite/ImageLayerComposite.h @@ -49,6 +49,8 @@ class ImageLayerComposite : public ImageLayer, virtual void CleanupResources() MOZ_OVERRIDE; + virtual void GenEffectChain(EffectChain& aEffect, CompositableHost* aHost) MOZ_OVERRIDE; + CompositableHost* GetCompositableHost() MOZ_OVERRIDE; virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/composite/LayerManagerComposite.h b/gfx/layers/composite/LayerManagerComposite.h index 1d065b0f45f21..9230a64f98213 100644 --- a/gfx/layers/composite/LayerManagerComposite.h +++ b/gfx/layers/composite/LayerManagerComposite.h @@ -74,7 +74,7 @@ class LayerManagerComposite : public LayerManager public: LayerManagerComposite(Compositor* aCompositor); ~LayerManagerComposite(); - + virtual void Destroy() MOZ_OVERRIDE; /** @@ -267,7 +267,7 @@ class LayerManagerComposite : public LayerManager RefPtr mCompositor; nsAutoPtr mClonedLayerTreeProperties; - /** + /** * Context target, nullptr when drawing directly to our swap chain. */ RefPtr mTarget; @@ -341,6 +341,8 @@ class LayerComposite void AddBlendModeEffect(EffectChain& aEffectChain); + virtual void GenEffectChain(EffectChain& aEffect, CompositableHost* aHost) { } + /** * The following methods are * diff --git a/gfx/layers/composite/ThebesLayerComposite.cpp b/gfx/layers/composite/ThebesLayerComposite.cpp index 896d4aa38fa80..c4fa994047841 100644 --- a/gfx/layers/composite/ThebesLayerComposite.cpp +++ b/gfx/layers/composite/ThebesLayerComposite.cpp @@ -193,6 +193,17 @@ ThebesLayerComposite::GetEffectiveResolution() return CSSToScreenScale(1.0); } +void +ThebesLayerComposite::GenEffectChain(EffectChain& aEffect, + CompositableHost* aHost) +{ + // Add layerRef + aEffect.mLayerRef = this; + + // Add primary effect, should be locked first + aEffect.mPrimaryEffect = aHost->GenEffect(gfx::Filter::LINEAR); +} + nsACString& ThebesLayerComposite::PrintInfo(nsACString& aTo, const char* aPrefix) { diff --git a/gfx/layers/composite/ThebesLayerComposite.h b/gfx/layers/composite/ThebesLayerComposite.h index 788aa2ad03a22..d938d3f1d5b40 100644 --- a/gfx/layers/composite/ThebesLayerComposite.h +++ b/gfx/layers/composite/ThebesLayerComposite.h @@ -56,6 +56,8 @@ class ThebesLayerComposite : public ThebesLayer, virtual void CleanupResources() MOZ_OVERRIDE; + virtual void GenEffectChain(EffectChain& aEffect, CompositableHost* aHost) MOZ_OVERRIDE; + virtual bool SetCompositableHost(CompositableHost* aHost) MOZ_OVERRIDE; virtual LayerComposite* AsLayerComposite() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/composite/TiledContentHost.cpp b/gfx/layers/composite/TiledContentHost.cpp index ce9b273470a17..29db7fb233f76 100644 --- a/gfx/layers/composite/TiledContentHost.cpp +++ b/gfx/layers/composite/TiledContentHost.cpp @@ -513,6 +513,11 @@ TiledContentHost::Dump(FILE* aFile, } } #endif +TemporaryRef +TiledContentHost::GenEffect(const gfx::Filter& aFilter) +{ + return nullptr; +} } // namespace } // namespace diff --git a/gfx/layers/composite/TiledContentHost.h b/gfx/layers/composite/TiledContentHost.h index 86c0290baf8ca..a3420fd6d4f87 100644 --- a/gfx/layers/composite/TiledContentHost.h +++ b/gfx/layers/composite/TiledContentHost.h @@ -246,7 +246,7 @@ class TiledContentHost : public ContentHost, mLowPrecisionTiledBuffer.SetReleaseFence(aReleaseFence); } #endif - + virtual TemporaryRef GenEffect(const gfx::Filter& aFilter) MOZ_OVERRIDE; private: void RenderLayerBuffer(TiledLayerBufferComposite& aLayerBuffer,