commit a1d4037cd14a9a83e9e0c939f33eecb30924bd3e
parent 74bd6c9d12f1f7b9ef0df8abccb43d037273c7d8
Author: Markus Stange <mstange.moz@gmail.com>
Date: Thu, 2 Oct 2025 20:49:12 +0000
Bug 1987007 - Extract a loop into GetMaxUpdateRequired. r=bradwerth
Differential Revision: https://phabricator.services.mozilla.com/D267145
Diffstat:
2 files changed, 56 insertions(+), 40 deletions(-)
diff --git a/gfx/layers/NativeLayerCA.h b/gfx/layers/NativeLayerCA.h
@@ -63,6 +63,17 @@ enum class VideoLowPowerType {
FailEnqueue, // Enqueueing the video didn't work.
};
+// The type of update needed to apply the pending changes to a NativeLayerCA
+// representation.
+//
+// Order is important. Each enum must fully encompass the work implied by the
+// previous enums.
+enum class NativeLayerCAUpdateType {
+ None,
+ OnlyVideo,
+ All,
+};
+
// NativeLayerRootCA is the CoreAnimation implementation of the NativeLayerRoot
// interface. A NativeLayerRootCA is created by the widget around an existing
// CALayer with a call to CreateForCALayer - this CALayer is the root of the
@@ -171,6 +182,12 @@ class NativeLayerRootCA : public NativeLayerRoot {
void SetMutatedLayerStructure();
+ using UpdateType = NativeLayerCAUpdateType;
+ UpdateType GetMaxUpdateRequired(
+ WhichRepresentation aRepresentation,
+ const nsTArray<RefPtr<NativeLayerCA>>& aSublayers,
+ bool aMutatedLayerStructure) const;
+
Mutex mMutex MOZ_UNANNOTATED; // protects all other fields
CALayer* mOnscreenRootCALayer = nullptr; // strong
CALayer* mOffscreenRootCALayer = nullptr; // strong
@@ -294,6 +311,8 @@ class NativeLayerCA : public NativeLayer {
protected:
friend class NativeLayerRootCA;
+ using UpdateType = NativeLayerCAUpdateType;
+ using WhichRepresentation = NativeLayerRootCA::WhichRepresentation;
NativeLayerCA(const gfx::IntSize& aSize, bool aIsOpaque,
SurfacePoolHandleCA* aSurfacePoolHandle);
@@ -306,16 +325,9 @@ class NativeLayerCA : public NativeLayer {
~NativeLayerCA() override;
// To be called by NativeLayerRootCA:
- typedef NativeLayerRootCA::WhichRepresentation WhichRepresentation;
CALayer* UnderlyingCALayer(WhichRepresentation aRepresentation);
- enum class UpdateType {
- None, // Order is important. Each enum must fully encompass the
- OnlyVideo, // work implied by the previous enums.
- All,
- };
-
- UpdateType HasUpdate(WhichRepresentation aRepresentation);
+ NativeLayerCAUpdateType HasUpdate(WhichRepresentation aRepresentation);
// Apply pending updates to the underlaying CALayer. Sets *aMustRebuild to
// true if the update requires changing which set of CALayers should be in the
diff --git a/gfx/layers/NativeLayerCA.mm b/gfx/layers/NativeLayerCA.mm
@@ -440,45 +440,48 @@ void NativeLayerRootCA::SetMutatedLayerStructure() {
mMutatedOffscreenLayerStructure = true;
}
+NativeLayerCAUpdateType NativeLayerRootCA::GetMaxUpdateRequired(
+ WhichRepresentation aRepresentation,
+ const nsTArray<RefPtr<NativeLayerCA>>& aSublayers,
+ bool aMutatedLayerStructure) const {
+ if (aMutatedLayerStructure) {
+ return UpdateType::All;
+ }
+
+ UpdateType maxUpdateRequired = UpdateType::None;
+ for (const auto& layer : aSublayers) {
+ UpdateType updateRequired = layer->HasUpdate(aRepresentation);
+ if (updateRequired == UpdateType::All) {
+ return UpdateType::All;
+ }
+ // Use the ordering of our UpdateType enum values.
+ maxUpdateRequired = std::max(maxUpdateRequired, updateRequired);
+ }
+ return maxUpdateRequired;
+}
+
void NativeLayerRootCA::CommitRepresentation(
WhichRepresentation aRepresentation, CALayer* aRootCALayer,
const nsTArray<RefPtr<NativeLayerCA>>& aSublayers,
bool aMutatedLayerStructure, bool aWindowIsFullscreen) {
- bool mustRebuild = aMutatedLayerStructure;
- if (!mustRebuild) {
- // Check which type of update we need to do, if any.
- NativeLayerCA::UpdateType updateRequired = NativeLayerCA::UpdateType::None;
-
- for (auto layer : aSublayers) {
- // Use the ordering of our UpdateType enums to build a maximal update
- // type.
- updateRequired =
- std::max(updateRequired, layer->HasUpdate(aRepresentation));
- if (updateRequired == NativeLayerCA::UpdateType::All) {
- break;
- }
- }
-
- if (updateRequired == NativeLayerCA::UpdateType::None) {
+ UpdateType updateRequired =
+ GetMaxUpdateRequired(aRepresentation, aSublayers, aMutatedLayerStructure);
+ if (updateRequired == NativeLayerCA::UpdateType::OnlyVideo) {
+ // Attempt a video-only update, which does not require being wrapped in a
+ // CATransaction.
+ bool allUpdatesSucceeded =
+ std::all_of(aSublayers.begin(), aSublayers.end(),
+ [=](const RefPtr<NativeLayerCA>& layer) {
+ bool ignoredMustRebuild = false;
+ return layer->ApplyChanges(
+ aRepresentation, NativeLayerCA::UpdateType::OnlyVideo,
+ &ignoredMustRebuild);
+ });
+
+ if (allUpdatesSucceeded) {
// Nothing more needed, so early exit.
return;
}
-
- if (updateRequired == NativeLayerCA::UpdateType::OnlyVideo) {
- bool allUpdatesSucceeded = std::all_of(
- aSublayers.begin(), aSublayers.end(),
- [=](const RefPtr<NativeLayerCA>& layer) {
- bool ignoredMustRebuild = false;
- return layer->ApplyChanges(aRepresentation,
- NativeLayerCA::UpdateType::OnlyVideo,
- &ignoredMustRebuild);
- });
-
- if (allUpdatesSucceeded) {
- // Nothing more needed, so early exit;
- return;
- }
- }
}
// We're going to do a full update now, which requires a transaction. Update
@@ -488,6 +491,7 @@ void NativeLayerRootCA::CommitRepresentation(
AutoCATransaction transaction;
NSMutableArray<CALayer*>* sublayers =
[NSMutableArray arrayWithCapacity:aSublayers.Length()];
+ bool mustRebuild = updateRequired == UpdateType::All;
for (const auto& layer : aSublayers) {
layer->ApplyChanges(aRepresentation, NativeLayerCA::UpdateType::All,
&mustRebuild);