mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-26 23:23:33 +00:00
Bug 786412. Conslidate container layer methods. r=mattwoodrow
This commit is contained in:
parent
f6b2473ad5
commit
31ac189fe3
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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:
|
||||
|
@ -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; }
|
||||
|
@ -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)
|
||||
|
@ -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; }
|
||||
|
||||
|
@ -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()
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -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; }
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user