Bug 1741767: Use shared memory surfaces in Canvas 2D recording. r=lsalzman
authorBob Owen <bobowencode@gmail.com>
Sat, 15 Jan 2022 05:17:21 +0000
changeset 604617 1f75710950a23a5c7141b8efa046c70dc6d8ba41
parent 604616 22212426ae629188a63a2a689a7056fa97650e5f
child 604618 a1cc440f0d9517edf08eb991a908f27616982f52
push id39152
push userabutkovits@mozilla.com
push dateSat, 15 Jan 2022 09:45:36 +0000
treeherdermozilla-central@60998033086a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1741767
milestone98.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1741767: Use shared memory surfaces in Canvas 2D recording. r=lsalzman This also changes SharedSurfacesParent to use a StaticMonitor, so that we can wait for the surface to be added. Differential Revision: https://phabricator.services.mozilla.com/D132703
gfx/layers/CanvasDrawEventRecorder.cpp
gfx/layers/CanvasDrawEventRecorder.h
gfx/layers/ipc/CanvasChild.cpp
gfx/layers/ipc/CanvasChild.h
gfx/layers/ipc/CanvasTranslator.cpp
gfx/layers/ipc/CanvasTranslator.h
gfx/layers/ipc/SharedSurfacesParent.cpp
gfx/layers/ipc/SharedSurfacesParent.h
--- a/gfx/layers/CanvasDrawEventRecorder.cpp
+++ b/gfx/layers/CanvasDrawEventRecorder.cpp
@@ -3,16 +3,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "CanvasDrawEventRecorder.h"
 
 #include <string.h>
 
+#include "mozilla/layers/SharedSurfacesChild.h"
 #include "nsThreadUtils.h"
 
 namespace mozilla {
 namespace layers {
 
 static const int32_t kCheckpointEventType = -1;
 static const uint32_t kMaxSpinCount = 200;
 
@@ -496,16 +497,28 @@ void CanvasEventRingBuffer::ReturnRead(c
     availableToRead = std::min(bufRemaining, (mRead->returnCount - readCount));
   }
 
   memcpy(aOut, mBuf + bufPos, aSize);
   readCount += aSize;
   mWrite->returnCount = readCount;
 }
 
+void CanvasDrawEventRecorder::StoreSourceSurfaceRecording(
+    gfx::SourceSurface* aSurface, const char* aReason) {
+  wr::ExternalImageId extId{};
+  nsresult rv = layers::SharedSurfacesChild::Share(aSurface, extId);
+  if (NS_FAILED(rv)) {
+    DrawEventRecorderPrivate::StoreSourceSurfaceRecording(aSurface, aReason);
+    return;
+  }
+
+  StoreExternalSurfaceRecording(aSurface, wr::AsUint64(extId));
+}
+
 void CanvasDrawEventRecorder::RecordSourceSurfaceDestruction(void* aSurface) {
   // We must only record things on the main thread and surfaces that have been
   // recorded can sometimes be destroyed off the main thread.
   if (NS_IsMainThread()) {
     DrawEventRecorderPrivate::RecordSourceSurfaceDestruction(aSurface);
     return;
   }
 
--- a/gfx/layers/CanvasDrawEventRecorder.h
+++ b/gfx/layers/CanvasDrawEventRecorder.h
@@ -248,16 +248,19 @@ class CanvasDrawEventRecorder final : pu
   void RecordEvent(const gfx::RecordedEvent& aEvent) final {
     if (!mOutputStream.good()) {
       return;
     }
 
     aEvent.RecordToStream(mOutputStream);
   }
 
+  void StoreSourceSurfaceRecording(gfx::SourceSurface* aSurface,
+                                   const char* aReason) final;
+
   void RecordSourceSurfaceDestruction(void* aSurface) final;
 
   void Flush() final {}
 
   void ReturnRead(char* aOut, size_t aSize) {
     mOutputStream.ReturnRead(aOut, aSize);
   }
 
--- a/gfx/layers/ipc/CanvasChild.cpp
+++ b/gfx/layers/ipc/CanvasChild.cpp
@@ -195,16 +195,23 @@ void CanvasChild::OnTextureForwarded() {
   if (mHasOutstandingWriteLock) {
     mRecorder->RecordEvent(RecordedCanvasFlush());
     if (!mRecorder->WaitForCheckpoint(mLastWriteLockCheckpoint)) {
       gfxWarning() << "Timed out waiting for last write lock to be processed.";
     }
 
     mHasOutstandingWriteLock = false;
   }
+
+  // We hold onto the last transaction's external surfaces until we have waited
+  // for the write locks in this transaction. This means we know that the
+  // surfaces have been picked up in the canvas threads and there is no race
+  // with them being removed from SharedSurfacesParent. Note this releases the
+  // current contents of mLastTransactionExternalSurfaces.
+  mRecorder->TakeExternalSurfaces(mLastTransactionExternalSurfaces);
 }
 
 void CanvasChild::EnsureBeginTransaction() {
   // We drop mRecorder in ActorDestroy to break the reference cycle.
   if (!mRecorder) {
     return;
   }
 
--- a/gfx/layers/ipc/CanvasChild.h
+++ b/gfx/layers/ipc/CanvasChild.h
@@ -136,16 +136,17 @@ class CanvasChild final : public PCanvas
 
   static bool mDeactivated;
 
   RefPtr<CanvasDrawEventRecorder> mRecorder;
   TextureType mTextureType = TextureType::Unknown;
   uint32_t mLastWriteLockCheckpoint = 0;
   uint32_t mTransactionsSinceGetDataSurface = kCacheDataSurfaceThreshold;
   TimeStamp mLastNonEmptyTransaction = TimeStamp::NowLoRes();
+  std::vector<RefPtr<gfx::SourceSurface>> mLastTransactionExternalSurfaces;
   bool mIsInTransaction = false;
   bool mHasOutstandingWriteLock = false;
 };
 
 }  // namespace layers
 }  // namespace mozilla
 
 #endif  // mozilla_layers_CanvasChild_h
