Bug 539356 - Part 7 - Store FrameLayerBuilder objects on the LayerManager instead of nsDisplayListBuilder. r=roc

This commit is contained in:
Matt Woodrow 2012-06-11 16:44:08 +12:00
parent 3546fceb5c
commit 1ff0a4086c
9 changed files with 130 additions and 49 deletions

View File

@ -57,6 +57,14 @@ public:
nsRefPtr<LayerManager> mLayerManager;
};
LayerManagerLayerBuilder::~LayerManagerLayerBuilder()
{
MOZ_COUNT_DTOR(LayerManagerLayerBuilder);
if (mDelete) {
delete mLayerBuilder;
}
}
namespace {
class RefCountedRegion : public RefCounted<RefCountedRegion> {
@ -109,10 +117,12 @@ class ContainerState {
public:
ContainerState(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
FrameLayerBuilder* aLayerBuilder,
nsIFrame* aContainerFrame,
ContainerLayer* aContainerLayer,
const FrameLayerBuilder::ContainerParameters& aParameters) :
mBuilder(aBuilder), mManager(aManager),
mLayerBuilder(aLayerBuilder),
mContainerFrame(aContainerFrame), mContainerLayer(aContainerLayer),
mParameters(aParameters),
mNextFreeRecycledThebesLayer(0), mNextFreeRecycledColorLayer(0),
@ -413,6 +423,7 @@ protected:
nsDisplayListBuilder* mBuilder;
LayerManager* mManager;
FrameLayerBuilder* mLayerBuilder;
nsIFrame* mContainerFrame;
ContainerLayer* mContainerLayer;
FrameLayerBuilder::ContainerParameters mParameters;
@ -538,6 +549,8 @@ ThebesDisplayItemLayerUserData* GetThebesDisplayItemLayerUserData(Layer* aLayer)
} // anonymous namespace
PRUint8 gLayerManagerLayerBuilder;
void
FrameLayerBuilder::Init(nsDisplayListBuilder* aBuilder)
{
@ -821,6 +834,30 @@ FrameLayerBuilder::GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
return nsnull;
}
/* static */ Layer*
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey)
{
FrameProperties props = aFrame->Properties();
LayerManagerData* data = static_cast<LayerManagerData*>(props.Get(LayerManagerDataProperty()));
if (!data) {
return nsnull;
}
DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame);
if (!entry)
return nsnull;
nsTArray<DisplayItemData> *array = &entry->mData;
if (!array)
return nsnull;
for (PRUint32 i = 0; i < array->Length(); ++i) {
if (array->ElementAt(i).mDisplayItemKey == aDisplayItemKey) {
return array->ElementAt(i).mLayer;
}
}
return nsnull;
}
/**
* Invalidate aRegion in aLayer. aLayer is in the coordinate system
* *after* aTranslation has been applied, so we need to
@ -1002,7 +1039,7 @@ ContainerState::CreateOrRecycleThebesLayer(nsIFrame* aActiveScrolledRoot)
data->mYScale = mParameters.mYScale;
layer->SetAllowResidualTranslation(mParameters.AllowResidualTranslation());
mBuilder->LayerBuilder()->SaveLastPaintOffset(layer);
mLayerBuilder->SaveLastPaintOffset(layer);
// Set up transform so that 0,0 in the Thebes layer corresponds to the
// (pixel-snapped) top-left of the aActiveScrolledRoot.
@ -1111,7 +1148,7 @@ ContainerState::FindOpaqueBackgroundColorFor(PRInt32 aThebesLayerIndex)
nsRect rect =
target->mVisibleRegion.GetBounds().ToAppUnits(mAppUnitsPerDevPixel);
rect.ScaleInverseRoundOut(mParameters.mXScale, mParameters.mYScale);
return mBuilder->LayerBuilder()->
return mLayerBuilder->
FindOpaqueColorCovering(mBuilder, candidate->mLayer, rect);
}
return NS_RGBA(0,0,0,0);
@ -1259,7 +1296,7 @@ ContainerState::PopThebesLayerData()
NS_ASSERTION(commonClipCount >= 0, "Inconsistent clip count.");
SetupMaskLayer(layer, data->mItemClip, commonClipCount);
// copy commonClipCount to the entry
FrameLayerBuilder::ThebesLayerItemsEntry* entry = mBuilder->LayerBuilder()->
FrameLayerBuilder::ThebesLayerItemsEntry* entry = mLayerBuilder->
GetThebesLayerItemsEntry(static_cast<ThebesLayer*>(layer.get()));
entry->mCommonClipCount = commonClipCount;
} else {
@ -1529,7 +1566,8 @@ static void
PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
nsDisplayItem* aItem,
gfxContext* aContext,
nsRenderingContext* aCtx)
nsRenderingContext* aCtx,
FrameLayerBuilder *aLayerBuilder)
{
// This item has an inactive layer. Render it to a ThebesLayer
// using a temporary BasicLayerManager.
@ -1549,6 +1587,7 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
#endif
nsRefPtr<BasicLayerManager> tempManager = new BasicLayerManager();
tempManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(aLayerBuilder, false));
tempManager->BeginTransactionWithTarget(context);
nsRefPtr<Layer> layer =
aItem->BuildLayer(aBuilder, tempManager, FrameLayerBuilder::ContainerParameters());
@ -1559,13 +1598,13 @@ PaintInactiveLayer(nsDisplayListBuilder* aBuilder,
RestrictVisibleRegionForLayer(layer, itemVisibleRect);
tempManager->SetRoot(layer);
aBuilder->LayerBuilder()->WillEndTransaction(tempManager);
aLayerBuilder->WillEndTransaction(tempManager);
if (aItem->GetType() == nsDisplayItem::TYPE_SVG_EFFECTS) {
static_cast<nsDisplaySVGEffects*>(aItem)->PaintAsLayer(aBuilder, aCtx, tempManager);
} else {
tempManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer, aBuilder);
}
aBuilder->LayerBuilder()->DidEndTransaction(tempManager);
aLayerBuilder->DidEndTransaction(tempManager);
#ifdef MOZ_DUMP_PAINTING
if (gfxUtils::sDumpPainting) {
@ -1710,7 +1749,7 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
InvalidateForLayerChange(item, ownLayer);
mNewChildLayers.AppendElement(ownLayer);
mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item, layerState);
mLayerBuilder->AddLayerDisplayItem(ownLayer, item, layerState);
} else {
ThebesLayerData* data =
FindThebesLayerFor(item, itemVisibleRect, itemDrawRect, aClip,
@ -1722,9 +1761,9 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
InvalidateForLayerChange(item, data->mLayer);
mBuilder->LayerBuilder()->AddThebesDisplayItem(data->mLayer, item, aClip,
mContainerFrame,
layerState);
mLayerBuilder->AddThebesDisplayItem(data->mLayer, item, aClip,
mContainerFrame,
layerState);
// check to see if the new item has rounded rect clips in common with
// other items in the layer
@ -1740,7 +1779,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
NS_ASSERTION(f, "Display items that render using Thebes must have a frame");
PRUint32 key = aItem->GetPerFrameKey();
NS_ASSERTION(key, "Display items that render using Thebes must have a key");
Layer* oldLayer = mBuilder->LayerBuilder()->GetOldLayerFor(f, key);
Layer* oldLayer = mLayerBuilder->GetOldLayerFor(f, key);
if (!oldLayer) {
// Nothing to do here, this item didn't have a layer before
return;
@ -1763,7 +1802,7 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
// or a new scale here
InvalidatePostTransformRegion(t,
bounds.ScaleToOutsidePixels(data->mXScale, data->mYScale, mAppUnitsPerDevPixel),
mBuilder->LayerBuilder()->GetLastPaintOffset(t));
mLayerBuilder->GetLastPaintOffset(t));
}
if (aNewLayer) {
ThebesLayer* newLayer = aNewLayer->AsThebesLayer();
@ -2102,8 +2141,8 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder,
ContainerParameters scaleParameters =
ChooseScaleAndSetTransform(this, aContainerFrame, aTransform, aParameters,
containerLayer);
ContainerState state(aBuilder, aManager, aContainerFrame, containerLayer,
scaleParameters);
ContainerState state(aBuilder, aManager, GetLayerBuilderForManager(aManager),
aContainerFrame, containerLayer, scaleParameters);
if (aManager == mRetainingManager) {
DisplayItemDataEntry* entry = mNewDisplayItemData.PutEntry(aContainerFrame);
@ -2397,15 +2436,16 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
nsDisplayListBuilder* builder = static_cast<nsDisplayListBuilder*>
(aCallbackData);
if (builder->LayerBuilder()->CheckDOMModified())
FrameLayerBuilder *layerBuilder = GetLayerBuilderForManager(aLayer->Manager());
if (layerBuilder->CheckDOMModified())
return;
nsTArray<ClippedDisplayItem> items;
PRUint32 commonClipCount;
nsIFrame* containerLayerFrame;
{
ThebesLayerItemsEntry* entry =
builder->LayerBuilder()->mThebesLayerItems.GetEntry(aLayer);
ThebesLayerItemsEntry* entry = layerBuilder->mThebesLayerItems.GetEntry(aLayer);
NS_ASSERTION(entry, "We shouldn't be drawing into a layer with no items!");
items.SwapElements(entry->mItems);
commonClipCount = entry->mCommonClipCount;
@ -2529,7 +2569,7 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
}
if (cdi->mInactiveLayer) {
PaintInactiveLayer(builder, cdi->mItem, aContext, rc);
PaintInactiveLayer(builder, cdi->mItem, aContext, rc, layerBuilder);
} else {
nsIFrame* frame = cdi->mItem->GetUnderlyingFrame();
if (frame) {
@ -2547,7 +2587,7 @@ FrameLayerBuilder::DrawThebesLayer(ThebesLayer* aLayer,
}
}
if (builder->LayerBuilder()->CheckDOMModified())
if (layerBuilder->CheckDOMModified())
break;
}
@ -2577,12 +2617,10 @@ FrameLayerBuilder::CheckDOMModified()
}
#ifdef MOZ_DUMP_PAINTING
void
FrameLayerBuilder::DumpRetainedLayerTree(FILE* aFile)
/* static */ void
FrameLayerBuilder::DumpRetainedLayerTree(LayerManager* aManager, FILE* aFile)
{
if (mRetainingManager) {
mRetainingManager->Dump(aFile);
}
aManager->Dump(aFile);
}
#endif

