diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index cb3fd8955e1..50fff935fa0 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -38,6 +38,10 @@ * * ***** END LICENSE BLOCK ***** */ +#ifdef MOZ_IPC +# include "mozilla/layers/ShadowLayers.h" +#endif // MOZ_IPC + #include "ImageLayers.h" #include "Layers.h" #include "gfxPlatform.h" @@ -200,8 +204,50 @@ Layer::CanUseOpaqueSurface() parent->CanUseOpaqueSurface(); } + +#ifdef MOZ_IPC +// NB: eventually these methods will be defined unconditionally, and +// can be moved into Layers.h +const nsIntRect* +Layer::GetEffectiveClipRect() +{ + if (ShadowLayer* shadow = AsShadowLayer()) { + return shadow->GetShadowClipRect(); + } + return GetClipRect(); +} + +const nsIntRegion& +Layer::GetEffectiveVisibleRegion() +{ + if (ShadowLayer* shadow = AsShadowLayer()) { + return shadow->GetShadowVisibleRegion(); + } + return GetVisibleRegion(); +} + +const gfx3DMatrix& +Layer::GetEffectiveTransform() +{ + if (ShadowLayer* shadow = AsShadowLayer()) { + return shadow->GetShadowTransform(); + } + return GetTransform(); +} + +#else + +const nsIntRect* Layer::GetEffectiveClipRect() { return GetClipRect(); } +const nsIntRegion& Layer::GetEffectiveVisibleRegion() { return GetVisibleRegion(); } +const gfx3DMatrix& Layer::GetEffectiveTransform() { return GetTransform(); } + +#endif // MOZ_IPC + + #ifdef MOZ_LAYERS_HAVE_LOG +static nsACString& PrintInfo(nsACString& aTo, ShadowLayer* aShadowLayer); + void Layer::Dump(FILE* aFile, const char* aPrefix) { @@ -260,6 +306,8 @@ Layer::PrintInfo(nsACString& aTo, const char* aPrefix) aTo += aPrefix; aTo += nsPrintfCString(64, "%s%s (0x%p)", mManager->Name(), Name(), this); + ::PrintInfo(aTo, AsShadowLayer()); + if (mUseClipRect) { AppendToString(aTo, mClipRect, " [clip=", "]"); } @@ -405,6 +453,28 @@ LayerManager::IsLogEnabled() return PR_LOG_TEST(sLog, PR_LOG_DEBUG); } +# ifdef MOZ_IPC +static nsACString& +PrintInfo(nsACString& aTo, ShadowLayer* aShadowLayer) +{ + if (!aShadowLayer) { + return aTo; + } + if (const nsIntRect* clipRect = aShadowLayer->GetShadowClipRect()) { + AppendToString(aTo, *clipRect, " [shadow-clip=", "]"); + } + if (!aShadowLayer->GetShadowTransform().IsIdentity()) { + AppendToString(aTo, aShadowLayer->GetShadowTransform(), " [shadow-transform=", "]"); + } + if (!aShadowLayer->GetShadowVisibleRegion().IsEmpty()) { + AppendToString(aTo, aShadowLayer->GetShadowVisibleRegion(), " [shadow-visible=", "]"); + } + return aTo; +} +# else +static nsACString& PrintInfo(nsACString& aTo, ShadowLayer* aShadowLayer) {} +# endif // MOZ_IPC + #else // !MOZ_LAYERS_HAVE_LOG void Layer::Dump(FILE* aFile, const char* aPrefix) {} diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 5b3e0ed3df4..9e522536e2c 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -77,6 +77,7 @@ class ImageLayer; class ColorLayer; class ImageContainer; class CanvasLayer; +class ShadowLayer; class SpecificLayerAttributes; /** @@ -643,6 +644,19 @@ public: */ virtual ThebesLayer* AsThebesLayer() { return nsnull; } + /** + * Dynamic cast to a ShadowLayer. Return null if this is not a + * ShadowLayer. Can be used anytime. + */ + virtual ShadowLayer* AsShadowLayer() { return nsnull; } + + // These getters can be used anytime. They return the effective + // values that should be used when drawing this layer to screen, + // accounting for this layer possibly being a shadow. + const nsIntRect* GetEffectiveClipRect(); + const nsIntRegion& GetEffectiveVisibleRegion(); + const gfx3DMatrix& GetEffectiveTransform(); + virtual const char* Name() const =0; virtual LayerType GetType() const =0; diff --git a/gfx/layers/ipc/ShadowLayers.h b/gfx/layers/ipc/ShadowLayers.h index 38aefd8533a..caf0907ed9e 100644 --- a/gfx/layers/ipc/ShadowLayers.h +++ b/gfx/layers/ipc/ShadowLayers.h @@ -385,18 +385,76 @@ protected: }; -class ShadowThebesLayer : public ThebesLayer +/** + * A ShadowLayer is the representation of a child-context's Layer in a + * parent context. They can be transformed, clipped, + * etc. independently of their origin Layers. + * + * Note that ShadowLayers can themselves have a shadow in a parent + * context. + */ +class ShadowLayer { public: + virtual ~ShadowLayer() {} + /** * CONSTRUCTION PHASE ONLY */ - void SetParent(PLayersParent* aParent) + void SetAllocator(PLayersParent* aAllocator) { - NS_ABORT_IF_FALSE(!mAllocator, "Stomping parent?"); - mAllocator = aParent; + NS_ABORT_IF_FALSE(!mAllocator, "Stomping allocator?"); + mAllocator = aAllocator; } + /** + * The following methods are + * + * CONSTRUCTION PHASE ONLY + * + * They are analogous to the Layer interface. + */ + void SetShadowVisibleRegion(const nsIntRegion& aRegion) + { + mShadowVisibleRegion = aRegion; + } + + void SetShadowClipRect(const nsIntRect* aRect) + { + mUseShadowClipRect = aRect != nsnull; + if (aRect) { + mShadowClipRect = *aRect; + } + } + + void SetShadowTransform(const gfx3DMatrix& aMatrix) + { + mShadowTransform = aMatrix; + } + + // These getters can be used anytime. + const nsIntRect* GetShadowClipRect() { return mUseShadowClipRect ? &mShadowClipRect : nsnull; } + const nsIntRegion& GetShadowVisibleRegion() { return mShadowVisibleRegion; } + const gfx3DMatrix& GetShadowTransform() { return mShadowTransform; } + +protected: + ShadowLayer() + : mAllocator(nsnull) + , mUseShadowClipRect(PR_FALSE) + {} + + PLayersParent* mAllocator; + nsIntRegion mShadowVisibleRegion; + gfx3DMatrix mShadowTransform; + nsIntRect mShadowClipRect; + PRPackedBool mUseShadowClipRect; +}; + + +class ShadowThebesLayer : public ShadowLayer, + public ThebesLayer +{ +public: /** * CONSTRUCTION PHASE ONLY * @@ -450,30 +508,21 @@ public: */ virtual void DestroyFrontBuffer() = 0; + virtual ShadowLayer* AsShadowLayer() { return this; } + MOZ_LAYER_DECL_NAME("ShadowThebesLayer", TYPE_SHADOW) protected: ShadowThebesLayer(LayerManager* aManager, void* aImplData) : ThebesLayer(aManager, aImplData) - , mAllocator(nsnull) {} - - PLayersParent* mAllocator; }; -class ShadowCanvasLayer : public CanvasLayer +class ShadowCanvasLayer : public ShadowLayer, + public CanvasLayer { public: - /** - * CONSTRUCTION PHASE ONLY - */ - void SetParent(PLayersParent* aParent) - { - NS_ABORT_IF_FALSE(!mAllocator, "Stomping parent?"); - mAllocator = aParent; - } - /** * CONSTRUCTION PHASE ONLY * @@ -491,30 +540,21 @@ public: */ virtual void DestroyFrontBuffer() = 0; + virtual ShadowLayer* AsShadowLayer() { return this; } + MOZ_LAYER_DECL_NAME("ShadowCanvasLayer", TYPE_SHADOW) protected: ShadowCanvasLayer(LayerManager* aManager, void* aImplData) : CanvasLayer(aManager, aImplData) - , mAllocator(nsnull) {} - - PLayersParent* mAllocator; }; -class ShadowImageLayer : public ImageLayer +class ShadowImageLayer : public ShadowLayer, + public ImageLayer { public: - /** - * CONSTRUCTION PHASE ONLY - */ - void SetParent(PLayersParent* aParent) - { - NS_ABORT_IF_FALSE(!mAllocator, "Stomping parent?"); - mAllocator = aParent; - } - /** * CONSTRUCTION PHASE ONLY * @@ -539,15 +579,14 @@ public: */ virtual void DestroyFrontBuffer() = 0; + virtual ShadowLayer* AsShadowLayer() { return this; } + MOZ_LAYER_DECL_NAME("ShadowImageLayer", TYPE_SHADOW) protected: ShadowImageLayer(LayerManager* aManager, void* aImplData) : ImageLayer(aManager, aImplData) - , mAllocator(nsnull) {} - - PLayersParent* mAllocator; }; diff --git a/gfx/layers/ipc/ShadowLayersParent.cpp b/gfx/layers/ipc/ShadowLayersParent.cpp index 6917ebf90c4..3840e1f1d6f 100644 --- a/gfx/layers/ipc/ShadowLayersParent.cpp +++ b/gfx/layers/ipc/ShadowLayersParent.cpp @@ -152,7 +152,7 @@ ShadowLayersParent::RecvUpdate(const nsTArray& cset, nsRefPtr layer = layer_manager()->CreateShadowThebesLayer(); - layer->SetParent(this); + layer->SetAllocator(this); AsShadowLayer(edit.get_OpCreateThebesLayer())->Bind(layer); break; } @@ -168,7 +168,7 @@ ShadowLayersParent::RecvUpdate(const nsTArray& cset, nsRefPtr layer = layer_manager()->CreateShadowImageLayer(); - layer->SetParent(this); + layer->SetAllocator(this); AsShadowLayer(edit.get_OpCreateImageLayer())->Bind(layer); break; } @@ -184,7 +184,7 @@ ShadowLayersParent::RecvUpdate(const nsTArray& cset, nsRefPtr layer = layer_manager()->CreateShadowCanvasLayer(); - layer->SetParent(this); + layer->SetAllocator(this); AsShadowLayer(edit.get_OpCreateCanvasLayer())->Bind(layer); break; }