commit 8bffb8f28dadfe6a26ecc5ff99c0a9a9182dd774
parent 8f6791c0b7e3ed49e19577f3cb3c71badfe33e53
Author: Markus Stange <mstange.moz@gmail.com>
Date: Thu, 2 Oct 2025 20:49:14 +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
@@ -153,7 +153,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,