AsyncImagePipelineManager.h (11708B)
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 <vector> 11 12 #include "CompositableHost.h" 13 #include "mozilla/gfx/Point.h" 14 #include "mozilla/layers/RemoteTextureMap.h" 15 #include "mozilla/layers/TextureHost.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 RenderTextureHostUsageInfo; 26 class WebRenderAPI; 27 class WebRenderPipelineInfo; 28 } // namespace wr 29 30 namespace layers { 31 32 class CompositableHost; 33 class CompositorVsyncScheduler; 34 class Fence; 35 class WebRenderImageHost; 36 class WebRenderTextureHost; 37 38 class AsyncImagePipelineManager final { 39 public: 40 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager) 41 42 explicit AsyncImagePipelineManager(RefPtr<wr::WebRenderAPI>&& aApi, 43 bool aUseCompositorWnd); 44 45 protected: 46 ~AsyncImagePipelineManager(); 47 48 public: 49 void Destroy(); 50 51 bool UseCompositorWnd() const { return mUseCompositorWnd; } 52 53 void AddPipeline(const wr::PipelineId& aPipelineId, 54 WebRenderBridgeParent* aWrBridge); 55 void RemovePipeline(const wr::PipelineId& aPipelineId, 56 const wr::Epoch& aEpoch); 57 WebRenderBridgeParent* GetWrBridge(const wr::PipelineId& aPipelineId); 58 59 void HoldExternalImage(const wr::PipelineId& aPipelineId, 60 const wr::Epoch& aEpoch, TextureHost* aTexture); 61 void HoldExternalImage(const wr::PipelineId& aPipelineId, 62 const wr::Epoch& aEpoch, 63 const wr::ExternalImageId& aImageId); 64 65 // This is called from the Renderer thread to notify this class about the 66 // pipelines in the most recently completed update. 67 // @param aInfo PipelineInfo for the update 68 // @param aLatestFrameId RenderedFrameId if a frame has been submitted for 69 // rendering, invalid if not 70 // @param aLastCompletedFrameId RenderedFrameId for the last completed frame 71 void NotifyPipelinesUpdated(RefPtr<const wr::WebRenderPipelineInfo> aInfo, 72 wr::RenderedFrameId aLatestFrameId, 73 wr::RenderedFrameId aLastCompletedFrameId, 74 RefPtr<Fence>&& aFence); 75 76 // This is run on the compositor thread to process mRenderSubmittedUpdates. We 77 // make this public because we need to invoke it from other places. 78 void ProcessPipelineUpdates(); 79 80 TimeStamp GetCompositionTime() const { return mCompositionTime; } 81 CompositionOpportunityId GetCompositionOpportunityId() const { 82 return mCompositionOpportunityId; 83 } 84 85 void SetCompositionInfo(TimeStamp aTimeStamp, 86 CompositionOpportunityId aCompositionOpportunityId) { 87 mCompositionTime = aTimeStamp; 88 mCompositionOpportunityId = aCompositionOpportunityId; 89 if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && 90 mCompositionTime >= mCompositeUntilTime) { 91 mCompositeUntilTime = TimeStamp(); 92 } 93 } 94 void CompositeUntil(TimeStamp aTimeStamp) { 95 if (mCompositeUntilTime.IsNull() || mCompositeUntilTime < aTimeStamp) { 96 mCompositeUntilTime = aTimeStamp; 97 } 98 } 99 TimeStamp GetCompositeUntilTime() const { return mCompositeUntilTime; } 100 101 void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId, 102 WebRenderImageHost* aImageHost); 103 void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId, 104 AsyncImagePipelineOps* aPendingOps, 105 wr::TransactionBuilder& aTxn); 106 107 void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId, 108 const LayoutDeviceRect& aScBounds, 109 wr::WrRotation aRotation, 110 const wr::ImageRendering& aFilter, 111 const wr::MixBlendMode& aMixBlendMode); 112 void ApplyAsyncImagesOfImageBridge(wr::TransactionBuilder& aSceneBuilderTxn, 113 wr::TransactionBuilder& aFastTxn); 114 void ApplyAsyncImageForPipeline( 115 const wr::PipelineId& aPipelineId, wr::TransactionBuilder& aTxn, 116 wr::TransactionBuilder& aTxnForImageBridge, 117 AsyncImagePipelineOps* aPendingOps, 118 RemoteTextureInfoList* aPendingRemoteTextures); 119 120 void ApplyAsyncImageForPipeline(const wr::PipelineId& aPipelineId, 121 TextureHost* aTexture, 122 wr::TransactionBuilder& aTxn); 123 124 void SetEmptyDisplayList(const wr::PipelineId& aPipelineId, 125 wr::TransactionBuilder& aTxn, 126 wr::TransactionBuilder& aTxnForImageBridge); 127 128 void AppendImageCompositeNotification( 129 const ImageCompositeNotificationInfo& aNotification) { 130 mImageCompositeNotifications.AppendElement(aNotification); 131 } 132 133 void FlushImageNotifications( 134 nsTArray<ImageCompositeNotificationInfo>* aNotifications) { 135 aNotifications->AppendElements(std::move(mImageCompositeNotifications)); 136 } 137 138 void SetWillGenerateFrame(); 139 bool GetAndResetWillGenerateFrame(); 140 141 static wr::ExternalImageId GetNextExternalImageId(); 142 143 void SetTextureFactoryIdentifier( 144 const TextureFactoryIdentifier& aTextureFactoryIdentifier) { 145 mTextureFactoryIdentifier = aTextureFactoryIdentifier; 146 } 147 148 TextureFactoryIdentifier GetTextureFactoryIdentifier() const { 149 return mTextureFactoryIdentifier; 150 } 151 152 private: 153 void ProcessPipelineRendered(const wr::PipelineId& aPipelineId, 154 const wr::Epoch& aEpoch, 155 wr::RenderedFrameId aRenderedFrameId); 156 void ProcessPipelineRemoved(const wr::RemovedPipeline& aRemovedPipeline, 157 wr::RenderedFrameId aRenderedFrameId); 158 159 wr::Epoch GetNextImageEpoch(); 160 uint32_t GetNextResourceId() { return ++mResourceId; } 161 wr::IdNamespace GetNamespace() { return mIdNamespace; } 162 wr::ImageKey GenerateImageKey() { 163 wr::ImageKey key; 164 key.mNamespace = GetNamespace(); 165 key.mHandle = GetNextResourceId(); 166 return key; 167 } 168 169 struct ForwardingTextureHost { 170 ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture) 171 : mEpoch(aEpoch), mTexture(aTexture) {} 172 wr::Epoch mEpoch; 173 CompositableTextureHostRef mTexture; 174 }; 175 176 struct ForwardingExternalImage { 177 ForwardingExternalImage(const wr::Epoch& aEpoch, 178 const wr::ExternalImageId& aImageId) 179 : mEpoch(aEpoch), mImageId(aImageId) {} 180 ~ForwardingExternalImage(); 181 wr::Epoch mEpoch; 182 wr::ExternalImageId mImageId; 183 }; 184 185 struct PipelineTexturesHolder { 186 // Holds forwarding WebRenderTextureHosts. 187 std::vector<ForwardingTextureHost> mTextureHostsUntilRenderSubmitted; 188 // TextureHosts that must be held until rendering has completed. UniquePtr 189 // is used to make the entries movable, ideally ForwardingTextureHost would 190 // be fully movable. 191 std::vector<UniquePtr<ForwardingTextureHost>> 192 mTextureHostsUntilRenderCompleted; 193 std::vector<UniquePtr<ForwardingExternalImage>> mExternalImages; 194 Maybe<wr::Epoch> mDestroyedEpoch; 195 WebRenderBridgeParent* MOZ_NON_OWNING_REF mWrBridge = nullptr; 196 }; 197 198 struct AsyncImagePipeline { 199 AsyncImagePipeline(wr::PipelineId aPipelineId, 200 layers::WebRenderBackend aBackend, 201 WebRenderImageHost* aImageHost); 202 void Update(const LayoutDeviceRect& aScBounds, wr::WrRotation aRotation, 203 const wr::ImageRendering& aFilter, 204 const wr::MixBlendMode& aMixBlendMode) { 205 mIsChanged |= !mScBounds.IsEqualEdges(aScBounds) || 206 mRotation != aRotation || mFilter != aFilter || 207 mMixBlendMode != aMixBlendMode; 208 mScBounds = aScBounds; 209 mRotation = aRotation; 210 mFilter = aFilter; 211 mMixBlendMode = aMixBlendMode; 212 } 213 214 bool mInitialised; 215 bool mIsChanged; 216 bool mUseExternalImage; 217 LayoutDeviceRect mScBounds; 218 wr::WrRotation mRotation; 219 wr::ImageRendering mFilter; 220 wr::MixBlendMode mMixBlendMode; 221 const RefPtr<WebRenderImageHost> mImageHost; 222 CompositableTextureHostRef mCurrentTexture; 223 nsTArray<wr::ImageKey> mKeys; 224 wr::DisplayListBuilder mDLBuilder; 225 bool mVideoOverlayDisabled = false; 226 }; 227 228 void ApplyAsyncImageForPipeline(const wr::Epoch& aEpoch, 229 const wr::PipelineId& aPipelineId, 230 AsyncImagePipeline* aPipeline, 231 TextureHost* aTexture, 232 wr::TransactionBuilder& aSceneBuilderTxn, 233 wr::TransactionBuilder& aMaybeFastTxn); 234 Maybe<TextureHost::ResourceUpdateOp> UpdateImageKeys( 235 const wr::Epoch& aEpoch, const wr::PipelineId& aPipelineId, 236 AsyncImagePipeline* aPipeline, TextureHost* aTexture, 237 nsTArray<wr::ImageKey>& aKeys, wr::TransactionBuilder& aSceneBuilderTxn, 238 wr::TransactionBuilder& aMaybeFastTxn); 239 Maybe<TextureHost::ResourceUpdateOp> UpdateWithoutExternalImage( 240 TextureHost* aTexture, wr::ImageKey aKey, TextureHost::ResourceUpdateOp, 241 wr::TransactionBuilder& aTxn); 242 243 void CheckForTextureHostsNotUsedByGPU(); 244 245 RefPtr<wr::WebRenderAPI> mApi; 246 bool mUseCompositorWnd; 247 TextureFactoryIdentifier mTextureFactoryIdentifier; 248 249 const wr::IdNamespace mIdNamespace; 250 const bool mUseTripleBuffering; 251 uint32_t mResourceId; 252 253 nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> 254 mPipelineTexturesHolders; 255 nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines; 256 wr::Epoch mAsyncImageEpoch; 257 bool mWillGenerateFrame; 258 bool mDestroyed; 259 260 #ifdef XP_WIN 261 bool mUseWebRenderDCompVideoHwOverlayWin; 262 bool mUseWebRenderDCompVideoSwOverlayWin; 263 bool mUseWebRenderDCompositionTextureOverlayWin; 264 #endif 265 266 // Render time for the current composition. 267 TimeStamp mCompositionTime; 268 269 // CompositionOpportunityId of the current composition. 270 CompositionOpportunityId mCompositionOpportunityId; 271 272 // When nonnull, during rendering, some compositable indicated that it will 273 // change its rendering at this time. In order not to miss it, we composite 274 // on every vsync until this time occurs (this is the latest such time). 275 TimeStamp mCompositeUntilTime; 276 277 nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications; 278 279 struct WebRenderPipelineInfoHolder { 280 WebRenderPipelineInfoHolder(RefPtr<const wr::WebRenderPipelineInfo>&& aInfo, 281 RefPtr<Fence>&& aFence); 282 ~WebRenderPipelineInfoHolder(); 283 WebRenderPipelineInfoHolder(WebRenderPipelineInfoHolder&&) = default; 284 RefPtr<const wr::WebRenderPipelineInfo> mInfo; 285 RefPtr<Fence> mFence; 286 }; 287 288 std::vector<std::pair<wr::RenderedFrameId, WebRenderPipelineInfoHolder>> 289 mRenderSubmittedUpdates; 290 Mutex mRenderSubmittedUpdatesLock MOZ_UNANNOTATED; 291 292 Atomic<uint64_t> mLastCompletedFrameId; 293 std::vector<std::pair<wr::RenderedFrameId, 294 std::vector<UniquePtr<ForwardingTextureHost>>>> 295 mTexturesInUseByGPU; 296 RefPtr<Fence> mReadFence; 297 }; 298 299 } // namespace layers 300 } // namespace mozilla 301 302 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */