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_WEBRENDERCOMPOSITABLE_HOLDER_H
8 #define MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H
12 #include "CompositableHost.h"
13 #include "mozilla/gfx/Point.h"
14 #include "mozilla/ipc/FileDescriptor.h"
15 #include "mozilla/layers/RemoteTextureMap.h"
16 #include "mozilla/layers/TextureHost.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/webrender/WebRenderAPI.h"
19 #include "mozilla/webrender/WebRenderTypes.h"
20 #include "nsClassHashtable.h"
25 class DisplayListBuilder
;
27 class WebRenderPipelineInfo
;
32 class CompositableHost
;
33 class CompositorVsyncScheduler
;
34 class WebRenderImageHost
;
35 class WebRenderTextureHost
;
37 class AsyncImagePipelineManager final
{
39 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager
)
41 explicit AsyncImagePipelineManager(RefPtr
<wr::WebRenderAPI
>&& aApi
,
42 bool aUseCompositorWnd
);
45 ~AsyncImagePipelineManager();
50 bool UseCompositorWnd() const { return mUseCompositorWnd
; }
52 void AddPipeline(const wr::PipelineId
& aPipelineId
,
53 WebRenderBridgeParent
* aWrBridge
);
54 void RemovePipeline(const wr::PipelineId
& aPipelineId
,
55 const wr::Epoch
& aEpoch
);
56 WebRenderBridgeParent
* GetWrBridge(const wr::PipelineId
& aPipelineId
);
58 void HoldExternalImage(const wr::PipelineId
& aPipelineId
,
59 const wr::Epoch
& aEpoch
, TextureHost
* aTexture
);
60 void HoldExternalImage(const wr::PipelineId
& aPipelineId
,
61 const wr::Epoch
& aEpoch
,
62 const wr::ExternalImageId
& aImageId
);
64 // This is called from the Renderer thread to notify this class about the
65 // pipelines in the most recently completed update.
66 // @param aInfo PipelineInfo for the update
67 // @param aLatestFrameId RenderedFrameId if a frame has been submitted for
68 // rendering, invalid if not
69 // @param aLastCompletedFrameId RenderedFrameId for the last completed frame
70 void NotifyPipelinesUpdated(RefPtr
<const wr::WebRenderPipelineInfo
> aInfo
,
71 wr::RenderedFrameId aLatestFrameId
,
72 wr::RenderedFrameId aLastCompletedFrameId
,
73 ipc::FileDescriptor
&& aFenceFd
);
75 // This is run on the compositor thread to process mRenderSubmittedUpdates. We
76 // make this public because we need to invoke it from other places.
77 void ProcessPipelineUpdates();
79 TimeStamp
GetCompositionTime() const { return mCompositionTime
; }
80 CompositionOpportunityId
GetCompositionOpportunityId() const {
81 return mCompositionOpportunityId
;
84 void SetCompositionInfo(TimeStamp aTimeStamp
,
85 CompositionOpportunityId aCompositionOpportunityId
) {
86 mCompositionTime
= aTimeStamp
;
87 mCompositionOpportunityId
= aCompositionOpportunityId
;
88 if (!mCompositionTime
.IsNull() && !mCompositeUntilTime
.IsNull() &&
89 mCompositionTime
>= mCompositeUntilTime
) {
90 mCompositeUntilTime
= TimeStamp();
93 void CompositeUntil(TimeStamp aTimeStamp
) {
94 if (mCompositeUntilTime
.IsNull() || mCompositeUntilTime
< aTimeStamp
) {
95 mCompositeUntilTime
= aTimeStamp
;
98 TimeStamp
GetCompositeUntilTime() const { return mCompositeUntilTime
; }
100 void AddAsyncImagePipeline(const wr::PipelineId
& aPipelineId
,
101 WebRenderImageHost
* aImageHost
);
102 void RemoveAsyncImagePipeline(const wr::PipelineId
& aPipelineId
,
103 wr::TransactionBuilder
& aTxn
);
105 void UpdateAsyncImagePipeline(const wr::PipelineId
& aPipelineId
,
106 const LayoutDeviceRect
& aScBounds
,
107 VideoInfo::Rotation aRotation
,
108 const wr::ImageRendering
& aFilter
,
109 const wr::MixBlendMode
& aMixBlendMode
);
110 void ApplyAsyncImagesOfImageBridge(wr::TransactionBuilder
& aSceneBuilderTxn
,
111 wr::TransactionBuilder
& aFastTxn
);
112 void ApplyAsyncImageForPipeline(const wr::PipelineId
& aPipelineId
,
113 wr::TransactionBuilder
& aTxn
,
114 wr::TransactionBuilder
& aTxnForImageBridge
,
115 RemoteTextureInfoList
* aList
);
117 void SetEmptyDisplayList(const wr::PipelineId
& aPipelineId
,
118 wr::TransactionBuilder
& aTxn
,
119 wr::TransactionBuilder
& aTxnForImageBridge
);
121 void AppendImageCompositeNotification(
122 const ImageCompositeNotificationInfo
& aNotification
) {
123 mImageCompositeNotifications
.AppendElement(aNotification
);
126 void FlushImageNotifications(
127 nsTArray
<ImageCompositeNotificationInfo
>* aNotifications
) {
128 aNotifications
->AppendElements(std::move(mImageCompositeNotifications
));
131 void SetWillGenerateFrame();
132 bool GetAndResetWillGenerateFrame();
134 static wr::ExternalImageId
GetNextExternalImageId();
137 void ProcessPipelineRendered(const wr::PipelineId
& aPipelineId
,
138 const wr::Epoch
& aEpoch
,
139 wr::RenderedFrameId aRenderedFrameId
);
140 void ProcessPipelineRemoved(const wr::RemovedPipeline
& aRemovedPipeline
,
141 wr::RenderedFrameId aRenderedFrameId
);
143 wr::Epoch
GetNextImageEpoch();
144 uint32_t GetNextResourceId() { return ++mResourceId
; }
145 wr::IdNamespace
GetNamespace() { return mIdNamespace
; }
146 wr::ImageKey
GenerateImageKey() {
148 key
.mNamespace
= GetNamespace();
149 key
.mHandle
= GetNextResourceId();
153 struct ForwardingTextureHost
{
154 ForwardingTextureHost(const wr::Epoch
& aEpoch
, TextureHost
* aTexture
)
155 : mEpoch(aEpoch
), mTexture(aTexture
) {}
157 CompositableTextureHostRef mTexture
;
160 struct ForwardingExternalImage
{
161 ForwardingExternalImage(const wr::Epoch
& aEpoch
,
162 const wr::ExternalImageId
& aImageId
)
163 : mEpoch(aEpoch
), mImageId(aImageId
) {}
164 ~ForwardingExternalImage();
166 wr::ExternalImageId mImageId
;
169 struct PipelineTexturesHolder
{
170 // Holds forwarding WebRenderTextureHosts.
171 std::vector
<ForwardingTextureHost
> mTextureHostsUntilRenderSubmitted
;
172 // TextureHosts that must be held until rendering has completed. UniquePtr
173 // is used to make the entries movable, ideally ForwardingTextureHost would
175 std::vector
<UniquePtr
<ForwardingTextureHost
>>
176 mTextureHostsUntilRenderCompleted
;
177 std::vector
<UniquePtr
<ForwardingExternalImage
>> mExternalImages
;
178 Maybe
<wr::Epoch
> mDestroyedEpoch
;
179 WebRenderBridgeParent
* MOZ_NON_OWNING_REF mWrBridge
= nullptr;
182 struct AsyncImagePipeline
{
183 AsyncImagePipeline(wr::PipelineId aPipelineId
,
184 layers::WebRenderBackend aBackend
);
185 void Update(const LayoutDeviceRect
& aScBounds
,
186 VideoInfo::Rotation aRotation
,
187 const wr::ImageRendering
& aFilter
,
188 const wr::MixBlendMode
& aMixBlendMode
) {
189 mIsChanged
|= !mScBounds
.IsEqualEdges(aScBounds
) ||
190 mRotation
!= aRotation
|| mFilter
!= aFilter
||
191 mMixBlendMode
!= aMixBlendMode
;
192 mScBounds
= aScBounds
;
193 mRotation
= aRotation
;
195 mMixBlendMode
= aMixBlendMode
;
200 bool mUseExternalImage
;
201 LayoutDeviceRect mScBounds
;
202 VideoInfo::Rotation mRotation
;
203 wr::ImageRendering mFilter
;
204 wr::MixBlendMode mMixBlendMode
;
205 RefPtr
<WebRenderImageHost
> mImageHost
;
206 CompositableTextureHostRef mCurrentTexture
;
207 nsTArray
<wr::ImageKey
> mKeys
;
208 wr::DisplayListBuilder mDLBuilder
;
211 void ApplyAsyncImageForPipeline(const wr::Epoch
& aEpoch
,
212 const wr::PipelineId
& aPipelineId
,
213 AsyncImagePipeline
* aPipeline
,
214 wr::TransactionBuilder
& aSceneBuilderTxn
,
215 wr::TransactionBuilder
& aMaybeFastTxn
,
216 RemoteTextureInfoList
* aList
);
217 Maybe
<TextureHost::ResourceUpdateOp
> UpdateImageKeys(
218 const wr::Epoch
& aEpoch
, const wr::PipelineId
& aPipelineId
,
219 AsyncImagePipeline
* aPipeline
, nsTArray
<wr::ImageKey
>& aKeys
,
220 wr::TransactionBuilder
& aSceneBuilderTxn
,
221 wr::TransactionBuilder
& aMaybeFastTxn
, RemoteTextureInfoList
* aList
);
222 Maybe
<TextureHost::ResourceUpdateOp
> UpdateWithoutExternalImage(
223 TextureHost
* aTexture
, wr::ImageKey aKey
, TextureHost::ResourceUpdateOp
,
224 wr::TransactionBuilder
& aTxn
);
226 void CheckForTextureHostsNotUsedByGPU();
228 RefPtr
<wr::WebRenderAPI
> mApi
;
229 bool mUseCompositorWnd
;
231 const wr::IdNamespace mIdNamespace
;
232 const bool mUseTripleBuffering
;
233 uint32_t mResourceId
;
235 nsClassHashtable
<nsUint64HashKey
, PipelineTexturesHolder
>
236 mPipelineTexturesHolders
;
237 nsClassHashtable
<nsUint64HashKey
, AsyncImagePipeline
> mAsyncImagePipelines
;
238 wr::Epoch mAsyncImageEpoch
;
239 bool mWillGenerateFrame
;
243 bool mUseWebRenderDCompVideoOverlayWin
;
246 // Render time for the current composition.
247 TimeStamp mCompositionTime
;
249 // CompositionOpportunityId of the current composition.
250 CompositionOpportunityId mCompositionOpportunityId
;
252 // When nonnull, during rendering, some compositable indicated that it will
253 // change its rendering at this time. In order not to miss it, we composite
254 // on every vsync until this time occurs (this is the latest such time).
255 TimeStamp mCompositeUntilTime
;
257 nsTArray
<ImageCompositeNotificationInfo
> mImageCompositeNotifications
;
259 struct WebRenderPipelineInfoHolder
{
260 WebRenderPipelineInfoHolder(RefPtr
<const wr::WebRenderPipelineInfo
>&& aInfo
,
261 ipc::FileDescriptor
&& aFenceFd
);
262 ~WebRenderPipelineInfoHolder();
263 RefPtr
<const wr::WebRenderPipelineInfo
> mInfo
;
264 ipc::FileDescriptor mFenceFd
;
267 std::vector
<std::pair
<wr::RenderedFrameId
, WebRenderPipelineInfoHolder
>>
268 mRenderSubmittedUpdates
;
269 Mutex mRenderSubmittedUpdatesLock MOZ_UNANNOTATED
;
271 Atomic
<uint64_t> mLastCompletedFrameId
;
272 std::vector
<std::pair
<wr::RenderedFrameId
,
273 std::vector
<UniquePtr
<ForwardingTextureHost
>>>>
275 ipc::FileDescriptor mReleaseFenceFd
;
278 } // namespace layers
279 } // namespace mozilla
281 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */