commit 6894c9a01b6f174c9b746299177e3129208da478
parent 01c978484fed93dc0ae0178fab8c303b81c7e5a5
Author: Markus Stange <mstange.moz@gmail.com>
Date: Thu, 2 Oct 2025 20:49:12 +0000
Bug 1987007 - Add a SnapshotterCADelegate interface. r=bradwerth
Differential Revision: https://phabricator.services.mozilla.com/D267146
Diffstat:
2 files changed, 48 insertions(+), 20 deletions(-)
diff --git a/gfx/layers/NativeLayerCA.h b/gfx/layers/NativeLayerCA.h
@@ -43,9 +43,7 @@ class RenderMacIOSurfaceTextureHost;
namespace layers {
-#ifdef XP_MACOSX
class NativeLayerRootSnapshotterCA;
-#endif
enum class VideoLowPowerType {
// These must be kept synchronized with the telemetry histogram enums.
@@ -74,6 +72,16 @@ enum class NativeLayerCAUpdateType {
All,
};
+class SnapshotterCADelegate {
+ public:
+ virtual ~SnapshotterCADelegate();
+
+ virtual float BackingScale() const { return 1.0f; }
+ virtual void UpdateSnapshotterLayers(CALayer* aRootCALayer) = 0;
+ virtual void OnSnapshotterDestroyed(
+ NativeLayerRootSnapshotterCA* aSnapshotter) {}
+};
+
// 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
@@ -106,7 +114,7 @@ enum class NativeLayerCAUpdateType {
// effect. To solve this problem, we build two CALayer representations, so that
// one representation can stay inside the window and the other can stay attached
// to the CARenderer.
-class NativeLayerRootCA : public NativeLayerRoot {
+class NativeLayerRootCA final : public NativeLayerRoot {
public:
static already_AddRefed<NativeLayerRootCA> CreateForCALayer(CALayer* aLayer);
@@ -118,10 +126,8 @@ class NativeLayerRootCA : public NativeLayerRoot {
bool CommitToScreen() override;
void CommitOffscreen(CALayer* aRootCALayer);
-#ifdef XP_MACOSX
void OnNativeLayerRootSnapshotterDestroyed(
NativeLayerRootSnapshotterCA* aNativeLayerRootSnapshotter);
-#endif
// Enters a mode during which CommitToScreen(), when called on a non-main
// thread, will not apply any updates to the CALayer tree.
@@ -188,11 +194,26 @@ class NativeLayerRootCA : public NativeLayerRoot {
const nsTArray<RefPtr<NativeLayerCA>>& aSublayers,
bool aMutatedLayerStructure) const;
+ // An implementation of SnapshotterCADelegate, backed by a NativeLayerRootCA.
+ struct SnapshotterDelegate final : public SnapshotterCADelegate {
+ explicit SnapshotterDelegate(NativeLayerRootCA* aLayerRoot);
+ virtual ~SnapshotterDelegate() override;
+ virtual float BackingScale() const override {
+ return mLayerRoot->BackingScale();
+ }
+ virtual void UpdateSnapshotterLayers(CALayer* aRootCALayer) override {
+ mLayerRoot->CommitOffscreen(aRootCALayer);
+ }
+ virtual void OnSnapshotterDestroyed(
+ NativeLayerRootSnapshotterCA* aSnapshotter) override {
+ mLayerRoot->OnNativeLayerRootSnapshotterDestroyed(aSnapshotter);
+ }
+ RefPtr<NativeLayerRootCA> mLayerRoot;
+ };
+
Mutex mMutex MOZ_UNANNOTATED; // protects all other fields
CALayer* mOnscreenRootCALayer = nullptr; // strong
-#ifdef XP_MACOSX
NativeLayerRootSnapshotterCA* mWeakSnapshotter = nullptr;
-#endif
nsTArray<RefPtr<NativeLayerCA>> mSublayers; // in z-order
float mBackingScale = 1.0f;
bool mMutated = false;
@@ -228,7 +249,7 @@ class RenderSourceNLRS;
class NativeLayerRootSnapshotterCA final : public NativeLayerRootSnapshotter {
public:
static UniquePtr<NativeLayerRootSnapshotterCA> Create(
- NativeLayerRootCA* aLayerRoot);
+ UniquePtr<SnapshotterCADelegate>&& aDelegate);
virtual ~NativeLayerRootSnapshotterCA();
bool ReadbackPixels(const gfx::IntSize& aReadbackSize,
@@ -242,11 +263,11 @@ class NativeLayerRootSnapshotterCA final : public NativeLayerRootSnapshotter {
CreateAsyncReadbackBuffer(const gfx::IntSize& aSize) override;
protected:
- NativeLayerRootSnapshotterCA(NativeLayerRootCA* aLayerRoot,
+ NativeLayerRootSnapshotterCA(UniquePtr<SnapshotterCADelegate>&& aDelegate,
RefPtr<gl::GLContext>&& aGL);
void UpdateSnapshot(const gfx::IntSize& aSize);
- RefPtr<NativeLayerRootCA> mLayerRoot;
+ UniquePtr<SnapshotterCADelegate> mDelegate;
RefPtr<gl::GLContext> mGL;
// Can be null. Created and updated in UpdateSnapshot.
diff --git a/gfx/layers/NativeLayerCA.mm b/gfx/layers/NativeLayerCA.mm
@@ -382,7 +382,8 @@ UniquePtr<NativeLayerRootSnapshotter> NativeLayerRootCA::CreateSnapshotter() {
"No NativeLayerRootSnapshotter for this NativeLayerRoot "
"should exist when this is called");
- auto cr = NativeLayerRootSnapshotterCA::Create(this);
+ auto cr = NativeLayerRootSnapshotterCA::Create(
+ MakeUnique<SnapshotterDelegate>(this));
if (cr) {
mWeakSnapshotter = cr.get();
}
@@ -392,14 +393,12 @@ UniquePtr<NativeLayerRootSnapshotter> NativeLayerRootCA::CreateSnapshotter() {
#endif
}
-#ifdef XP_MACOSX
void NativeLayerRootCA::OnNativeLayerRootSnapshotterDestroyed(
NativeLayerRootSnapshotterCA* aNativeLayerRootSnapshotter) {
MutexAutoLock lock(mMutex);
MOZ_RELEASE_ASSERT(mWeakSnapshotter == aNativeLayerRootSnapshotter);
mWeakSnapshotter = nullptr;
}
-#endif
void NativeLayerRootCA::CommitOffscreen(CALayer* aRootCALayer) {
MutexAutoLock lock(mMutex);
@@ -478,9 +477,17 @@ void NativeLayerRootCA::CommitRepresentation(
}
}
+SnapshotterCADelegate::~SnapshotterCADelegate() = default;
+
+NativeLayerRootCA::SnapshotterDelegate::SnapshotterDelegate(
+ NativeLayerRootCA* aLayerRoot)
+ : mLayerRoot(aLayerRoot) {}
+NativeLayerRootCA::SnapshotterDelegate::~SnapshotterDelegate() = default;
+
#ifdef XP_MACOSX
/* static */ UniquePtr<NativeLayerRootSnapshotterCA>
-NativeLayerRootSnapshotterCA::Create(NativeLayerRootCA* aLayerRoot) {
+NativeLayerRootSnapshotterCA::Create(
+ UniquePtr<SnapshotterCADelegate>&& aDelegate) {
if (NS_IsMainThread()) {
// Disallow creating snapshotters on the main thread.
// On the main thread, any explicit CATransaction / NSAnimationContext is
@@ -501,7 +508,7 @@ NativeLayerRootSnapshotterCA::Create(NativeLayerRootCA* aLayerRoot) {
}
return UniquePtr<NativeLayerRootSnapshotterCA>(
- new NativeLayerRootSnapshotterCA(aLayerRoot, std::move(gl)));
+ new NativeLayerRootSnapshotterCA(std::move(aDelegate), std::move(gl)));
}
#endif
@@ -665,11 +672,11 @@ VideoLowPowerType NativeLayerRootCA::CheckVideoLowPower(
#ifdef XP_MACOSX
NativeLayerRootSnapshotterCA::NativeLayerRootSnapshotterCA(
- NativeLayerRootCA* aLayerRoot, RefPtr<GLContext>&& aGL)
- : mLayerRoot(aLayerRoot), mGL(aGL) {}
+ UniquePtr<SnapshotterCADelegate>&& aDelegate, RefPtr<GLContext>&& aGL)
+ : mDelegate(std::move(aDelegate)), mGL(aGL) {}
NativeLayerRootSnapshotterCA::~NativeLayerRootSnapshotterCA() {
- mLayerRoot->OnNativeLayerRootSnapshotterDestroyed(this);
+ mDelegate->OnSnapshotterDestroyed(this);
if (mRenderer) {
AutoCATransaction transaction;
@@ -720,12 +727,12 @@ void NativeLayerRootSnapshotterCA::UpdateSnapshot(const IntSize& aSize) {
// HiDPI. So in order to render at the full device pixel resolution, we set
// a scale transform on the root offscreen layer.
mRenderer.layer.bounds = bounds;
- float scale = mLayerRoot->BackingScale();
+ float scale = mDelegate->BackingScale();
mRenderer.layer.sublayerTransform = CATransform3DMakeScale(scale, scale, 1);
mRenderer.bounds = bounds;
}
- mLayerRoot->CommitOffscreen(mRenderer.layer);
+ mDelegate->UpdateSnapshotterLayers(mRenderer.layer);
mGL->MakeCurrent();