Bug 1725267 - Split Paint entry points to make them easier to understand. r=tnikkel

Differential Revision: https://phabricator.services.mozilla.com/D125800
This commit is contained in:
Matt Woodrow 2021-09-22 03:36:52 +00:00
Родитель 5d982b06d4
Коммит 2572ff38a4
6 изменённых файлов: 80 добавлений и 42 удалений

Просмотреть файл

@ -360,7 +360,8 @@ nsDOMWindowUtils::UpdateLayerTree() {
RefPtr<nsViewManager> vm = presShell->GetViewManager();
if (nsView* view = vm->GetRootView()) {
nsAutoScriptBlocker scriptBlocker;
presShell->Paint(view, PaintFlags::PaintSyncDecodeImages);
presShell->PaintAndRequestComposite(view,
PaintFlags::PaintSyncDecodeImages);
presShell->GetWindowRenderer()->WaitOnTransactionProcessed();
}
}

Просмотреть файл

@ -2734,7 +2734,7 @@ mozilla::ipc::IPCResult BrowserChild::RecvRenderLayers(
} else {
RefPtr<nsViewManager> vm = presShell->GetViewManager();
if (nsView* view = vm->GetRootView()) {
presShell->Paint(view, PaintFlags::None);
presShell->PaintAndRequestComposite(view, PaintFlags::None);
}
}
presShell->SuppressDisplayport(false);

Просмотреть файл

