mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 580494. Avoid creating an empty ThebesLayer when an inactive nsDisplayItem::BuildLayer returns null. r=tnikkel
--HG-- extra : rebase_source : a22225bb3b5c2bbc12ab2f9b50594083143dbdf0
This commit is contained in:
parent
ac5a6eaab0
commit
44555f22b8
@ -858,6 +858,33 @@ ContainerState::FindThebesLayerFor(const nsIntRect& aVisibleRect,
|
||||
return layer.forget();
|
||||
}
|
||||
|
||||
static already_AddRefed<BasicLayerManager>
|
||||
BuildTempManagerForInactiveLayer(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem)
|
||||
{
|
||||
// This item has an inactive layer. We will render it to a ThebesLayer
|
||||
// using a temporary BasicLayerManager. Set up the layer
|
||||
// manager now so that if we need to modify the retained layer
|
||||
// tree during this process, those modifications will happen
|
||||
// during the construction phase for the retained layer tree.
|
||||
nsRefPtr<BasicLayerManager> tempManager = new BasicLayerManager();
|
||||
tempManager->BeginTransaction();
|
||||
nsRefPtr<Layer> layer = aItem->BuildLayer(aBuilder, tempManager);
|
||||
if (!layer) {
|
||||
tempManager->EndTransaction(nsnull, nsnull);
|
||||
return nsnull;
|
||||
}
|
||||
PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
|
||||
nsIntRect itemVisibleRect =
|
||||
aItem->GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
|
||||
SetVisibleRectForLayer(layer, itemVisibleRect);
|
||||
|
||||
tempManager->SetRoot(layer);
|
||||
// No painting should occur yet, since there is no target context.
|
||||
tempManager->EndTransaction(nsnull, nsnull);
|
||||
return tempManager.forget();
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate through the non-clip items in aList and its descendants.
|
||||
* For each item we compute the effective clip rect. Each item is assigned
|
||||
@ -946,6 +973,13 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
mNewChildLayers.AppendElement(ownLayer);
|
||||
mBuilder->LayerBuilder()->AddLayerDisplayItem(ownLayer, item);
|
||||
} else {
|
||||
nsRefPtr<BasicLayerManager> tempLayerManager;
|
||||
if (layerState == LAYER_INACTIVE) {
|
||||
tempLayerManager = BuildTempManagerForInactiveLayer(mBuilder, item);
|
||||
if (!tempLayerManager)
|
||||
continue;
|
||||
}
|
||||
|
||||
nsIFrame* f = item->GetUnderlyingFrame();
|
||||
nsPoint offsetToActiveScrolledRoot;
|
||||
nsIFrame* activeScrolledRoot =
|
||||
@ -981,9 +1015,8 @@ ContainerState::ProcessDisplayItems(const nsDisplayList& aList,
|
||||
InvalidateForLayerChange(item, thebesLayer);
|
||||
|
||||
mBuilder->LayerBuilder()->
|
||||
AddThebesDisplayItem(thebesLayer, mBuilder,
|
||||
item, aClipRect, mContainerFrame,
|
||||
layerState);
|
||||
AddThebesDisplayItem(thebesLayer, item, aClipRect, mContainerFrame,
|
||||
layerState, tempLayerManager);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1030,36 +1063,12 @@ ContainerState::InvalidateForLayerChange(nsDisplayItem* aItem, Layer* aNewLayer)
|
||||
|
||||
void
|
||||
FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem,
|
||||
const nsRect* aClipRect,
|
||||
nsIFrame* aContainerLayerFrame,
|
||||
LayerState aLayerState)
|
||||
LayerState aLayerState,
|
||||
LayerManager* aTempManager)
|
||||
{
|
||||
nsRefPtr<BasicLayerManager> tempManager;
|
||||
if (aLayerState == LAYER_INACTIVE) {
|
||||
// This item has an inactive layer. We will render it to a ThebesLayer
|
||||
// using a temporary BasicLayerManager. Set up the layer
|
||||
// manager now so that if we need to modify the retained layer
|
||||
// tree during this process, those modifications will happen
|
||||
// during the construction phase for the retained layer tree.
|
||||
tempManager = new BasicLayerManager();
|
||||
tempManager->BeginTransaction();
|
||||
nsRefPtr<Layer> layer = aItem->BuildLayer(aBuilder, tempManager);
|
||||
if (!layer) {
|
||||
tempManager->EndTransaction(nsnull, nsnull);
|
||||
return;
|
||||
}
|
||||
PRInt32 appUnitsPerDevPixel = AppUnitsPerDevPixel(aItem);
|
||||
nsIntRect itemVisibleRect =
|
||||
aItem->GetVisibleRect().ToNearestPixels(appUnitsPerDevPixel);
|
||||
SetVisibleRectForLayer(layer, itemVisibleRect);
|
||||
|
||||
tempManager->SetRoot(layer);
|
||||
// No painting should occur yet, since there is no target context.
|
||||
tempManager->EndTransaction(nsnull, nsnull);
|
||||
}
|
||||
|
||||
AddLayerDisplayItem(aLayer, aItem);
|
||||
|
||||
ThebesLayerItemsEntry* entry = mThebesLayerItems.PutEntry(aLayer);
|
||||
@ -1068,7 +1077,7 @@ FrameLayerBuilder::AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||
NS_ASSERTION(aItem->GetUnderlyingFrame(), "Must have frame");
|
||||
ClippedDisplayItem* cdi =
|
||||
entry->mItems.AppendElement(ClippedDisplayItem(aItem, aClipRect));
|
||||
cdi->mTempLayerManager = tempManager.forget();
|
||||
cdi->mTempLayerManager = aTempManager;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -225,11 +225,11 @@ public:
|
||||
* aItem must have an underlying frame.
|
||||
*/
|
||||
void AddThebesDisplayItem(ThebesLayer* aLayer,
|
||||
nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayItem* aItem,
|
||||
const nsRect* aClipRect,
|
||||
nsIFrame* aContainerLayerFrame,
|
||||
LayerState aLayerState);
|
||||
LayerState aLayerState,
|
||||
LayerManager* aTempManager);
|
||||
|
||||
/**
|
||||
* Given a frame and a display item key that uniquely identifies a
|
||||
|
1
layout/base/crashtests/580494-1.html
Normal file
1
layout/base/crashtests/580494-1.html
Normal file
@ -0,0 +1 @@
|
||||
<html><body><marquee><video></video></marquee></body></html>
|
@ -305,3 +305,4 @@ load 567292-1.xhtml
|
||||
load 569018-1.html
|
||||
load 572003.xul
|
||||
load 572582-1.xhtml
|
||||
load 580494-1.html
|
||||
|
Loading…
Reference in New Issue
Block a user