From 31ac189fe38cee0efdab89dae95f380f104c25cd Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Mon, 2 Sep 2013 10:19:18 +1200 Subject: [PATCH] Bug 786412. Conslidate container layer methods. r=mattwoodrow --- gfx/layers/Layers.cpp | 125 +++++ gfx/layers/Layers.h | 8 +- gfx/layers/basic/BasicContainerLayer.cpp | 41 +- gfx/layers/basic/BasicContainerLayer.h | 177 +----- gfx/layers/client/ClientContainerLayer.h | 145 +---- .../composite/ContainerLayerComposite.cpp | 114 ---- .../composite/ContainerLayerComposite.h | 6 - gfx/layers/d3d10/ContainerLayerD3D10.cpp | 134 ----- gfx/layers/d3d10/ContainerLayerD3D10.h | 20 - gfx/layers/d3d9/ContainerLayerD3D9.cpp | 300 +++------- gfx/layers/d3d9/ContainerLayerD3D9.h | 25 - gfx/layers/opengl/ContainerLayerOGL.cpp | 531 ++++++------------ gfx/layers/opengl/ContainerLayerOGL.h | 34 -- 13 files changed, 426 insertions(+), 1234 deletions(-) diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index fdba9778dd59..7f1ca633b424 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -712,6 +712,121 @@ ContainerLayer::ContainerLayer(LayerManager* aManager, void* aImplData) ContainerLayer::~ContainerLayer() {} +void +ContainerLayer::InsertAfter(Layer* aChild, Layer* aAfter) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(!aChild->GetParent(), + "aChild already in the tree"); + NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), + "aChild already has siblings?"); + NS_ASSERTION(!aAfter || + (aAfter->Manager() == Manager() && + aAfter->GetParent() == this), + "aAfter is not our child"); + + aChild->SetParent(this); + if (aAfter == mLastChild) { + mLastChild = aChild; + } + if (!aAfter) { + aChild->SetNextSibling(mFirstChild); + if (mFirstChild) { + mFirstChild->SetPrevSibling(aChild); + } + mFirstChild = aChild; + NS_ADDREF(aChild); + DidInsertChild(aChild); + return; + } + + Layer* next = aAfter->GetNextSibling(); + aChild->SetNextSibling(next); + aChild->SetPrevSibling(aAfter); + if (next) { + next->SetPrevSibling(aChild); + } + aAfter->SetNextSibling(aChild); + NS_ADDREF(aChild); + DidInsertChild(aChild); +} + +void +ContainerLayer::RemoveChild(Layer *aChild) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(aChild->GetParent() == this, + "aChild not our child"); + + Layer* prev = aChild->GetPrevSibling(); + Layer* next = aChild->GetNextSibling(); + if (prev) { + prev->SetNextSibling(next); + } else { + this->mFirstChild = next; + } + if (next) { + next->SetPrevSibling(prev); + } else { + this->mLastChild = prev; + } + + aChild->SetNextSibling(nullptr); + aChild->SetPrevSibling(nullptr); + aChild->SetParent(nullptr); + + this->DidRemoveChild(aChild); + NS_RELEASE(aChild); +} + + +void +ContainerLayer::RepositionChild(Layer* aChild, Layer* aAfter) +{ + NS_ASSERTION(aChild->Manager() == Manager(), + "Child has wrong manager"); + NS_ASSERTION(aChild->GetParent() == this, + "aChild not our child"); + NS_ASSERTION(!aAfter || + (aAfter->Manager() == Manager() && + aAfter->GetParent() == this), + "aAfter is not our child"); + + Layer* prev = aChild->GetPrevSibling(); + Layer* next = aChild->GetNextSibling(); + if (prev == aAfter) { + // aChild is already in the correct position, nothing to do. + return; + } + if (prev) { + prev->SetNextSibling(next); + } + if (next) { + next->SetPrevSibling(prev); + } + if (!aAfter) { + aChild->SetPrevSibling(nullptr); + aChild->SetNextSibling(mFirstChild); + if (mFirstChild) { + mFirstChild->SetPrevSibling(aChild); + } + mFirstChild = aChild; + return; + } + + Layer* afterNext = aAfter->GetNextSibling(); + if (afterNext) { + afterNext->SetPrevSibling(aChild); + } else { + mLastChild = aChild; + } + aAfter->SetNextSibling(aChild); + aChild->SetPrevSibling(aAfter); + aChild->SetNextSibling(afterNext); +} + void ContainerLayer::FillSpecificAttributes(SpecificLayerAttributes& aAttrs) { @@ -827,6 +942,16 @@ ContainerLayer::ComputeEffectiveTransformsForChildren(const gfx3DMatrix& aTransf } } +/* static */ bool +ContainerLayer::HasOpaqueAncestorLayer(Layer* aLayer) +{ + for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { + if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) + return true; + } + return false; +} + void ContainerLayer::DidRemoveChild(Layer* aLayer) { diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 002055d1fd2b..fa29819997a4 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1411,13 +1411,13 @@ public: * If aAfter is non-null, it must be a child of this container and * we insert after that layer. If it's null we insert at the start. */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter) = 0; + virtual void InsertAfter(Layer* aChild, Layer* aAfter); /** * CONSTRUCTION PHASE ONLY * Remove aChild from the child list of this container. aChild must * be a child of this container. */ - virtual void RemoveChild(Layer* aChild) = 0; + virtual void RemoveChild(Layer* aChild); /** * CONSTRUCTION PHASE ONLY * Reposition aChild from the child list of this container. aChild must @@ -1425,7 +1425,7 @@ public: * If aAfter is non-null, it must be a child of this container and we * reposition after that layer. If it's null, we reposition at the start. */ - virtual void RepositionChild(Layer* aChild, Layer* aAfter) = 0; + virtual void RepositionChild(Layer* aChild, Layer* aAfter); /** * CONSTRUCTION PHASE ONLY @@ -1530,6 +1530,8 @@ public: protected: friend class ReadbackProcessor; + static bool HasOpaqueAncestorLayer(Layer* aLayer); + void DidInsertChild(Layer* aLayer); void DidRemoveChild(Layer* aLayer); diff --git a/gfx/layers/basic/BasicContainerLayer.cpp b/gfx/layers/basic/BasicContainerLayer.cpp index 9b9fbd9af083..6973aad37f03 100644 --- a/gfx/layers/basic/BasicContainerLayer.cpp +++ b/gfx/layers/basic/BasicContainerLayer.cpp @@ -15,6 +15,9 @@ #include "nsISupportsImpl.h" // for Layer::AddRef, etc #include "nsPoint.h" // for nsIntPoint #include "nsRect.h" // for nsIntRect +#include "gfx3DMatrix.h" // for gfx3DMatrix +#include "gfxMatrix.h" // for gfxMatrix +#include "nsRegion.h" // for nsIntRegion using namespace mozilla::gfx; @@ -24,12 +27,48 @@ namespace layers { BasicContainerLayer::~BasicContainerLayer() { while (mFirstChild) { - ContainerRemoveChild(mFirstChild, this); + ContainerLayer::RemoveChild(mFirstChild); } MOZ_COUNT_DTOR(BasicContainerLayer); } +void +BasicContainerLayer::ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) +{ + // We push groups for container layers if we need to, which always + // are aligned in device space, so it doesn't really matter how we snap + // containers. + gfxMatrix residual; + gfx3DMatrix idealTransform = GetLocalTransform()*aTransformToSurface; + idealTransform.ProjectTo2D(); + + if (!idealTransform.CanDraw2D()) { + mEffectiveTransform = idealTransform; + ComputeEffectiveTransformsForChildren(gfx3DMatrix()); + ComputeEffectiveTransformForMaskLayer(gfx3DMatrix()); + mUseIntermediateSurface = true; + return; + } + + mEffectiveTransform = SnapTransformTranslation(idealTransform, &residual); + // We always pass the ideal matrix down to our children, so there is no + // need to apply any compensation using the residual from SnapTransformTranslation. + ComputeEffectiveTransformsForChildren(idealTransform); + + ComputeEffectiveTransformForMaskLayer(aTransformToSurface); + + /* If we have a single child, it can just inherit our opacity, + * otherwise we need a PushGroup and we need to mark ourselves as using + * an intermediate surface so our children don't inherit our opacity + * via GetEffectiveOpacity. + * Having a mask layer always forces our own push group + */ + mUseIntermediateSurface = + GetMaskLayer() || (GetEffectiveOpacity() != 1.0 && + HasMultipleChildren()); +} + bool BasicContainerLayer::ChildrenPartitionVisibleRegion(const nsIntRect& aInRect) { diff --git a/gfx/layers/basic/BasicContainerLayer.h b/gfx/layers/basic/BasicContainerLayer.h index d444b30b5332..7673e28253a4 100644 --- a/gfx/layers/basic/BasicContainerLayer.h +++ b/gfx/layers/basic/BasicContainerLayer.h @@ -9,181 +9,15 @@ #include "BasicImplData.h" // for BasicImplData #include "BasicLayers.h" // for BasicLayerManager #include "Layers.h" // for Layer, ContainerLayer -#include "gfx3DMatrix.h" // for gfx3DMatrix -#include "gfxMatrix.h" // for gfxMatrix #include "nsDebug.h" // for NS_ASSERTION #include "nsISupportsUtils.h" // for NS_ADDREF, NS_RELEASE -#include "nsRegion.h" // for nsIntRegion #include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR struct nsIntRect; namespace mozilla { namespace layers { -template void -ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template void -ContainerRemoveChild(Layer* aChild, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template void -ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -template -static void -ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface, - Container* aContainer) -{ - // We push groups for container layers if we need to, which always - // are aligned in device space, so it doesn't really matter how we snap - // containers. - gfxMatrix residual; - gfx3DMatrix idealTransform = aContainer->GetLocalTransform()*aTransformToSurface; - idealTransform.ProjectTo2D(); - - if (!idealTransform.CanDraw2D()) { - aContainer->mEffectiveTransform = idealTransform; - aContainer->ComputeEffectiveTransformsForChildren(gfx3DMatrix()); - aContainer->ComputeEffectiveTransformForMaskLayer(gfx3DMatrix()); - aContainer->mUseIntermediateSurface = true; - return; - } - - aContainer->mEffectiveTransform = - aContainer->SnapTransformTranslation(idealTransform, &residual); - // We always pass the ideal matrix down to our children, so there is no - // need to apply any compensation using the residual from SnapTransformTranslation. - aContainer->ComputeEffectiveTransformsForChildren(idealTransform); - - aContainer->ComputeEffectiveTransformForMaskLayer(aTransformToSurface); - - /* If we have a single child, it can just inherit our opacity, - * otherwise we need a PushGroup and we need to mark ourselves as using - * an intermediate surface so our children don't inherit our opacity - * via GetEffectiveOpacity. - * Having a mask layer always forces our own push group - */ - aContainer->mUseIntermediateSurface = - aContainer->GetMaskLayer() || (aContainer->GetEffectiveOpacity() != 1.0 && - aContainer->HasMultipleChildren()); -} - class BasicContainerLayer : public ContainerLayer, public BasicImplData { - template - friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerRemoveChild(Layer* aChild, Container* aContainer); - template - friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface, - Container* aContainer); - public: BasicContainerLayer(BasicLayerManager* aManager) : ContainerLayer(aManager, @@ -204,27 +38,24 @@ public: { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerInsertAfter(aChild, aAfter, this); + ContainerLayer::InsertAfter(aChild, aAfter); } virtual void RemoveChild(Layer* aChild) { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerRemoveChild(aChild, this); + ContainerLayer::RemoveChild(aChild); } virtual void RepositionChild(Layer* aChild, Layer* aAfter) { NS_ASSERTION(BasicManager()->InConstruction(), "Can only set properties in construction phase"); - ContainerRepositionChild(aChild, aAfter, this); + ContainerLayer::RepositionChild(aChild, aAfter); } - virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface) - { - ContainerComputeEffectiveTransforms(aTransformToSurface, this); - } + virtual void ComputeEffectiveTransforms(const gfx3DMatrix& aTransformToSurface); /** * Returns true when: diff --git a/gfx/layers/client/ClientContainerLayer.h b/gfx/layers/client/ClientContainerLayer.h index cecfa628de3d..20df9320f5fe 100644 --- a/gfx/layers/client/ClientContainerLayer.h +++ b/gfx/layers/client/ClientContainerLayer.h @@ -23,140 +23,9 @@ namespace layers { class ShadowableLayer; -template void -ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template void -ContainerRemoveChild(Layer* aChild, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template void -ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; - } - return false; -} - class ClientContainerLayer : public ContainerLayer, public ClientLayer { - template - friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer); - template - friend void ContainerRemoveChild(Layer* aChild, Container* aContainer); - template - friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer); - public: ClientContainerLayer(ClientLayerManager* aManager) : ContainerLayer(aManager, @@ -168,7 +37,7 @@ public: virtual ~ClientContainerLayer() { while (mFirstChild) { - ContainerRemoveChild(mFirstChild, this); + ContainerLayer::RemoveChild(mFirstChild); } MOZ_COUNT_DTOR(ClientContainerLayer); @@ -219,33 +88,33 @@ public: "Can only set properties in construction phase"); ContainerLayer::SetVisibleRegion(aRegion); } - virtual void InsertAfter(Layer* aChild, Layer* aAfter) + virtual void InsertAfter(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->InsertAfter(ClientManager()->Hold(this), ClientManager()->Hold(aChild), aAfter ? ClientManager()->Hold(aAfter) : nullptr); - ContainerInsertAfter(aChild, aAfter, this); + ContainerLayer::InsertAfter(aChild, aAfter); } - virtual void RemoveChild(Layer* aChild) + virtual void RemoveChild(Layer* aChild) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->RemoveChild(ClientManager()->Hold(this), ClientManager()->Hold(aChild)); - ContainerRemoveChild(aChild, this); + ContainerLayer::RemoveChild(aChild); } - virtual void RepositionChild(Layer* aChild, Layer* aAfter) + virtual void RepositionChild(Layer* aChild, Layer* aAfter) MOZ_OVERRIDE { NS_ASSERTION(ClientManager()->InConstruction(), "Can only set properties in construction phase"); ClientManager()->RepositionChild(ClientManager()->Hold(this), ClientManager()->Hold(aChild), aAfter ? ClientManager()->Hold(aAfter) : nullptr); - ContainerRepositionChild(aChild, aAfter, this); + ContainerLayer::RepositionChild(aChild, aAfter); } virtual Layer* AsLayer() { return this; } diff --git a/gfx/layers/composite/ContainerLayerComposite.cpp b/gfx/layers/composite/ContainerLayerComposite.cpp index 3ffa7d15835b..0562d81977c7 100644 --- a/gfx/layers/composite/ContainerLayerComposite.cpp +++ b/gfx/layers/composite/ContainerLayerComposite.cpp @@ -216,75 +216,6 @@ ContainerLayerComposite::~ContainerLayerComposite() } } -void -ContainerLayerComposite::InsertAfter(Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == Manager() && - aAfter->GetParent() == this), - "aAfter is not our child"); - - aChild->SetParent(this); - if (aAfter == mLastChild) { - mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(mFirstChild); - if (mFirstChild) { - mFirstChild->SetPrevSibling(aChild); - } - mFirstChild = aChild; - NS_ADDREF(aChild); - DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - DidInsertChild(aChild); -} - -void -ContainerLayerComposite::RemoveChild(Layer *aChild) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == this, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - this->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - this->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - this->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - void ContainerLayerComposite::Destroy() { @@ -306,51 +237,6 @@ ContainerLayerComposite::GetFirstChildComposite() return static_cast(mFirstChild->ImplData()); } -void -ContainerLayerComposite::RepositionChild(Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == this, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == Manager() && - aAfter->GetParent() == this), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(mFirstChild); - if (mFirstChild) { - mFirstChild->SetPrevSibling(aChild); - } - mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - void ContainerLayerComposite::RenderLayer(const nsIntPoint& aOffset, const nsIntRect& aClipRect) diff --git a/gfx/layers/composite/ContainerLayerComposite.h b/gfx/layers/composite/ContainerLayerComposite.h index 1b587a4e2ec0..8b7f7dfc1bed 100644 --- a/gfx/layers/composite/ContainerLayerComposite.h +++ b/gfx/layers/composite/ContainerLayerComposite.h @@ -33,12 +33,6 @@ public: ~ContainerLayerComposite(); - void InsertAfter(Layer* aChild, Layer* aAfter); - - void RemoveChild(Layer* aChild); - - void RepositionChild(Layer* aChild, Layer* aAfter); - // LayerComposite Implementation virtual Layer* GetLayer() MOZ_OVERRIDE { return this; } diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.cpp b/gfx/layers/d3d10/ContainerLayerD3D10.cpp index a8af6dda593c..dfd913581e19 100644 --- a/gfx/layers/d3d10/ContainerLayerD3D10.cpp +++ b/gfx/layers/d3d10/ContainerLayerD3D10.cpp @@ -28,140 +28,6 @@ ContainerLayerD3D10::~ContainerLayerD3D10() RemoveChild(mFirstChild); } } -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -void -ContainerLayerD3D10::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerD3D10::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerD3D10::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} Layer* ContainerLayerD3D10::GetLayer() diff --git a/gfx/layers/d3d10/ContainerLayerD3D10.h b/gfx/layers/d3d10/ContainerLayerD3D10.h index 40d3948a251b..2a136afb0ce6 100644 --- a/gfx/layers/d3d10/ContainerLayerD3D10.h +++ b/gfx/layers/d3d10/ContainerLayerD3D10.h @@ -11,35 +11,15 @@ namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - class ContainerLayerD3D10 : public ContainerLayer, public LayerD3D10 { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); public: ContainerLayerD3D10(LayerManagerD3D10 *aManager); ~ContainerLayerD3D10(); nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); } - /* ContainerLayer implementation */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter); - - virtual void RemoveChild(Layer* aChild); - - virtual void RepositionChild(Layer* aChild, Layer* aAfter); - /* LayerD3D10 implementation */ virtual Layer* GetLayer(); diff --git a/gfx/layers/d3d9/ContainerLayerD3D9.cpp b/gfx/layers/d3d9/ContainerLayerD3D9.cpp index c00a87e1055e..8c654b843c3f 100644 --- a/gfx/layers/d3d9/ContainerLayerD3D9.cpp +++ b/gfx/layers/d3d9/ContainerLayerD3D9.cpp @@ -12,155 +12,37 @@ namespace mozilla { namespace layers { -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) +ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager) + : ContainerLayer(aManager, nullptr) + , LayerD3D9(aManager) { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); + mImplData = static_cast(this); } -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) +ContainerLayerD3D9::~ContainerLayerD3D9() { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; + while (mFirstChild) { + RemoveChild(mFirstChild); } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); } -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) +Layer* +ContainerLayerD3D9::GetLayer() { - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); + return this; } -static inline LayerD3D9* -GetNextSibling(LayerD3D9* aLayer) +LayerD3D9* +ContainerLayerD3D9::GetFirstChildD3D9() { - Layer* layer = aLayer->GetLayer()->GetNextSibling(); - return layer ? static_cast(layer-> - ImplData()) - : nullptr; -} - -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; + if (!mFirstChild) { + return nullptr; } - return false; + return static_cast(mFirstChild->ImplData()); } -static inline LayerD3D9* -GetNextSiblingD3D9(LayerD3D9* aLayer) -{ - Layer* layer = aLayer->GetLayer()->GetNextSibling(); - return layer ? static_cast(layer-> - ImplData()) - : nullptr; -} - -template -static void -ContainerRender(Container* aContainer, - LayerManagerD3D9* aManager) +void +ContainerLayerD3D9::RenderLayer() { nsRefPtr previousRenderTarget; nsRefPtr renderTexture; @@ -169,7 +51,7 @@ ContainerRender(Container* aContainer, float oldViewMatrix[4][4]; RECT containerD3D9ClipRect; - aManager->device()->GetScissorRect(&containerD3D9ClipRect); + device()->GetScissorRect(&containerD3D9ClipRect); // Convert scissor to an nsIntRect. RECT's are exclusive on the bottom and // right values. nsIntRect oldScissor(containerD3D9ClipRect.left, @@ -178,44 +60,44 @@ ContainerRender(Container* aContainer, containerD3D9ClipRect.bottom - containerD3D9ClipRect.top); ReadbackProcessor readback; - readback.BuildUpdates(aContainer); + readback.BuildUpdates(this); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); - bool useIntermediate = aContainer->UseIntermediateSurface(); + nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); + bool useIntermediate = UseIntermediateSurface(); - aContainer->mSupportsComponentAlphaChildren = false; + mSupportsComponentAlphaChildren = false; if (useIntermediate) { nsRefPtr renderSurface; - if (!aManager->CompositingDisabled()) { - aManager->device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); - HRESULT hr = aManager->device()->CreateTexture(visibleRect.width, visibleRect.height, 1, - D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, - D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), - nullptr); + if (!mD3DManager->CompositingDisabled()) { + device()->GetRenderTarget(0, getter_AddRefs(previousRenderTarget)); + HRESULT hr = device()->CreateTexture(visibleRect.width, visibleRect.height, 1, + D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, + D3DPOOL_DEFAULT, getter_AddRefs(renderTexture), + nullptr); if (FAILED(hr)) { - aManager->ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"), + ReportFailure(NS_LITERAL_CSTRING("ContainerLayerD3D9::ContainerRender(): Failed to create texture"), hr); return; } nsRefPtr renderSurface; renderTexture->GetSurfaceLevel(0, getter_AddRefs(renderSurface)); - aManager->device()->SetRenderTarget(0, renderSurface); + device()->SetRenderTarget(0, renderSurface); } - if (aContainer->mVisibleRegion.GetNumRects() == 1 && - (aContainer->GetContentFlags() & aContainer->CONTENT_OPAQUE)) { + if (mVisibleRegion.GetNumRects() == 1 && + (GetContentFlags() & CONTENT_OPAQUE)) { // don't need a background, we're going to paint all opaque stuff - aContainer->mSupportsComponentAlphaChildren = true; + mSupportsComponentAlphaChildren = true; } else { - const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); + const gfx3DMatrix& transform3D = GetEffectiveTransform(); gfxMatrix transform; // If we have an opaque ancestor layer, then we can be sure that // all the pixels we draw into are either opaque already or will be // covered by something opaque. Otherwise copying up the background is // not safe. HRESULT hr = E_FAIL; - if (HasOpaqueAncestorLayer(aContainer) && + if (HasOpaqueAncestorLayer(this) && transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { // Copy background up from below RECT dest = { 0, 0, visibleRect.width, visibleRect.height }; @@ -223,24 +105,24 @@ ContainerRender(Container* aContainer, ::OffsetRect(&src, visibleRect.x + int32_t(transform.x0), visibleRect.y + int32_t(transform.y0)); - if (!aManager->CompositingDisabled()) { - hr = aManager->device()-> + if (!mD3DManager->CompositingDisabled()) { + hr = device()-> StretchRect(previousRenderTarget, &src, renderSurface, &dest, D3DTEXF_NONE); } } if (hr == S_OK) { - aContainer->mSupportsComponentAlphaChildren = true; - } else if (!aManager->CompositingDisabled()) { - aManager->device()-> + mSupportsComponentAlphaChildren = true; + } else if (!mD3DManager->CompositingDisabled()) { + device()-> Clear(0, 0, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 0), 0, 0); } } - aManager->device()-> + device()-> GetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); renderTargetOffset[0] = (float)visibleRect.x; renderTargetOffset[1] = (float)visibleRect.y; - aManager->device()-> + device()-> SetVertexShaderConstantF(CBvRenderTargetOffset, renderTargetOffset, 1); gfx3DMatrix viewMatrix; @@ -253,19 +135,19 @@ ContainerRender(Container* aContainer, viewMatrix._41 = -1.0f; viewMatrix._42 = 1.0f; - aManager->device()-> + device()-> GetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); - aManager->device()-> + device()-> SetVertexShaderConstantF(CBmProjection, &viewMatrix._11, 4); } else { - aContainer->mSupportsComponentAlphaChildren = - (aContainer->GetContentFlags() & aContainer->CONTENT_OPAQUE) || - (aContainer->mParent && - aContainer->mParent->SupportsComponentAlphaChildren()); + mSupportsComponentAlphaChildren = + (GetContentFlags() & CONTENT_OPAQUE) || + (mParent && + mParent->SupportsComponentAlphaChildren()); } nsAutoTArray children; - aContainer->SortChildrenBy3DZOrder(children); + SortChildrenBy3DZOrder(children); /* * Render this container's contents. @@ -288,94 +170,40 @@ ContainerRender(Container* aContainer, d3drect.top = scissorRect.y; d3drect.right = scissorRect.x + scissorRect.width; d3drect.bottom = scissorRect.y + scissorRect.height; - aManager->device()->SetScissorRect(&d3drect); + device()->SetScissorRect(&d3drect); - if (layerToRender->GetLayer()->GetType() == aContainer->TYPE_THEBES) { + if (layerToRender->GetLayer()->GetType() == TYPE_THEBES) { static_cast(layerToRender)->RenderThebesLayer(&readback); } else { layerToRender->RenderLayer(); } } - if (useIntermediate && !aManager->CompositingDisabled()) { - aManager->device()->SetRenderTarget(0, previousRenderTarget); - aManager->device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); - aManager->device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); + if (useIntermediate && !mD3DManager->CompositingDisabled()) { + device()->SetRenderTarget(0, previousRenderTarget); + device()->SetVertexShaderConstantF(CBvRenderTargetOffset, previousRenderTargetOffset, 1); + device()->SetVertexShaderConstantF(CBmProjection, &oldViewMatrix[0][0], 4); - aManager->device()->SetVertexShaderConstantF(CBvLayerQuad, + device()->SetVertexShaderConstantF(CBvLayerQuad, ShaderConstantRect(visibleRect.x, visibleRect.y, visibleRect.width, visibleRect.height), 1); - aContainer->SetShaderTransformAndOpacity(); - aManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, - aContainer->GetMaskLayer(), - aContainer->GetTransform().CanDraw2D()); + SetShaderTransformAndOpacity(); + mD3DManager->SetShaderMode(DeviceManagerD3D9::RGBALAYER, + GetMaskLayer(), + GetTransform().CanDraw2D()); - aManager->device()->SetTexture(0, renderTexture); - aManager->device()->SetScissorRect(&containerD3D9ClipRect); - aManager->device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); + device()->SetTexture(0, renderTexture); + device()->SetScissorRect(&containerD3D9ClipRect); + device()->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); } else { - aManager->device()->SetScissorRect(&containerD3D9ClipRect); + device()->SetScissorRect(&containerD3D9ClipRect); } } - -ContainerLayerD3D9::ContainerLayerD3D9(LayerManagerD3D9 *aManager) - : ContainerLayer(aManager, nullptr) - , LayerD3D9(aManager) -{ - mImplData = static_cast(this); -} - -ContainerLayerD3D9::~ContainerLayerD3D9() -{ - while (mFirstChild) { - RemoveChild(mFirstChild); - } -} - -void -ContainerLayerD3D9::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerD3D9::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerD3D9::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} - -Layer* -ContainerLayerD3D9::GetLayer() -{ - return this; -} - -LayerD3D9* -ContainerLayerD3D9::GetFirstChildD3D9() -{ - if (!mFirstChild) { - return nullptr; - } - return static_cast(mFirstChild->ImplData()); -} - -void -ContainerLayerD3D9::RenderLayer() -{ - ContainerRender(this, mD3DManager); -} - void ContainerLayerD3D9::LayerManagerDestroyed() { diff --git a/gfx/layers/d3d9/ContainerLayerD3D9.h b/gfx/layers/d3d9/ContainerLayerD3D9.h index 099e69f30d8a..b7d94829b387 100644 --- a/gfx/layers/d3d9/ContainerLayerD3D9.h +++ b/gfx/layers/d3d9/ContainerLayerD3D9.h @@ -12,40 +12,15 @@ namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRender(Container* aContainer, LayerManagerD3D9* aManager); - class ContainerLayerD3D9 : public ContainerLayer, public LayerD3D9 { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRender(Container* aContainer, LayerManagerD3D9* aManager); - public: ContainerLayerD3D9(LayerManagerD3D9 *aManager); ~ContainerLayerD3D9(); nsIntRect GetVisibleRect() { return mVisibleRegion.GetBounds(); } - /* ContainerLayer implementation */ - virtual void InsertAfter(Layer* aChild, Layer* aAfter); - - virtual void RemoveChild(Layer* aChild); - - virtual void RepositionChild(Layer* aChild, Layer* aAfter); - /* LayerD3D9 implementation */ Layer* GetLayer(); diff --git a/gfx/layers/opengl/ContainerLayerOGL.cpp b/gfx/layers/opengl/ContainerLayerOGL.cpp index 0e0cbcf407a7..6b02dead09b5 100644 --- a/gfx/layers/opengl/ContainerLayerOGL.cpp +++ b/gfx/layers/opengl/ContainerLayerOGL.cpp @@ -28,146 +28,6 @@ class gfxImageSurface; namespace mozilla { namespace layers { -template -static void -ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(!aChild->GetParent(), - "aChild already in the tree"); - NS_ASSERTION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(), - "aChild already has siblings?"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - aChild->SetParent(aContainer); - if (aAfter == aContainer->mLastChild) { - aContainer->mLastChild = aChild; - } - if (!aAfter) { - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); - return; - } - - Layer* next = aAfter->GetNextSibling(); - aChild->SetNextSibling(next); - aChild->SetPrevSibling(aAfter); - if (next) { - next->SetPrevSibling(aChild); - } - aAfter->SetNextSibling(aChild); - NS_ADDREF(aChild); - aContainer->DidInsertChild(aChild); -} - -template -static void -ContainerRemoveChild(Container* aContainer, Layer* aChild) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev) { - prev->SetNextSibling(next); - } else { - aContainer->mFirstChild = next; - } - if (next) { - next->SetPrevSibling(prev); - } else { - aContainer->mLastChild = prev; - } - - aChild->SetNextSibling(nullptr); - aChild->SetPrevSibling(nullptr); - aChild->SetParent(nullptr); - - aContainer->DidRemoveChild(aChild); - NS_RELEASE(aChild); -} - -template -static void -ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter) -{ - NS_ASSERTION(aChild->Manager() == aContainer->Manager(), - "Child has wrong manager"); - NS_ASSERTION(aChild->GetParent() == aContainer, - "aChild not our child"); - NS_ASSERTION(!aAfter || - (aAfter->Manager() == aContainer->Manager() && - aAfter->GetParent() == aContainer), - "aAfter is not our child"); - - Layer* prev = aChild->GetPrevSibling(); - Layer* next = aChild->GetNextSibling(); - if (prev == aAfter) { - // aChild is already in the correct position, nothing to do. - return; - } - if (prev) { - prev->SetNextSibling(next); - } - if (next) { - next->SetPrevSibling(prev); - } - if (!aAfter) { - aChild->SetPrevSibling(nullptr); - aChild->SetNextSibling(aContainer->mFirstChild); - if (aContainer->mFirstChild) { - aContainer->mFirstChild->SetPrevSibling(aChild); - } - aContainer->mFirstChild = aChild; - return; - } - - Layer* afterNext = aAfter->GetNextSibling(); - if (afterNext) { - afterNext->SetPrevSibling(aChild); - } else { - aContainer->mLastChild = aChild; - } - aAfter->SetNextSibling(aChild); - aChild->SetPrevSibling(aAfter); - aChild->SetNextSibling(afterNext); -} - -template -static void -ContainerDestroy(Container* aContainer) - { - if (!aContainer->mDestroyed) { - while (aContainer->mFirstChild) { - aContainer->GetFirstChildOGL()->Destroy(); - aContainer->RemoveChild(aContainer->mFirstChild); - } - aContainer->mDestroyed = true; - } -} - -template -static void -ContainerCleanupResources(Container* aContainer) -{ - for (Layer* l = aContainer->GetFirstChild(); l; l = l->GetNextSibling()) { - LayerOGL* layerToRender = static_cast(l->ImplData()); - layerToRender->CleanupResources(); - } -} - static inline LayerOGL* GetNextSibling(LayerOGL* aLayer) { @@ -177,195 +37,9 @@ GetNextSibling(LayerOGL* aLayer) : nullptr; } -static bool -HasOpaqueAncestorLayer(Layer* aLayer) -{ - for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) { - if (l->GetContentFlags() & Layer::CONTENT_OPAQUE) - return true; - } - return false; -} - -template -static void -ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager) -{ - /** - * Setup our temporary texture for rendering the contents of this container. - */ - GLuint containerSurface; - GLuint frameBuffer; - - nsIntPoint childOffset(aOffset); - nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds(); - - nsIntRect cachedScissor = aContainer->gl()->ScissorRect(); - aContainer->gl()->PushScissorRect(); - aContainer->mSupportsComponentAlphaChildren = false; - - float opacity = aContainer->GetEffectiveOpacity(); - const gfx3DMatrix& transform = aContainer->GetEffectiveTransform(); - bool needsFramebuffer = aContainer->UseIntermediateSurface(); - if (needsFramebuffer) { - nsIntRect framebufferRect = visibleRect; - // we're about to create a framebuffer backed by textures to use as an intermediate - // surface. What to do if its size (as given by framebufferRect) would exceed the - // maximum texture size supported by the GL? The present code chooses the compromise - // of just clamping the framebuffer's size to the max supported size. - // This gives us a lower resolution rendering of the intermediate surface (children layers). - // See bug 827170 for a discussion. - GLint maxTexSize; - aContainer->gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); - framebufferRect.width = std::min(framebufferRect.width, maxTexSize); - framebufferRect.height = std::min(framebufferRect.height, maxTexSize); - - LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; - if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 && - (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE)) - { - // don't need a background, we're going to paint all opaque stuff - aContainer->mSupportsComponentAlphaChildren = true; - mode = LayerManagerOGL::InitModeNone; - } else { - const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform(); - gfxMatrix transform; - // If we have an opaque ancestor layer, then we can be sure that - // all the pixels we draw into are either opaque already or will be - // covered by something opaque. Otherwise copying up the background is - // not safe. - if (HasOpaqueAncestorLayer(aContainer) && - transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { - mode = gfxPlatform::ComponentAlphaEnabled() ? - LayerManagerOGL::InitModeCopy : - LayerManagerOGL::InitModeClear; - framebufferRect.x += transform.x0; - framebufferRect.y += transform.y0; - aContainer->mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); - } - } - - aContainer->gl()->PushViewportRect(); - framebufferRect -= childOffset; - if (!aManager->CompositingDisabled()) { - if (!aManager->CreateFBOWithTexture(framebufferRect, - mode, - aPreviousFrameBuffer, - &frameBuffer, - &containerSurface)) { - aContainer->gl()->PopViewportRect(); - aContainer->gl()->PopScissorRect(); - aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); - return; - } - } - childOffset.x = visibleRect.x; - childOffset.y = visibleRect.y; - } else { - frameBuffer = aPreviousFrameBuffer; - aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) || - (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren()); - } - - nsAutoTArray children; - aContainer->SortChildrenBy3DZOrder(children); - - /** - * Render this container's contents. - */ - for (uint32_t i = 0; i < children.Length(); i++) { - LayerOGL* layerToRender = static_cast(children.ElementAt(i)->ImplData()); - - if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { - continue; - } - - nsIntRect scissorRect = layerToRender->GetLayer()-> - CalculateScissorRect(cachedScissor, &aManager->GetWorldTransform()); - if (scissorRect.IsEmpty()) { - continue; - } - - aContainer->gl()->fScissor(scissorRect.x, - scissorRect.y, - scissorRect.width, - scissorRect.height); - - layerToRender->RenderLayer(frameBuffer, childOffset); - aContainer->gl()->MakeCurrent(); - } - - - if (needsFramebuffer) { - // Unbind the current framebuffer and rebind the previous one. -#ifdef MOZ_DUMP_PAINTING - if (gfxUtils::sDumpPainting) { - nsRefPtr surf = - aContainer->gl()->GetTexImage(containerSurface, true, aManager->GetFBOTextureFormat()); - - WriteSnapshotToDumpFile(aContainer, surf); - } -#endif - - // Restore the viewport - aContainer->gl()->PopViewportRect(); - nsIntRect viewport = aContainer->gl()->ViewportRect(); - aManager->SetupPipeline(viewport.width, viewport.height, - LayerManagerOGL::ApplyWorldTransform); - aContainer->gl()->PopScissorRect(); - - if (!aManager->CompositingDisabled()) { - aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); - aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer); - - aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0); - - aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface); - - MaskType maskType = MaskNone; - if (aContainer->GetMaskLayer()) { - if (!aContainer->GetTransform().CanDraw2D()) { - maskType = Mask3d; - } else { - maskType = Mask2d; - } - } - ShaderProgramOGL *rgb = - aManager->GetFBOLayerProgram(maskType); - - rgb->Activate(); - rgb->SetLayerQuadRect(visibleRect); - rgb->SetLayerTransform(transform); - rgb->SetTextureTransform(gfx3DMatrix()); - rgb->SetLayerOpacity(opacity); - rgb->SetRenderOffset(aOffset); - rgb->SetTextureUnit(0); - rgb->LoadMask(aContainer->GetMaskLayer()); - - if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { - // 2DRect case, get the multiplier right for a sampler2DRect - rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); - } - - // Drawing is always flipped, but when copying between surfaces we want to avoid - // this. Pass true for the flip parameter to introduce a second flip - // that cancels the other one out. - aManager->BindAndDrawQuad(rgb, true); - - // Clean up resources. This also unbinds the texture. - aContainer->gl()->fDeleteTextures(1, &containerSurface); - } - } else { - aContainer->gl()->PopScissorRect(); - } -} - -ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *aManager) - : ContainerLayer(aManager, nullptr) - , LayerOGL(aManager) +ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *mOGLManager) + : ContainerLayer(mOGLManager, nullptr) + , LayerOGL(mOGLManager) { mImplData = static_cast(this); } @@ -375,28 +49,16 @@ ContainerLayerOGL::~ContainerLayerOGL() Destroy(); } -void -ContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter) -{ - ContainerInsertAfter(this, aChild, aAfter); -} - -void -ContainerLayerOGL::RemoveChild(Layer *aChild) -{ - ContainerRemoveChild(this, aChild); -} - -void -ContainerLayerOGL::RepositionChild(Layer* aChild, Layer* aAfter) -{ - ContainerRepositionChild(this, aChild, aAfter); -} - void ContainerLayerOGL::Destroy() { - ContainerDestroy(this); + if (!mDestroyed) { + while (mFirstChild) { + GetFirstChildOGL()->Destroy(); + RemoveChild(mFirstChild); + } + mDestroyed = true; + } } LayerOGL* @@ -412,13 +74,182 @@ void ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer, const nsIntPoint& aOffset) { - ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager); + /** + * Setup our temporary texture for rendering the contents of this container. + */ + GLuint containerSurface; + GLuint frameBuffer; + + nsIntPoint childOffset(aOffset); + nsIntRect visibleRect = GetEffectiveVisibleRegion().GetBounds(); + + nsIntRect cachedScissor = gl()->ScissorRect(); + gl()->PushScissorRect(); + mSupportsComponentAlphaChildren = false; + + float opacity = GetEffectiveOpacity(); + const gfx3DMatrix& transform = GetEffectiveTransform(); + bool needsFramebuffer = UseIntermediateSurface(); + if (needsFramebuffer) { + nsIntRect framebufferRect = visibleRect; + // we're about to create a framebuffer backed by textures to use as an intermediate + // surface. What to do if its size (as given by framebufferRect) would exceed the + // maximum texture size supported by the GL? The present code chooses the compromise + // of just clamping the framebuffer's size to the max supported size. + // This gives us a lower resolution rendering of the intermediate surface (children layers). + // See bug 827170 for a discussion. + GLint maxTexSize; + gl()->fGetIntegerv(LOCAL_GL_MAX_TEXTURE_SIZE, &maxTexSize); + framebufferRect.width = std::min(framebufferRect.width, maxTexSize); + framebufferRect.height = std::min(framebufferRect.height, maxTexSize); + + LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear; + if (GetEffectiveVisibleRegion().GetNumRects() == 1 && + (GetContentFlags() & Layer::CONTENT_OPAQUE)) + { + // don't need a background, we're going to paint all opaque stuff + mSupportsComponentAlphaChildren = true; + mode = LayerManagerOGL::InitModeNone; + } else { + const gfx3DMatrix& transform3D = GetEffectiveTransform(); + gfxMatrix transform; + // If we have an opaque ancestor layer, then we can be sure that + // all the pixels we draw into are either opaque already or will be + // covered by something opaque. Otherwise copying up the background is + // not safe. + if (HasOpaqueAncestorLayer(this) && + transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) { + mode = gfxPlatform::ComponentAlphaEnabled() ? + LayerManagerOGL::InitModeCopy : + LayerManagerOGL::InitModeClear; + framebufferRect.x += transform.x0; + framebufferRect.y += transform.y0; + mSupportsComponentAlphaChildren = gfxPlatform::ComponentAlphaEnabled(); + } + } + + gl()->PushViewportRect(); + framebufferRect -= childOffset; + if (!mOGLManager->CompositingDisabled()) { + if (!mOGLManager->CreateFBOWithTexture(framebufferRect, + mode, + aPreviousFrameBuffer, + &frameBuffer, + &containerSurface)) { + gl()->PopViewportRect(); + gl()->PopScissorRect(); + gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); + return; + } + } + childOffset.x = visibleRect.x; + childOffset.y = visibleRect.y; + } else { + frameBuffer = aPreviousFrameBuffer; + mSupportsComponentAlphaChildren = (GetContentFlags() & Layer::CONTENT_OPAQUE) || + (GetParent() && GetParent()->SupportsComponentAlphaChildren()); + } + + nsAutoTArray children; + SortChildrenBy3DZOrder(children); + + /** + * Render this container's contents. + */ + for (uint32_t i = 0; i < children.Length(); i++) { + LayerOGL* layerToRender = static_cast(children.ElementAt(i)->ImplData()); + + if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) { + continue; + } + + nsIntRect scissorRect = layerToRender->GetLayer()-> + CalculateScissorRect(cachedScissor, &mOGLManager->GetWorldTransform()); + if (scissorRect.IsEmpty()) { + continue; + } + + gl()->fScissor(scissorRect.x, + scissorRect.y, + scissorRect.width, + scissorRect.height); + + layerToRender->RenderLayer(frameBuffer, childOffset); + gl()->MakeCurrent(); + } + + + if (needsFramebuffer) { + // Unbind the current framebuffer and rebind the previous one. +#ifdef MOZ_DUMP_PAINTING + if (gfxUtils::sDumpPainting) { + nsRefPtr surf = + gl()->GetTexImage(containerSurface, true, mOGLManager->GetFBOTextureFormat()); + + WriteSnapshotToDumpFile(this, surf); + } +#endif + + // Restore the viewport + gl()->PopViewportRect(); + nsIntRect viewport = gl()->ViewportRect(); + mOGLManager->SetupPipeline(viewport.width, viewport.height, + LayerManagerOGL::ApplyWorldTransform); + gl()->PopScissorRect(); + + if (!mOGLManager->CompositingDisabled()) { + gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer); + gl()->fDeleteFramebuffers(1, &frameBuffer); + + gl()->fActiveTexture(LOCAL_GL_TEXTURE0); + + gl()->fBindTexture(mOGLManager->FBOTextureTarget(), containerSurface); + + MaskType maskType = MaskNone; + if (GetMaskLayer()) { + if (!GetTransform().CanDraw2D()) { + maskType = Mask3d; + } else { + maskType = Mask2d; + } + } + ShaderProgramOGL *rgb = + mOGLManager->GetFBOLayerProgram(maskType); + + rgb->Activate(); + rgb->SetLayerQuadRect(visibleRect); + rgb->SetLayerTransform(transform); + rgb->SetTextureTransform(gfx3DMatrix()); + rgb->SetLayerOpacity(opacity); + rgb->SetRenderOffset(aOffset); + rgb->SetTextureUnit(0); + rgb->LoadMask(GetMaskLayer()); + + if (rgb->GetTexCoordMultiplierUniformLocation() != -1) { + // 2DRect case, get the multiplier right for a sampler2DRect + rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height); + } + + // Drawing is always flipped, but when copying between surfaces we want to avoid + // this. Pass true for the flip parameter to introduce a second flip + // that cancels the other one out. + mOGLManager->BindAndDrawQuad(rgb, true); + + // Clean up resources. This also unbinds the texture. + gl()->fDeleteTextures(1, &containerSurface); + } + } else { + gl()->PopScissorRect(); + } } void ContainerLayerOGL::CleanupResources() { - ContainerCleanupResources(this); + for (Layer* l = GetFirstChild(); l; l = l->GetNextSibling()) { + LayerOGL* layerToRender = static_cast(l->ImplData()); + layerToRender->CleanupResources(); + } } } /* layers */ diff --git a/gfx/layers/opengl/ContainerLayerOGL.h b/gfx/layers/opengl/ContainerLayerOGL.h index 84d1bbf32aaf..1e80d23d58dc 100644 --- a/gfx/layers/opengl/ContainerLayerOGL.h +++ b/gfx/layers/opengl/ContainerLayerOGL.h @@ -14,47 +14,13 @@ struct nsIntPoint; namespace mozilla { namespace layers { -template -static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerRemoveChild(Container* aContainer, Layer* aChild); -template -static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); -template -static void ContainerDestroy(Container* aContainer); -template -static void ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager); - class ContainerLayerOGL : public ContainerLayer, public LayerOGL { - template - friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerRemoveChild(Container* aContainer, Layer* aChild); - template - friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter); - template - friend void ContainerDestroy(Container* aContainer); - template - friend void ContainerRender(Container* aContainer, - int aPreviousFrameBuffer, - const nsIntPoint& aOffset, - LayerManagerOGL* aManager); - public: ContainerLayerOGL(LayerManagerOGL *aManager); ~ContainerLayerOGL(); - void InsertAfter(Layer* aChild, Layer* aAfter); - - void RemoveChild(Layer* aChild); - - void RepositionChild(Layer* aChild, Layer* aAfter); - /** LayerOGL implementation */ Layer* GetLayer() { return this; }