Bug 1919083 - [ci] Enable os-integration variant for more suites, r=jmaher
[gecko.git] / gfx / layers / RemoteTextureMap.h
blobcf41c15da50e296ff0ed1306231efe4d25aa712f
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
10 #include <deque>
11 #include <functional>
12 #include <list>
13 #include <map>
14 #include <memory>
15 #include <queue>
16 #include <unordered_set>
17 #include <utility>
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;
33 namespace mozilla {
35 namespace ipc {
36 class IProtocol;
39 namespace gl {
40 class SharedSurface;
43 namespace webgpu {
44 class ExternalTexture;
47 namespace layers {
49 class CompositableHost;
50 class RemoteTextureHostWrapper;
51 class TextureData;
52 class TextureHost;
54 struct RemoteTextureInfo {
55 RemoteTextureInfo(const RemoteTextureId aTextureId,
56 const RemoteTextureOwnerId aOwnerId,
57 const base::ProcessId aForPid)
58 : mTextureId(aTextureId),
59 mOwnerId(aOwnerId),
60 mForPid(aForPid),
61 mWaitForRemoteTextureOwner(false) {}
63 RemoteTextureInfo(const RemoteTextureId aTextureId,
64 const RemoteTextureOwnerId aOwnerId,
65 const base::ProcessId aForPid,
66 const bool aWaitForRemoteTextureOwner)
67 : mTextureId(aTextureId),
68 mOwnerId(aOwnerId),
69 mForPid(aForPid),
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 {
83 public:
84 enum class Tag { SharedSurface, ExternalTexture };
85 const Tag mTag;
87 static UniquePtr<SharedResourceWrapper> SharedSurface(
88 const std::shared_ptr<gl::SharedSurface>& aSharedSurface) {
89 return MakeUnique<SharedResourceWrapper>(Tag::SharedSurface,
90 aSharedSurface);
93 static UniquePtr<SharedResourceWrapper> ExternalTexture(
94 const std::shared_ptr<webgpu::ExternalTexture>& aExternalTexture) {
95 return MakeUnique<SharedResourceWrapper>(Tag::ExternalTexture,
96 aExternalTexture);
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(
105 const Tag aTag,
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");
119 return nullptr;
122 std::shared_ptr<webgpu::ExternalTexture> ExternalTexture() {
123 if (mTag == Tag::ExternalTexture) {
124 return mExternalTexture;
126 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
127 return nullptr;
131 class RemoteTextureRecycleBin final {
132 public:
133 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureRecycleBin)
135 explicit RemoteTextureRecycleBin(bool aIsShared);
137 private:
138 friend class RemoteTextureMap;
140 ~RemoteTextureRecycleBin();
142 struct RecycledTextureHolder {
143 gfx::IntSize mSize;
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 {
170 public:
171 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureTxnScheduler)
173 static already_AddRefed<RemoteTextureTxnScheduler> Create(
174 mozilla::ipc::IProtocol* aProtocol);
176 void NotifyTxn(RemoteTextureTxnId aTxnId);
178 private:
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);
188 struct Wait {
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 {
210 public:
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);
234 void PushTexture(
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;
262 protected:
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 {
274 public:
275 static void Init();
276 static void Shutdown();
277 static RemoteTextureMap* Get() { return sInstance; }
279 RemoteTextureMap();
280 ~RemoteTextureMap();
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);
366 protected:
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
411 // list.
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>>
489 mTextureOwners;
491 std::map<std::pair<base::ProcessId, RemoteTextureId>,
492 UniquePtr<RemoteTextureHostWrapperHolder>>
493 mRemoteTextureHostWrapperHolders;
495 std::map<std::pair<base::ProcessId, RemoteTextureTxnType>,
496 RemoteTextureTxnScheduler*>
497 mTxnSchedulers;
499 static StaticAutoPtr<RemoteTextureMap> sInstance;
502 } // namespace layers
503 } // namespace mozilla
505 #endif // MOZILLA_GFX_RemoteTextureMap_H