--- a/gfx/layers/ipc/CanvasTranslator.cpp
+++ b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -6,16 +6,17 @@
 
 #include "CanvasTranslator.h"
 
 #include "gfxGradientCache.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/GPUParent.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/ipc/Endpoint.h"
+#include "mozilla/layers/SharedSurfacesParent.h"
 #include "mozilla/layers/TextureClient.h"
 #include "mozilla/SyncRunnable.h"
 #include "mozilla/Telemetry.h"
 #include "nsTHashSet.h"
 #include "RecordedCanvasEventImpl.h"
 
 #if defined(XP_WIN)
 #  include "mozilla/gfx/DeviceManagerDx.h"
@@ -497,16 +498,21 @@ UniquePtr<SurfaceDescriptor> CanvasTrans
     }
   }
 
   UniquePtr<SurfaceDescriptor> descriptor = std::move(result->second);
   mSurfaceDescriptors.erase(aTextureId);
   return descriptor;
 }
 
+already_AddRefed<gfx::SourceSurface> CanvasTranslator::LookupExternalSurface(
+    uint64_t aKey) {
+  return SharedSurfacesParent::Get(wr::ToExternalImageId(aKey));
+}
+
 already_AddRefed<gfx::GradientStops> CanvasTranslator::GetOrCreateGradientStops(
     gfx::GradientStop* aRawStops, uint32_t aNumStops,
     gfx::ExtendMode aExtendMode) {
   nsTArray<gfx::GradientStop> rawStopArray(aRawStops, aNumStops);
   RefPtr<DrawTarget> drawTarget = GetReferenceDrawTarget();
   if (!drawTarget) {
     // We might end up with a null reference draw target due to a device
     // failure, just return false so that we can recover.
--- a/gfx/layers/ipc/CanvasTranslator.h
+++ b/gfx/layers/ipc/CanvasTranslator.h
@@ -170,16 +170,19 @@ class CanvasTranslator final : public gf
    *
    * @param aRefPtr the key to the objects to remove
    */
   void RemoveSourceSurface(gfx::ReferencePtr aRefPtr) final {
     RemoveDataSurface(aRefPtr);
     InlineTranslator::RemoveSourceSurface(aRefPtr);
   }
 
+  already_AddRefed<gfx::SourceSurface> LookupExternalSurface(
+      uint64_t aKey) final;
+
   /**
    * Gets the cached DataSourceSurface, if it exists, associated with a
    * SourceSurface from another process.
    *
    * @param aRefPtr the key used to find the DataSourceSurface
    * @returns the DataSourceSurface or nullptr if not found
    */
   gfx::DataSourceSurface* LookupDataSurface(gfx::ReferencePtr aRefPtr);
--- a/gfx/layers/ipc/SharedSurfacesParent.cpp
+++ b/gfx/layers/ipc/SharedSurfacesParent.cpp
@@ -17,62 +17,66 @@
 #include "mozilla/webrender/RenderThread.h"
 #include "nsThreadUtils.h"  // for GetCurrentEventTarget
 
 namespace mozilla {
 namespace layers {
 
 using namespace mozilla::gfx;
 
-StaticMutex SharedSurfacesParent::sMutex;
+StaticMonitor SharedSurfacesParent::sMonitor;
 StaticAutoPtr<SharedSurfacesParent> SharedSurfacesParent::sInstance;
 
+// Short wait to allow for a surface to be added, where the consumer has a
+// different thread route.
+static const TimeDuration kGetTimeout = TimeDuration::FromMilliseconds(50);
+
 void SharedSurfacesParent::MappingTracker::NotifyExpiredLocked(
     SourceSurfaceSharedDataWrapper* aSurface,
-    const StaticMutexAutoLock& aAutoLock) {
+    const StaticMonitorAutoLock& aAutoLock) {
   RemoveObjectLocked(aSurface, aAutoLock);
   mExpired.AppendElement(aSurface);
 }
 
 void SharedSurfacesParent::MappingTracker::TakeExpired(
     nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>>& aExpired,
-    const StaticMutexAutoLock& aAutoLock) {
+    const StaticMonitorAutoLock& aAutoLock) {
   aExpired = std::move(mExpired);
 }
 
 void SharedSurfacesParent::MappingTracker::NotifyHandlerEnd() {
   nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>> expired;
   {
-    StaticMutexAutoLock lock(sMutex);
+    StaticMonitorAutoLock lock(sMonitor);
     TakeExpired(expired, lock);
   }
 
   SharedSurfacesParent::ExpireMap(expired);
 }
 
 SharedSurfacesParent::SharedSurfacesParent()
     : mTracker(
           StaticPrefs::image_mem_shared_unmap_min_expiration_ms_AtStartup(),
           mozilla::GetCurrentEventTarget()) {}
 
 /* static */
 void SharedSurfacesParent::Initialize() {
   MOZ_ASSERT(NS_IsMainThread());
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     sInstance = new SharedSurfacesParent();
   }
 }
 
 /* static */
 void SharedSurfacesParent::ShutdownRenderThread() {
   // The main thread should blocked on waiting for the render thread to
   // complete so this should be safe to release off the main thread.
   MOZ_ASSERT(wr::RenderThread::IsInRenderThread());
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   MOZ_ASSERT(sInstance);
 
   for (const auto& key : sInstance->mSurfaces.Keys()) {
     // There may be lingering consumers of the surfaces that didn't get shutdown
     // yet but since we are here, we know the render thread is finished and we
     // can unregister everything.
     wr::RenderThread::Get()->UnregisterExternalImageDuringShutdown(
         wr::ToExternalImageId(key));
@@ -80,38 +84,44 @@ void SharedSurfacesParent::ShutdownRende
 }
 
 /* static */
 void SharedSurfacesParent::Shutdown() {
   // The compositor thread and render threads are shutdown, so this is the last
   // thread that could use it. The expiration tracker needs to be freed on the
   // main thread.
   MOZ_ASSERT(NS_IsMainThread());
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   sInstance = nullptr;
 }
 
 /* static */
 already_AddRefed<DataSourceSurface> SharedSurfacesParent::Get(
     const wr::ExternalImageId& aId) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     gfxCriticalNote << "SSP:Get " << wr::AsUint64(aId) << " shtd";
     return nullptr;
   }
 
   RefPtr<SourceSurfaceSharedDataWrapper> surface;
-  sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface));
+  while (
+      !sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface))) {
+    CVStatus status = lock.Wait(kGetTimeout);
+    if (status == CVStatus::Timeout) {
+      return nullptr;
+    }
+  }
   return surface.forget();
 }
 
 /* static */
 already_AddRefed<DataSourceSurface> SharedSurfacesParent::Acquire(
     const wr::ExternalImageId& aId) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     gfxCriticalNote << "SSP:Acq " << wr::AsUint64(aId) << " shtd";
     return nullptr;
   }
 
   RefPtr<SourceSurfaceSharedDataWrapper> surface;
   sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface));
 
