зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1440177 - Part 6: Don't dereference display items during AddPaintedDisplayItem for the LAYER_NONE case. r=jnicol
The display items are almost certainly gone from the cache at this point, so dereferencing them can take a while. This moves the DisplayItemData lookup, and the IsReused/HasMergedFrames checks into the ProcessDisplayItems pass (where we already use the items), and then just uses the AssignedDisplayItem entry for everything. MozReview-Commit-ID: 3NibNGSVsax --HG-- extra : rebase_source : b5b4d82798404ad4c8d84ca33bfb30d4afa55fb6
This commit is contained in:
Родитель
e7ccc78c95
Коммит
3eb2633a17
|
@ -196,6 +196,16 @@ DisplayItemData::EndUpdate(nsAutoPtr<nsDisplayItemGeometry> aGeometry)
|
|||
void
|
||||
DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
|
||||
nsDisplayItem* aItem /* = nullptr */)
|
||||
{
|
||||
BeginUpdate(aLayer, aState, aItem,
|
||||
aItem ? aItem->IsReused() : false,
|
||||
aItem ? aItem->HasMergedFrames() : false);
|
||||
}
|
||||
|
||||
void
|
||||
DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
|
||||
nsDisplayItem* aItem, bool aIsReused,
|
||||
bool aIsMerged)
|
||||
{
|
||||
MOZ_RELEASE_ASSERT(mLayer);
|
||||
MOZ_RELEASE_ASSERT(aLayer);
|
||||
|
@ -207,13 +217,18 @@ DisplayItemData::BeginUpdate(Layer* aLayer, LayerState aState,
|
|||
|
||||
if (aLayer->AsPaintedLayer()) {
|
||||
mItem = aItem;
|
||||
mReusedItem = aItem->IsReused();
|
||||
mReusedItem = aIsReused;
|
||||
}
|
||||
|
||||
if (!aItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!aIsMerged && mFrameList.Length() == 1) {
|
||||
MOZ_ASSERT(mFrameList[0] == aItem->Frame());
|
||||
return;
|
||||
}
|
||||
|
||||
// We avoid adding or removing element unnecessarily
|
||||
// since we have to modify userdata each time
|
||||
AutoTArray<nsIFrame*, 4> copy(mFrameList);
|
||||
|
@ -3208,15 +3223,10 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB
|
|||
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_LAYER_EVENT_REGIONS);
|
||||
MOZ_ASSERT(item.mItem->GetType() != DisplayItemType::TYPE_COMPOSITOR_HITTEST_INFO);
|
||||
|
||||
DisplayItemData* oldData =
|
||||
mLayerBuilder->GetOldLayerForFrame(item.mItem->Frame(),
|
||||
item.mItem->GetPerFrameKey(),
|
||||
item.mItem->HasMergedFrames() ? nullptr : item.mItem->GetDisplayItemData());
|
||||
InvalidateForLayerChange(item.mItem, data->mLayer, oldData);
|
||||
mLayerBuilder->AddPaintedDisplayItem(data, item.mItem, item.mClip,
|
||||
*this, item.mLayerState,
|
||||
data->mAnimatedGeometryRootOffset,
|
||||
oldData, item);
|
||||
InvalidateForLayerChange(item.mItem, data->mLayer, item.mDisplayItemData);
|
||||
mLayerBuilder->AddPaintedDisplayItem(data, item, *this,
|
||||
data->mAnimatedGeometryRootOffset);
|
||||
item.mDisplayItemData = nullptr;
|
||||
}
|
||||
|
||||
PaintedDisplayItemLayerUserData* userData = GetPaintedDisplayItemLayerUserData(data->mLayer);
|
||||
|
@ -3516,7 +3526,11 @@ PaintedLayerData::Accumulate(ContainerState* aState,
|
|||
bool clipMatches = mItemClip == aClip;
|
||||
mItemClip = aClip;
|
||||
|
||||
mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState));
|
||||
DisplayItemData* oldData =
|
||||
aState->mLayerBuilder->GetOldLayerForFrame(aItem->Frame(),
|
||||
aItem->GetPerFrameKey(),
|
||||
aItem->HasMergedFrames() ? nullptr : aItem->GetDisplayItemData());
|
||||
mAssignedDisplayItems.AppendElement(AssignedDisplayItem(aItem, aClip, aLayerState, oldData));
|
||||
|
||||
if (aItem->MustPaintOnContentSide()) {
|
||||
mShouldPaintOnContentSide = true;
|
||||
|
@ -4624,9 +4638,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
* No need to allocate geometry for items that aren't
|
||||
* part of a PaintedLayer.
|
||||
*/
|
||||
oldData =
|
||||
mLayerBuilder->GetOldLayerForFrame(item->Frame(), item->GetPerFrameKey());
|
||||
mLayerBuilder->AddLayerDisplayItem(ownLayer, item, layerState, nullptr, oldData);
|
||||
if (ownLayer->Manager() == mLayerBuilder->GetRetainingLayerManager()) {
|
||||
oldData =
|
||||
mLayerBuilder->GetOldLayerForFrame(item->Frame(), item->GetPerFrameKey());
|
||||
mLayerBuilder->StoreDataForFrame(item, ownLayer, layerState, oldData);
|
||||
}
|
||||
} else {
|
||||
const bool backfaceHidden = item->In3DContextAndBackfaceIsHidden();
|
||||
const nsIFrame* referenceFrame = item->ReferenceFrame();
|
||||
|
@ -4817,13 +4833,9 @@ FrameLayerBuilder::ComputeGeometryChangeForItem(DisplayItemData* aData)
|
|||
|
||||
void
|
||||
FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
||||
nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
ContainerState& aContainerState,
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft,
|
||||
DisplayItemData* aData,
|
||||
AssignedDisplayItem& aAssignedDisplayItem)
|
||||
AssignedDisplayItem& aItem,
|
||||
ContainerState& aContainerState,
|
||||
const nsPoint& aTopLeft)
|
||||
{
|
||||
PaintedLayer* layer = aLayerData->mLayer;
|
||||
PaintedDisplayItemLayerUserData* paintedData =
|
||||
|
@ -4832,13 +4844,13 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
RefPtr<BasicLayerManager> tempManager;
|
||||
nsIntRect intClip;
|
||||
bool hasClip = false;
|
||||
if (aLayerState != LAYER_NONE) {
|
||||
if (aData) {
|
||||
tempManager = aData->mInactiveManager;
|
||||
if (aItem.mLayerState != LAYER_NONE) {
|
||||
if (aItem.mDisplayItemData) {
|
||||
tempManager = aItem.mDisplayItemData->mInactiveManager;
|
||||
|
||||
// We need to grab these before calling AddLayerDisplayItem because it will overwrite them.
|
||||
// We need to grab these before updating the DisplayItemData because it will overwrite them.
|
||||
nsRegion clip;
|
||||
if (aClip.ComputeRegionInClips(&aData->GetClip(),
|
||||
if (aItem.mClip.ComputeRegionInClips(&aItem.mDisplayItemData->GetClip(),
|
||||
aTopLeft - paintedData->mLastAnimatedGeometryRootOrigin,
|
||||
&clip)) {
|
||||
intClip = clip.GetBounds().ScaleToOutsidePixels(paintedData->mXScale,
|
||||
|
@ -4851,13 +4863,23 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
}
|
||||
}
|
||||
|
||||
AddLayerDisplayItem(layer, aItem, aLayerState, tempManager, aData);
|
||||
if (layer->Manager() == mRetainingManager) {
|
||||
DisplayItemData *data = aItem.mDisplayItemData;
|
||||
if (data) {
|
||||
if (!data->mUsed) {
|
||||
data->BeginUpdate(layer, aItem.mLayerState, aItem.mItem, aItem.mReused, aItem.mMerged);
|
||||
}
|
||||
} else {
|
||||
data = StoreDataForFrame(aItem.mItem, layer, aItem.mLayerState, nullptr);
|
||||
}
|
||||
data->mInactiveManager = tempManager;
|
||||
}
|
||||
|
||||
if (tempManager) {
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem);
|
||||
FLB_LOG_PAINTED_LAYER_DECISION(aLayerData, "Creating nested FLB for item %p\n", aItem.mItem);
|
||||
FrameLayerBuilder* layerBuilder = new FrameLayerBuilder();
|
||||
layerBuilder->Init(mDisplayListBuilder, tempManager, aLayerData, true,
|
||||
&aClip);
|
||||
&aItem.mClip);
|
||||
|
||||
tempManager->BeginTransaction();
|
||||
if (mRetainingManager) {
|
||||
|
@ -4866,24 +4888,24 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
|
||||
UniquePtr<LayerProperties> props(LayerProperties::CloneFrom(tempManager->GetRoot()));
|
||||
RefPtr<Layer> tmpLayer =
|
||||
aItem->BuildLayer(mDisplayListBuilder, tempManager, ContainerLayerParameters());
|
||||
aItem.mItem->BuildLayer(mDisplayListBuilder, tempManager, ContainerLayerParameters());
|
||||
// We have no easy way of detecting if this transaction will ever actually get finished.
|
||||
// For now, I've just silenced the warning with nested transactions in BasicLayers.cpp
|
||||
if (!tmpLayer) {
|
||||
tempManager->EndTransaction(nullptr, nullptr);
|
||||
tempManager->SetUserData(&gLayerManagerLayerBuilder, nullptr);
|
||||
aAssignedDisplayItem.mItem = nullptr;
|
||||
aItem.mItem = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
bool snap;
|
||||
nsRect visibleRect =
|
||||
aItem->GetVisibleRect().Intersect(aItem->GetBounds(mDisplayListBuilder, &snap));
|
||||
aItem.mItem->GetVisibleRect().Intersect(aItem.mItem->GetBounds(mDisplayListBuilder, &snap));
|
||||
nsIntRegion rgn = visibleRect.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel);
|
||||
|
||||
// Convert the visible rect to a region and give the item
|
||||
// a chance to try restrict it further.
|
||||
nsRegion tightBounds = aItem->GetTightBounds(mDisplayListBuilder, &snap);
|
||||
nsRegion tightBounds = aItem.mItem->GetTightBounds(mDisplayListBuilder, &snap);
|
||||
if (!tightBounds.IsEmpty()) {
|
||||
rgn.AndWith(tightBounds.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel));
|
||||
}
|
||||
|
@ -4899,8 +4921,8 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
(tempManager->GetUserData(&gLayerManagerUserData));
|
||||
lmd->mParent = parentLmd;
|
||||
#endif
|
||||
DisplayItemData* data = layerBuilder->GetDisplayItemDataForManager(aItem, tempManager);
|
||||
layerBuilder->StoreDataForFrame(aItem, tmpLayer, LAYER_ACTIVE, data);
|
||||
DisplayItemData* data = layerBuilder->GetDisplayItemDataForManager(aItem.mItem, tempManager);
|
||||
layerBuilder->StoreDataForFrame(aItem.mItem, tmpLayer, LAYER_ACTIVE, data);
|
||||
}
|
||||
|
||||
tempManager->SetRoot(tmpLayer);
|
||||
|
@ -4909,7 +4931,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (gfxUtils::DumpDisplayList() || gfxEnv::DumpPaint()) {
|
||||
fprintf_stderr(gfxUtils::sDumpPaintFile, "Basic layer tree for painting contents of display item %s(%p):\n", aItem->Name(), aItem->Frame());
|
||||
fprintf_stderr(gfxUtils::sDumpPaintFile, "Basic layer tree for painting contents of display item %s(%p):\n", aItem.mItem->Name(), aItem.mItem->Frame());
|
||||
std::stringstream stream;
|
||||
tempManager->Dump(stream, "", gfxEnv::DumpPaintToFile());
|
||||
fprint_stderr(gfxUtils::sDumpPaintFile, stream); // not a typo, fprint_stderr declared in LayersLogging.h
|
||||
|
@ -4922,18 +4944,18 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
tmpLayer->ComputeEffectiveTransforms(Matrix4x4());
|
||||
nsIntRegion invalid;
|
||||
if (!props->ComputeDifferences(tmpLayer, invalid, nullptr)) {
|
||||
nsRect visible = aItem->Frame()->GetVisualOverflowRect();
|
||||
nsRect visible = aItem.mItem->Frame()->GetVisualOverflowRect();
|
||||
invalid = visible.ToOutsidePixels(paintedData->mAppUnitsPerDevPixel);
|
||||
}
|
||||
if (aLayerState == LAYER_SVG_EFFECTS) {
|
||||
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem->Frame(),
|
||||
aItem->ToReferenceFrame(),
|
||||
if (aItem.mLayerState == LAYER_SVG_EFFECTS) {
|
||||
invalid = nsSVGIntegrationUtils::AdjustInvalidAreaForSVGEffects(aItem.mItem->Frame(),
|
||||
aItem.mItem->ToReferenceFrame(),
|
||||
invalid);
|
||||
}
|
||||
if (!invalid.IsEmpty()) {
|
||||
#ifdef MOZ_DUMP_PAINTING
|
||||
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
|
||||
printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem->Name(), aItem->Frame(), layer);
|
||||
printf_stderr("Inactive LayerManager(%p) for display item %s(%p) has an invalid region - invalidating layer %p\n", tempManager.get(), aItem.mItem->Name(), aItem.mItem->Frame(), layer);
|
||||
}
|
||||
#endif
|
||||
invalid.ScaleRoundOut(paintedData->mXScale, paintedData->mYScale);
|
||||
|
@ -4946,7 +4968,7 @@ FrameLayerBuilder::AddPaintedDisplayItem(PaintedLayerData* aLayerData,
|
|||
GetTranslationForPaintedLayer(layer));
|
||||
}
|
||||
}
|
||||
aAssignedDisplayItem.mInactiveLayerManager = tempManager;
|
||||
aItem.mInactiveLayerManager = tempManager;
|
||||
}
|
||||
|
||||
DisplayItemData*
|
||||
|
@ -4999,6 +5021,18 @@ FrameLayerBuilder::StoreDataForFrame(nsIFrame* aFrame,
|
|||
lmd->mDisplayItems.PutEntry(data);
|
||||
}
|
||||
|
||||
AssignedDisplayItem::AssignedDisplayItem(nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState,
|
||||
DisplayItemData* aData)
|
||||
: mItem(aItem)
|
||||
, mClip(aClip)
|
||||
, mLayerState(aLayerState)
|
||||
, mDisplayItemData(aData)
|
||||
, mReused(aItem->IsReused())
|
||||
, mMerged(aItem->HasMergedFrames())
|
||||
{}
|
||||
|
||||
AssignedDisplayItem::~AssignedDisplayItem()
|
||||
{
|
||||
if (mInactiveLayerManager) {
|
||||
|
@ -5006,20 +5040,6 @@ AssignedDisplayItem::~AssignedDisplayItem()
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
FrameLayerBuilder::AddLayerDisplayItem(Layer* aLayer,
|
||||
nsDisplayItem* aItem,
|
||||
LayerState aLayerState,
|
||||
BasicLayerManager* aManager,
|
||||
DisplayItemData* aData)
|
||||
{
|
||||
if (aLayer->Manager() != mRetainingManager)
|
||||
return;
|
||||
|
||||
DisplayItemData *data = StoreDataForFrame(aItem, aLayer, aLayerState, aData);
|
||||
data->mInactiveManager = aManager;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
FrameLayerBuilder::GetLastPaintOffset(PaintedLayer* aLayer)
|
||||
{
|
||||
|
|
|
@ -156,6 +156,8 @@ private:
|
|||
*/
|
||||
void BeginUpdate(layers::Layer* aLayer, LayerState aState,
|
||||
nsDisplayItem* aItem = nullptr);
|
||||
void BeginUpdate(layers::Layer* aLayer, LayerState aState,
|
||||
nsDisplayItem* aItem, bool aIsReused, bool aIsMerged);
|
||||
|
||||
/**
|
||||
* Completes the update of this, and removes any references to data that won't live
|
||||
|
@ -212,17 +214,14 @@ struct AssignedDisplayItem
|
|||
{
|
||||
AssignedDisplayItem(nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
LayerState aLayerState)
|
||||
: mItem(aItem)
|
||||
, mClip(aClip)
|
||||
, mLayerState(aLayerState)
|
||||
{}
|
||||
|
||||
LayerState aLayerState,
|
||||
DisplayItemData* aData);
|
||||
~AssignedDisplayItem();
|
||||
|
||||
nsDisplayItem* mItem;
|
||||
DisplayItemClip mClip;
|
||||
LayerState mLayerState;
|
||||
DisplayItemData* mDisplayItemData;
|
||||
|
||||
/**
|
||||
* If the display item is being rendered as an inactive
|
||||
|
@ -230,6 +229,9 @@ struct AssignedDisplayItem
|
|||
* used for the inactive transaction.
|
||||
*/
|
||||
RefPtr<layers::LayerManager> mInactiveLayerManager;
|
||||
|
||||
bool mReused;
|
||||
bool mMerged;
|
||||
};
|
||||
|
||||
|
||||
|
@ -501,21 +503,6 @@ public:
|
|||
* to be called by file-scope helper functions in FrameLayerBuilder.cpp.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Record aItem as a display item that is rendered by aLayer.
|
||||
*
|
||||
* @param aLayer Layer that the display item will be rendered into
|
||||
* @param aItem Display item to be drawn.
|
||||
* @param aLayerState What LayerState the item is using.
|
||||
* @param aManager If the layer is in the LAYER_INACTIVE state,
|
||||
* then this is the temporary layer manager to draw with.
|
||||
*/
|
||||
void AddLayerDisplayItem(Layer* aLayer,
|
||||
nsDisplayItem* aItem,
|
||||
LayerState aLayerState,
|
||||
BasicLayerManager* aManager,
|
||||
DisplayItemData* aData);
|
||||
|
||||
/**
|
||||
* Record aItem as a display item that is rendered by the PaintedLayer
|
||||
* aLayer, with aClipRect, where aContainerLayerFrame is the frame
|
||||
|
@ -524,13 +511,9 @@ public:
|
|||
* @param aTopLeft offset from active scrolled root to reference frame
|
||||
*/
|
||||
void AddPaintedDisplayItem(PaintedLayerData* aLayer,
|
||||
nsDisplayItem* aItem,
|
||||
const DisplayItemClip& aClip,
|
||||
ContainerState& aContainerState,
|
||||
LayerState aLayerState,
|
||||
const nsPoint& aTopLeft,
|
||||
DisplayItemData* aData,
|
||||
AssignedDisplayItem& aAssignedDisplayItem);
|
||||
AssignedDisplayItem& aAssignedDisplayItem,
|
||||
ContainerState& aContainerState,
|
||||
const nsPoint& aTopLeft);
|
||||
|
||||
/**
|
||||
* Calls GetOldLayerForFrame on the underlying frame of the display item,
|
||||
|
@ -627,10 +610,6 @@ public:
|
|||
*/
|
||||
DisplayItemData* GetOldLayerForFrame(nsIFrame* aFrame, uint32_t aDisplayItemKey, DisplayItemData* aOldData = nullptr);
|
||||
|
||||
protected:
|
||||
|
||||
friend class LayerManagerData;
|
||||
|
||||
/**
|
||||
* Stores DisplayItemData associated with aFrame, stores the data in
|
||||
* mNewDisplayItemData.
|
||||
|
@ -642,6 +621,9 @@ protected:
|
|||
Layer* aLayer,
|
||||
LayerState aState);
|
||||
|
||||
protected:
|
||||
friend class LayerManagerData;
|
||||
|
||||
// Flash the area within the context clip if paint flashing is enabled.
|
||||
static void FlashPaint(gfxContext *aContext);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче