commit d2e4f8aafe188d6a3e73c71fc8a3ed2b42db2fa5
parent 79e88998d6c2ddf916cfb7d749cfa21c5868cd05
Author: Cristian Tuns <ctuns@mozilla.com>
Date: Thu, 9 Oct 2025 18:38:30 -0400
Revert "Bug 1993570 - Make painting code not use views directly. r=layout-reviewers,dshin" for causing build bustages in nsViewManager.cpp
This reverts commit 403aa6265d08c81a7b10bad851313cd01f3277d4.
Diffstat:
8 files changed, 60 insertions(+), 65 deletions(-)
diff --git a/dom/base/nsDOMWindowUtils.cpp b/dom/base/nsDOMWindowUtils.cpp
@@ -426,9 +426,8 @@ nsDOMWindowUtils::UpdateLayerTree() {
RefPtr<nsViewManager> vm = presShell->GetViewManager();
if (nsView* view = vm->GetRootView()) {
nsAutoScriptBlocker scriptBlocker;
- presShell->PaintAndRequestComposite(
- view->GetFrame(), view->GetWidget()->GetWindowRenderer(),
- PaintFlags::PaintSyncDecodeImages);
+ presShell->PaintAndRequestComposite(view,
+ PaintFlags::PaintSyncDecodeImages);
presShell->GetWindowRenderer()->WaitOnTransactionProcessed();
}
}
diff --git a/dom/ipc/BrowserChild.cpp b/dom/ipc/BrowserChild.cpp
@@ -3070,9 +3070,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvRenderLayers(const bool& aEnabled) {
} else {
RefPtr<nsViewManager> vm = presShell->GetViewManager();
if (nsView* view = vm->GetRootView()) {
- presShell->PaintAndRequestComposite(
- view->GetFrame(), view->GetWidget()->GetWindowRenderer(),
- PaintFlags::None);
+ presShell->PaintAndRequestComposite(view, PaintFlags::None);
}
}
presShell->SuppressDisplayport(false);
diff --git a/dom/view-transitions/ViewTransition.cpp b/dom/view-transitions/ViewTransition.cpp
@@ -1352,16 +1352,13 @@ Maybe<SkipTransitionReason> ViewTransition::CaptureOldState() {
if (RefPtr<PresShell> ps =
nsContentUtils::GetInProcessSubtreeRootDocument(mDocument)
->GetPresShell()) {
+ VT_LOG("ViewTransitions::CaptureOldState(), requesting composite");
// Build a display list and send it to WR in order to perform the
// capturing of old content.
RefPtr<nsViewManager> vm = ps->GetViewManager();
- if (RefPtr widget = vm->GetRootWidget()) {
- VT_LOG("ViewTransitions::CaptureOldState(), requesting composite");
- ps->PaintAndRequestComposite(ps->GetRootFrame(),
- widget->GetWindowRenderer(),
- PaintFlags::PaintCompositeOffscreen);
- VT_LOG("ViewTransitions::CaptureOldState(), requesting composite end");
- }
+ ps->PaintAndRequestComposite(vm->GetRootView(),
+ PaintFlags::PaintCompositeOffscreen);
+ VT_LOG("ViewTransitions::CaptureOldState(), requesting composite end");
}
}
diff --git a/layout/base/PresShell.cpp b/layout/base/PresShell.cpp
@@ -5763,8 +5763,8 @@ PresShell::CanvasBackground PresShell::ComputeCanvasBackground() const {
return {viewportBg, pageBg};
}
-nscolor PresShell::ComputeBackstopColor(nsIFrame* aDisplayRoot) {
- nsIWidget* widget = aDisplayRoot ? aDisplayRoot->GetNearestWidget() : nullptr;
+nscolor PresShell::ComputeBackstopColor(nsView* aDisplayRoot) {
+ nsIWidget* widget = aDisplayRoot->GetWidget();
if (widget &&
(widget->GetTransparencyMode() != widget::TransparencyMode::Opaque ||
widget->WidgetPaintsBackground())) {
@@ -6703,21 +6703,18 @@ void PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) {
}
}
-void PresShell::PaintAndRequestComposite(nsIFrame* aFrame,
- WindowRenderer* aRenderer,
- PaintFlags aFlags) {
+void PresShell::PaintAndRequestComposite(nsView* aView, PaintFlags aFlags) {
if (!mIsActive) {
return;
}
- NS_ASSERTION(aRenderer, "Must be in paint event");
- if (aRenderer->AsFallback()) {
- // The fallback renderer doesn't do any retaining, so we just need to
- // notify the view and widget that we're invalid, and we'll do a
- // paint+composite from the PaintWindow callback.
- if (auto* view = aFrame ? aFrame->GetView() : nullptr) {
- GetViewManager()->InvalidateView(view);
- }
+ WindowRenderer* renderer = aView->GetWidget()->GetWindowRenderer();
+ NS_ASSERTION(renderer, "Must be in paint event");
+ if (renderer->AsFallback()) {
+ // The fallback renderer doesn't do any retaining, so we
+ // just need to notify the view and widget that we're invalid, and
+ // we'll do a paint+composite from the PaintWindow callback.
+ GetViewManager()->InvalidateView(aView);
return;
}
@@ -6730,28 +6727,26 @@ void PresShell::PaintAndRequestComposite(nsIFrame* aFrame,
if (aFlags & PaintFlags::PaintCompositeOffscreen) {
flags |= PaintInternalFlags::PaintCompositeOffscreen;
}
- PaintInternal(aFrame, aRenderer, flags);
+ PaintInternal(aView, flags);
}
-void PresShell::SyncPaintFallback(nsIFrame* aFrame, WindowRenderer* aRenderer) {
+void PresShell::SyncPaintFallback(nsView* aView) {
if (!mIsActive) {
return;
}
- NS_ASSERTION(aRenderer->AsFallback(),
+ WindowRenderer* renderer = aView->GetWidget()->GetWindowRenderer();
+ NS_ASSERTION(renderer->AsFallback(),
"Can't do Sync paint for remote renderers");
- if (!aRenderer->AsFallback()) {
+ if (!renderer->AsFallback()) {
return;
}
- PaintInternal(aFrame, aRenderer, PaintInternalFlags::PaintComposite);
+ PaintInternal(aView, PaintInternalFlags::PaintComposite);
GetPresContext()->NotifyDidPaintForSubtree();
}
-void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
- PaintInternalFlags aFlags) {
- MOZ_ASSERT_IF(aFrame,
- aFrame->IsViewportFrame() || aFrame->IsMenuPopupFrame());
+void PresShell::PaintInternal(nsView* aViewToPaint, PaintInternalFlags aFlags) {
nsCString url;
nsIURI* uri = mDocument->GetDocumentURI();
Document* contentRoot = GetPrimaryContentDocument();
@@ -6776,7 +6771,7 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
#endif
NS_ASSERTION(!mIsDestroying, "painting a destroyed PresShell");
- NS_ASSERTION(aRenderer, "null renderer");
+ NS_ASSERTION(aViewToPaint, "null view");
MOZ_ASSERT(!mApproximateFrameVisibilityVisited, "Should have been cleared");
@@ -6784,15 +6779,19 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
return;
}
+ nsIFrame* frame = aViewToPaint->GetFrame();
+
FocusTarget focusTarget;
if (StaticPrefs::apz_keyboard_enabled_AtStartup()) {
// Update the focus target for async keyboard scrolling. This will be
// forwarded to APZ by nsDisplayList::PaintRoot. We need to to do this
// before we enter the paint phase because dispatching eVoid events can
// cause layout to happen.
- uint64_t focusSequenceNumber = mAPZFocusSequenceNumber;
- if (nsMenuPopupFrame* popup = do_QueryFrame(aFrame)) {
+ uint64_t focusSequenceNumber;
+ if (nsMenuPopupFrame* popup = do_QueryFrame(frame)) {
focusSequenceNumber = popup->GetAPZFocusSequenceNumber();
+ } else {
+ focusSequenceNumber = mAPZFocusSequenceNumber;
}
focusTarget = FocusTarget(this, focusSequenceNumber);
}
@@ -6800,7 +6799,9 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
nsPresContext* presContext = GetPresContext();
AUTO_LAYOUT_PHASE_ENTRY_POINT(presContext, Paint);
- WebRenderLayerManager* layerManager = aRenderer->AsWebRender();
+ WindowRenderer* renderer = aViewToPaint->GetWidget()->GetWindowRenderer();
+ NS_ASSERTION(renderer, "Must be in paint event");
+ WebRenderLayerManager* layerManager = renderer->AsWebRender();
// Whether or not we should set first paint when painting is suppressed
// is debatable. For now we'll do it because B2G relied on first paint
@@ -6819,7 +6820,7 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
const bool offscreen =
bool(aFlags & PaintInternalFlags::PaintCompositeOffscreen);
- if (!aRenderer->BeginTransaction(url)) {
+ if (!renderer->BeginTransaction(url)) {
return;
}
@@ -6829,24 +6830,24 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
layerManager->SetFocusTarget(focusTarget);
}
- if (aFrame) {
+ if (frame) {
if (!(aFlags & PaintInternalFlags::PaintSyncDecodeImages) &&
- !aFrame->HasAnyStateBits(NS_FRAME_UPDATE_LAYER_TREE)) {
+ !frame->HasAnyStateBits(NS_FRAME_UPDATE_LAYER_TREE)) {
if (layerManager) {
layerManager->SetTransactionIdAllocator(presContext->RefreshDriver());
}
- if (aRenderer->EndEmptyTransaction(
+ if (renderer->EndEmptyTransaction(
(aFlags & PaintInternalFlags::PaintComposite)
? WindowRenderer::END_DEFAULT
: WindowRenderer::END_NO_COMPOSITE)) {
return;
}
}
- aFrame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
+ frame->RemoveStateBits(NS_FRAME_UPDATE_LAYER_TREE);
}
- nscolor bgcolor = ComputeBackstopColor(aFrame);
+ nscolor bgcolor = ComputeBackstopColor(aViewToPaint);
PaintFrameFlags flags =
PaintFrameFlags::WidgetLayers | PaintFrameFlags::ExistingTransaction;
@@ -6861,21 +6862,21 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
if (aFlags & PaintInternalFlags::PaintCompositeOffscreen) {
flags |= PaintFrameFlags::CompositeOffscreen;
}
- if (aRenderer->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
+ if (renderer->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
flags |= PaintFrameFlags::ForWebRender;
}
- if (aFrame) {
+ if (frame) {
// We can paint directly into the widget using its layer manager.
SelectionNodeCache cache(*this);
- nsLayoutUtils::PaintFrame(nullptr, aFrame, nsRegion(), bgcolor,
+ nsLayoutUtils::PaintFrame(nullptr, frame, nsRegion(), bgcolor,
nsDisplayListBuilderMode::Painting, flags);
return;
}
bgcolor = NS_ComposeColors(bgcolor, mCanvasBackground.mViewport.mColor);
- if (aRenderer->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
+ if (renderer->GetBackendType() == layers::LayersBackend::LAYERS_WR) {
LayoutDeviceRect bounds = LayoutDeviceRect::FromAppUnits(
presContext->GetVisibleArea(), presContext->AppUnitsPerDevPixel());
WebRenderBackgroundData data(wr::ToLayoutRect(bounds),
@@ -6888,7 +6889,7 @@ void PresShell::PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
return;
}
- FallbackRenderer* fallback = aRenderer->AsFallback();
+ FallbackRenderer* fallback = renderer->AsFallback();
MOZ_ASSERT(fallback);
if (aFlags & PaintInternalFlags::PaintComposite) {
diff --git a/layout/base/PresShell.h b/layout/base/PresShell.h
@@ -965,7 +965,7 @@ class PresShell final : public nsStubDocumentObserver,
* widget, otherwise the PresContext default background color. This color is
* only visible if the contents of the view as a whole are translucent.
*/
- nscolor ComputeBackstopColor(nsIFrame* aDisplayRoot);
+ nscolor ComputeBackstopColor(nsView* aDisplayRoot);
void ObserveNativeAnonMutationsForPrint(bool aObserve) {
mObservesMutationsForPrint = aObserve;
@@ -1367,15 +1367,14 @@ class PresShell final : public nsStubDocumentObserver,
* SyncPaintFallback from the widget paint event.
*/
MOZ_CAN_RUN_SCRIPT
- void PaintAndRequestComposite(nsIFrame* aFrame, WindowRenderer* aRenderer,
- PaintFlags aFlags);
+ void PaintAndRequestComposite(nsView* aView, PaintFlags aFlags);
/**
* Does an immediate paint+composite using the FallbackRenderer (which must
* be the current WindowRenderer for the root frame's widget).
*/
MOZ_CAN_RUN_SCRIPT
- void SyncPaintFallback(nsIFrame* aFrame, WindowRenderer* aRenderer);
+ void SyncPaintFallback(nsView* aView);
/**
* Notify that we're going to call Paint with PaintFlags::PaintLayers
@@ -1869,8 +1868,7 @@ class PresShell final : public nsStubDocumentObserver,
bool ComputeActiveness() const;
MOZ_CAN_RUN_SCRIPT
- void PaintInternal(nsIFrame* aFrame, WindowRenderer* aRenderer,
- PaintInternalFlags aFlags);
+ void PaintInternal(nsView* aViewToPaint, PaintInternalFlags aFlags);
// Refresh observer management.
void ScheduleFlush();
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
@@ -2860,9 +2860,12 @@ void nsLayoutUtils::PaintFrame(gfxContext* aRenderingContext, nsIFrame* aFrame,
nsIFrame* displayRoot = GetDisplayRootFrame(aFrame);
- if ((aFlags & PaintFrameFlags::WidgetLayers) && displayRoot != aFrame) {
- aFlags &= ~PaintFrameFlags::WidgetLayers;
- NS_ASSERTION(aRenderingContext, "need a rendering context");
+ if (aFlags & PaintFrameFlags::WidgetLayers) {
+ nsView* view = aFrame->GetView();
+ if (!(view && view->GetWidget() && displayRoot == aFrame)) {
+ aFlags &= ~PaintFrameFlags::WidgetLayers;
+ NS_ASSERTION(aRenderingContext, "need a rendering context");
+ }
}
nsPresContext* presContext = aFrame->PresContext();
@@ -6687,7 +6690,7 @@ bool nsLayoutUtils::HasNonZeroCornerOnSide(const BorderRadius& aCorners,
/* static */
widget::TransparencyMode nsLayoutUtils::GetFrameTransparency(
- const nsIFrame* aBackgroundFrame, const nsIFrame* aCSSRootFrame) {
+ nsIFrame* aBackgroundFrame, nsIFrame* aCSSRootFrame) {
if (!aCSSRootFrame->StyleEffects()->IsOpaque()) {
return TransparencyMode::Transparent;
}
diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h
@@ -2166,8 +2166,8 @@ class nsLayoutUtils {
* @return a value suitable for passing to SetWindowTranslucency.
*/
using TransparencyMode = mozilla::widget::TransparencyMode;
- static TransparencyMode GetFrameTransparency(const nsIFrame* aBackgroundFrame,
- const nsIFrame* aCSSRootFrame);
+ static TransparencyMode GetFrameTransparency(nsIFrame* aBackgroundFrame,
+ nsIFrame* aCSSRootFrame);
/**
* A frame is a popup if it has its own floating window. Menus, panels
diff --git a/view/nsViewManager.cpp b/view/nsViewManager.cpp
@@ -273,7 +273,7 @@ void nsViewManager::Refresh(nsView* aView,
if (!renderer->NeedsWidgetInvalidation()) {
renderer->FlushRendering(wr::RenderReasons::WIDGET);
} else {
- presShell->SyncPaintFallback(aView->GetFrame(), renderer);
+ presShell->SyncPaintFallback(aView);
}
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
@@ -396,8 +396,7 @@ void nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget) {
}
#endif
- presShell->PaintAndRequestComposite(
- view->GetFrame(), aWidget->GetWindowRenderer(), PaintFlags::None);
+ presShell->PaintAndRequestComposite(view, PaintFlags::None);
view->SetForcedRepaint(false);
#ifdef MOZ_DUMP_PAINTING