@@ -120,17 +130,17 @@ already_AddRefed<DataSourceSurface> Shar
     MOZ_ASSERT(!rv);
   }
   return surface.forget();
 }
 
 /* static */
 bool SharedSurfacesParent::Release(const wr::ExternalImageId& aId,
                                    bool aForCreator) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return false;
   }
 
   uint64_t id = wr::AsUint64(aId);
   RefPtr<SourceSurfaceSharedDataWrapper> surface;
   sInstance->mSurfaces.Get(wr::AsUint64(aId), getter_AddRefs(surface));
   if (!surface) {
@@ -146,17 +156,17 @@ bool SharedSurfacesParent::Release(const
   return true;
 }
 
 /* static */
 void SharedSurfacesParent::AddSameProcess(const wr::ExternalImageId& aId,
                                           SourceSurfaceSharedData* aSurface) {
   MOZ_ASSERT(XRE_IsParentProcess());
   MOZ_ASSERT(NS_IsMainThread());
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     gfxCriticalNote << "SSP:Ads " << wr::AsUint64(aId) << " shtd";
     return;
   }
 
   // If the child bridge detects it is in the combined UI/GPU process, then it
   // will insert a wrapper surface holding the shared memory buffer directly.
   // This is good because we avoid mapping the same shared memory twice, but
@@ -169,21 +179,22 @@ void SharedSurfacesParent::AddSameProces
   uint64_t id = wr::AsUint64(aId);
   MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
 
   auto texture = MakeRefPtr<wr::RenderSharedSurfaceTextureHost>(surface);
   wr::RenderThread::Get()->RegisterExternalImage(aId, texture.forget());
 
   surface->AddConsumer();
   sInstance->mSurfaces.InsertOrUpdate(id, std::move(surface));
+  lock.NotifyAll();
 }
 
 /* static */
 void SharedSurfacesParent::DestroyProcess(base::ProcessId aPid) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return;
   }
 
   // Note that the destruction of a parent may not be cheap if it still has a
   // lot of surfaces still bound that require unmapping.
   for (auto i = sInstance->mSurfaces.Iter(); !i.Done(); i.Next()) {
     SourceSurfaceSharedDataWrapper* surface = i.Data();
@@ -212,96 +223,97 @@ void SharedSurfacesParent::Add(const wr:
   // will ensure we add the surface to the expiration tracker. We do it outside
   // the mutex to ensure we always lock the surface mutex first, and our mutex
   // second, to avoid deadlock.
   //
   // Note that the surface wrapper maps in the given handle as read only.
   surface->Init(aDesc.size(), aDesc.stride(), aDesc.format(),
                 std::move(aDesc.handle()), aPid);
 
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     gfxCriticalNote << "SSP:Add " << wr::AsUint64(aId) << " shtd";
     return;
   }
 
   uint64_t id = wr::AsUint64(aId);
   MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
 
   auto texture = MakeRefPtr<wr::RenderSharedSurfaceTextureHost>(surface);
   wr::RenderThread::Get()->RegisterExternalImage(aId, texture.forget());
 
   surface->AddConsumer();
   sInstance->mSurfaces.InsertOrUpdate(id, std::move(surface));
+  lock.NotifyAll();
 }
 
 /* static */
 void SharedSurfacesParent::Remove(const wr::ExternalImageId& aId) {
   DebugOnly<bool> rv = Release(aId, /* aForCreator */ true);
   MOZ_ASSERT(rv);
 }
 
 /* static */
 void SharedSurfacesParent::AddTrackingLocked(
     SourceSurfaceSharedDataWrapper* aSurface,
-    const StaticMutexAutoLock& aAutoLock) {
+    const StaticMonitorAutoLock& aAutoLock) {
   MOZ_ASSERT(!aSurface->GetExpirationState()->IsTracked());
   sInstance->mTracker.AddObjectLocked(aSurface, aAutoLock);
 }
 
 /* static */
 void SharedSurfacesParent::AddTracking(
     SourceSurfaceSharedDataWrapper* aSurface) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return;
   }
 
   AddTrackingLocked(aSurface, lock);
 }
 
 /* static */
 void SharedSurfacesParent::RemoveTrackingLocked(
     SourceSurfaceSharedDataWrapper* aSurface,
-    const StaticMutexAutoLock& aAutoLock) {
+    const StaticMonitorAutoLock& aAutoLock) {
   if (!aSurface->GetExpirationState()->IsTracked()) {
     return;
   }
 
   sInstance->mTracker.RemoveObjectLocked(aSurface, aAutoLock);
 }
 
 /* static */
 void SharedSurfacesParent::RemoveTracking(
     SourceSurfaceSharedDataWrapper* aSurface) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return;
   }
 
   RemoveTrackingLocked(aSurface, lock);
 }
 
 /* static */
 bool SharedSurfacesParent::AgeOneGenerationLocked(
     nsTArray<RefPtr<SourceSurfaceSharedDataWrapper>>& aExpired,
-    const StaticMutexAutoLock& aAutoLock) {
+    const StaticMonitorAutoLock& aAutoLock) {
   if (sInstance->mTracker.IsEmptyLocked(aAutoLock)) {
     return false;
   }
 
   sInstance->mTracker.AgeOneGenerationLocked(aAutoLock);
   sInstance->mTracker.TakeExpired(aExpired, aAutoLock);
   return true;
 }
 
 /* static */
 bool SharedSurfacesParent::AgeOneGeneration(
     nsTArray<RefPtr<SourceSurfaceSharedDataWrapper>>& aExpired) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return false;
   }
 
   return AgeOneGenerationLocked(aExpired, lock);
 }
 
 /* static */
