RemoteTextureMap.h (19335B)
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/. */ 6 7 #ifndef MOZILLA_GFX_RemoteTextureMap_H 8 #define MOZILLA_GFX_RemoteTextureMap_H 9 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> 18 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/UniquePtr.h" 28 #include "mozilla/webrender/WebRenderTypes.h" 29 30 class nsISerialEventTarget; 31 32 namespace mozilla { 33 34 namespace ipc { 35 class IProtocol; 36 } 37 38 namespace gl { 39 class SharedSurface; 40 } 41 42 namespace webgpu { 43 class SharedTexture; 44 } 45 46 namespace layers { 47 48 class CompositableHost; 49 class RemoteTextureHostWrapper; 50 class TextureData; 51 class TextureHost; 52 53 struct RemoteTextureInfo { 54 RemoteTextureInfo(const RemoteTextureId aTextureId, 55 const RemoteTextureOwnerId aOwnerId, 56 const base::ProcessId aForPid) 57 : mTextureId(aTextureId), 58 mOwnerId(aOwnerId), 59 mForPid(aForPid), 60 mWaitForRemoteTextureOwner(false) {} 61 62 RemoteTextureInfo(const RemoteTextureId aTextureId, 63 const RemoteTextureOwnerId aOwnerId, 64 const base::ProcessId aForPid, 65 const bool aWaitForRemoteTextureOwner) 66 : mTextureId(aTextureId), 67 mOwnerId(aOwnerId), 68 mForPid(aForPid), 69 mWaitForRemoteTextureOwner(aWaitForRemoteTextureOwner) {} 70 71 const RemoteTextureId mTextureId; 72 const RemoteTextureOwnerId mOwnerId; 73 const base::ProcessId mForPid; 74 const bool mWaitForRemoteTextureOwner; 75 }; 76 77 struct RemoteTextureInfoList { 78 std::queue<RemoteTextureInfo> mList; 79 }; 80 81 class SharedResourceWrapper { 82 public: 83 enum class Tag { SharedSurface, SharedTexture }; 84 const Tag mTag; 85 86 static UniquePtr<SharedResourceWrapper> SharedSurface( 87 const std::shared_ptr<gl::SharedSurface>& aSharedSurface) { 88 return MakeUnique<SharedResourceWrapper>(Tag::SharedSurface, 89 aSharedSurface); 90 } 91 92 static UniquePtr<SharedResourceWrapper> SharedTexture( 93 const std::shared_ptr<webgpu::SharedTexture>& aSharedTexture) { 94 return MakeUnique<SharedResourceWrapper>(Tag::SharedTexture, 95 aSharedTexture); 96 } 97 98 SharedResourceWrapper( 99 const Tag aTag, const std::shared_ptr<gl::SharedSurface>& aSharedSurface) 100 : mTag(aTag), mSharedSurface(aSharedSurface) { 101 MOZ_ASSERT(mTag == Tag::SharedSurface); 102 } 103 SharedResourceWrapper( 104 const Tag aTag, 105 const std::shared_ptr<webgpu::SharedTexture>& aSharedTexture) 106 : mTag(aTag), mSharedTexture(aSharedTexture) { 107 MOZ_ASSERT(mTag == Tag::SharedTexture); 108 } 109 110 const std::shared_ptr<gl::SharedSurface> mSharedSurface; 111 const std::shared_ptr<webgpu::SharedTexture> mSharedTexture; 112 113 std::shared_ptr<gl::SharedSurface> SharedSurface() { 114 if (mTag == Tag::SharedSurface) { 115 return mSharedSurface; 116 } 117 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 118 return nullptr; 119 } 120 121 std::shared_ptr<webgpu::SharedTexture> SharedTexture() { 122 if (mTag == Tag::SharedTexture) { 123 return mSharedTexture; 124 } 125 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 126 return nullptr; 127 } 128 }; 129 130 class RemoteTextureRecycleBin final { 131 public: 132 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureRecycleBin) 133 134 explicit RemoteTextureRecycleBin(bool aIsShared); 135 136 private: 137 friend class RemoteTextureMap; 138 139 ~RemoteTextureRecycleBin(); 140 141 struct RecycledTextureHolder { 142 gfx::IntSize mSize; 143 gfx::SurfaceFormat mFormat = gfx::SurfaceFormat::UNKNOWN; 144 SurfaceDescriptor::Type mType = SurfaceDescriptor::Tnull_t; 145 UniquePtr<TextureData> mTextureData; 146 UniquePtr<SharedResourceWrapper> mResourceWrapper; 147 }; 148 149 bool mIsShared = false; 150 std::list<RecycledTextureHolder> mRecycledTextures; 151 }; 152 153 /** 154 * RemoteTextureTxnScheduler manages dependencies on transaction numbers for a 155 * given top-level protocol ("type"). It expects that transaction numbers are 156 * all sequenced and comparable for this top-level protocol. Dependencies may 157 * then be issued on a given future transaction number. Clients must notify the 158 * scheduler when transactions are completed, so that any dependencies can be 159 * cleared as the transaction number advances. Generally, transaction numbers 160 * will be generated by a FwdTransactionCounter on a top-level protocol child, 161 * and there should be a RemoteTextureTxnScheduler instantiated on the top-level 162 * protocol parent that corresponds to the same protocol lifetime as the child. 163 * To ease sharing in sub-protocols, RemoteTextureTxnScheduler is ref-counted 164 * and may be multiply-registered by the various sub-protocols that derive from 165 * a given top-level protocol, without having to directly refer to the original 166 * top-level protocol. 167 */ 168 class RemoteTextureTxnScheduler final { 169 public: 170 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureTxnScheduler) 171 172 static already_AddRefed<RemoteTextureTxnScheduler> Create( 173 mozilla::ipc::IProtocol* aProtocol); 174 175 void NotifyTxn(RemoteTextureTxnId aTxnId); 176 177 private: 178 friend class RemoteTextureMap; 179 180 RemoteTextureTxnScheduler(base::ProcessId aForPid, RemoteTextureTxnType aType) 181 : mForPid(aForPid), mType(aType) {} 182 ~RemoteTextureTxnScheduler(); 183 184 bool WaitForTxn(const MonitorAutoLock& aProofOfLock, 185 RemoteTextureOwnerId aOwnerId, RemoteTextureTxnId aTxnId); 186 187 struct Wait { 188 RemoteTextureOwnerId mOwnerId; 189 RemoteTextureTxnId mTxnId; 190 191 friend bool operator<(RemoteTextureTxnId aTxnId, const Wait& aWait) { 192 return aTxnId < aWait.mTxnId; 193 } 194 }; 195 196 base::ProcessId mForPid = base::kInvalidProcessId; 197 RemoteTextureTxnType mType = 0; 198 RemoteTextureTxnId mLastTxnId = 0; 199 std::deque<Wait> mWaits; 200 }; 201 202 typedef std::unordered_set<RemoteTextureOwnerId, RemoteTextureOwnerId::HashFn> 203 RemoteTextureOwnerIdSet; 204 205 /** 206 * A class provides API for remote texture owners. 207 */ 208 class RemoteTextureOwnerClient final { 209 public: 210 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureOwnerClient) 211 212 explicit RemoteTextureOwnerClient(const base::ProcessId aForPid); 213 214 bool IsRegistered(const RemoteTextureOwnerId aOwnerId); 215 void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId, 216 bool aSharedRecycling = false); 217 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId); 218 void UnregisterAllTextureOwners(); 219 bool WaitForTxn(const RemoteTextureOwnerId aOwnerId, 220 RemoteTextureTxnType aTxnType, RemoteTextureTxnId aTxnId); 221 void ClearRecycledTextures(); 222 void NotifyContextLost(const RemoteTextureOwnerIdSet* aOwnerIds = nullptr); 223 void NotifyContextRestored( 224 const RemoteTextureOwnerIdSet* aOwnerIds = nullptr); 225 void PushTexture(const RemoteTextureId aTextureId, 226 const RemoteTextureOwnerId aOwnerId, 227 UniquePtr<TextureData>&& aTextureData); 228 void PushTexture(const RemoteTextureId aTextureId, 229 const RemoteTextureOwnerId aOwnerId, 230 const std::shared_ptr<gl::SharedSurface>& aSharedSurface, 231 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 232 const SurfaceDescriptor& aDesc); 233 void PushTexture(const RemoteTextureId aTextureId, 234 const RemoteTextureOwnerId aOwnerId, 235 const std::shared_ptr<webgpu::SharedTexture>& aSharedTexture, 236 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 237 const SurfaceDescriptor& aDesc); 238 void PushDummyTexture(const RemoteTextureId aTextureId, 239 const RemoteTextureOwnerId aOwnerId); 240 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId, 241 const mozilla::ipc::Shmem& aDestShmem, 242 const gfx::IntSize& aSize); 243 UniquePtr<TextureData> GetRecycledTextureData( 244 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 245 TextureType aTextureType, 246 RemoteTextureOwnerId aOwnerId = RemoteTextureOwnerId()); 247 UniquePtr<TextureData> CreateOrRecycleBufferTextureData( 248 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 249 RemoteTextureOwnerId aOwnerId = RemoteTextureOwnerId()); 250 std::shared_ptr<gl::SharedSurface> GetRecycledSharedSurface( 251 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 252 SurfaceDescriptor::Type aType, 253 RemoteTextureOwnerId aOwnerId = RemoteTextureOwnerId()); 254 std::shared_ptr<webgpu::SharedTexture> GetRecycledSharedTexture( 255 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 256 SurfaceDescriptor::Type aType, 257 RemoteTextureOwnerId aOwnerId = RemoteTextureOwnerId()); 258 259 const base::ProcessId mForPid; 260 261 protected: 262 ~RemoteTextureOwnerClient(); 263 264 RemoteTextureOwnerIdSet mOwnerIds; 265 RefPtr<RemoteTextureRecycleBin> mSharedRecycleBin; 266 }; 267 268 /** 269 * A class to map RemoteTextureId to remote texture(TextureHost). 270 * Remote textures are provided by texture owner. 271 */ 272 class RemoteTextureMap { 273 public: 274 static void Init(); 275 static void Shutdown(); 276 static RemoteTextureMap* Get() { return sInstance; } 277 278 RemoteTextureMap(); 279 ~RemoteTextureMap(); 280 281 // Push remote texture data and gl::SharedSurface from texture owner. 282 // The texture data is used for creating TextureHost. 283 // gl::SharedSurface is pushed only when the surface needs to be kept alive 284 // during TextureHost usage. The texture data and the surface might be 285 // recycled when TextureHost is destroyed. 286 void PushTexture(const RemoteTextureId aTextureId, 287 const RemoteTextureOwnerId aOwnerId, 288 const base::ProcessId aForPid, 289 UniquePtr<TextureData>&& aTextureData, 290 RefPtr<TextureHost>& aTextureHost, 291 UniquePtr<SharedResourceWrapper>&& aResourceWrapper); 292 293 // Remove waiting texture that will not be used. 294 bool RemoveTexture(const RemoteTextureId aTextureId, 295 const RemoteTextureOwnerId aOwnerId, 296 const base::ProcessId aForPid); 297 298 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId, 299 const base::ProcessId aForPid, 300 const mozilla::ipc::Shmem& aDestShmem, 301 const gfx::IntSize& aSize); 302 303 void RegisterTextureOwner( 304 const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, 305 const RefPtr<RemoteTextureRecycleBin>& aRecycleBin = nullptr); 306 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId, 307 const base::ProcessId aForPid); 308 void UnregisterTextureOwners(const RemoteTextureOwnerIdSet& aOwnerIds, 309 const base::ProcessId aForPid); 310 311 void ClearRecycledTextures( 312 const RemoteTextureOwnerIdSet& aOwnerIds, const base::ProcessId aForPid, 313 const RefPtr<RemoteTextureRecycleBin>& aRecycleBin = nullptr); 314 void NotifyContextLost(const RemoteTextureOwnerIdSet& aOwnerIds, 315 const base::ProcessId aForPid); 316 void NotifyContextRestored(const RemoteTextureOwnerIdSet& aOwnerIds, 317 const base::ProcessId aForPid); 318 319 bool WaitForRemoteTextureOwner(RemoteTextureHostWrapper* aTextureHostWrapper); 320 321 // Get remote texture's TextureHost for RemoteTextureHostWrapper. 322 void GetRemoteTexture(RemoteTextureHostWrapper* aTextureHostWrapper); 323 324 bool WaitForTxn(const RemoteTextureOwnerId aOwnerId, 325 const base::ProcessId aForPid, RemoteTextureTxnType aTxnType, 326 RemoteTextureTxnId aTxnId); 327 328 void ReleaseRemoteTextureHost(RemoteTextureHostWrapper* aTextureHostWrapper); 329 330 RefPtr<TextureHost> GetOrCreateRemoteTextureHostWrapper( 331 const RemoteTextureId aTextureId, const RemoteTextureOwnerId aOwnerId, 332 const base::ProcessId aForPid, const gfx::IntSize& aSize, 333 const TextureFlags aFlags); 334 335 void UnregisterRemoteTextureHostWrapper(const RemoteTextureId aTextureId, 336 const RemoteTextureOwnerId aOwnerId, 337 const base::ProcessId aForPid); 338 339 bool CheckRemoteTextureReady( 340 const RemoteTextureInfo& aInfo, 341 std::function<void(const RemoteTextureInfo&)>&& aCallback); 342 343 bool WaitRemoteTextureReady(const RemoteTextureInfo& aInfo); 344 345 void SuppressRemoteTextureReadyCheck(const RemoteTextureInfo& aInfo); 346 347 UniquePtr<TextureData> GetRecycledTextureData( 348 const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, 349 const RefPtr<RemoteTextureRecycleBin>& aRecycleBin, 350 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 351 TextureType aTextureType); 352 353 UniquePtr<SharedResourceWrapper> GetRecycledSharedTexture( 354 const RemoteTextureOwnerId aOwnerId, const base::ProcessId aForPid, 355 const RefPtr<RemoteTextureRecycleBin>& aRecycleBin, 356 const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, 357 SurfaceDescriptor::Type aType); 358 359 static RefPtr<TextureHost> CreateRemoteTexture(TextureData* aTextureData, 360 TextureFlags aTextureFlags); 361 362 already_AddRefed<RemoteTextureTxnScheduler> RegisterTxnScheduler( 363 base::ProcessId aForPid, RemoteTextureTxnType aType); 364 365 protected: 366 friend class RemoteTextureTxnScheduler; 367 368 // Holds data related to remote texture 369 struct TextureDataHolder { 370 TextureDataHolder(const RemoteTextureId aTextureId, 371 RefPtr<TextureHost> aTextureHost, 372 UniquePtr<TextureData>&& aTextureData, 373 UniquePtr<SharedResourceWrapper>&& aResourceWrapper); 374 375 const RemoteTextureId mTextureId; 376 // TextureHost of remote texture 377 // Compositable ref of the mTextureHost should be updated within mMonitor. 378 // The compositable ref is used to check if TextureHost(remote texture) is 379 // still in use by WebRender. 380 RefPtr<TextureHost> mTextureHost; 381 // Holds BufferTextureData of TextureHost 382 UniquePtr<TextureData> mTextureData; 383 // Holds gl::SharedSurface of TextureHost 384 UniquePtr<SharedResourceWrapper> mResourceWrapper; 385 }; 386 387 struct RenderingReadyCallbackHolder { 388 RenderingReadyCallbackHolder( 389 const RemoteTextureId aTextureId, 390 std::function<void(const RemoteTextureInfo&)>&& aCallback); 391 392 const RemoteTextureId mTextureId; 393 // callback of RemoteTexture ready 394 std::function<void(const RemoteTextureInfo&)> mCallback; 395 }; 396 397 struct WaitingTextureOwner { 398 std::deque<UniquePtr<RenderingReadyCallbackHolder>> 399 mRenderingReadyCallbackHolders; 400 }; 401 402 struct TextureOwner { 403 bool mIsContextLost = false; 404 // Whether to wait for a transaction to complete before unregistering. 405 bool mWaitForTxn = false; 406 // The thread on which to finally unregister when ready. 407 RefPtr<nsISerialEventTarget> mDeferUnregister; 408 409 // Holds TextureDataHolders that wait to be used for building wr display 410 // list. 411 std::deque<UniquePtr<TextureDataHolder>> mWaitingTextureDataHolders; 412 // Holds TextureDataHolders that are used for building wr display list. 413 std::deque<UniquePtr<TextureDataHolder>> mUsingTextureDataHolders; 414 std::deque<UniquePtr<TextureDataHolder>> mReleasingTextureDataHolders; 415 // Holds RemoteTexture ready callbacks. 416 std::deque<UniquePtr<RenderingReadyCallbackHolder>> 417 mRenderingReadyCallbackHolders; 418 419 RemoteTextureId mLatestPushedTextureId = {0}; 420 RemoteTextureId mLatestUsingTextureId = {0}; 421 CompositableTextureHostRef mLatestTextureHost; 422 CompositableTextureHostRef mLatestRenderedTextureHost; 423 // Holds compositable refs to TextureHosts of RenderTextureHosts that are 424 // waiting to be released in non-RenderThread. 425 std::deque<CompositableTextureHostRef> mReleasingRenderedTextureHosts; 426 RefPtr<RemoteTextureRecycleBin> mRecycleBin; 427 }; 428 429 // Holds data related to remote texture wrapper 430 struct RemoteTextureHostWrapperHolder { 431 explicit RemoteTextureHostWrapperHolder( 432 RefPtr<TextureHost> aRemoteTextureHostWrapper); 433 434 const RefPtr<TextureHost> mRemoteTextureHostWrapper; 435 // Hold compositable ref of remote texture of the RemoteTextureId. 436 CompositableTextureHostRef mRemoteTextureHost; 437 bool mReadyCheckSuppressed = false; 438 }; 439 440 void UpdateTexture(const MonitorAutoLock& aProofOfLock, 441 RemoteTextureMap::TextureOwner* aOwner, 442 const RemoteTextureId aTextureId); 443 444 UniquePtr<TextureOwner> UnregisterTextureOwner( 445 MonitorAutoLock& aProofOfLock, const RemoteTextureOwnerId aOwnerId, 446 const base::ProcessId aForPid, 447 std::vector<RefPtr<TextureHost>>& aReleasingTextures, 448 std::vector<std::function<void(const RemoteTextureInfo&)>>& 449 aRenderingReadyCallbacks); 450 451 void GetRenderingReadyCallbacks( 452 const MonitorAutoLock& aProofOfLock, 453 RemoteTextureMap::TextureOwner* aOwner, const RemoteTextureId aTextureId, 454 std::vector<std::function<void(const RemoteTextureInfo&)>>& aFunctions); 455 456 void GetAllRenderingReadyCallbacks( 457 const MonitorAutoLock& aProofOfLock, 458 RemoteTextureMap::TextureOwner* aOwner, 459 std::vector<std::function<void(const RemoteTextureInfo&)>>& aFunctions); 460 461 void KeepTextureDataAliveForTextureHostIfNecessary( 462 const MonitorAutoLock& aProofOfLock, 463 RemoteTextureMap::TextureOwner* aOwner, 464 std::deque<UniquePtr<TextureDataHolder>>& aHolders); 465 466 bool RecycleTexture(const RefPtr<RemoteTextureRecycleBin>& aRecycleBin, 467 TextureDataHolder& aHolder, bool aExpireOldTextures); 468 469 RemoteTextureMap::TextureOwner* GetTextureOwner( 470 const MonitorAutoLock& aProofOfLock, const RemoteTextureOwnerId aOwnerId, 471 const base::ProcessId aForPid); 472 473 void NotifyTxn(const MonitorAutoLock& aProofOfLock, 474 const RemoteTextureOwnerId aOwnerId, 475 const base::ProcessId aForPid); 476 477 void UnregisterTxnScheduler(base::ProcessId aForPid, 478 RemoteTextureTxnType aType); 479 480 Monitor mMonitor MOZ_UNANNOTATED; 481 482 std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>, 483 UniquePtr<WaitingTextureOwner>> 484 mWaitingTextureOwners; 485 486 std::map<std::pair<base::ProcessId, RemoteTextureOwnerId>, 487 UniquePtr<TextureOwner>> 488 mTextureOwners; 489 490 std::map<std::pair<base::ProcessId, RemoteTextureId>, 491 UniquePtr<RemoteTextureHostWrapperHolder>> 492 mRemoteTextureHostWrapperHolders; 493 494 std::map<std::pair<base::ProcessId, RemoteTextureTxnType>, 495 RemoteTextureTxnScheduler*> 496 mTxnSchedulers; 497 498 static StaticAutoPtr<RemoteTextureMap> sInstance; 499 }; 500 501 } // namespace layers 502 } // namespace mozilla 503 504 #endif // MOZILLA_GFX_RemoteTextureMap_H