Bug 1771579 part 1: Process text leaf updates in the order in which they were received from layout. r=eeejay

Differential Revision: https://phabricator.services.mozilla.com/D191815
This commit is contained in:
James Teh
2023-10-26 22:37:22 +00:00
parent bc4af84bd7
commit b9d8bf905e
2 changed files with 18 additions and 8 deletions

View File

@@ -95,7 +95,7 @@ void NotificationController::Shutdown() {
mDocument = nullptr;
mPresShell = nullptr;
mTextHash.Clear();
mTextArray.Clear();
mContentInsertions.Clear();
mNotifications.Clear();
mFocusEvent = nullptr;
@@ -465,7 +465,7 @@ bool NotificationController::IsUpdatePending() {
return mPresShell->IsLayoutFlushObserver() ||
mObservingState == eRefreshProcessingForUpdate || WaitingForParent() ||
mContentInsertions.Count() != 0 || mNotifications.Length() != 0 ||
mTextHash.Count() != 0 ||
!mTextArray.IsEmpty() ||
!mDocument->HasLoadState(DocAccessible::eTreeConstructed);
}
@@ -735,8 +735,14 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) {
mDocument->ProcessPendingUpdates();
// Process rendered text change notifications.
for (nsIContent* textNode : mTextHash) {
// Process rendered text change notifications. Even though we want to process
// them in the order in which they were queued, we still want to avoid
// duplicates.
nsTHashSet<nsIContent*> textHash;
for (nsIContent* textNode : mTextArray) {
if (!textHash.EnsureInserted(textNode)) {
continue; // Already processed.
}
LocalAccessible* textAcc = mDocument->GetAccessible(textNode);
// If the text node is not in tree or doesn't have a frame, or placed in
@@ -825,7 +831,8 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) {
}
}
}
mTextHash.Clear();
textHash.Clear();
mTextArray.Clear();
// Process content inserted notifications to update the tree.
// Processing an insertion can indirectly run script (e.g. querying a XUL
@@ -1008,7 +1015,7 @@ void NotificationController::WillRefresh(mozilla::TimeStamp aTime) {
// Stop further processing if there are no new notifications of any kind or
// events and document load is processed.
if (mContentInsertions.Count() == 0 && mNotifications.IsEmpty() &&
!mFocusEvent && mEvents.IsEmpty() && mTextHash.Count() == 0 &&
!mFocusEvent && mEvents.IsEmpty() && mTextArray.IsEmpty() &&
mHangingChildDocuments.IsEmpty() &&
mDocument->HasLoadState(DocAccessible::eCompletelyLoaded) &&
mPresShell->RemoveRefreshObserver(this, FlushType::Display)) {

View File

@@ -142,7 +142,7 @@ class NotificationController final : public EventQueue,
MOZ_ASSERT(aTextNode->GetPrimaryFrame()->StyleVisibility()->IsVisible(),
"A text node is not visible");
mTextHash.Insert(aTextNode);
mTextArray.AppendElement(aTextNode);
ScheduleProcessing();
}
@@ -340,8 +340,11 @@ class NotificationController final : public EventQueue,
/**
* Pending accessible tree update notifications for rendered text changes.
* When there are a lot of nearby text insertions (e.g. during a reflow), it
* is much more performant to process them in order because we then benefit
* from the layout line cursor. Therefore, we use an array here.
*/
nsTHashSet<nsCOMPtrHashKey<nsIContent>> mTextHash;
nsTArray<nsCOMPtr<nsIContent>> mTextArray;
/**
* Other notifications like DOM events. Don't make this an AutoTArray; we