tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit ee2b31a7dbbf17c3bf786dfca7fb09720b767399
parent 5df96aec501cad8d3641d20f897c0d779f62ee77
Author: Markus Stange <mstange.moz@gmail.com>
Date:   Fri,  3 Oct 2025 12:45:27 +0000

Bug 1987007 - Use NativeLayerRootSnapshotterCA for NativeLayerRootRemoteMacChild. r=bradwerth

This makes profiler screenshots and the window recorder work correctly.

Differential Revision: https://phabricator.services.mozilla.com/D267149

Diffstat:
Mgfx/layers/NativeLayerRemoteMac.h | 7++++++-
Mgfx/layers/NativeLayerRemoteMac.mm | 37++++++++++++++++++++++++++++++++++++-
Mgfx/layers/NativeLayerRootRemoteMacChild.h | 22+++++++++++++++++++++-
Mgfx/layers/NativeLayerRootRemoteMacChild.mm | 41++++++++++++++++++++++++++++++++++++++---
4 files changed, 101 insertions(+), 6 deletions(-)

diff --git a/gfx/layers/NativeLayerRemoteMac.h b/gfx/layers/NativeLayerRemoteMac.h @@ -11,6 +11,7 @@ #include "mozilla/layers/NativeLayer.h" #include "mozilla/layers/NativeLayerCommandQueue.h" #include "mozilla/layers/NativeLayerMacSurfaceHandler.h" +#include "NativeLayerCA.h" #include "nsRegion.h" namespace mozilla { @@ -72,10 +73,14 @@ class NativeLayerRemoteMac final : public NativeLayer { // If dirty, add a CommandLayerInfo to the queue. Clear dirty flag. void FlushDirtyLayerInfoToCommandQueue(); + void UpdateSnapshotLayer(); + CALayer* CALayerForSnapshot(); + protected: + NativeLayerCARepresentation mSnapshotLayer; Maybe<NativeLayerMacSurfaceHandler> mSurfaceHandler; RefPtr<NativeLayerCommandQueue> mCommandQueue; - const gfx::DeviceColor mColor; + const Maybe<gfx::DeviceColor> mColor; const bool mIsOpaque = false; bool mDirtyLayerInfo = true; diff --git a/gfx/layers/NativeLayerRemoteMac.mm b/gfx/layers/NativeLayerRemoteMac.mm @@ -8,6 +8,7 @@ #include <algorithm> #include <utility> +#include "CFTypeRefPtr.h" #include "gfxUtils.h" #include "GLBlitHelper.h" #ifdef XP_MACOSX @@ -20,6 +21,7 @@ #include "mozilla/gfx/Swizzle.h" #include "mozilla/glean/GfxMetrics.h" #include "mozilla/webrender/RenderMacIOSurfaceTextureHost.h" +#include "NativeLayerCA.h" #include "ScopedGLHelpers.h" namespace mozilla { @@ -43,7 +45,7 @@ NativeLayerRemoteMac::NativeLayerRemoteMac(bool aIsOpaque) : mIsOpaque(aIsOpaque) {} NativeLayerRemoteMac::NativeLayerRemoteMac(gfx::DeviceColor aColor) - : mColor(aColor), mIsOpaque(aColor.a >= 1.0f) {} + : mColor(Some(aColor)), mIsOpaque(aColor.a >= 1.0f) {} NativeLayerRemoteMac::~NativeLayerRemoteMac() { if (mCommandQueue) { @@ -72,6 +74,7 @@ void NativeLayerRemoteMac::AttachExternalImage( mDisplayRect = displayRect; bool isDRM = aExternalImage->IsFromDRMSource(); + bool changedIsDRM = mIsDRM != isDRM; mIsDRM = isDRM; bool isHDR = false; @@ -88,6 +91,10 @@ void NativeLayerRemoteMac::AttachExternalImage( mIsHDR = isHDR; mDirtyLayerInfo |= changedDisplayRect; + mSnapshotLayer.mMutatedFrontSurface = true; + mSnapshotLayer.mMutatedSize |= changedDisplayRect; + mSnapshotLayer.mMutatedDisplayRect |= changedDisplayRect; + mSnapshotLayer.mMutatedIsDRM |= changedIsDRM; mDirtyChangedSurface = true; } @@ -103,6 +110,7 @@ IntSize NativeLayerRemoteMac::GetSize() { void NativeLayerRemoteMac::SetPosition(const IntPoint& aPosition) { if (mPosition != aPosition) { mDirtyLayerInfo = true; + mSnapshotLayer.mMutatedPosition = true; mPosition = aPosition; } } @@ -114,6 +122,7 @@ void NativeLayerRemoteMac::SetTransform(const Matrix4x4& aTransform) { if (mTransform != aTransform) { mDirtyLayerInfo = true; + mSnapshotLayer.mMutatedTransform = true; mTransform = aTransform; } } @@ -122,6 +131,7 @@ void NativeLayerRemoteMac::SetSamplingFilter( gfx::SamplingFilter aSamplingFilter) { if (mSamplingFilter != aSamplingFilter) { mDirtyLayerInfo = true; + mSnapshotLayer.mMutatedSamplingFilter = true; mSamplingFilter = aSamplingFilter; } } @@ -155,6 +165,7 @@ void NativeLayerRemoteMac::SetRoundedClipRect( const Maybe<gfx::RoundedRect>& aRoundedClipRect) { if (mRoundedClipRect != aRoundedClipRect) { mDirtyLayerInfo = true; + mSnapshotLayer.mMutatedRoundedClipRect = true; mRoundedClipRect = aRoundedClipRect; } } @@ -173,6 +184,7 @@ gfx::IntRect NativeLayerRemoteMac::CurrentSurfaceDisplayRect() { void NativeLayerRemoteMac::SetSurfaceIsFlipped(bool aIsFlipped) { if (SurfaceIsFlipped() != aIsFlipped) { mDirtyLayerInfo = true; + mSnapshotLayer.mMutatedSurfaceIsFlipped = true; if (mSurfaceHandler) { mSurfaceHandler->SetSurfaceIsFlipped(aIsFlipped); } else { @@ -223,6 +235,7 @@ void NativeLayerRemoteMac::NotifySurfaceReady() { bool changedDisplayRect = mSurfaceHandler->NotifySurfaceReady(); mDirtyLayerInfo |= changedDisplayRect; mDirtyChangedSurface = true; + mSnapshotLayer.mMutatedFrontSurface = true; } void NativeLayerRemoteMac::DiscardBackbuffers() { @@ -258,5 +271,27 @@ void NativeLayerRemoteMac::FlushDirtyLayerInfoToCommandQueue() { } } +void NativeLayerRemoteMac::UpdateSnapshotLayer() { + CFTypeRefPtr<IOSurfaceRef> surface; + if (auto frontSurface = FrontSurface()) { + surface = frontSurface->mSurface; + } + + IntRect rect = GetRect(); + IntRect displayRect = CurrentSurfaceDisplayRect(); + + bool specializeVideo = false; + bool isVideo = false; + mSnapshotLayer.ApplyChanges( + NativeLayerCAUpdateType::All, rect.Size(), mIsOpaque, rect.TopLeft(), + mTransform, displayRect, mClipRect, mRoundedClipRect, mBackingScale, + mSurfaceIsFlipped, mSamplingFilter, specializeVideo, surface, mColor, + mIsDRM, isVideo); +} + +CALayer* NativeLayerRemoteMac::CALayerForSnapshot() { + return mSnapshotLayer.UnderlyingCALayer(); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/NativeLayerRootRemoteMacChild.h b/gfx/layers/NativeLayerRootRemoteMacChild.h @@ -47,12 +47,32 @@ class NativeLayerRootRemoteMacChild final : public NativeLayerRoot { virtual ~NativeLayerRootRemoteMacChild(); + void CommitForSnapshot(CALayer* aRootCALayer); + void OnNativeLayerRootSnapshotterDestroyed( + NativeLayerRootSnapshotterCA* aNativeLayerRootSnapshotter); + + // An implementation of SnapshotterCADelegate, backed by a + // NativeLayerRootRemoteMacChild. + struct SnapshotterDelegate final : public SnapshotterCADelegate { + explicit SnapshotterDelegate(NativeLayerRootRemoteMacChild* aLayerRoot); + virtual ~SnapshotterDelegate() override; + virtual void UpdateSnapshotterLayers(CALayer* aRootCALayer) override { + mLayerRoot->CommitForSnapshot(aRootCALayer); + } + virtual void OnSnapshotterDestroyed( + NativeLayerRootSnapshotterCA* aSnapshotter) override { + mLayerRoot->OnNativeLayerRootSnapshotterDestroyed(aSnapshotter); + } + RefPtr<NativeLayerRootRemoteMacChild> mLayerRoot; + }; + RefPtr<NativeLayerRemoteChild> mRemoteChild; RefPtr<NativeLayerCommandQueue> mCommandQueue; nsTArray<RefPtr<NativeLayerRemoteMac>> mNativeLayers; - NativeLayerRootSnapshotter* mWeakSnapshotter = nullptr; + NativeLayerRootSnapshotterCA* mWeakSnapshotter = nullptr; bool mNativeLayersChanged = false; + bool mNativeLayersChangedForSnapshot = false; bool ReadbackPixels(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, const Range<uint8_t>& aBuffer); diff --git a/gfx/layers/NativeLayerRootRemoteMacChild.mm b/gfx/layers/NativeLayerRootRemoteMacChild.mm @@ -5,7 +5,6 @@ #include "mozilla/layers/NativeLayerRemoteMac.h" #include "mozilla/layers/NativeLayerRootRemoteMacChild.h" -#include "mozilla/layers/NativeLayerRootRemoteMacSnapshotter.h" #include "mozilla/layers/SurfacePool.h" namespace mozilla { @@ -66,21 +65,32 @@ void NativeLayerRootRemoteMacChild::SetLayers( } mNativeLayersChanged = true; + mNativeLayersChangedForSnapshot = true; mNativeLayers.Clear(); mNativeLayers.AppendElements(layers); } UniquePtr<NativeLayerRootSnapshotter> NativeLayerRootRemoteMacChild::CreateSnapshotter() { +#ifdef XP_MACOSX MOZ_RELEASE_ASSERT(!mWeakSnapshotter, "No NativeLayerRootSnapshotter for this NativeLayerRoot " "should exist when this is called"); - - auto cr = NativeLayerRootRemoteMacSnapshotter::Create(this); + auto cr = NativeLayerRootSnapshotterCA::Create( + MakeUnique<SnapshotterDelegate>(this)); if (cr) { mWeakSnapshotter = cr.get(); } return cr; +#else + return nullptr; +#endif +} + +void NativeLayerRootRemoteMacChild::OnNativeLayerRootSnapshotterDestroyed( + NativeLayerRootSnapshotterCA* aNativeLayerRootSnapshotter) { + MOZ_RELEASE_ASSERT(mWeakSnapshotter == aNativeLayerRootSnapshotter); + mWeakSnapshotter = nullptr; } void NativeLayerRootRemoteMacChild::PrepareForCommit() { @@ -127,6 +137,25 @@ bool NativeLayerRootRemoteMacChild::CommitToScreen() { return true; } +void NativeLayerRootRemoteMacChild::CommitForSnapshot(CALayer* aRootCALayer) { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; // disable cross-fade + + NSMutableArray<CALayer*>* sublayers = + [NSMutableArray arrayWithCapacity:mNativeLayers.Length()]; + for (const auto& layer : mNativeLayers) { + layer->UpdateSnapshotLayer(); + if (CALayer* caLayer = layer->CALayerForSnapshot()) { + [sublayers addObject:caLayer]; + } + } + + aRootCALayer.sublayers = sublayers; + [CATransaction commit]; + + mNativeLayersChangedForSnapshot = false; +} + bool NativeLayerRootRemoteMacChild::ReadbackPixels( const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, const Range<uint8_t>& aBuffer) { @@ -160,5 +189,11 @@ NativeLayerRootRemoteMacChild::NativeLayerRootRemoteMacChild() NativeLayerRootRemoteMacChild::~NativeLayerRootRemoteMacChild() {} +NativeLayerRootRemoteMacChild::SnapshotterDelegate::SnapshotterDelegate( + NativeLayerRootRemoteMacChild* aLayerRoot) + : mLayerRoot(aLayerRoot) {} +NativeLayerRootRemoteMacChild::SnapshotterDelegate::~SnapshotterDelegate() = + default; + } // namespace layers } // namespace mozilla