diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index 4820130a98ab..a75c90612d71 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -57,6 +57,14 @@ public: nsRefPtr mLayerManager; }; +LayerManagerLayerBuilder::~LayerManagerLayerBuilder() +{ + MOZ_COUNT_DTOR(LayerManagerLayerBuilder); + if (mDelete) { + delete mLayerBuilder; + } +} + namespace { class RefCountedRegion : public RefCounted { @@ -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(props.Get(LayerManagerDataProperty())); + if (!data) { + return nsnull; + } + DisplayItemDataEntry *entry = data->mFramesWithLayers.GetEntry(aFrame); + if (!entry) + return nsnull; + + nsTArray *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(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 tempManager = new BasicLayerManager(); + tempManager->SetUserData(&gLayerManagerLayerBuilder, new LayerManagerLayerBuilder(aLayerBuilder, false)); tempManager->BeginTransactionWithTarget(context); nsRefPtr 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(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 (aCallbackData); - if (builder->LayerBuilder()->CheckDOMModified()) + FrameLayerBuilder *layerBuilder = GetLayerBuilderForManager(aLayer->Manager()); + + if (layerBuilder->CheckDOMModified()) return; nsTArray 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 diff --git a/layout/base/FrameLayerBuilder.h b/layout/base/FrameLayerBuilder.h index 4fabf94c0cf1..ccd13dfa1489 100644 --- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -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(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. diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index cea648504c0f..df84f96254e9 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -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 root = aBuilder->LayerBuilder()-> + nsRefPtr 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 nsDisplayOpacity::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters) { - nsRefPtr layer = aBuilder->LayerBuilder()-> + nsRefPtr layer = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nsnull); if (!layer) @@ -1996,7 +2002,7 @@ already_AddRefed nsDisplayOwnLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters) { - nsRefPtr layer = aBuilder->LayerBuilder()-> + nsRefPtr layer = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nsnull); return layer.forget(); @@ -2063,7 +2069,7 @@ already_AddRefed nsDisplayScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters) { - nsRefPtr layer = aBuilder->LayerBuilder()-> + nsRefPtr layer = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nsnull); @@ -2246,7 +2252,7 @@ already_AddRefed nsDisplaySimpleScrollLayer::BuildLayer(nsDisplayListBuilder* aBuilder, LayerManager* aManager, const ContainerParameters& aContainerParameters) { - nsRefPtr layer = aBuilder->LayerBuilder()-> + nsRefPtr layer = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nsnull); @@ -2881,7 +2887,7 @@ already_AddRefed nsDisplayTransform::BuildLayer(nsDisplayListBuilder *aBu return nsnull; } - nsRefPtr container = aBuilder->LayerBuilder()-> + nsRefPtr container = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, *mStoredList.GetList(), aContainerParameters, &newTransformMatrix); @@ -3297,7 +3303,7 @@ nsDisplaySVGEffects::BuildLayer(nsDisplayListBuilder* aBuilder, return nsnull; } - nsRefPtr container = aBuilder->LayerBuilder()-> + nsRefPtr container = GetLayerBuilderForManager(aManager)-> BuildContainerLayerFor(aBuilder, aManager, mFrame, this, mList, aContainerParameters, nsnull); diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index f61cb40168ec..79e01fe3a4ba 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -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; diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index 34039ebf7482..7a31ca2153c6 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -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, " layer=%p", layer, layer); } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index b1de48cfb7cc..0a679dccc354 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -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 = widget->GetLayerManager(); + if (layerManager) { + FrameLayerBuilder::DumpRetainedLayerTree(layerManager, gfxUtils::sDumpPaintFile); + } + } fprintf(gfxUtils::sDumpPaintFile, ""); if (gfxUtils::sDumpPaintingToFile) { diff --git a/layout/generic/nsHTMLCanvasFrame.cpp b/layout/generic/nsHTMLCanvasFrame.cpp index bacde0e14a04..47fd9d435327 100644 --- a/layout/generic/nsHTMLCanvasFrame.cpp +++ b/layout/generic/nsHTMLCanvasFrame.cpp @@ -265,7 +265,7 @@ nsHTMLCanvasFrame::BuildLayer(nsDisplayListBuilder* aBuilder, return nsnull; CanvasLayer* oldLayer = static_cast - (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem)); + (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem)); nsRefPtr layer = element->GetCanvasLayer(aBuilder, oldLayer, aManager); if (!layer) return nsnull; diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 1f596f9825ce..70d4784792f8 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -1530,7 +1530,7 @@ nsObjectFrame::BuildLayer(nsDisplayListBuilder* aBuilder, // to provide crisper and faster drawing. r.Round(); nsRefPtr layer = - (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem)); + (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem)); if (aItem->GetType() == nsDisplayItem::TYPE_PLUGIN) { if (!layer) { diff --git a/layout/generic/nsVideoFrame.cpp b/layout/generic/nsVideoFrame.cpp index 9768e8b96ed9..7cabeebe5f83 100644 --- a/layout/generic/nsVideoFrame.cpp +++ b/layout/generic/nsVideoFrame.cpp @@ -191,7 +191,7 @@ nsVideoFrame::BuildLayer(nsDisplayListBuilder* aBuilder, container->SetScaleHint(scaleHint); nsRefPtr layer = static_cast - (aBuilder->LayerBuilder()->GetLeafLayerFor(aBuilder, aManager, aItem)); + (GetLayerBuilderForManager(aManager)->GetLeafLayerFor(aBuilder, aManager, aItem)); if (!layer) { layer = aManager->CreateImageLayer(); if (!layer)