@@ -318,17 +330,17 @@ void SharedSurfacesParent::ExpireMap(
   for (auto& surface : aExpired) {
     surface->ExpireMap();
   }
 }
 
 /* static */
 void SharedSurfacesParent::AccumulateMemoryReport(
     base::ProcessId aPid, SharedSurfacesMemoryReport& aReport) {
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return;
   }
 
   for (const auto& entry : sInstance->mSurfaces) {
     SourceSurfaceSharedDataWrapper* surface = entry.GetData();
     if (surface->GetCreatorPid() == aPid) {
       aReport.mSurfaces.insert(std::make_pair(
@@ -347,17 +359,17 @@ bool SharedSurfacesParent::AccumulateMem
     GPUProcessManager* gpm = GPUProcessManager::Get();
     if (!gpm || gpm->GPUProcessPid() != -1) {
       return false;
     }
   } else if (!XRE_IsGPUProcess()) {
     return false;
   }
 
-  StaticMutexAutoLock lock(sMutex);
+  StaticMonitorAutoLock lock(sMonitor);
   if (!sInstance) {
     return true;
   }
 
   for (const auto& entry : sInstance->mSurfaces) {
     SourceSurfaceSharedDataWrapper* surface = entry.GetData();
     aReport.mSurfaces.insert(std::make_pair(
         entry.GetKey(),
--- a/gfx/layers/ipc/SharedSurfacesParent.h
+++ b/gfx/layers/ipc/SharedSurfacesParent.h
@@ -4,17 +4,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef MOZILLA_GFX_SHAREDSURFACESPARENT_H
 #define MOZILLA_GFX_SHAREDSURFACESPARENT_H
 
 #include <stdint.h>                         // for uint32_t
 #include "mozilla/Attributes.h"             // for override
-#include "mozilla/StaticMutex.h"            // for StaticMutex
+#include "mozilla/StaticMonitor.h"          // for StaticMutex
 #include "mozilla/StaticPtr.h"              // for StaticAutoPtr
 #include "mozilla/RefPtr.h"                 // for already_AddRefed
 #include "mozilla/ipc/SharedMemory.h"       // for SharedMemory, etc
 #include "mozilla/gfx/2D.h"                 // for SurfaceFormat
 #include "mozilla/gfx/Point.h"              // for IntSize
 #include "mozilla/layers/LayersSurfaces.h"  // for SurfaceDescriptorShared
 #include "mozilla/layers/SourceSurfaceSharedData.h"
 #include "mozilla/webrender/WebRenderTypes.h"  // for wr::ExternalImageId
@@ -73,60 +73,60 @@ class SharedSurfacesParent final {
   friend class gfx::SourceSurfaceSharedDataWrapper;
 
   SharedSurfacesParent();
 
   static void AddSameProcess(const wr::ExternalImageId& aId,
                              gfx::SourceSurfaceSharedData* aSurface);
 
   static void AddTrackingLocked(gfx::SourceSurfaceSharedDataWrapper* aSurface,
-                                const StaticMutexAutoLock& aAutoLock);
+                                const StaticMonitorAutoLock& aAutoLock);
 
   static void RemoveTrackingLocked(
       gfx::SourceSurfaceSharedDataWrapper* aSurface,
-      const StaticMutexAutoLock& aAutoLock);
+      const StaticMonitorAutoLock& aAutoLock);
 
   static bool AgeOneGenerationLocked(
       nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>>& aExpired,
-      const StaticMutexAutoLock& aAutoLock);
+      const StaticMonitorAutoLock& aAutoLock);
 
   static void ExpireMap(
       nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>>& aExpired);
 
-  static StaticMutex sMutex;
+  static StaticMonitor sMonitor;
 
   static StaticAutoPtr<SharedSurfacesParent> sInstance;
 
   nsRefPtrHashtable<nsUint64HashKey, gfx::SourceSurfaceSharedDataWrapper>
       mSurfaces;
 
   class MappingTracker final
       : public ExpirationTrackerImpl<gfx::SourceSurfaceSharedDataWrapper, 4,
-                                     StaticMutex, StaticMutexAutoLock> {
+                                     StaticMonitor, StaticMonitorAutoLock> {
    public:
     explicit MappingTracker(uint32_t aExpirationTimeoutMS,
                             nsIEventTarget* aEventTarget)
         : ExpirationTrackerImpl<gfx::SourceSurfaceSharedDataWrapper, 4,
-                                StaticMutex, StaticMutexAutoLock>(
+                                StaticMonitor, StaticMonitorAutoLock>(
               aExpirationTimeoutMS, "SharedMappingTracker", aEventTarget) {}
 
     void TakeExpired(
         nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>>& aExpired,
-        const StaticMutexAutoLock& aAutoLock);
+        const StaticMonitorAutoLock& aAutoLock);
 
    protected:
     void NotifyExpiredLocked(gfx::SourceSurfaceSharedDataWrapper* aSurface,
-                             const StaticMutexAutoLock& aAutoLock) override;
+                             const StaticMonitorAutoLock& aAutoLock) override;
 
-    void NotifyHandlerEndLocked(const StaticMutexAutoLock& aAutoLock) override {
-    }
+    void NotifyHandlerEndLocked(
+        const StaticMonitorAutoLock& aAutoLock) override {}
 
     void NotifyHandlerEnd() override;
 
-    StaticMutex& GetMutex() override { return sMutex; }
+    StaticMonitor& GetMutex() override { return sMonitor; }
 
     nsTArray<RefPtr<gfx::SourceSurfaceSharedDataWrapper>> mExpired;
   };
 
   MappingTracker mTracker;
 };
 
 }  // namespace layers