1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef MOZILLA_GFX_RemoteTextureMap_H
8 #define MOZILLA_GFX_RemoteTextureMap_H
16 #include <unordered_set>
19 #include "mozilla/gfx/Point.h" // for IntSize
20 #include "mozilla/gfx/Types.h" // for SurfaceFormat
21 #include "mozilla/ipc/Shmem.h"
22 #include "mozilla/layers/CompositorTypes.h" // for TextureFlags, etc
23 #include "mozilla/layers/LayersSurfaces.h" // for SurfaceDescriptor
24 #include "mozilla/layers/TextureHost.h"
25 #include "mozilla/Monitor.h"
26 #include "mozilla/StaticPtr.h"
27 #include "mozilla/ThreadSafeWeakPtr.h"
28 #include "mozilla/UniquePtr.h"
29 #include "mozilla/webrender/WebRenderTypes.h"
31 class nsISerialEventTarget
;
44 class ExternalTexture
;
49 class CompositableHost
;
50 class RemoteTextureHostWrapper
;
54 struct RemoteTextureInfo
{
55 RemoteTextureInfo(const RemoteTextureId aTextureId
,
56 const RemoteTextureOwnerId aOwnerId
,
57 const base::ProcessId aForPid
)
58 : mTextureId(aTextureId
),
61 mWaitForRemoteTextureOwner(false) {}
63 RemoteTextureInfo(const RemoteTextureId aTextureId
,
64 const RemoteTextureOwnerId aOwnerId
,
65 const base::ProcessId aForPid
,
66 const bool aWaitForRemoteTextureOwner
)
67 : mTextureId(aTextureId
),
70 mWaitForRemoteTextureOwner(aWaitForRemoteTextureOwner
) {}
72 const RemoteTextureId mTextureId
;
73 const RemoteTextureOwnerId mOwnerId
;
74 const base::ProcessId mForPid
;
75 const bool mWaitForRemoteTextureOwner
;
78 struct RemoteTextureInfoList
{
79 std::queue
<RemoteTextureInfo
> mList
;
82 class SharedResourceWrapper
{
84 enum class Tag
{ SharedSurface
, ExternalTexture
};
87 static UniquePtr
<SharedResourceWrapper
> SharedSurface(
88 const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
) {
89 return MakeUnique
<SharedResourceWrapper
>(Tag::SharedSurface
,
93 static UniquePtr
<SharedResourceWrapper
> ExternalTexture(
94 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
) {
95 return MakeUnique
<SharedResourceWrapper
>(Tag::ExternalTexture
,
99 SharedResourceWrapper(
100 const Tag aTag
, const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
)
101 : mTag(aTag
), mSharedSurface(aSharedSurface
) {
102 MOZ_ASSERT(mTag
== Tag::SharedSurface
);
104 SharedResourceWrapper(
106 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
)
107 : mTag(aTag
), mExternalTexture(aExternalTexture
) {
108 MOZ_ASSERT(mTag
== Tag::ExternalTexture
);
111 const std::shared_ptr
<gl::SharedSurface
> mSharedSurface
;
112 const std::shared_ptr
<webgpu::ExternalTexture
> mExternalTexture
;
114 std::shared_ptr
<gl::SharedSurface
> SharedSurface() {
115 if (mTag
== Tag::SharedSurface
) {
116 return mSharedSurface
;
118 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
122 std::shared_ptr
<webgpu::ExternalTexture
> ExternalTexture() {
123 if (mTag
== Tag::ExternalTexture
) {
124 return mExternalTexture
;
126 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
131 class RemoteTextureRecycleBin final
{
133 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureRecycleBin
)
135 explicit RemoteTextureRecycleBin(bool aIsShared
);
138 friend class RemoteTextureMap
;
140 ~RemoteTextureRecycleBin();
142 struct RecycledTextureHolder
{
144 gfx::SurfaceFormat mFormat
= gfx::SurfaceFormat::UNKNOWN
;
145 SurfaceDescriptor::Type mType
= SurfaceDescriptor::Tnull_t
;
146 UniquePtr
<TextureData
> mTextureData
;
147 UniquePtr
<SharedResourceWrapper
> mResourceWrapper
;
150 bool mIsShared
= false;
151 std::list
<RecycledTextureHolder
> mRecycledTextures
;
155 * RemoteTextureTxnScheduler manages dependencies on transaction numbers for a
156 * given top-level protocol ("type"). It expects that transaction numbers are
157 * all sequenced and comparable for this top-level protocol. Dependencies may
158 * then be issued on a given future transaction number. Clients must notify the
159 * scheduler when transactions are completed, so that any dependencies can be
160 * cleared as the transaction number advances. Generally, transaction numbers
161 * will be generated by a FwdTransactionCounter on a top-level protocol child,
162 * and there should be a RemoteTextureTxnScheduler instantiated on the top-level
163 * protocol parent that corresponds to the same protocol lifetime as the child.
164 * To ease sharing in sub-protocols, RemoteTextureTxnScheduler is ref-counted
165 * and may be multiply-registered by the various sub-protocols that derive from
166 * a given top-level protocol, without having to directly refer to the original
167 * top-level protocol.
169 class RemoteTextureTxnScheduler final
{
171 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureTxnScheduler
)
173 static already_AddRefed
<RemoteTextureTxnScheduler
> Create(
174 mozilla::ipc::IProtocol
* aProtocol
);
176 void NotifyTxn(RemoteTextureTxnId aTxnId
);
179 friend class RemoteTextureMap
;
181 RemoteTextureTxnScheduler(base::ProcessId aForPid
, RemoteTextureTxnType aType
)
182 : mForPid(aForPid
), mType(aType
) {}
183 ~RemoteTextureTxnScheduler();
185 bool WaitForTxn(const MonitorAutoLock
& aProofOfLock
,
186 RemoteTextureOwnerId aOwnerId
, RemoteTextureTxnId aTxnId
);
189 RemoteTextureOwnerId mOwnerId
;
190 RemoteTextureTxnId mTxnId
;
192 friend bool operator<(RemoteTextureTxnId aTxnId
, const Wait
& aWait
) {
193 return aTxnId
< aWait
.mTxnId
;
197 base::ProcessId mForPid
= base::kInvalidProcessId
;
198 RemoteTextureTxnType mType
= 0;
199 RemoteTextureTxnId mLastTxnId
= 0;
200 std::deque
<Wait
> mWaits
;
203 typedef std::unordered_set
<RemoteTextureOwnerId
, RemoteTextureOwnerId::HashFn
>
204 RemoteTextureOwnerIdSet
;
207 * A class provides API for remote texture owners.
209 class RemoteTextureOwnerClient final
{
211 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureOwnerClient
)
213 explicit RemoteTextureOwnerClient(const base::ProcessId aForPid
);
215 bool IsRegistered(const RemoteTextureOwnerId aOwnerId
);
216 void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId
,
217 bool aSharedRecycling
= false);
218 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId
);
219 void UnregisterAllTextureOwners();
220 bool WaitForTxn(const RemoteTextureOwnerId aOwnerId
,
221 RemoteTextureTxnType aTxnType
, RemoteTextureTxnId aTxnId
);
222 void ClearRecycledTextures();
223 void NotifyContextLost(const RemoteTextureOwnerIdSet
* aOwnerIds
= nullptr);
224 void NotifyContextRestored(
225 const RemoteTextureOwnerIdSet
* aOwnerIds
= nullptr);
226 void PushTexture(const RemoteTextureId aTextureId
,
227 const RemoteTextureOwnerId aOwnerId
,
228 UniquePtr
<TextureData
>&& aTextureData
);
229 void PushTexture(const RemoteTextureId aTextureId
,
230 const RemoteTextureOwnerId aOwnerId
,
231 const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
,
232 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
233 const SurfaceDescriptor
& aDesc
);
235 const RemoteTextureId aTextureId
, const RemoteTextureOwnerId aOwnerId
,
236 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
,
237 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
238 const SurfaceDescriptor
& aDesc
);
239 void PushDummyTexture(const RemoteTextureId aTextureId
,
240 const RemoteTextureOwnerId aOwnerId
);
241 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId
,
242 const mozilla::ipc::Shmem
& aDestShmem
,
243 const gfx::IntSize
& aSize
);
244 UniquePtr
<TextureData
> GetRecycledTextureData(
245 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
246 TextureType aTextureType
,
247 RemoteTextureOwnerId aOwnerId
= RemoteTextureOwnerId());
248 UniquePtr
<TextureData
> CreateOrRecycleBufferTextureData(
249 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
250 RemoteTextureOwnerId aOwnerId
= RemoteTextureOwnerId());
251 std::shared_ptr
<gl::SharedSurface
> GetRecycledSharedSurface(
252 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
253 SurfaceDescriptor::Type aType
,
254 RemoteTextureOwnerId aOwnerId
= RemoteTextureOwnerId());
255 std::shared_ptr
<webgpu::ExternalTexture
> GetRecycledExternalTexture(
256 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
257 SurfaceDescriptor::Type aType
,
258 RemoteTextureOwnerId aOwnerId
= RemoteTextureOwnerId());
260 const base::ProcessId mForPid
;
263 ~RemoteTextureOwnerClient();
265 RemoteTextureOwnerIdSet mOwnerIds
;
266 RefPtr
<RemoteTextureRecycleBin
> mSharedRecycleBin
;
270 * A class to map RemoteTextureId to remote texture(TextureHost).
271 * Remote textures are provided by texture owner.
273 class RemoteTextureMap
{
276 static void Shutdown();
277 static RemoteTextureMap
* Get() { return sInstance
; }
282 // Push remote texture data and gl::SharedSurface from texture owner.
283 // The texture data is used for creating TextureHost.
284 // gl::SharedSurface is pushed only when the surface needs to be kept alive
285 // during TextureHost usage. The texture data and the surface might be
286 // recycled when TextureHost is destroyed.
287 void PushTexture(const RemoteTextureId aTextureId
,
288 const RemoteTextureOwnerId aOwnerId
,
289 const base::ProcessId aForPid
,
290 UniquePtr
<TextureData
>&& aTextureData
,
291 RefPtr
<TextureHost
>& aTextureHost
,
292 UniquePtr
<SharedResourceWrapper
>&& aResourceWrapper
);
294 // Remove waiting texture that will not be used.
295 bool RemoveTexture(const RemoteTextureId aTextureId
,
296 const RemoteTextureOwnerId aOwnerId
,
297 const base::ProcessId aForPid
);
299 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId
,
300 const base::ProcessId aForPid
,
301 const mozilla::ipc::Shmem
& aDestShmem
,
302 const gfx::IntSize
& aSize
);
304 void RegisterTextureOwner(
305 const RemoteTextureOwnerId aOwnerId
, const base::ProcessId aForPid
,
306 const RefPtr
<RemoteTextureRecycleBin
>& aRecycleBin
= nullptr);
307 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId
,
308 const base::ProcessId aForPid
);
309 void UnregisterTextureOwners(const RemoteTextureOwnerIdSet
& aOwnerIds
,
310 const base::ProcessId aForPid
);
312 void ClearRecycledTextures(
313 const RemoteTextureOwnerIdSet
& aOwnerIds
, const base::ProcessId aForPid
,
314 const RefPtr
<RemoteTextureRecycleBin
>& aRecycleBin
= nullptr);
315 void NotifyContextLost(const RemoteTextureOwnerIdSet
& aOwnerIds
,
316 const base::ProcessId aForPid
);
317 void NotifyContextRestored(const RemoteTextureOwnerIdSet
& aOwnerIds
,
318 const base::ProcessId aForPid
);
320 bool WaitForRemoteTextureOwner(RemoteTextureHostWrapper
* aTextureHostWrapper
);
322 // Get remote texture's TextureHost for RemoteTextureHostWrapper.
323 void GetRemoteTexture(RemoteTextureHostWrapper
* aTextureHostWrapper
);
325 bool WaitForTxn(const RemoteTextureOwnerId aOwnerId
,
326 const base::ProcessId aForPid
, RemoteTextureTxnType aTxnType
,
327 RemoteTextureTxnId aTxnId
);
329 void ReleaseRemoteTextureHost(RemoteTextureHostWrapper
* aTextureHostWrapper
);
331 RefPtr
<TextureHost
> GetOrCreateRemoteTextureHostWrapper(
332 const RemoteTextureId aTextureId
, const RemoteTextureOwnerId aOwnerId
,
333 const base::ProcessId aForPid
, const gfx::IntSize
& aSize
,
334 const TextureFlags aFlags
);
336 void UnregisterRemoteTextureHostWrapper(const RemoteTextureId aTextureId
,
337 const RemoteTextureOwnerId aOwnerId
,
338 const base::ProcessId aForPid
);
340 bool CheckRemoteTextureReady(
341 const RemoteTextureInfo
& aInfo
,
342 std::function
<void(const RemoteTextureInfo
&)>&& aCallback
);
344 bool WaitRemoteTextureReady(const RemoteTextureInfo
& aInfo
);
346 void SuppressRemoteTextureReadyCheck(const RemoteTextureInfo
& aInfo
);
348 UniquePtr
<TextureData
> GetRecycledTextureData(
349 const RemoteTextureOwnerId aOwnerId
, const base::ProcessId aForPid
,
350 const RefPtr
<RemoteTextureRecycleBin
>& aRecycleBin
,
351 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
352 TextureType aTextureType
);
354 UniquePtr
<SharedResourceWrapper
> GetRecycledSharedTexture(
355 const RemoteTextureOwnerId aOwnerId
, const base::ProcessId aForPid
,
356 const RefPtr
<RemoteTextureRecycleBin
>& aRecycleBin
,
357 const gfx::IntSize
& aSize
, gfx::SurfaceFormat aFormat
,
358 SurfaceDescriptor::Type aType
);
360 static RefPtr
<TextureHost
> CreateRemoteTexture(TextureData
* aTextureData
,
361 TextureFlags aTextureFlags
);
363 already_AddRefed
<RemoteTextureTxnScheduler
> RegisterTxnScheduler(
364 base::ProcessId aForPid
, RemoteTextureTxnType aType
);
367 friend class RemoteTextureTxnScheduler
;
369 // Holds data related to remote texture
370 struct TextureDataHolder
{
371 TextureDataHolder(const RemoteTextureId aTextureId
,
372 RefPtr
<TextureHost
> aTextureHost
,
373 UniquePtr
<TextureData
>&& aTextureData
,
374 UniquePtr
<SharedResourceWrapper
>&& aResourceWrapper
);
376 const RemoteTextureId mTextureId
;
377 // TextureHost of remote texture
378 // Compositable ref of the mTextureHost should be updated within mMonitor.
379 // The compositable ref is used to check if TextureHost(remote texture) is
380 // still in use by WebRender.
381 RefPtr
<TextureHost
> mTextureHost
;
382 // Holds BufferTextureData of TextureHost
383 UniquePtr
<TextureData
> mTextureData
;
384 // Holds gl::SharedSurface of TextureHost
385 UniquePtr
<SharedResourceWrapper
> mResourceWrapper
;
388 struct RenderingReadyCallbackHolder
{
389 RenderingReadyCallbackHolder(
390 const RemoteTextureId aTextureId
,
391 std::function
<void(const RemoteTextureInfo
&)>&& aCallback
);
393 const RemoteTextureId mTextureId
;
394 // callback of RemoteTexture ready
395 std::function
<void(const RemoteTextureInfo
&)> mCallback
;
398 struct WaitingTextureOwner
{
399 std::deque
<UniquePtr
<RenderingReadyCallbackHolder
>>
400 mRenderingReadyCallbackHolders
;
403 struct TextureOwner
{
404 bool mIsContextLost
= false;
405 // Whether to wait for a transaction to complete before unregistering.
406 bool mWaitForTxn
= false;
407 // The thread on which to finally unregister when ready.
408 RefPtr
<nsISerialEventTarget
> mDeferUnregister
;
410 // Holds TextureDataHolders that wait to be used for building wr display
412 std::deque
<UniquePtr
<TextureDataHolder
>> mWaitingTextureDataHolders
;
413 // Holds TextureDataHolders that are used for building wr display list.
414 std::deque
<UniquePtr
<TextureDataHolder
>> mUsingTextureDataHolders
;
415 std::deque
<UniquePtr
<TextureDataHolder
>> mReleasingTextureDataHolders
;
416 // Holds RemoteTexture ready callbacks.
417 std::deque
<UniquePtr
<RenderingReadyCallbackHolder
>>
418 mRenderingReadyCallbackHolders
;
420 RemoteTextureId mLatestPushedTextureId
= {0};
421 RemoteTextureId mLatestUsingTextureId
= {0};
422 CompositableTextureHostRef mLatestTextureHost
;
423 CompositableTextureHostRef mLatestRenderedTextureHost
;
424 // Holds compositable refs to TextureHosts of RenderTextureHosts that are
425 // waiting to be released in non-RenderThread.
426 std::deque
<CompositableTextureHostRef
> mReleasingRenderedTextureHosts
;
427 RefPtr
<RemoteTextureRecycleBin
> mRecycleBin
;
430 // Holds data related to remote texture wrapper
431 struct RemoteTextureHostWrapperHolder
{
432 explicit RemoteTextureHostWrapperHolder(
433 RefPtr
<TextureHost
> aRemoteTextureHostWrapper
);
435 const RefPtr
<TextureHost
> mRemoteTextureHostWrapper
;
436 // Hold compositable ref of remote texture of the RemoteTextureId.
437 CompositableTextureHostRef mRemoteTextureHost
;
438 bool mReadyCheckSuppressed
= false;
441 void UpdateTexture(const MonitorAutoLock
& aProofOfLock
,
442 RemoteTextureMap::TextureOwner
* aOwner
,
443 const RemoteTextureId aTextureId
);
445 UniquePtr
<TextureOwner
> UnregisterTextureOwner(
446 MonitorAutoLock
& aProofOfLock
, const RemoteTextureOwnerId aOwnerId
,
447 const base::ProcessId aForPid
,
448 std::vector
<RefPtr
<TextureHost
>>& aReleasingTextures
,
449 std::vector
<std::function
<void(const RemoteTextureInfo
&)>>&
450 aRenderingReadyCallbacks
);
452 void GetRenderingReadyCallbacks(
453 const MonitorAutoLock
& aProofOfLock
,
454 RemoteTextureMap::TextureOwner
* aOwner
, const RemoteTextureId aTextureId
,
455 std::vector
<std::function
<void(const RemoteTextureInfo
&)>>& aFunctions
);
457 void GetAllRenderingReadyCallbacks(
458 const MonitorAutoLock
& aProofOfLock
,
459 RemoteTextureMap::TextureOwner
* aOwner
,
460 std::vector
<std::function
<void(const RemoteTextureInfo
&)>>& aFunctions
);
462 void KeepTextureDataAliveForTextureHostIfNecessary(
463 const MonitorAutoLock
& aProofOfLock
,
464 RemoteTextureMap::TextureOwner
* aOwner
,
465 std::deque
<UniquePtr
<TextureDataHolder
>>& aHolders
);
467 bool RecycleTexture(const RefPtr
<RemoteTextureRecycleBin
>& aRecycleBin
,
468 TextureDataHolder
& aHolder
, bool aExpireOldTextures
);
470 RemoteTextureMap::TextureOwner
* GetTextureOwner(
471 const MonitorAutoLock
& aProofOfLock
, const RemoteTextureOwnerId aOwnerId
,
472 const base::ProcessId aForPid
);
474 void NotifyTxn(const MonitorAutoLock
& aProofOfLock
,
475 const RemoteTextureOwnerId aOwnerId
,
476 const base::ProcessId aForPid
);
478 void UnregisterTxnScheduler(base::ProcessId aForPid
,
479 RemoteTextureTxnType aType
);
481 Monitor mMonitor MOZ_UNANNOTATED
;
483 std::map
<std::pair
<base::ProcessId
, RemoteTextureOwnerId
>,
484 UniquePtr
<WaitingTextureOwner
>>
485 mWaitingTextureOwners
;
487 std::map
<std::pair
<base::ProcessId
, RemoteTextureOwnerId
>,
488 UniquePtr
<TextureOwner
>>
491 std::map
<std::pair
<base::ProcessId
, RemoteTextureId
>,
492 UniquePtr
<RemoteTextureHostWrapperHolder
>>
493 mRemoteTextureHostWrapperHolders
;
495 std::map
<std::pair
<base::ProcessId
, RemoteTextureTxnType
>,
496 RemoteTextureTxnScheduler
*>
499 static StaticAutoPtr
<RemoteTextureMap
> sInstance
;
502 } // namespace layers
503 } // namespace mozilla
505 #endif // MOZILLA_GFX_RemoteTextureMap_H