Bug 1803984 - Add tests for the interaction between speculative preloading and module...
[gecko.git] / gfx / layers / wr / AsyncImagePipelineManager.h
blob1ed144c5484fb02b82a95b2e94cae3b3d8ccdb1e
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
10 #include <vector>
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"
22 namespace mozilla {
24 namespace wr {
25 class DisplayListBuilder;
26 class WebRenderAPI;
27 class WebRenderPipelineInfo;
28 } // namespace wr
30 namespace layers {
32 class CompositableHost;
33 class CompositorVsyncScheduler;
34 class WebRenderImageHost;
35 class WebRenderTextureHost;
37 class AsyncImagePipelineManager final {
38 public:
39 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager)
41 explicit AsyncImagePipelineManager(RefPtr<wr::WebRenderAPI>&& aApi,
42 bool aUseCompositorWnd);
44 protected:
45 ~AsyncImagePipelineManager();
47 public:
48 void Destroy();
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();
136 private:
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() {
147 wr::ImageKey key;
148 key.mNamespace = GetNamespace();
149 key.mHandle = GetNextResourceId();
150 return key;
153 struct ForwardingTextureHost {
154 ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture)
155 : mEpoch(aEpoch), mTexture(aTexture) {}
156 wr::Epoch mEpoch;
157 CompositableTextureHostRef mTexture;
160 struct ForwardingExternalImage {
161 ForwardingExternalImage(const wr::Epoch& aEpoch,
162 const wr::ExternalImageId& aImageId)
163 : mEpoch(aEpoch), mImageId(aImageId) {}
164 ~ForwardingExternalImage();
165 wr::Epoch mEpoch;
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
174 // be fully movable.
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;
194 mFilter = aFilter;
195 mMixBlendMode = aMixBlendMode;
198 bool mInitialised;
199 bool mIsChanged;
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;
240 bool mDestroyed;
242 #ifdef XP_WIN
243 bool mUseWebRenderDCompVideoOverlayWin;
244 #endif
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>>>>
274 mTexturesInUseByGPU;
275 ipc::FileDescriptor mReleaseFenceFd;
278 } // namespace layers
279 } // namespace mozilla
281 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */