Bug 786412. Conslidate container layer methods. r=mattwoodrow

This commit is contained in:
Nicholas Cameron 2013-09-02 10:19:18 +12:00
parent f6b2473ad5
commit 31ac189fe3
13 changed files with 426 additions and 1234 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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)
{

View File

@ -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<class Container> 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<class Container> 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<class Container> 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<class Container>
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<class Container>
friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer);
template<class Container>
friend void ContainerRemoveChild(Layer* aChild, Container* aContainer);
template<class Container>
friend void ContainerRepositionChild(Layer* aChild, Layer* aAfter, Container* aContainer);
template<class Container>
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:

View File

@ -23,140 +23,9 @@ namespace layers {
class ShadowableLayer;
template<class Container> 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<class Container> 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<class Container> 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<class Container>
friend void ContainerInsertAfter(Layer* aChild, Layer* aAfter, Container* aContainer);
template<class Container>
friend void ContainerRemoveChild(Layer* aChild, Container* aContainer);
template<class Container>
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; }

View File

@ -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<LayerComposite*>(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)

View File

@ -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; }

View File

@ -28,140 +28,6 @@ ContainerLayerD3D10::~ContainerLayerD3D10()
RemoveChild(mFirstChild);
}
}
template<class Container>
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<class Container>
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<class Container>
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()

View File

@ -11,35 +11,15 @@
namespace mozilla {
namespace layers {
template<class Container>
static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter);
class ContainerLayerD3D10 : public ContainerLayer,
public LayerD3D10
{
template<class Container>
friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
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();

View File

@ -12,155 +12,37 @@
namespace mozilla {
namespace layers {
template<class Container>
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<LayerD3D9*>(this);
}
template<class Container>
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<class Container>
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<LayerD3D9*>(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<LayerD3D9*>(mFirstChild->ImplData());
}
static inline LayerD3D9*
GetNextSiblingD3D9(LayerD3D9* aLayer)
{
Layer* layer = aLayer->GetLayer()->GetNextSibling();
return layer ? static_cast<LayerD3D9*>(layer->
ImplData())
: nullptr;
}
template<class Container>
static void
ContainerRender(Container* aContainer,
LayerManagerD3D9* aManager)
void
ContainerLayerD3D9::RenderLayer()
{
nsRefPtr<IDirect3DSurface9> previousRenderTarget;
nsRefPtr<IDirect3DTexture9> 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<IDirect3DSurface9> 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<IDirect3DSurface9> 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<Layer*, 12> 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<ThebesLayerD3D9*>(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<LayerD3D9*>(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<LayerD3D9*>(mFirstChild->ImplData());
}
void
ContainerLayerD3D9::RenderLayer()
{
ContainerRender(this, mD3DManager);
}
void
ContainerLayerD3D9::LayerManagerDestroyed()
{

View File

@ -12,40 +12,15 @@
namespace mozilla {
namespace layers {
template<class Container>
static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerRender(Container* aContainer, LayerManagerD3D9* aManager);
class ContainerLayerD3D9 : public ContainerLayer,
public LayerD3D9
{
template<class Container>
friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
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();

View File

@ -28,146 +28,6 @@ class gfxImageSurface;
namespace mozilla {
namespace layers {
template<class Container>
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<class Container>
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<class Container>
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<class Container>
static void
ContainerDestroy(Container* aContainer)
{
if (!aContainer->mDestroyed) {
while (aContainer->mFirstChild) {
aContainer->GetFirstChildOGL()->Destroy();
aContainer->RemoveChild(aContainer->mFirstChild);
}
aContainer->mDestroyed = true;
}
}
template<class Container>
static void
ContainerCleanupResources(Container* aContainer)
{
for (Layer* l = aContainer->GetFirstChild(); l; l = l->GetNextSibling()) {
LayerOGL* layerToRender = static_cast<LayerOGL*>(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<class Container>
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<Layer*, 12> children;
aContainer->SortChildrenBy3DZOrder(children);
/**
* Render this container's contents.
*/
for (uint32_t i = 0; i < children.Length(); i++) {
LayerOGL* layerToRender = static_cast<LayerOGL*>(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<gfxImageSurface> 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<LayerOGL*>(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<Layer*, 12> children;
SortChildrenBy3DZOrder(children);
/**
* Render this container's contents.
*/
for (uint32_t i = 0; i < children.Length(); i++) {
LayerOGL* layerToRender = static_cast<LayerOGL*>(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<gfxImageSurface> 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<LayerOGL*>(l->ImplData());
layerToRender->CleanupResources();
}
}
} /* layers */

View File

@ -14,47 +14,13 @@ struct nsIntPoint;
namespace mozilla {
namespace layers {
template<class Container>
static void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
static void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
static void ContainerDestroy(Container* aContainer);
template<class Container>
static void ContainerRender(Container* aContainer,
int aPreviousFrameBuffer,
const nsIntPoint& aOffset,
LayerManagerOGL* aManager);
class ContainerLayerOGL : public ContainerLayer,
public LayerOGL
{
template<class Container>
friend void ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerRemoveChild(Container* aContainer, Layer* aChild);
template<class Container>
friend void ContainerRepositionChild(Container* aContainer, Layer* aChild, Layer* aAfter);
template<class Container>
friend void ContainerDestroy(Container* aContainer);
template<class Container>
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; }