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