commit bf3b8d787faaf12a0574ec578f0ae5316d70a2cc
parent 0791aef2a884dec744601ac73fa33f365a8a19f3
Author: Markus Stange <mstange.moz@gmail.com>
Date: Fri, 3 Oct 2025 12:45:28 +0000
Bug 1987007 - Keep doing reftest snapshots in the parent, even though we can now do them in the GPU process. r=bradwerth
Asking the parent lets us detect bugs in the cross-process synchronization of
the layer trees.
Differential Revision: https://phabricator.services.mozilla.com/D267279
Diffstat:
4 files changed, 35 insertions(+), 3 deletions(-)
diff --git a/gfx/layers/NativeLayerCA.h b/gfx/layers/NativeLayerCA.h
@@ -77,6 +77,11 @@ class SnapshotterCADelegate {
virtual ~SnapshotterCADelegate();
virtual float BackingScale() const { return 1.0f; }
+ virtual bool DoCustomReadbackForReftestsIfDesired(
+ const gfx::IntSize& aReadbackSize, gfx::SurfaceFormat aReadbackFormat,
+ const Range<uint8_t>& aReadbackBuffer) {
+ return false;
+ }
virtual void UpdateSnapshotterLayers(CALayer* aRootCALayer) = 0;
virtual void OnSnapshotterDestroyed(
NativeLayerRootSnapshotterCA* aSnapshotter) {}
diff --git a/gfx/layers/NativeLayerCA.mm b/gfx/layers/NativeLayerCA.mm
@@ -790,6 +790,11 @@ void NativeLayerRootSnapshotterCA::UpdateSnapshot(const IntSize& aSize) {
bool NativeLayerRootSnapshotterCA::ReadbackPixels(
const IntSize& aReadbackSize, SurfaceFormat aReadbackFormat,
const Range<uint8_t>& aReadbackBuffer) {
+ if (mDelegate->DoCustomReadbackForReftestsIfDesired(
+ aReadbackSize, aReadbackFormat, aReadbackBuffer)) {
+ return true;
+ }
+
if (aReadbackFormat != SurfaceFormat::B8G8R8A8) {
return false;
}
diff --git a/gfx/layers/NativeLayerRootRemoteMacChild.h b/gfx/layers/NativeLayerRootRemoteMacChild.h
@@ -59,6 +59,12 @@ class NativeLayerRootRemoteMacChild final : public NativeLayerRoot {
virtual void UpdateSnapshotterLayers(CALayer* aRootCALayer) override {
mLayerRoot->CommitForSnapshot(aRootCALayer);
}
+ virtual bool DoCustomReadbackForReftestsIfDesired(
+ const gfx::IntSize& aReadbackSize, gfx::SurfaceFormat aReadbackFormat,
+ const Range<uint8_t>& aReadbackBuffer) override {
+ return mLayerRoot->ReadbackPixelsFromParent(
+ aReadbackSize, aReadbackFormat, aReadbackBuffer);
+ }
virtual void OnSnapshotterDestroyed(
NativeLayerRootSnapshotterCA* aSnapshotter) override {
mLayerRoot->OnNativeLayerRootSnapshotterDestroyed(aSnapshotter);
@@ -74,8 +80,24 @@ class NativeLayerRootRemoteMacChild final : public NativeLayerRoot {
bool mNativeLayersChanged = false;
bool mNativeLayersChangedForSnapshot = false;
- bool ReadbackPixels(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat,
- const Range<uint8_t>& aBuffer);
+ // Send a sync message to the parent to get the window pixels.
+ // Used for reftests.
+ //
+ // This is different from what we do for "window recorder" and
+ // "profiler screenshot" snapshotting, where we do the snapshotting
+ // within the GPU process, using CARenderer on a CALayer tree we
+ // construct within the GPU process.
+ //
+ // Here's why we have two different snapshotting paths:
+ // - Profiler screenshots and window recording care about minimal overhead
+ // and need to minimize blocking on the GPU.
+ // - Reftests care about catching bugs, and don't need maximum performance.
+ // By doing the readback in the parent, we can catch more bugs, for
+ // example bugs in the IPC serialization of layer updates and how those
+ // updates are applied on the parent side.
+ bool ReadbackPixelsFromParent(const gfx::IntSize& aSize,
+ gfx::SurfaceFormat aFormat,
+ const Range<uint8_t>& aBuffer);
};
} // namespace layers
diff --git a/gfx/layers/NativeLayerRootRemoteMacChild.mm b/gfx/layers/NativeLayerRootRemoteMacChild.mm
@@ -156,7 +156,7 @@ void NativeLayerRootRemoteMacChild::CommitForSnapshot(CALayer* aRootCALayer) {
mNativeLayersChangedForSnapshot = false;
}
-bool NativeLayerRootRemoteMacChild::ReadbackPixels(
+bool NativeLayerRootRemoteMacChild::ReadbackPixelsFromParent(
const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat,
const Range<uint8_t>& aBuffer) {
// In this process we only have the pixels of the individual layers,