diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-15 03:34:42 +0000 |
commit | da4c7e7ed675c3bf405668739c3012d140856109 (patch) | |
tree | cdd868dba063fecba609a1d819de271f0d51b23e /gfx/layers/wr | |
parent | Adding upstream version 125.0.3. (diff) | |
download | firefox-da4c7e7ed675c3bf405668739c3012d140856109.tar.xz firefox-da4c7e7ed675c3bf405668739c3012d140856109.zip |
Adding upstream version 126.0.upstream/126.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'gfx/layers/wr')
-rw-r--r-- | gfx/layers/wr/StackingContextHelper.cpp | 9 | ||||
-rw-r--r-- | gfx/layers/wr/StackingContextHelper.h | 30 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderBridgeParent.cpp | 16 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderBridgeParent.h | 2 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderCommandBuilder.cpp | 29 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderCommandBuilder.h | 3 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderLayerManager.cpp | 25 | ||||
-rw-r--r-- | gfx/layers/wr/WebRenderLayerManager.h | 3 |
8 files changed, 66 insertions, 51 deletions
diff --git a/gfx/layers/wr/StackingContextHelper.cpp b/gfx/layers/wr/StackingContextHelper.cpp index d5ffbf26a0..2c0627f63f 100644 --- a/gfx/layers/wr/StackingContextHelper.cpp +++ b/gfx/layers/wr/StackingContextHelper.cpp @@ -272,5 +272,14 @@ Maybe<gfx::Matrix4x4> StackingContextHelper::GetDeferredTransformMatrix() } } +void StackingContextHelper::ClearDeferredTransformItem() const { + mDeferredTransformItem = nullptr; +} + +void StackingContextHelper::RestoreDeferredTransformItem( + nsDisplayTransform* aItem) const { + mDeferredTransformItem = aItem; +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/wr/StackingContextHelper.h b/gfx/layers/wr/StackingContextHelper.h index 368449a2fd..8239b2db0d 100644 --- a/gfx/layers/wr/StackingContextHelper.h +++ b/gfx/layers/wr/StackingContextHelper.h @@ -56,6 +56,12 @@ class MOZ_RAII StackingContextHelper { nsDisplayTransform* GetDeferredTransformItem() const; Maybe<gfx::Matrix4x4> GetDeferredTransformMatrix() const; + // Functions for temporarily clearing and restoring the deferred + // transform item during WebRender display list building. These are + // used to ensure deferred transforms are not applied in duplicate + // to nested nodes in the WebRenderScrollData tree. + void ClearDeferredTransformItem() const; + void RestoreDeferredTransformItem(nsDisplayTransform* aItem) const; bool AffectsClipPositioning() const { return mAffectsClipPositioning; } Maybe<wr::WrSpatialId> ReferenceFrameId() const { return mReferenceFrameId; } @@ -105,19 +111,19 @@ class MOZ_RAII StackingContextHelper { // item (i.e. the closest ancestor nsDisplayTransform item of the item that // created this StackingContextHelper). And then we use // mDeferredAncestorTransform to store the product of all the other transforms - // that were deferred. As a result, there is an invariant here that if - // mDeferredTransformItem is nullptr, mDeferredAncestorTransform will also - // be Nothing(). Note that we can only do this if the nsDisplayTransform items - // share the same ASR. If we are processing an nsDisplayTransform item with a - // different ASR than the previously-deferred item, we assume that the - // previously-deferred transform will get sent to APZ as part of a separate - // WebRenderLayerScrollData item, and so we don't need to bother with any - // merging. (The merging probably wouldn't even make sense because the - // coordinate spaces might be different in the face of async scrolling). This - // behaviour of forcing a WebRenderLayerScrollData item to be generated when - // the ASR changes is implemented in + // that were deferred. Note that this means we only need to look at + // mDeferredAncestorTransform if mDeferredTransformItem is set. Note that we + // can only do this if the nsDisplayTransform items share the same ASR. If we + // are processing an nsDisplayTransform item with a different ASR than the + // previously-deferred item, we assume that the previously-deferred transform + // will get sent to APZ as part of a separate WebRenderLayerScrollData item, + // and so we don't need to bother with any merging. (The merging probably + // wouldn't even make sense because the coordinate spaces might be different + // in the face of async scrolling). This behaviour of forcing a + // WebRenderLayerScrollData item to be generated when the ASR changes is + // implemented in // WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList. - nsDisplayTransform* mDeferredTransformItem; + mutable nsDisplayTransform* mDeferredTransformItem; Maybe<gfx::Matrix4x4> mDeferredAncestorTransform; bool mRasterizeLocally; diff --git a/gfx/layers/wr/WebRenderBridgeParent.cpp b/gfx/layers/wr/WebRenderBridgeParent.cpp index 83139b6af6..68e0c7af8c 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.cpp +++ b/gfx/layers/wr/WebRenderBridgeParent.cpp @@ -1919,6 +1919,10 @@ mozilla::ipc::IPCResult WebRenderBridgeParent::RecvClearCachedResources() { wr::AsUint64(mPipelineId), wr::AsUint64(mApi->GetId()), IsRootWebRenderBridgeParent()); + if (!IsRootWebRenderBridgeParent()) { + mApi->FlushPendingWrTransactionEventsWithoutWait(); + } + // Clear resources wr::TransactionBuilder txn(mApi); txn.SetLowPriority(true); @@ -2618,17 +2622,17 @@ void WebRenderBridgeParent::ScheduleGenerateFrame(wr::RenderReasons aReasons) { } void WebRenderBridgeParent::FlushRendering(wr::RenderReasons aReasons, - bool aWaitForPresent) { + bool aBlocking) { if (mDestroyed) { return; } - // This gets called during e.g. window resizes, so we need to flush the - // scene (which has the display list at the new window size). - FlushSceneBuilds(); - FlushFrameGeneration(aReasons); - if (aWaitForPresent) { + if (aBlocking) { + FlushSceneBuilds(); + FlushFrameGeneration(aReasons); FlushFramePresentation(); + } else { + ScheduleGenerateFrame(aReasons); } } diff --git a/gfx/layers/wr/WebRenderBridgeParent.h b/gfx/layers/wr/WebRenderBridgeParent.h index d8d80d1047..2c23779fb2 100644 --- a/gfx/layers/wr/WebRenderBridgeParent.h +++ b/gfx/layers/wr/WebRenderBridgeParent.h @@ -244,7 +244,7 @@ class WebRenderBridgeParent final : public PWebRenderBridgeParent, return aFontKey.mNamespace == mIdNamespace; } - void FlushRendering(wr::RenderReasons aReasons, bool aWaitForPresent = true); + void FlushRendering(wr::RenderReasons aReasons, bool aBlocking = true); /** * Schedule generating WebRender frame definitely at next composite timing. diff --git a/gfx/layers/wr/WebRenderCommandBuilder.cpp b/gfx/layers/wr/WebRenderCommandBuilder.cpp index e1bb2e1127..d7c7468f56 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.cpp +++ b/gfx/layers/wr/WebRenderCommandBuilder.cpp @@ -1882,9 +1882,8 @@ struct NewLayerData { ScrollableLayerGuid::ViewID mDeferredId = ScrollableLayerGuid::NULL_SCROLL_ID; bool mTransformShouldGetOwnLayer = false; - void ComputeDeferredTransformInfo( - const StackingContextHelper& aSc, nsDisplayItem* aItem, - nsDisplayTransform* aLastDeferredTransform) { + void ComputeDeferredTransformInfo(const StackingContextHelper& aSc, + nsDisplayItem* aItem) { // See the comments on StackingContextHelper::mDeferredTransformItem // for an overview of what deferred transforms are. // In the case where we deferred a transform, but have a child display @@ -1900,14 +1899,6 @@ struct NewLayerData { // that we deferred, and a child WebRenderLayerScrollData item that // holds the scroll metadata for the child's ASR. mDeferredItem = aSc.GetDeferredTransformItem(); - // If this deferred transform is already slated to be emitted onto an - // ancestor layer, do not emit it on this layer as well. Note that it's - // sufficient to check the most recently deferred item here, because - // there's only one per stacking context, and we emit it when changing - // stacking contexts. - if (mDeferredItem == aLastDeferredTransform) { - mDeferredItem = nullptr; - } if (mDeferredItem) { // It's possible the transform's ASR is not only an ancestor of // the item's ASR, but an ancestor of stopAtAsr. In such cases, @@ -2071,10 +2062,7 @@ void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList( newLayerData->mLayerCountBeforeRecursing = mLayerScrollData.size(); newLayerData->mStopAtAsr = mAsrStack.empty() ? nullptr : mAsrStack.back(); - newLayerData->ComputeDeferredTransformInfo( - aSc, item, - mDeferredTransformStack.empty() ? nullptr - : mDeferredTransformStack.back()); + newLayerData->ComputeDeferredTransformInfo(aSc, item); // Ensure our children's |stopAtAsr| is not be an ancestor of our // |stopAtAsr|, otherwise we could get cyclic scroll metadata @@ -2096,10 +2084,12 @@ void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList( mAsrStack.push_back(stopAtAsrForChildren); // If we're going to emit a deferred transform onto this layer, - // keep track of that so descendant layers know not to emit the - // same deferred transform. + // clear the deferred transform from the StackingContextHelper + // while we are building the subtree of descendant layers. + // This ensures that the deferred transform is not applied in + // duplicate to any of our descendant layers. if (newLayerData->mDeferredItem) { - mDeferredTransformStack.push_back(newLayerData->mDeferredItem); + aSc.ClearDeferredTransformItem(); } } } @@ -2143,8 +2133,7 @@ void WebRenderCommandBuilder::CreateWebRenderCommandsFromDisplayList( mAsrStack.pop_back(); if (newLayerData->mDeferredItem) { - MOZ_ASSERT(!mDeferredTransformStack.empty()); - mDeferredTransformStack.pop_back(); + aSc.RestoreDeferredTransformItem(newLayerData->mDeferredItem); } const ActiveScrolledRoot* stopAtAsr = newLayerData->mStopAtAsr; diff --git a/gfx/layers/wr/WebRenderCommandBuilder.h b/gfx/layers/wr/WebRenderCommandBuilder.h index 68c9a4ce63..8f17a73e3f 100644 --- a/gfx/layers/wr/WebRenderCommandBuilder.h +++ b/gfx/layers/wr/WebRenderCommandBuilder.h @@ -208,9 +208,6 @@ class WebRenderCommandBuilder final { // need this so that WebRenderLayerScrollData items that deeper in the // tree don't duplicate scroll metadata that their ancestors already have. std::vector<const ActiveScrolledRoot*> mAsrStack; - // A similar stack to track the deferred transform that we decided to emit - // most recently. - std::vector<nsDisplayTransform*> mDeferredTransformStack; const ActiveScrolledRoot* mLastAsr; WebRenderUserDataRefTable mWebRenderUserDatas; diff --git a/gfx/layers/wr/WebRenderLayerManager.cpp b/gfx/layers/wr/WebRenderLayerManager.cpp index 66b98a7db3..c29517c696 100644 --- a/gfx/layers/wr/WebRenderLayerManager.cpp +++ b/gfx/layers/wr/WebRenderLayerManager.cpp @@ -96,6 +96,7 @@ bool WebRenderLayerManager::Initialize( } mWrChild = static_cast<WebRenderBridgeChild*>(bridge); + mHasFlushedThisChild = false; TextureFactoryIdentifier textureFactoryIdentifier; wr::MaybeIdNamespace idNamespace; @@ -694,24 +695,30 @@ void WebRenderLayerManager::FlushRendering(wr::RenderReasons aReasons) { } MOZ_ASSERT(mWidget); - // If value of IsResizingNativeWidget() is nothing, we assume that resizing - // might happen. - bool resizing = mWidget && mWidget->IsResizingNativeWidget().valueOr(true); + // If widget bounds size is different from the last flush, consider + // this to be a resize. It's important to use GetClientSize here, + // because that has extra plumbing to support initial display cases + // where the widget doesn't yet have real bounds. + LayoutDeviceIntSize widgetSize = mWidget->GetClientSize(); + bool resizing = widgetSize != mFlushWidgetSize; + mFlushWidgetSize = widgetSize; if (resizing) { aReasons = aReasons | wr::RenderReasons::RESIZE; } - // Limit async FlushRendering to !resizing and Win DComp. - // XXX relax the limitation - if (WrBridge()->GetCompositorUseDComp() && !resizing) { - cBridge->SendFlushRenderingAsync(aReasons); - } else if (mWidget->SynchronouslyRepaintOnResize() || - StaticPrefs::layers_force_synchronous_resize()) { + // Check for the conditions where we we force a sync flush. The first + // flush for this child should always be sync. Resizes should be + // sometimes be sync. Everything else can be async. + if (!mHasFlushedThisChild || + (resizing && (mWidget->SynchronouslyRepaintOnResize() || + StaticPrefs::layers_force_synchronous_resize()))) { cBridge->SendFlushRendering(aReasons); } else { cBridge->SendFlushRenderingAsync(aReasons); } + + mHasFlushedThisChild = true; } void WebRenderLayerManager::WaitOnTransactionProcessed() { diff --git a/gfx/layers/wr/WebRenderLayerManager.h b/gfx/layers/wr/WebRenderLayerManager.h index 31fc9b6678..5ee2cc76a5 100644 --- a/gfx/layers/wr/WebRenderLayerManager.h +++ b/gfx/layers/wr/WebRenderLayerManager.h @@ -226,6 +226,7 @@ class WebRenderLayerManager final : public WindowRenderer { nsIWidget* MOZ_NON_OWNING_REF mWidget; RefPtr<WebRenderBridgeChild> mWrChild; + bool mHasFlushedThisChild; RefPtr<TransactionIdAllocator> mTransactionIdAllocator; TransactionId mLatestTransactionId; @@ -273,6 +274,8 @@ class WebRenderLayerManager final : public WindowRenderer { UniquePtr<wr::DisplayListBuilder> mDLBuilder; ScrollUpdatesMap mPendingScrollUpdates; + + LayoutDeviceIntSize mFlushWidgetSize; }; } // namespace layers |