Bug 1837960. Remove array of all nsViewManagers. r=emilio

The only thing it's used for is calling will paint on a document tree. To iterate every viewmanager looking for those in one document tree is a bit silly, we can just walk the view tree. Since there are only 3 types of views (root views, popup views for menupopupframes, and subdocument frame views (and their inner view)) we don't have to walk many pointers: menupopupframes are controlled by chrome code and are limited, and the other two types of views correspond to the number of view managers in the tree (one view manager per document).

Differential Revision: https://phabricator.services.mozilla.com/D180677
This commit is contained in:
Timothy Nikkel 2023-06-22 09:38:27 +00:00
parent f321008c6b
commit d4712d5e3e
2 changed files with 25 additions and 39 deletions

View file

@ -49,8 +49,6 @@ using namespace mozilla::layers;
#undef DEBUG_MOUSE_LOCATION
// Weakly held references to all of the view managers
StaticAutoPtr<nsTArray<nsViewManager*>> nsViewManager::gViewManagers;
uint32_t nsViewManager::gLastUserEventTime = 0;
nsViewManager::nsViewManager()
@ -60,14 +58,7 @@ nsViewManager::nsViewManager()
mRefreshDisableCount(0),
mPainting(false),
mRecursiveRefreshPending(false),
mHasPendingWidgetGeometryChanges(false) {
if (gViewManagers == nullptr) {
// Create an array to hold a list of view managers
gViewManagers = new nsTArray<nsViewManager*>;
}
gViewManagers->AppendElement(this);
}
mHasPendingWidgetGeometryChanges(false) {}
nsViewManager::~nsViewManager() {
if (mRootView) {
@ -78,22 +69,6 @@ nsViewManager::~nsViewManager() {
mRootViewManager = nullptr;
NS_ASSERTION(gViewManagers != nullptr, "About to use null gViewManagers");
#ifdef DEBUG
bool removed =
#endif
gViewManagers->RemoveElement(this);
NS_ASSERTION(
removed,
"Viewmanager instance was not in the global list of viewmanagers");
if (gViewManagers->IsEmpty()) {
// There aren't any more view managers so
// release the global array of view managers
gViewManagers = nullptr;
}
MOZ_RELEASE_ASSERT(!mPresShell,
"Releasing nsViewManager without having called Destroy on "
"the PresShell!");
@ -960,22 +935,33 @@ void nsViewManager::UpdateWidgetGeometry() {
}
}
/* static */ void nsViewManager::CollectVMsForWillPaint(
nsView* aView, nsViewManager* aParentVM,
nsTArray<RefPtr<nsViewManager>>& aVMs) {
nsViewManager* vm = aView->GetViewManager();
if (vm != aParentVM) {
aVMs.AppendElement(vm);
}
for (nsView* child = aView->GetFirstChild(); child;
child = child->GetNextSibling()) {
CollectVMsForWillPaint(child, vm, aVMs);
}
}
void nsViewManager::CallWillPaintOnObservers() {
MOZ_ASSERT(IsRootVM(), "Must be root VM for this to be called!");
if (NS_WARN_IF(!gViewManagers)) {
if (!mRootView) {
return;
}
uint32_t index;
for (index = 0; index < gViewManagers->Length(); index++) {
nsViewManager* vm = gViewManagers->ElementAt(index);
if (vm->RootViewManager() == this) {
// One of our kids.
if (vm->mRootView && vm->mRootView->IsEffectivelyVisible()) {
if (RefPtr<PresShell> presShell = vm->GetPresShell()) {
presShell->WillPaint();
}
AutoTArray<RefPtr<nsViewManager>, 2> VMs;
CollectVMsForWillPaint(mRootView, nullptr, VMs);
for (const auto& vm : VMs) {
if (vm->GetRootView() && vm->GetRootView()->IsEffectivelyVisible()) {
if (RefPtr<PresShell> presShell = vm->GetPresShell()) {
presShell->WillPaint();
}
}
}

View file

@ -342,6 +342,9 @@ class nsViewManager final {
* Call WillPaint() on all view observers under this vm root.
*/
MOZ_CAN_RUN_SCRIPT_BOUNDARY void CallWillPaintOnObservers();
static void CollectVMsForWillPaint(nsView* aView, nsViewManager* aParentVM,
nsTArray<RefPtr<nsViewManager>>& aVMs);
void ReparentChildWidgets(nsView* aView, nsIWidget* aNewWidget);
void ReparentWidgets(nsView* aView, nsView* aParent);
void InvalidateWidgetArea(nsView* aWidgetView,
@ -422,9 +425,6 @@ class nsViewManager final {
bool mHasPendingWidgetGeometryChanges;
// from here to public should be static and locked... MMP
// list of view managers
static mozilla::StaticAutoPtr<nsTArray<nsViewManager*>> gViewManagers;
};
/**