@ -6195,22 +6195,47 @@ void PresShell::RemoveFrameFromApproximatelyVisibleList(nsIFrame* aFrame) {
}
}
class nsAutoNotifyDidPaint {
public:
nsAutoNotifyDidPaint(PresShell* aShell, PaintFlags aFlags)
: mShell(aShell), mFlags(aFlags) {}
~nsAutoNotifyDidPaint() {
if (!!(mFlags & PaintFlags::PaintComposite)) {
mShell->GetPresContext()->NotifyDidPaintForSubtree();
}
void PresShell::PaintAndRequestComposite(nsView* aView, PaintFlags aFlags) {
if (!mIsActive) {
return;
}
private:
PresShell* mShell;
PaintFlags mFlags;
};
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;
}
void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
// Otherwise we're a retained WebRenderLayerManager, so we want to call
// Paint to update with any changes and push those to WR.
PaintInternalFlags flags = PaintInternalFlags::None;
if (aFlags & PaintFlags::PaintSyncDecodeImages) {
flags |= PaintInternalFlags::PaintSyncDecodeImages;
}
PaintInternal(aView, flags);
}
void PresShell::SyncPaintFallback(nsView* aView) {
if (!mIsActive) {
return;
}
WindowRenderer* renderer = aView->GetWidget()->GetWindowRenderer();
NS_ASSERTION(renderer->AsFallback(),
"Can't do Sync paint for remote renderers");
if (!renderer->AsFallback()) {
return;
}
PaintInternal(aView, PaintInternalFlags::PaintComposite);
GetPresContext()->NotifyDidPaintForSubtree();
}
void PresShell::PaintInternal(nsView* aViewToPaint, PaintInternalFlags aFlags) {
nsCString url;
nsIURI* uri = mDocument->GetDocumentURI();
Document* contentRoot = GetPrimaryContentDocument();
@ -6226,7 +6251,7 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
// assert there. However, we don't rely on this assertion on Android because
// we don't paint while JS is running.
#if !defined(MOZ_WIDGET_ANDROID)
if (!(aFlags & PaintFlags::PaintComposite)) {
if (!(aFlags & PaintInternalFlags::PaintComposite)) {
// We need to allow content JS when the flag is set since we may trigger
// MozAfterPaint events in content in those cases.
nojs.emplace(dom::danger::GetJSContext());
@ -6258,9 +6283,6 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
WindowRenderer* renderer = aViewToPaint->GetWidget()->GetWindowRenderer();
NS_ASSERTION(renderer, "Must be in paint event");
WebRenderLayerManager* layerManager = renderer->AsWebRender();
bool shouldInvalidate = renderer->NeedsWidgetInvalidation();
nsAutoNotifyDidPaint notifyDidPaint(this, aFlags);
// 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
@ -6277,13 +6299,6 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
}
if (!renderer->BeginTransaction(url)) {
if (renderer->AsFallback() && !(aFlags & PaintFlags::PaintComposite)) {
// The fallback renderer doesn't do any retaining, and so always
// fails when called without PaintComposite (from the refresh driver).
// We just need to notify the view and widget that we're invalid, and
// we'll do a paint+composite from the PaintWindow callback.
aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
}
return;
}
@ -6294,19 +6309,16 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
}
if (frame) {
if (!(aFlags & PaintFlags::PaintSyncDecodeImages) &&
if (!(aFlags & PaintInternalFlags::PaintSyncDecodeImages) &&
!frame->HasAnyStateBits(NS_FRAME_UPDATE_LAYER_TREE)) {
if (layerManager) {
layerManager->SetTransactionIdAllocator(presContext->RefreshDriver());
}
if (renderer->EndEmptyTransaction((aFlags & PaintFlags::PaintComposite)
if (renderer->EndEmptyTransaction(
(aFlags & PaintInternalFlags::PaintComposite)
? LayerManager::END_DEFAULT
: LayerManager::END_NO_COMPOSITE)) {
if (shouldInvalidate) {
aViewToPaint->GetViewManager()->InvalidateView(aViewToPaint);
}
frame->UpdatePaintCountForPaintedPresShells();
return;
}
@ -6323,7 +6335,7 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
// We force sync-decode for printing / print-preview (printing already does
// this from nsPageSequenceFrame::PrintNextSheet).
if (aFlags & PaintFlags::PaintSyncDecodeImages ||
if (aFlags & PaintInternalFlags::PaintSyncDecodeImages ||
mDocument->IsStaticDocument()) {
flags |= PaintFrameFlags::SyncDecodeImages;
}
@ -6356,7 +6368,7 @@ void PresShell::Paint(nsView* aViewToPaint, PaintFlags aFlags) {
FallbackRenderer* fallback = renderer->AsFallback();
MOZ_ASSERT(fallback);
if (aFlags & PaintFlags::PaintComposite) {
if (aFlags & PaintInternalFlags::PaintComposite) {
nsIntRect bounds = presContext->GetVisibleArea().ToOutsidePixels(
presContext->AppUnitsPerDevPixel());
fallback->EndTransactionWithColor(bounds, ToDeviceColor(bgcolor));

Просмотреть файл

@ -90,6 +90,7 @@ struct nsCallbackEventRequest;
namespace mozilla {
class nsDisplayList;
class nsDisplayListBuilder;
class FallbackRenderer;
class AccessibleCaretEventHub;
class EventStates;
@ -1265,8 +1266,21 @@ class PresShell final : public nsStubDocumentObserver,
void BackingScaleFactorChanged() { mPresContext->UIResolutionChangedSync(); }
/**
* Does any painting work required to update retained paint state, and pushes
* it the compositor (if any). Requests a composite, either by scheduling a
* remote composite, or invalidating the widget so that we get a call to
* SyncPaintFallback from the widget paint event.
*/
MOZ_CAN_RUN_SCRIPT
void Paint(nsView* aViewToPaint, 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(nsView* aView);
/**
* Notify that we're going to call Paint with PaintFlags::PaintLayers
@ -1699,6 +1713,9 @@ class PresShell final : public nsStubDocumentObserver,
void SetIsActive(bool aIsActive);
bool ShouldBeActive() const;
MOZ_CAN_RUN_SCRIPT
void PaintInternal(nsView* aViewToPaint, PaintInternalFlags aFlags);
/**
* Refresh observer management.
*/

Просмотреть файл

@ -188,14 +188,22 @@ MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(AddCanvasBackgroundColorFlags)
enum class PaintFlags {
None = 0,
/* Composite layers to the window. */
PaintComposite = 1 << 1,
/* Sync-decode images. */
PaintSyncDecodeImages = 1 << 2,
PaintSyncDecodeImages = 1 << 1,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PaintFlags)
enum class PaintInternalFlags {
None = 0,
/* Sync-decode images. */
PaintSyncDecodeImages = 1 << 1,
/* Composite layers to the window. */
PaintComposite = 1 << 2,
};
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(PaintInternalFlags)
// This is a private enum class of PresShell, but currently,
// MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS isn't available in class definition.
// Therefore, we need to put this here.

Просмотреть файл

@ -318,7 +318,7 @@ void nsViewManager::Refresh(nsView* aView,
if (!renderer->NeedsWidgetInvalidation()) {
renderer->FlushRendering();
} else {
presShell->Paint(aView, PaintFlags::PaintComposite);
presShell->SyncPaintFallback(aView);
}
#ifdef MOZ_DUMP_PAINTING
if (nsLayoutUtils::InvalidationDebuggingIsEnabled()) {
@ -441,7 +441,7 @@ void nsViewManager::ProcessPendingUpdatesPaint(nsIWidget* aWidget) {
}
#endif
presShell->Paint(view, PaintFlags::None);
presShell->PaintAndRequestComposite(view, PaintFlags::None);
view->SetForcedRepaint(false);
#ifdef MOZ_DUMP_PAINTING