View File

@ -21,6 +21,8 @@ class nsRootPresContext;
namespace mozilla {
class FrameLayerBuilder;
enum LayerState {
LAYER_NONE,
LAYER_INACTIVE,
@ -34,6 +36,35 @@ enum LayerState {
LAYER_SVG_EFFECTS
};
class LayerManagerLayerBuilder : public layers::LayerUserData {
public:
LayerManagerLayerBuilder(FrameLayerBuilder* aBuilder, bool aDelete = true)
: mLayerBuilder(aBuilder)
, mDelete(aDelete)
{
MOZ_COUNT_CTOR(LayerManagerLayerBuilder);
}
~LayerManagerLayerBuilder();
FrameLayerBuilder* mLayerBuilder;
bool mDelete;
};
extern PRUint8 gLayerManagerLayerBuilder;
class ContainerLayerPresContext : public layers::LayerUserData {
public:
nsPresContext* mPresContext;
};
extern PRUint8 gContainerLayerPresContext;
static inline FrameLayerBuilder *GetLayerBuilderForManager(layers::LayerManager* aManager)
{
LayerManagerLayerBuilder *data = static_cast<LayerManagerLayerBuilder*>(aManager->GetUserData(&gLayerManagerLayerBuilder));
return data ? data->mLayerBuilder : nsnull;
}
/**
* The FrameLayerBuilder belongs to an nsDisplayListBuilder and is
* responsible for converting display lists into layer trees.
@ -85,9 +116,14 @@ public:
mDetectedDOMModification(false),
mInvalidateAllLayers(false)
{
MOZ_COUNT_CTOR(FrameLayerBuilder);
mNewDisplayItemData.Init();
mThebesLayerItems.Init();
}
~FrameLayerBuilder()
{
MOZ_COUNT_DTOR(FrameLayerBuilder);
}
void Init(nsDisplayListBuilder* aBuilder);
@ -230,7 +266,7 @@ public:
* Dumps this FrameLayerBuilder's retained layer manager's retained
* layer tree to stderr.
*/
void DumpRetainedLayerTree(FILE* aFile = stdout);
static void DumpRetainedLayerTree(LayerManager* aManager, FILE* aFile = stdout);
#endif
/******* PRIVATE METHODS to FrameLayerBuilder.cpp ********/
@ -267,6 +303,7 @@ public:
*/
Layer* GetOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
static Layer* GetDebugOldLayerFor(nsIFrame* aFrame, PRUint32 aDisplayItemKey);
/**
* Try to determine whether the ThebesLayer aLayer paints an opaque
* single color everywhere it's visible in aRect.

View File

@ -86,8 +86,6 @@ nsDisplayListBuilder::nsDisplayListBuilder(nsIFrame* aReferenceFrame,
}
}
LayerBuilder()->Init(this);
PR_STATIC_ASSERT(nsDisplayItem::TYPE_MAX < (1 << nsDisplayItem::TYPE_BITS));
}
@ -586,6 +584,10 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
layerManager = new BasicLayerManager();
}
FrameLayerBuilder *layerBuilder = new FrameLayerBuilder();
layerBuilder->Init(aBuilder);
layerManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(layerBuilder));
if (aFlags & PAINT_FLUSH_LAYERS) {
FrameLayerBuilder::InvalidateAllLayers(layerManager);
}
@ -598,7 +600,7 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
}
}
if (allowRetaining) {
aBuilder->LayerBuilder()->DidBeginRetainedLayerTransaction(layerManager);
layerBuilder->DidBeginRetainedLayerTransaction(layerManager);
}
nsPresContext* presContext = aForFrame->PresContext();
@ -606,11 +608,14 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
nsDisplayItem::ContainerParameters containerParameters
(presShell->GetXResolution(), presShell->GetYResolution());
nsRefPtr<ContainerLayer> root = aBuilder->LayerBuilder()->
nsRefPtr<ContainerLayer> root = layerBuilder->
BuildContainerLayerFor(aBuilder, layerManager, aForFrame, nsnull, *this,
containerParameters, nsnull);
if (!root)
if (!root) {
layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
return;
}
// Root is being scaled up by the X/Y resolution. Scale it back down.
gfx3DMatrix rootTransform = root->GetTransform()*
gfx3DMatrix::ScalingMatrix(1.0f/containerParameters.mXScale,
@ -641,16 +646,17 @@ void nsDisplayList::PaintForFrame(nsDisplayListBuilder* aBuilder,
}
layerManager->SetRoot(root);
aBuilder->LayerBuilder()->WillEndTransaction(layerManager);
layerBuilder->WillEndTransaction(layerManager);
layerManager->EndTransaction(FrameLayerBuilder::DrawThebesLayer,
aBuilder);
aBuilder->LayerBuilder()->DidEndTransaction(layerManager);
layerBuilder->DidEndTransaction(layerManager);
if (aFlags & PAINT_FLUSH_LAYERS) {
FrameLayerBuilder::InvalidateAllLayers(layerManager);
}
nsCSSRendering::DidPaint();
layerManager->RemoveUserData(&gLayerManagerLayerBuilder);
}
PRUint32 nsDisplayList::Count() const {
@ -1910,7 +1916,7 @@ already_AddRefed<Layer>
nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsRefPtr<Layer> layer = aBuilder->LayerBuilder()->
nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);
if (!layer)
@ -1996,7 +2002,7 @@ already_AddRefed<Layer>
nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsRefPtr<Layer> layer = aBuilder->LayerBuilder()->
nsRefPtr<Layer> layer = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);
return layer.forget();
@ -2063,7 +2069,7 @@ already_AddRefed<Layer>
nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsRefPtr<ContainerLayer> layer = aBuilder->LayerBuilder()->
nsRefPtr<ContainerLayer> layer = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);
@ -2246,7 +2252,7 @@ already_AddRefed<Layer>
nsDisplaySimpleScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder,
LayerManager* aManager,
const ContainerParameters& aContainerParameters) {
nsRefPtr<ContainerLayer> layer = aBuilder->LayerBuilder()->
nsRefPtr<ContainerLayer> layer = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);
@ -2881,7 +2887,7 @@ already_AddRefed<Layer> nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu
return nsnull;
}
nsRefPtr<ContainerLayer> container = aBuilder->LayerBuilder()->
nsRefPtr<ContainerLayer> container = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetList(),
aContainerParameters, &newTransformMatrix);
@ -3297,7 +3303,7 @@ nsDisplaySVGEffects::BuildLayer(nsDisplayListBuilder* aBuilder,
return nsnull;
}
nsRefPtr<ContainerLayer> container = aBuilder->LayerBuilder()->
nsRefPtr<ContainerLayer> container = GetLayerBuilderForManager(aManager)->
BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList,
aContainerParameters, nsnull);

View File

@ -329,11 +329,6 @@ public:
*/
void MarkPreserve3DFramesForDisplayList(nsIFrame* aDirtyFrame, const nsRect& aDirtyRect);
/**
* Return the FrameLayerBuilder.
*/
FrameLayerBuilder* LayerBuilder() { return &mLayerBuilder; }
/**
* Get the area of the final transparent region.
*/
@ -503,7 +498,6 @@ private:
return &mPresShellStates[mPresShellStates.Length() - 1];
}
FrameLayerBuilder mLayerBuilder;
nsIFrame* mReferenceFrame;
nsIFrame* mIgnoreScrollFrame;
PLArenaPool mPool;

View File

@ -180,7 +180,7 @@ PrintDisplayListTo(nsDisplayListBuilder* aBuilder, const nsDisplayList& aList,
}
if (f) {
PRUint32 key = i->GetPerFrameKey();
Layer* layer = aBuilder->LayerBuilder()->GetOldLayerFor(f, key);
Layer* layer = mozilla::FrameLayerBuilder::GetDebugOldLayerFor(f, key);
if (layer) {
fprintf(aOutput, " <a href=\"#%p\">layer=%p</a>", layer, layer);
}

View File

@ -1806,7 +1806,13 @@ nsLayoutUtils::PaintFrame(nsRenderingContext* aRenderingContext, nsIFrame* aFram
nsFrame::PrintDisplayList(&builder, list, gfxUtils::sDumpPaintFile);
fprintf(gfxUtils::sDumpPaintFile, "Painting --- retained layer tree:\n");
builder.LayerBuilder()->DumpRetainedLayerTree(gfxUtils::sDumpPaintFile);
nsIWidget* widget = aFrame->GetNearestWidget();
if (widget) {
nsRefPtr<LayerManager> layerManager = widget->GetLayerManager();
if (layerManager) {
FrameLayerBuilder::DumpRetainedLayerTree(layerManager, gfxUtils::sDumpPaintFile);
}
}
fprintf(gfxUtils::sDumpPaintFile, "</body></html>");
if (gfxUtils::sDumpPaintingToFile) {

View File

@ -265,7 +265,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
return nsnull;
CanvasLayer* oldLayer = static_cast<CanvasLayer*>
(aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
nsRefPtr<CanvasLayer> layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager);
if (!layer)
return nsnull;

View File

@ -1530,7 +1530,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
// to provide crisper and faster drawing.
r.Round();
nsRefPtr<Layer> layer =
(aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) {
if (!layer) {

View File

@ -191,7 +191,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder,
container->SetScaleHint(scaleHint);
nsRefPtr<ImageLayer> layer = static_cast<ImageLayer*>
(aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem));
(GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem));
if (!layer) {
layer = aManager->CreateImageLayer();
if (!layer)