mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 22:37:50 +00:00
Bug 1722346 - Only append to the end/top of the display list r=mstange
Differential Revision: https://phabricator.services.mozilla.com/D137894
This commit is contained in:
parent
ce80a4e5b7
commit
ad4c9a454d
@ -5215,12 +5215,20 @@ already_AddRefed<SourceSurface> PresShell::RenderSelection(
|
||||
aScreenRect, aFlags);
|
||||
}
|
||||
|
||||
void AddDisplayItemToBottom(nsDisplayList* aList, nsDisplayItem* aItem) {
|
||||
nsDisplayList list;
|
||||
list.AppendToTop(aItem);
|
||||
list.AppendToTop(aList);
|
||||
aList->AppendToTop(&list);
|
||||
}
|
||||
|
||||
void PresShell::AddPrintPreviewBackgroundItem(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* aList,
|
||||
nsIFrame* aFrame,
|
||||
const nsRect& aBounds) {
|
||||
aList->AppendNewToBottom<nsDisplaySolidColor>(aBuilder, aFrame, aBounds,
|
||||
NS_RGB(115, 115, 115));
|
||||
nsDisplayItem* item = MakeDisplayItem<nsDisplaySolidColor>(
|
||||
aBuilder, aFrame, aBounds, NS_RGB(115, 115, 115));
|
||||
AddDisplayItemToBottom(aList, item);
|
||||
}
|
||||
|
||||
static bool AddCanvasBackgroundColor(const nsDisplayList* aList,
|
||||
@ -5274,16 +5282,15 @@ void PresShell::AddCanvasBackgroundColorItem(
|
||||
// color background behind a scrolled transparent background. Instead,
|
||||
// we'll try to move the color background into the scrolled content
|
||||
// by making nsDisplayCanvasBackground paint it.
|
||||
// If we're only adding an unscrolled item, then pretend that we've
|
||||
// already done it.
|
||||
bool addedScrollingBackgroundColor =
|
||||
!!(aFlags & AddCanvasBackgroundColorFlags::AppendUnscrolledOnly);
|
||||
if (!aFrame->GetParent() && !addedScrollingBackgroundColor) {
|
||||
bool addedScrollingBackgroundColor = false;
|
||||
if (!aFrame->GetParent()) {
|
||||
nsIScrollableFrame* sf =
|
||||
aFrame->PresShell()->GetRootScrollFrameAsScrollable();
|
||||
if (sf) {
|
||||
nsCanvasFrame* canvasFrame = do_QueryFrame(sf->GetScrolledFrame());
|
||||
if (canvasFrame && canvasFrame->IsVisibleForPainting()) {
|
||||
// TODO: We should be able to set canvas background color during display
|
||||
// list building to avoid calling this function.
|
||||
addedScrollingBackgroundColor = AddCanvasBackgroundColor(
|
||||
aList, canvasFrame, bgcolor, mHasCSSBackgroundColor);
|
||||
}
|
||||
@ -5299,8 +5306,9 @@ void PresShell::AddCanvasBackgroundColorItem(
|
||||
nsLayoutUtils::UsesAsyncScrolling(aFrame) && NS_GET_A(bgcolor) == 255;
|
||||
|
||||
if (!addedScrollingBackgroundColor || forceUnscrolledItem) {
|
||||
aList->AppendNewToBottom<nsDisplaySolidColor>(aBuilder, aFrame, aBounds,
|
||||
bgcolor);
|
||||
nsDisplayItem* item = MakeDisplayItem<nsDisplaySolidColor>(
|
||||
aBuilder, aFrame, aBounds, bgcolor);
|
||||
AddDisplayItemToBottom(aList, item);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -181,8 +181,6 @@ enum class ResolutionChangeOrigin : uint8_t {
|
||||
enum class AddCanvasBackgroundColorFlags {
|
||||
None = 0,
|
||||
ForceDraw = 1 << 0,
|
||||
AddForSubDocument = 1 << 1,
|
||||
AppendUnscrolledOnly = 1 << 2,
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AddCanvasBackgroundColorFlags)
|
||||
|
@ -502,6 +502,8 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
return false;
|
||||
}();
|
||||
|
||||
nsDisplayList layerItems;
|
||||
|
||||
// Create separate items for each background layer.
|
||||
const nsStyleImageLayers& layers = bg->StyleBackground()->mImage;
|
||||
NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(i, layers) {
|
||||
@ -573,7 +575,7 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
aBuilder, this, i + 1, &thisItemList, layers.mLayers[i].mBlendMode,
|
||||
thisItemASR, true);
|
||||
}
|
||||
aLists.BorderBackground()->AppendToTop(&thisItemList);
|
||||
layerItems.AppendToTop(&thisItemList);
|
||||
}
|
||||
|
||||
bool hasFixedBottomLayer =
|
||||
@ -591,10 +593,12 @@ void nsCanvasFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// interleaving the two with a scrolled background color.
|
||||
// PresShell::AddCanvasBackgroundColorItem makes sure there always is a
|
||||
// non-scrolled background color item at the bottom.
|
||||
aLists.BorderBackground()
|
||||
->AppendNewToBottom<nsDisplayCanvasBackgroundColor>(aBuilder, this);
|
||||
aLists.BorderBackground()->AppendNewToTop<nsDisplayCanvasBackgroundColor>(
|
||||
aBuilder, this);
|
||||
}
|
||||
|
||||
aLists.BorderBackground()->AppendToTop(&layerItems);
|
||||
|
||||
if (needBlendContainer) {
|
||||
const ActiveScrolledRoot* containerASR = contASRTracker.GetContainerASR();
|
||||
DisplayListClipState::AutoSaveRestore blendContainerClip(aBuilder);
|
||||
|
@ -498,11 +498,9 @@ void nsSubDocumentFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
|
||||
// happens after we've built the list so that
|
||||
// AddCanvasBackgroundColorItem can monkey with the contents if
|
||||
// necessary.
|
||||
AddCanvasBackgroundColorFlags flags =
|
||||
AddCanvasBackgroundColorFlags::ForceDraw |
|
||||
AddCanvasBackgroundColorFlags::AddForSubDocument;
|
||||
presShell->AddCanvasBackgroundColorItem(
|
||||
aBuilder, &childItems, frame, bounds, NS_RGBA(0, 0, 0, 0), flags);
|
||||
aBuilder, &childItems, frame, bounds, NS_RGBA(0, 0, 0, 0),
|
||||
AddCanvasBackgroundColorFlags::ForceDraw);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -334,35 +334,46 @@ static bool GenerateAndPushTextMask(nsIFrame* aFrame, gfxContext* aContext,
|
||||
return true;
|
||||
}
|
||||
|
||||
nsDisplayWrapper* nsDisplayWrapList::CreateShallowCopy(
|
||||
nsDisplayListBuilder* aBuilder) {
|
||||
const nsDisplayWrapList* wrappedItem = AsDisplayWrapList();
|
||||
MOZ_ASSERT(wrappedItem);
|
||||
|
||||
// Create a new nsDisplayWrapList using a copy-constructor. This is done
|
||||
// to preserve the information about bounds.
|
||||
nsDisplayWrapper* wrapper =
|
||||
new (aBuilder) nsDisplayWrapper(aBuilder, *wrappedItem);
|
||||
wrapper->SetType(nsDisplayWrapper::ItemType());
|
||||
MOZ_ASSERT(wrapper);
|
||||
|
||||
// Set the display list pointer of the new wrapper item to the display list
|
||||
// of the wrapped item.
|
||||
wrapper->mListPtr = wrappedItem->mListPtr;
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
nsDisplayWrapList* nsDisplayListBuilder::MergeItems(
|
||||
nsTArray<nsDisplayWrapList*>& aItems) {
|
||||
// For merging, we create a temporary item by cloning the last item of the
|
||||
// mergeable items list. This ensures that the temporary item will have the
|
||||
// correct frame and bounds.
|
||||
nsDisplayWrapList* merged = nullptr;
|
||||
nsDisplayWrapList* last = aItems.PopLastElement();
|
||||
nsDisplayWrapList* merged = last->Clone(this);
|
||||
MOZ_ASSERT(merged);
|
||||
AddTemporaryItem(merged);
|
||||
|
||||
// Create nsDisplayWrappers that point to the internal display lists of the
|
||||
// items we are merging. These nsDisplayWrappers are added to the display list
|
||||
// of the temporary item.
|
||||
for (nsDisplayWrapList* item : Reversed(aItems)) {
|
||||
MOZ_ASSERT(item);
|
||||
|
||||
if (!merged) {
|
||||
// Create the temporary item.
|
||||
merged = item->Clone(this);
|
||||
MOZ_ASSERT(merged);
|
||||
|
||||
AddTemporaryItem(merged);
|
||||
} else {
|
||||
// Merge the item properties (frame/bounds/etc) with the previously
|
||||
// created temporary item.
|
||||
MOZ_ASSERT(merged->CanMerge(item));
|
||||
merged->Merge(item);
|
||||
}
|
||||
|
||||
// Create nsDisplayWrapList that points to the internal display list of the
|
||||
// item we are merging. This nsDisplayWrapList is added to the display list
|
||||
// of the temporary item.
|
||||
merged->MergeDisplayListFromItem(this, item);
|
||||
MOZ_ASSERT(merged->CanMerge(item));
|
||||
merged->Merge(item);
|
||||
merged->GetChildren()->AppendToTop(item->CreateShallowCopy(this));
|
||||
}
|
||||
|
||||
merged->GetChildren()->AppendToTop(last->CreateShallowCopy(this));
|
||||
|
||||
return merged;
|
||||
}
|
||||
|
||||
@ -4627,25 +4638,6 @@ nsDisplayWrapList::nsDisplayWrapList(nsDisplayListBuilder* aBuilder,
|
||||
|
||||
nsDisplayWrapList::~nsDisplayWrapList() { MOZ_COUNT_DTOR(nsDisplayWrapList); }
|
||||
|
||||
void nsDisplayWrapList::MergeDisplayListFromItem(
|
||||
nsDisplayListBuilder* aBuilder, const nsDisplayWrapList* aItem) {
|
||||
const nsDisplayWrapList* wrappedItem = aItem->AsDisplayWrapList();
|
||||
MOZ_ASSERT(wrappedItem);
|
||||
|
||||
// Create a new nsDisplayWrapList using a copy-constructor. This is done
|
||||
// to preserve the information about bounds.
|
||||
nsDisplayWrapList* wrapper =
|
||||
new (aBuilder) nsDisplayWrapper(aBuilder, *wrappedItem);
|
||||
wrapper->SetType(nsDisplayWrapper::ItemType());
|
||||
MOZ_ASSERT(wrapper);
|
||||
|
||||
// Set the display list pointer of the new wrapper item to the display list
|
||||
// of the wrapped item.
|
||||
wrapper->mListPtr = wrappedItem->mListPtr;
|
||||
|
||||
mListPtr->AppendToBottom(wrapper);
|
||||
}
|
||||
|
||||
void nsDisplayWrapList::HitTest(nsDisplayListBuilder* aBuilder,
|
||||
const nsRect& aRect, HitTestState* aState,
|
||||
nsTArray<nsIFrame*>* aOutFrames) {
|
||||
|
@ -2996,8 +2996,8 @@ class nsPaintedDisplayItem : public nsDisplayItem {
|
||||
* (HitTest()) internally build a temporary array of all
|
||||
* the items while they do the downward traversal, so overall they're still
|
||||
* linear time. We have optimized for efficient AppendToTop() of both
|
||||
* items and lists, with minimal codesize. AppendToBottom() is efficient too.
|
||||
*/
|
||||
* items and lists, with minimal codesize.
|
||||
* */
|
||||
class nsDisplayList {
|
||||
public:
|
||||
class Iterator {
|
||||
@ -3144,41 +3144,6 @@ class nsDisplayList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a new item to the bottom of the list. The item must be non-null
|
||||
* and not already in a list.
|
||||
*/
|
||||
void AppendToBottom(nsDisplayItem* aItem) {
|
||||
if (!aItem) {
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(!aItem->mAbove, "Already in a list!");
|
||||
aItem->mAbove = mSentinel.mAbove;
|
||||
mSentinel.mAbove = aItem;
|
||||
if (mTop == &mSentinel) {
|
||||
mTop = aItem;
|
||||
}
|
||||
mLength++;
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename... Args>
|
||||
void AppendNewToBottom(nsDisplayListBuilder* aBuilder, F* aFrame,
|
||||
Args&&... aArgs) {
|
||||
AppendNewToBottomWithIndex<T>(aBuilder, aFrame, 0,
|
||||
std::forward<Args>(aArgs)...);
|
||||
}
|
||||
|
||||
template <typename T, typename F, typename... Args>
|
||||
void AppendNewToBottomWithIndex(nsDisplayListBuilder* aBuilder, F* aFrame,
|
||||
const uint16_t aIndex, Args&&... aArgs) {
|
||||
nsDisplayItem* item = MakeDisplayItemWithIndex<T>(
|
||||
aBuilder, aFrame, aIndex, std::forward<Args>(aArgs)...);
|
||||
|
||||
if (item) {
|
||||
AppendToBottom(item);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all items from aList and appends them to the top of this list
|
||||
*/
|
||||
@ -3193,24 +3158,6 @@ class nsDisplayList {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all items from aList and prepends them to the bottom of this list
|
||||
*/
|
||||
void AppendToBottom(nsDisplayList* aList) {
|
||||
if (aList->mSentinel.mAbove) {
|
||||
aList->mTop->mAbove = mSentinel.mAbove;
|
||||
mSentinel.mAbove = aList->mSentinel.mAbove;
|
||||
if (mTop == &mSentinel) {
|
||||
mTop = aList->mTop;
|
||||
}
|
||||
|
||||
aList->mTop = &aList->mSentinel;
|
||||
aList->mSentinel.mAbove = nullptr;
|
||||
mLength += aList->mLength;
|
||||
aList->mLength = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an item from the bottom of the list and return it.
|
||||
*/
|
||||
@ -4732,6 +4679,8 @@ class nsDisplayCompositorHitTestInfo final : public nsDisplayItem {
|
||||
Maybe<int32_t> mOverrideZIndex;
|
||||
};
|
||||
|
||||
class nsDisplayWrapper;
|
||||
|
||||
/**
|
||||
* A class that lets you wrap a display list as a display item.
|
||||
*
|
||||
@ -4806,12 +4755,10 @@ class nsDisplayWrapList : public nsPaintedDisplayItem {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new nsDisplayWrapList that holds a pointer to the display list
|
||||
* owned by the given nsDisplayItem. The new nsDisplayWrapList will be added
|
||||
* to the bottom of this item's contents.
|
||||
* Creates a new nsDisplayWrapper that holds a pointer to the display list
|
||||
* owned by the given nsDisplayItem.
|
||||
*/
|
||||
void MergeDisplayListFromItem(nsDisplayListBuilder* aBuilder,
|
||||
const nsDisplayWrapList* aItem);
|
||||
nsDisplayWrapper* CreateShallowCopy(nsDisplayListBuilder* aBuilder);
|
||||
|
||||
/**
|
||||
* Call this if the wrapped list is changed.
|
||||
|
Loading…
x
Reference in New Issue
Block a user