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
;
40 class ExternalTexture
;
45 class CompositableHost
;
46 class RemoteTextureHostWrapper
;
50 struct RemoteTextureInfo
{
51 RemoteTextureInfo(const RemoteTextureId aTextureId
,
52 const RemoteTextureOwnerId aOwnerId
,
53 const base::ProcessId aForPid
)
54 : mTextureId(aTextureId
), mOwnerId(aOwnerId
), mForPid(aForPid
) {}
56 const RemoteTextureId mTextureId
;
57 const RemoteTextureOwnerId mOwnerId
;
58 const base::ProcessId mForPid
;
61 struct RemoteTextureInfoList
{
62 std::queue
<RemoteTextureInfo
> mList
;
65 class SharedResourceWrapper
{
67 enum class Tag
{ SharedSurface
, ExternalTexture
};
70 static UniquePtr
<SharedResourceWrapper
> SharedSurface(
71 const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
) {
72 return MakeUnique
<SharedResourceWrapper
>(Tag::SharedSurface
,
76 static UniquePtr
<SharedResourceWrapper
> ExternalTexture(
77 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
) {
78 return MakeUnique
<SharedResourceWrapper
>(Tag::ExternalTexture
,
82 SharedResourceWrapper(
83 const Tag aTag
, const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
)
84 : mTag(aTag
), mSharedSurface(aSharedSurface
) {
85 MOZ_ASSERT(mTag
== Tag::SharedSurface
);
87 SharedResourceWrapper(
89 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
)
90 : mTag(aTag
), mExternalTexture(aExternalTexture
) {
91 MOZ_ASSERT(mTag
== Tag::ExternalTexture
);
94 const std::shared_ptr
<gl::SharedSurface
> mSharedSurface
;
95 const std::shared_ptr
<webgpu::ExternalTexture
> mExternalTexture
;
97 std::shared_ptr
<gl::SharedSurface
> SharedSurface() {
98 if (mTag
== Tag::SharedSurface
) {
99 return mSharedSurface
;
101 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
105 std::shared_ptr
<webgpu::ExternalTexture
> ExternalTexture() {
106 if (mTag
== Tag::ExternalTexture
) {
107 return mExternalTexture
;
109 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
115 * A class provides API for remote texture owners.
117 class RemoteTextureOwnerClient final
{
119 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RemoteTextureOwnerClient
)
121 explicit RemoteTextureOwnerClient(const base::ProcessId aForPid
);
123 bool IsRegistered(const RemoteTextureOwnerId aOwnerId
);
124 void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId
,
126 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerId
);
127 void UnregisterAllTextureOwners();
128 void NotifyContextLost();
129 void PushTexture(const RemoteTextureId aTextureId
,
130 const RemoteTextureOwnerId aOwnerId
,
131 UniquePtr
<TextureData
>&& aTextureData
);
132 void PushTexture(const RemoteTextureId aTextureId
,
133 const RemoteTextureOwnerId aOwnerId
,
134 UniquePtr
<TextureData
>&& aTextureData
,
135 const std::shared_ptr
<gl::SharedSurface
>& aSharedSurface
);
137 const RemoteTextureId aTextureId
, const RemoteTextureOwnerId aOwnerId
,
138 UniquePtr
<TextureData
>&& aTextureData
,
139 const std::shared_ptr
<webgpu::ExternalTexture
>& aExternalTexture
);
140 void PushDummyTexture(const RemoteTextureId aTextureId
,
141 const RemoteTextureOwnerId aOwnerId
);
142 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId
,
143 const mozilla::ipc::Shmem
& aDestShmem
,
144 const gfx::IntSize
& aSize
);
145 UniquePtr
<TextureData
> CreateOrRecycleBufferTextureData(
146 const RemoteTextureOwnerId aOwnerId
, gfx::IntSize aSize
,
147 gfx::SurfaceFormat aFormat
);
148 std::shared_ptr
<gl::SharedSurface
> GetRecycledSharedSurface(
149 const RemoteTextureOwnerId aOwnerId
);
150 std::shared_ptr
<webgpu::ExternalTexture
> GetRecycledExternalTexture(
151 const RemoteTextureOwnerId aOwnerId
);
153 const base::ProcessId mForPid
;
156 ~RemoteTextureOwnerClient();
158 std::unordered_set
<RemoteTextureOwnerId
, RemoteTextureOwnerId::HashFn
>
163 * A class to map RemoteTextureId to remote texture(TextureHost).
164 * Remote textures are provided by texture owner.
166 class RemoteTextureMap
{
169 static void Shutdown();
170 static RemoteTextureMap
* Get() { return sInstance
; }
175 // Push remote texture data and gl::SharedSurface from texture owner.
176 // The texture data is used for creating TextureHost.
177 // gl::SharedSurface is pushed only when the surface needs to be kept alive
178 // during TextureHost usage. The texture data and the surface might be
179 // recycled when TextureHost is destroyed.
180 void PushTexture(const RemoteTextureId aTextureId
,
181 const RemoteTextureOwnerId aOwnerId
,
182 const base::ProcessId aForPid
,
183 UniquePtr
<TextureData
>&& aTextureData
,
184 RefPtr
<TextureHost
>& aTextureHost
,
185 UniquePtr
<SharedResourceWrapper
>&& aResourceWrapper
);
187 void GetLatestBufferSnapshot(const RemoteTextureOwnerId aOwnerId
,
188 const base::ProcessId aForPid
,
189 const mozilla::ipc::Shmem
& aDestShmem
,
190 const gfx::IntSize
& aSize
);
192 // aIsSyncMode defines if RemoteTextureMap::GetRemoteTextureForDisplayList()
193 // works synchronously.
194 void RegisterTextureOwner(const RemoteTextureOwnerId aOwnerId
,
195 const base::ProcessId aForPid
, bool aIsSyncMode
);
196 void UnregisterTextureOwner(const RemoteTextureOwnerId aOwnerIds
,
197 const base::ProcessId aForPid
);
198 void UnregisterTextureOwners(
199 const std::unordered_set
<RemoteTextureOwnerId
,
200 RemoteTextureOwnerId::HashFn
>& aOwnerIds
,
201 const base::ProcessId aForPid
);
203 void NotifyContextLost(
204 const std::unordered_set
<RemoteTextureOwnerId
,
205 RemoteTextureOwnerId::HashFn
>& aOwnerIds
,
206 const base::ProcessId aForPid
);
208 // Get TextureHost that is used for building wr display list.
209 // In sync mode, mRemoteTextureForDisplayList holds TextureHost of mTextureId.
210 // In async mode, it could be previous remote texture's TextureHost that is
211 // compatible to the mTextureId's TextureHost.
213 // return true when aReadyCallback will be called.
214 bool GetRemoteTextureForDisplayList(
215 RemoteTextureHostWrapper
* aTextureHostWrapper
,
216 std::function
<void(const RemoteTextureInfo
&)>&& aReadyCallback
);
218 // Get ExternalImageId of remote texture for WebRender rendering.
219 wr::MaybeExternalImageId
GetExternalImageIdOfRemoteTexture(
220 const RemoteTextureId aTextureId
, const RemoteTextureOwnerId aOwnerId
,
221 const base::ProcessId aForPid
);
223 void ReleaseRemoteTextureHostForDisplayList(
224 RemoteTextureHostWrapper
* aTextureHostWrapper
);
226 RefPtr
<TextureHost
> GetOrCreateRemoteTextureHostWrapper(
227 const RemoteTextureId aTextureId
, const RemoteTextureOwnerId aOwnerId
,
228 const base::ProcessId aForPid
, const gfx::IntSize aSize
,
229 const TextureFlags aFlags
);
231 void UnregisterRemoteTextureHostWrapper(const RemoteTextureId aTextureId
,
232 const RemoteTextureOwnerId aOwnerId
,
233 const base::ProcessId aForPid
);
235 void RegisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId
,
236 const base::ProcessId aForPid
,
237 CompositableHost
* aListener
);
239 void UnregisterRemoteTexturePushListener(const RemoteTextureOwnerId aOwnerId
,
240 const base::ProcessId aForPid
,
241 CompositableHost
* aListener
);
243 bool CheckRemoteTextureReady(
244 const RemoteTextureInfo
& aInfo
,
245 std::function
<void(const RemoteTextureInfo
&)>&& aCallback
);
247 bool WaitRemoteTextureReady(const RemoteTextureInfo
& aInfo
);
249 void SuppressRemoteTextureReadyCheck(const RemoteTextureId aTextureId
,
250 const base::ProcessId aForPid
);
252 UniquePtr
<TextureData
> GetRecycledBufferTextureData(
253 const RemoteTextureOwnerId aOwnerId
, const base::ProcessId aForPid
,
254 gfx::IntSize aSize
, gfx::SurfaceFormat aFormat
);
256 UniquePtr
<SharedResourceWrapper
> GetRecycledSharedTexture(
257 const RemoteTextureOwnerId aOwnerId
, const base::ProcessId aForPid
);
259 static RefPtr
<TextureHost
> CreateRemoteTexture(TextureData
* aTextureData
,
260 TextureFlags aTextureFlags
);
263 // Holds data related to remote texture
264 struct TextureDataHolder
{
265 TextureDataHolder(const RemoteTextureId aTextureId
,
266 RefPtr
<TextureHost
> aTextureHost
,
267 UniquePtr
<TextureData
>&& aTextureData
,
268 UniquePtr
<SharedResourceWrapper
>&& aResourceWrapper
);
270 const RemoteTextureId mTextureId
;
271 // TextureHost of remote texture
272 // Compositable ref of the mTextureHost should be updated within mMonitor.
273 // The compositable ref is used to check if TextureHost(remote texture) is
274 // still in use by WebRender.
275 RefPtr
<TextureHost
> mTextureHost
;
276 // Holds BufferTextureData of TextureHost
277 UniquePtr
<TextureData
> mTextureData
;
278 // Holds gl::SharedSurface of TextureHost
279 UniquePtr
<SharedResourceWrapper
> mResourceWrapper
;
282 struct RenderingReadyCallbackHolder
{
283 RenderingReadyCallbackHolder(
284 const RemoteTextureId aTextureId
,
285 std::function
<void(const RemoteTextureInfo
&)>&& aCallback
);
287 const RemoteTextureId mTextureId
;
288 // callback of async RemoteTexture ready
289 std::function
<void(const RemoteTextureInfo
&)> mCallback
;
292 struct TextureOwner
{
293 bool mIsSyncMode
= true;
294 bool mIsContextLost
= false;
295 // Holds TextureDataHolders that wait to be used for building wr display
297 std::deque
<UniquePtr
<TextureDataHolder
>> mWaitingTextureDataHolders
;
298 // Holds TextureDataHolders that are used for building wr display list.
299 std::deque
<UniquePtr
<TextureDataHolder
>> mUsingTextureDataHolders
;
300 // Holds async RemoteTexture ready callbacks.
301 std::deque
<UniquePtr
<RenderingReadyCallbackHolder
>>
302 mRenderingReadyCallbackHolders
;
304 RemoteTextureId mLatestTextureId
= {0};
305 CompositableTextureHostRef mLatestTextureHost
;
306 CompositableTextureHostRef mLatestRenderedTextureHost
;
307 // Holds compositable refs to TextureHosts of RenderTextureHosts that are
308 // waiting to be released in non-RenderThread.
309 std::deque
<CompositableTextureHostRef
> mReleasingRenderedTextureHosts
;
310 std::stack
<UniquePtr
<TextureData
>> mRecycledTextures
;
311 std::queue
<UniquePtr
<SharedResourceWrapper
>> mRecycledSharedTextures
;
314 // Holds data related to remote texture wrapper
315 struct RemoteTextureHostWrapperHolder
{
316 explicit RemoteTextureHostWrapperHolder(
317 RefPtr
<TextureHost
> aRemoteTextureHostWrapper
);
319 const RefPtr
<TextureHost
> mRemoteTextureHostWrapper
;
320 // Hold compositable ref of remote texture of the RemoteTextureId in async
321 // mode. It is for keeping the texture alive during its rendering by
323 CompositableTextureHostRef mAsyncRemoteTextureHost
;
324 bool mReadyCheckSuppressed
= false;
327 void UpdateTexture(const MonitorAutoLock
& aProofOfLock
,
328 RemoteTextureMap::TextureOwner
* aOwner
,
329 const RemoteTextureId aTextureId
);
331 std::vector
<std::function
<void(const RemoteTextureInfo
&)>>
332 GetRenderingReadyCallbacks(const MonitorAutoLock
& aProofOfLock
,
333 RemoteTextureMap::TextureOwner
* aOwner
,
334 const RemoteTextureId aTextureId
);
336 std::vector
<std::function
<void(const RemoteTextureInfo
&)>>
337 GetAllRenderingReadyCallbacks(const MonitorAutoLock
& aProofOfLock
,
338 RemoteTextureMap::TextureOwner
* aOwner
);
340 void KeepTextureDataAliveForTextureHostIfNecessary(
341 const MonitorAutoLock
& aProofOfLock
,
342 std::deque
<UniquePtr
<TextureDataHolder
>>& aHolders
);
344 RemoteTextureMap::TextureOwner
* GetTextureOwner(
345 const MonitorAutoLock
& aProofOfLock
, const RemoteTextureOwnerId aOwnerId
,
346 const base::ProcessId aForPid
);
348 Monitor mMonitor MOZ_UNANNOTATED
;
350 std::map
<std::pair
<base::ProcessId
, RemoteTextureOwnerId
>,
351 UniquePtr
<TextureOwner
>>
354 std::map
<std::pair
<base::ProcessId
, RemoteTextureId
>,
355 UniquePtr
<RemoteTextureHostWrapperHolder
>>
356 mRemoteTextureHostWrapperHolders
;
358 std::map
<std::pair
<base::ProcessId
, RemoteTextureOwnerId
>,
359 RefPtr
<CompositableHost
>>
360 mRemoteTexturePushListeners
;
362 static StaticAutoPtr
<RemoteTextureMap
> sInstance
;
365 } // namespace layers
366 } // namespace mozilla
368 #endif // MOZILLA_GFX_RemoteTextureMap_H