/src/mozilla-central/gfx/layers/wr/AsyncImagePipelineManager.h
Line | Count | Source (jump to first uncovered line) |
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_WEBRENDERCOMPOSITABLE_HOLDER_H |
8 | | #define MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H |
9 | | |
10 | | #include <queue> |
11 | | |
12 | | #include "CompositableHost.h" |
13 | | #include "mozilla/gfx/Point.h" |
14 | | #include "mozilla/layers/TextureHost.h" |
15 | | #include "mozilla/layers/WebRenderTextureHostWrapper.h" |
16 | | #include "mozilla/Maybe.h" |
17 | | #include "mozilla/webrender/WebRenderAPI.h" |
18 | | #include "mozilla/webrender/WebRenderTypes.h" |
19 | | #include "nsClassHashtable.h" |
20 | | |
21 | | namespace mozilla { |
22 | | |
23 | | namespace wr { |
24 | | class DisplayListBuilder; |
25 | | class WebRenderAPI; |
26 | | } |
27 | | |
28 | | namespace layers { |
29 | | |
30 | | class CompositableHost; |
31 | | class CompositorVsyncScheduler; |
32 | | class WebRenderImageHost; |
33 | | class WebRenderTextureHost; |
34 | | class WebRenderTextureHostWrapper; |
35 | | |
36 | | class AsyncImagePipelineManager final |
37 | | { |
38 | | public: |
39 | | NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager) |
40 | | |
41 | | explicit AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi); |
42 | | |
43 | | protected: |
44 | | ~AsyncImagePipelineManager(); |
45 | | |
46 | | public: |
47 | | void Destroy(); |
48 | | |
49 | | void AddPipeline(const wr::PipelineId& aPipelineId); |
50 | | void RemovePipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch); |
51 | | |
52 | | void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHost* aTexture); |
53 | | void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, WebRenderTextureHostWrapper* aWrTextureWrapper); |
54 | | void HoldExternalImage(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, const wr::ExternalImageId& aImageId); |
55 | | |
56 | | // This is called from the Renderer thread to notify this class about the |
57 | | // pipelines in the most recently completed render. A copy of the update |
58 | | // information is put into mUpdatesQueue. |
59 | | void NotifyPipelinesUpdated(wr::WrPipelineInfo aInfo); |
60 | | |
61 | | // This is run on the compositor thread to process mUpdatesQueue. We make |
62 | | // this a public entry point because we need to invoke it from other places. |
63 | | void ProcessPipelineUpdates(); |
64 | | |
65 | | TimeStamp GetCompositionTime() const { |
66 | | return mCompositionTime; |
67 | | } |
68 | | void SetCompositionTime(TimeStamp aTimeStamp) { |
69 | | mCompositionTime = aTimeStamp; |
70 | | if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && |
71 | | mCompositionTime >= mCompositeUntilTime) { |
72 | | mCompositeUntilTime = TimeStamp(); |
73 | | } |
74 | | } |
75 | | void CompositeUntil(TimeStamp aTimeStamp) { |
76 | | if (mCompositeUntilTime.IsNull() || |
77 | | mCompositeUntilTime < aTimeStamp) { |
78 | | mCompositeUntilTime = aTimeStamp; |
79 | | } |
80 | | } |
81 | | TimeStamp GetCompositeUntilTime() const { |
82 | | return mCompositeUntilTime; |
83 | | } |
84 | | |
85 | | void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId, WebRenderImageHost* aImageHost); |
86 | | void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn); |
87 | | |
88 | | void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId, |
89 | | const LayoutDeviceRect& aScBounds, |
90 | | const gfx::Matrix4x4& aScTransform, |
91 | | const gfx::MaybeIntSize& aScaleToSize, |
92 | | const wr::ImageRendering& aFilter, |
93 | | const wr::MixBlendMode& aMixBlendMode); |
94 | | void ApplyAsyncImagesOfImageBridge(wr::TransactionBuilder& aSceneBuilderTxn, wr::TransactionBuilder& aFastTxn); |
95 | | void ApplyAsyncImageForPipeline(const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aSceneBuilderTxn); |
96 | | |
97 | | void SetEmptyDisplayList(const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn); |
98 | | |
99 | | void AppendImageCompositeNotification(const ImageCompositeNotificationInfo& aNotification) |
100 | | { |
101 | | mImageCompositeNotifications.AppendElement(aNotification); |
102 | | } |
103 | | |
104 | | void FlushImageNotifications(nsTArray<ImageCompositeNotificationInfo>* aNotifications) |
105 | | { |
106 | | aNotifications->AppendElements(std::move(mImageCompositeNotifications)); |
107 | | } |
108 | | |
109 | | void SetWillGenerateFrame(); |
110 | | bool GetAndResetWillGenerateFrame(); |
111 | | |
112 | | wr::ExternalImageId GetNextExternalImageId(); |
113 | | |
114 | | private: |
115 | | void ProcessPipelineRendered(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch); |
116 | | void ProcessPipelineRemoved(const wr::PipelineId& aPipelineId); |
117 | | |
118 | | wr::Epoch GetNextImageEpoch(); |
119 | 0 | uint32_t GetNextResourceId() { return ++mResourceId; } |
120 | 0 | wr::IdNamespace GetNamespace() { return mIdNamespace; } |
121 | | wr::ImageKey GenerateImageKey() |
122 | 0 | { |
123 | 0 | wr::ImageKey key; |
124 | 0 | key.mNamespace = GetNamespace(); |
125 | 0 | key.mHandle = GetNextResourceId(); |
126 | 0 | return key; |
127 | 0 | } |
128 | | |
129 | | struct ForwardingTextureHost { |
130 | | ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture) |
131 | | : mEpoch(aEpoch) |
132 | | , mTexture(aTexture) |
133 | 0 | {} |
134 | | wr::Epoch mEpoch; |
135 | | CompositableTextureHostRef mTexture; |
136 | | }; |
137 | | |
138 | | struct ForwardingTextureHostWrapper { |
139 | | ForwardingTextureHostWrapper(const wr::Epoch& aEpoch, WebRenderTextureHostWrapper* aWrTextureWrapper) |
140 | | : mEpoch(aEpoch) |
141 | | , mWrTextureWrapper(aWrTextureWrapper) |
142 | 0 | {} |
143 | | wr::Epoch mEpoch; |
144 | | RefPtr<WebRenderTextureHostWrapper> mWrTextureWrapper; |
145 | | }; |
146 | | |
147 | | struct ForwardingExternalImage { |
148 | | ForwardingExternalImage(const wr::Epoch& aEpoch, const wr::ExternalImageId& aImageId) |
149 | | : mEpoch(aEpoch) |
150 | | , mImageId(aImageId) |
151 | 0 | {} |
152 | | wr::Epoch mEpoch; |
153 | | wr::ExternalImageId mImageId; |
154 | | }; |
155 | | |
156 | | struct PipelineTexturesHolder { |
157 | | // Holds forwarding WebRenderTextureHosts. |
158 | | std::queue<ForwardingTextureHost> mTextureHosts; |
159 | | std::queue<ForwardingTextureHostWrapper> mTextureHostWrappers; |
160 | | std::queue<ForwardingExternalImage> mExternalImages; |
161 | | Maybe<wr::Epoch> mDestroyedEpoch; |
162 | | }; |
163 | | |
164 | | struct AsyncImagePipeline { |
165 | | AsyncImagePipeline(); |
166 | | void Update(const LayoutDeviceRect& aScBounds, |
167 | | const gfx::Matrix4x4& aScTransform, |
168 | | const gfx::MaybeIntSize& aScaleToSize, |
169 | | const wr::ImageRendering& aFilter, |
170 | | const wr::MixBlendMode& aMixBlendMode) |
171 | 0 | { |
172 | 0 | mIsChanged |= !mScBounds.IsEqualEdges(aScBounds) || |
173 | 0 | mScTransform != aScTransform || |
174 | 0 | mScaleToSize != aScaleToSize || |
175 | 0 | mFilter != aFilter || |
176 | 0 | mMixBlendMode != aMixBlendMode; |
177 | 0 | mScBounds = aScBounds; |
178 | 0 | mScTransform = aScTransform; |
179 | 0 | mScaleToSize = aScaleToSize; |
180 | 0 | mFilter = aFilter; |
181 | 0 | mMixBlendMode = aMixBlendMode; |
182 | 0 | } |
183 | | |
184 | | bool mInitialised; |
185 | | bool mIsChanged; |
186 | | bool mUseExternalImage; |
187 | | LayoutDeviceRect mScBounds; |
188 | | gfx::Matrix4x4 mScTransform; |
189 | | gfx::MaybeIntSize mScaleToSize; |
190 | | wr::ImageRendering mFilter; |
191 | | wr::MixBlendMode mMixBlendMode; |
192 | | RefPtr<WebRenderImageHost> mImageHost; |
193 | | CompositableTextureHostRef mCurrentTexture; |
194 | | RefPtr<WebRenderTextureHostWrapper> mWrTextureWrapper; |
195 | | nsTArray<wr::ImageKey> mKeys; |
196 | | }; |
197 | | |
198 | | void ApplyAsyncImageForPipeline(const wr::Epoch& aEpoch, |
199 | | const wr::PipelineId& aPipelineId, |
200 | | AsyncImagePipeline* aPipeline, |
201 | | wr::TransactionBuilder& aSceneBuilderTxn, |
202 | | wr::TransactionBuilder& aMaybeFastTxn); |
203 | | Maybe<TextureHost::ResourceUpdateOp> |
204 | | UpdateImageKeys(const wr::Epoch& aEpoch, |
205 | | const wr::PipelineId& aPipelineId, |
206 | | AsyncImagePipeline* aPipeline, |
207 | | nsTArray<wr::ImageKey>& aKeys, |
208 | | wr::TransactionBuilder& aSceneBuilderTxn, |
209 | | wr::TransactionBuilder& aMaybeFastTxn); |
210 | | Maybe<TextureHost::ResourceUpdateOp> |
211 | | UpdateWithoutExternalImage(TextureHost* aTexture, |
212 | | wr::ImageKey aKey, |
213 | | TextureHost::ResourceUpdateOp, |
214 | | wr::TransactionBuilder& aTxn); |
215 | | |
216 | | RefPtr<wr::WebRenderAPI> mApi; |
217 | | wr::IdNamespace mIdNamespace; |
218 | | uint32_t mResourceId; |
219 | | |
220 | | nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> mPipelineTexturesHolders; |
221 | | nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines; |
222 | | wr::Epoch mAsyncImageEpoch; |
223 | | bool mWillGenerateFrame; |
224 | | bool mDestroyed; |
225 | | |
226 | | // Render time for the current composition. |
227 | | TimeStamp mCompositionTime; |
228 | | |
229 | | // When nonnull, during rendering, some compositable indicated that it will |
230 | | // change its rendering at this time. In order not to miss it, we composite |
231 | | // on every vsync until this time occurs (this is the latest such time). |
232 | | TimeStamp mCompositeUntilTime; |
233 | | |
234 | | nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications; |
235 | | |
236 | | // The lock that protects mUpdatesQueue |
237 | | Mutex mUpdatesLock; |
238 | | // Queue to store rendered pipeline epoch information. This is populated from |
239 | | // the Renderer thread after a render, and is read from the compositor thread |
240 | | // to free resources (e.g. textures) that are no longer needed. Each entry |
241 | | // in the queue is a pair that holds the pipeline id and Some(x) for |
242 | | // a render of epoch x, or Nothing() for a removed pipeline. |
243 | | std::queue<std::pair<wr::PipelineId, Maybe<wr::Epoch>>> mUpdatesQueue; |
244 | | }; |
245 | | |
246 | | } // namespace layers |
247 | | } // namespace mozilla |
248 | | |
249 | | #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */ |