Bug 1477831 - Merge items in FLBDisplayItemIterator r=mattwoodrow

MozReview-Commit-ID: AWxVue3tjN1

--HG--
extra : rebase_source : 94a3a2bbc70b2259c7ad0caeaec62fc10770b872
This commit is contained in:
Miko Mynttinen 2018-07-24 16:31:04 +02:00
parent 9388b988a3
commit 1f7081c0aa
3 changed files with 56 additions and 35 deletions

View File

@ -218,15 +218,7 @@ public:
return DisplayItemEntry { next, DisplayItemEntryType::ITEM };
}
nsDisplayItem* GetNext()
{
// This function is only supposed to be called if there are no markers set.
// Breaking this invariant can potentially break effect flattening and/or
// display item merging.
MOZ_ASSERT(mMarkers.empty());
return FlattenedDisplayItemIterator::GetNext();
}
nsDisplayItem* GetNext();
bool HasNext() const
{
@ -1749,6 +1741,49 @@ protected:
CachedScrollMetadata mCachedScrollMetadata;
};
nsDisplayItem*
FLBDisplayItemIterator::GetNext()
{
// This function is only supposed to be called if there are no markers set.
// Breaking this invariant can potentially break effect flattening and/or
// display item merging.
MOZ_ASSERT(mMarkers.empty());
nsDisplayItem* next = mNext;
// Advance mNext to the following item
if (next) {
nsDisplayItem* peek = next->GetAbove();
// Peek ahead to the next item and see if it can be merged with the
// current item.
if (peek && next->CanMerge(peek)) {
// Create a list of consecutive items that can be merged together.
AutoTArray<nsDisplayItem*, 2> mergedItems { next, peek };
while ((peek = peek->GetAbove())) {
if (!next->CanMerge(peek)) {
break;
}
mergedItems.AppendElement(peek);
}
// We have items that can be merged together.
// Merge them into a temporary item and process that item immediately.
MOZ_ASSERT(mergedItems.Length() > 1);
next = mState->mBuilder->MergeItems(mergedItems);
}
// |mNext| is either the first item that could not be merged with |next|,
// or a nullptr.
mNext = peek;
ResolveFlattening();
}
return next;
}
bool
FLBDisplayItemIterator::NextItemWantsInactiveLayer()
{
@ -4593,32 +4628,6 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList)
}
}
if (marker == DisplayItemEntryType::ITEM) {
// Peek ahead to the next item and see if it can be merged with the
// current item.
nsDisplayItem* peek = iter.PeekNext();
if (peek && item->CanMerge(peek)) {
// Create a list of consecutive items that can be merged together.
AutoTArray<nsDisplayItem*, 2> mergedItems { item };
while ((peek = iter.PeekNext())) {
if (!item->CanMerge(peek)) {
break;
}
mergedItems.AppendElement(peek);
// Move the iterator forward since we will merge this item.
iter.GetNext();
}
// We have items that can be merged together.
// Merge them into a temporary item and process that item immediately.
MOZ_ASSERT(mergedItems.Length() > 1);
item = mBuilder->MergeItems(mergedItems);
MOZ_ASSERT(item && itemType == item->GetType());
}
}
MOZ_ASSERT(item->GetType() != DisplayItemType::TYPE_WRAP_LIST);
NS_ASSERTION(mAppUnitsPerDevPixel == AppUnitsPerDevPixel(item),

View File

@ -0,0 +1,11 @@
<style>
* {
margin-left: 1vw;
columns: 2;
opacity: 0.2;
-webkit-transform: rotate(0deg);
}
#a { float: left; }
</style>
<content id="a">
<dd>A</dd>

View File

@ -14,3 +14,4 @@ load 1455944-1.html
load 1465305-1.html
load 1468124-1.html
load 1469472.html
load 1477831-1.html