summaryrefslogtreecommitdiffstats
path: root/gfx/layers/wr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-15 03:34:50 +0000
commitdef92d1b8e9d373e2f6f27c366d578d97d8960c6 (patch)
tree2ef34b9ad8bb9a9220e05d60352558b15f513894 /gfx/layers/wr
parentAdding debian version 125.0.3-1. (diff)
downloadfirefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.tar.xz
firefox-def92d1b8e9d373e2f6f27c366d578d97d8960c6.zip
Merging upstream version 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.cpp9
-rw-r--r--gfx/layers/wr/StackingContextHelper.h30
-rw-r--r--gfx/layers/wr/WebRenderBridgeParent.cpp16
-rw-r--r--gfx/layers/wr/WebRenderBridgeParent.h2
-rw-r--r--gfx/layers/wr/WebRenderCommandBuilder.cpp29
-rw-r--r--gfx/layers/wr/WebRenderCommandBuilder.h3
-rw-r--r--gfx/layers/wr/WebRenderLayerManager.cpp25
-rw-r--r--gfx/layers/wr/WebRenderLayerManager.h3
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