зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1407815 - Allow merging of items that are in different wrap lists. r=miko
This commit is contained in:
Родитель
71d7fc5d25
Коммит
8b1212fa67
|
@ -114,7 +114,8 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
|||
bool apzEnabled = mManager->AsyncPanZoomEnabled();
|
||||
EventRegions eventRegions;
|
||||
|
||||
for (nsDisplayItem* i = aDisplayList->GetBottom(); i; i = i->GetAbove()) {
|
||||
FlattenedDisplayItemIterator iter(aDisplayListBuilder, aDisplayList);
|
||||
while (nsDisplayItem* i = iter.GetNext()) {
|
||||
nsDisplayItem* item = i;
|
||||
DisplayItemType itemType = item->GetType();
|
||||
|
||||
|
@ -132,7 +133,7 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
|||
// if necessary.
|
||||
AutoTArray<nsDisplayItem*, 1> mergedItems;
|
||||
mergedItems.AppendElement(item);
|
||||
for (nsDisplayItem* peek = item->GetAbove(); peek; peek = peek->GetAbove()) {
|
||||
while (nsDisplayItem* peek = iter.PeekNext()) {
|
||||
if (!item->CanMerge(peek)) {
|
||||
break;
|
||||
}
|
||||
|
@ -140,7 +141,7 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
|||
mergedItems.AppendElement(peek);
|
||||
|
||||
// Move the iterator forward since we will merge this item.
|
||||
i = peek;
|
||||
i = iter.GetNext();
|
||||
}
|
||||
|
||||
if (mergedItems.Length() > 1) {
|
||||
|
@ -212,21 +213,14 @@ WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList(nsDisplayList* a
|
|||
}
|
||||
}
|
||||
|
||||
nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
|
||||
if (item->ShouldFlattenAway(aDisplayListBuilder)) {
|
||||
MOZ_ASSERT(childItems);
|
||||
CreateWebRenderCommandsFromDisplayList(childItems, aDisplayListBuilder, aSc,
|
||||
aBuilder, aResources);
|
||||
} else {
|
||||
// ensure the scope of ScrollingLayersHelper is maintained
|
||||
ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache, apzEnabled);
|
||||
// ensure the scope of ScrollingLayersHelper is maintained
|
||||
ScrollingLayersHelper clip(item, aBuilder, aSc, mClipIdCache, apzEnabled);
|
||||
|
||||
// Note: this call to CreateWebRenderCommands can recurse back into
|
||||
// this function if the |item| is a wrapper for a sublist.
|
||||
if (!item->CreateWebRenderCommands(aBuilder, aResources, aSc, mManager,
|
||||
aDisplayListBuilder)) {
|
||||
PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
|
||||
}
|
||||
// Note: this call to CreateWebRenderCommands can recurse back into
|
||||
// this function if the |item| is a wrapper for a sublist.
|
||||
if (!item->CreateWebRenderCommands(aBuilder, aResources, aSc, mManager,
|
||||
aDisplayListBuilder)) {
|
||||
PushItemAsImage(item, aBuilder, aResources, aSc, aDisplayListBuilder);
|
||||
}
|
||||
|
||||
if (apzEnabled) {
|
||||
|
|
|
@ -1101,13 +1101,6 @@ public:
|
|||
* the child layers.
|
||||
*/
|
||||
void ProcessDisplayItems(nsDisplayList* aList);
|
||||
void ProcessDisplayItems(nsDisplayList* aList,
|
||||
AnimatedGeometryRoot* aLastAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot* aLastASR,
|
||||
const nsPoint& aLastAGRTopLeft,
|
||||
nsPoint& aTopLeft,
|
||||
int32_t aMaxLayers,
|
||||
int& aLayerCount);
|
||||
/**
|
||||
* This finalizes all the open PaintedLayers by popping every element off
|
||||
* mPaintedLayerDataStack, then sets the children of the container layer
|
||||
|
@ -3983,20 +3976,8 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
|
|||
int32_t maxLayers = gfxPrefs::MaxActiveLayers();
|
||||
int layerCount = 0;
|
||||
|
||||
ProcessDisplayItems(aList, lastAnimatedGeometryRoot, lastASR,
|
||||
lastAGRTopLeft, topLeft, maxLayers, layerCount);
|
||||
}
|
||||
|
||||
void
|
||||
ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
||||
AnimatedGeometryRoot* aLastAnimatedGeometryRoot,
|
||||
const ActiveScrolledRoot* aLastASR,
|
||||
const nsPoint& aLastAGRTopLeft,
|
||||
nsPoint& aTopLeft,
|
||||
int32_t aMaxLayers,
|
||||
int& aLayerCount)
|
||||
{
|
||||
for (nsDisplayItem* i = aList->GetBottom(); i; i = i->GetAbove()) {
|
||||
FlattenedDisplayItemIterator iter(mBuilder, aList);
|
||||
while (nsDisplayItem* i = iter.GetNext()) {
|
||||
nsDisplayItem* item = i;
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
|
@ -4017,7 +3998,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
// item. We create a list of consecutive items that can be merged together.
|
||||
AutoTArray<nsDisplayItem*, 1> mergedItems;
|
||||
mergedItems.AppendElement(item);
|
||||
for (nsDisplayItem* peek = item->GetAbove(); peek; peek = peek->GetAbove()) {
|
||||
while (nsDisplayItem* peek = iter.PeekNext()) {
|
||||
if (!item->CanMerge(peek)) {
|
||||
break;
|
||||
}
|
||||
|
@ -4025,7 +4006,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
mergedItems.AppendElement(peek);
|
||||
|
||||
// Move the iterator forward since we will merge this item.
|
||||
i = peek;
|
||||
i = iter.GetNext();
|
||||
}
|
||||
|
||||
if (mergedItems.Length() > 1) {
|
||||
|
@ -4035,18 +4016,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
MOZ_ASSERT(item && itemType == item->GetType());
|
||||
}
|
||||
|
||||
nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
|
||||
|
||||
if (item->ShouldFlattenAway(mBuilder)) {
|
||||
MOZ_ASSERT(childItems);
|
||||
ProcessDisplayItems(childItems, aLastAnimatedGeometryRoot, aLastASR,
|
||||
aLastAGRTopLeft, aTopLeft, aMaxLayers, aLayerCount);
|
||||
if (childItems->NeedsTransparentSurface()) {
|
||||
aList->SetNeedsTransparentSurface();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(item->GetType() != DisplayItemType::TYPE_WRAP_LIST);
|
||||
|
||||
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),
|
||||
|
@ -4074,9 +4043,9 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
const DisplayItemClipChain* layerClipChain = nullptr;
|
||||
if (mFlattenToSingleLayer && layerState != LAYER_ACTIVE_FORCE) {
|
||||
forceInactive = true;
|
||||
animatedGeometryRoot = aLastAnimatedGeometryRoot;
|
||||
itemASR = aLastASR;
|
||||
aTopLeft = aLastAGRTopLeft;
|
||||
animatedGeometryRoot = lastAnimatedGeometryRoot;
|
||||
itemASR = lastASR;
|
||||
topLeft = lastAGRTopLeft;
|
||||
item->FuseClipChainUpTo(mBuilder, mContainerASR);
|
||||
} else {
|
||||
forceInactive = false;
|
||||
|
@ -4098,7 +4067,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
itemASR = mContainerASR;
|
||||
item->FuseClipChainUpTo(mBuilder, mContainerASR);
|
||||
}
|
||||
aTopLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
topLeft = (*animatedGeometryRoot)->GetOffsetToCrossDoc(mContainerReferenceFrame);
|
||||
}
|
||||
|
||||
const ActiveScrolledRoot* scrollMetadataASR =
|
||||
|
@ -4155,7 +4124,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
ScaleToOutsidePixels(item->GetVisibleRect(), false));
|
||||
}
|
||||
|
||||
if (aMaxLayers != -1 && aLayerCount >= aMaxLayers) {
|
||||
if (maxLayers != -1 && layerCount >= maxLayers) {
|
||||
forceInactive = true;
|
||||
}
|
||||
|
||||
|
@ -4166,7 +4135,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
(layerState == LAYER_ACTIVE_EMPTY ||
|
||||
layerState == LAYER_ACTIVE))) {
|
||||
|
||||
aLayerCount++;
|
||||
layerCount++;
|
||||
|
||||
// LAYER_ACTIVE_EMPTY means the layer is created just for its metadata.
|
||||
// We should never see an empty layer with any visible content!
|
||||
|
@ -4371,11 +4340,11 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
nsDisplayMask* maskItem = static_cast<nsDisplayMask*>(item);
|
||||
SetupMaskLayerForCSSMask(ownLayer, maskItem);
|
||||
|
||||
if (i->GetAbove() &&
|
||||
i->GetAbove()->GetType() == DisplayItemType::TYPE_SCROLL_INFO_LAYER) {
|
||||
if (iter.PeekNext() &&
|
||||
iter.PeekNext()->GetType() == DisplayItemType::TYPE_SCROLL_INFO_LAYER) {
|
||||
// Since we do build a layer for mask, there is no need for this
|
||||
// scroll info layer anymore.
|
||||
i = i->GetAbove();
|
||||
i = iter.GetNext();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4484,7 +4453,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
item->Frame()->In3DContextAndBackfaceIsHidden(),
|
||||
[&]() {
|
||||
return NewPaintedLayerData(item, animatedGeometryRoot, itemASR, layerClipChain, scrollMetadataASR,
|
||||
aTopLeft);
|
||||
topLeft);
|
||||
});
|
||||
|
||||
if (itemType == DisplayItemType::TYPE_LAYER_EVENT_REGIONS) {
|
||||
|
@ -4502,7 +4471,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
if (!paintedLayerData->mLayer) {
|
||||
// Try to recycle the old layer of this display item.
|
||||
RefPtr<PaintedLayer> layer =
|
||||
AttemptToRecyclePaintedLayer(animatedGeometryRoot, item, aTopLeft);
|
||||
AttemptToRecyclePaintedLayer(animatedGeometryRoot, item, topLeft);
|
||||
if (layer) {
|
||||
paintedLayerData->mLayer = layer;
|
||||
|
||||
|
@ -4514,6 +4483,7 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList,
|
|||
}
|
||||
}
|
||||
|
||||
nsDisplayList* childItems = item->GetSameCoordinateSystemChildren();
|
||||
if (childItems && childItems->NeedsTransparentSurface()) {
|
||||
aList->SetNeedsTransparentSurface();
|
||||
}
|
||||
|
|
|
@ -6155,6 +6155,13 @@ CollectItemsWithOpacity(nsDisplayList* aList,
|
|||
bool
|
||||
nsDisplayOpacity::ShouldFlattenAway(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
if (mFrame->GetPrevContinuation() ||
|
||||
mFrame->GetNextContinuation()) {
|
||||
// If we've been split, then we might need to merge, so
|
||||
// don't flatten us away.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NeedsActiveLayer(aBuilder, mFrame) || mOpacity == 0.0) {
|
||||
// If our opacity is zero then we'll discard all descendant display items
|
||||
// except for layer event regions, so there's no point in doing this
|
||||
|
|
|
@ -5588,6 +5588,73 @@ public:
|
|||
mutable mozilla::Maybe<bool> mIsFrameSelected;
|
||||
};
|
||||
|
||||
class FlattenedDisplayItemIterator
|
||||
{
|
||||
public:
|
||||
FlattenedDisplayItemIterator(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList)
|
||||
: mBuilder(aBuilder)
|
||||
, mNext(aList->GetBottom())
|
||||
{
|
||||
ResolveFlattening();
|
||||
}
|
||||
|
||||
nsDisplayItem* GetNext()
|
||||
{
|
||||
nsDisplayItem* next = mNext;
|
||||
|
||||
// Advance mNext to the following item
|
||||
if (next) {
|
||||
mNext = mNext->GetAbove();
|
||||
ResolveFlattening();
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
nsDisplayItem* PeekNext()
|
||||
{
|
||||
return mNext;
|
||||
}
|
||||
|
||||
private:
|
||||
bool AtEndOfNestedList()
|
||||
{
|
||||
return !mNext && mStack.Length() > 0;
|
||||
}
|
||||
|
||||
bool ShouldFlattenNextItem()
|
||||
{
|
||||
return mNext && mNext->ShouldFlattenAway(mBuilder);
|
||||
}
|
||||
|
||||
void ResolveFlattening()
|
||||
{
|
||||
// Handle the case where we reach the end of a nested list, or the current
|
||||
// item should start a new nested list. Repeat this until we find an actual
|
||||
// item, or the very end of the outer list.
|
||||
while (AtEndOfNestedList() || ShouldFlattenNextItem()) {
|
||||
if (AtEndOfNestedList()) {
|
||||
// Pop the last item off the stack.
|
||||
mNext = mStack.LastElement();
|
||||
mStack.RemoveElementAt(mStack.Length() - 1);
|
||||
// We stored the item that was flattened, so advance to the next.
|
||||
mNext = mNext->GetAbove();
|
||||
} else {
|
||||
// This item wants to be flattened. Store the current item on the stack,
|
||||
// and use the first item in the child list instead.
|
||||
mStack.AppendElement(mNext);
|
||||
nsDisplayList* childItems = mNext->GetSameCoordinateSystemChildren();
|
||||
mNext = childItems->GetBottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
nsDisplayListBuilder* mBuilder;
|
||||
nsDisplayItem* mNext;
|
||||
AutoTArray<nsDisplayItem*, 10> mStack;
|
||||
};
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class PaintTelemetry
|
||||
|
|
|
@ -1687,7 +1687,7 @@ fuzzy-if(skiaContent,1,4500) == 654950-1.html 654950-1-ref.html # Quartz alpha b
|
|||
== 655836-1.html 655836-1-ref.html
|
||||
!= 656875.html about:blank
|
||||
== 658952.html 658952-ref.html
|
||||
fuzzy-if(skiaContent,1,3500) == 660682-1.html 660682-1-ref.html
|
||||
fuzzy-if(skiaContent,7,3500) fails-if(webrender) == 660682-1.html 660682-1-ref.html
|
||||
fuzzy-if(d2d,1,256) skip-if(Android) fuzzy-if(skiaContent,1,68000) fails-if(styloVsGecko) asserts-if(stylo,16-18) == 664127-1.xul 664127-1-ref.xul # Android: Intermittent failures - bug 1019131, stylo: bug 1397644
|
||||
== 665597-1.html 665597-1-ref.html
|
||||
== 665597-2.html 665597-2-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче