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/Maybe.h" 16 #include "mozilla/webrender/WebRenderAPI.h" 17 #include "mozilla/webrender/WebRenderTypes.h" 18 #include "nsClassHashtable.h" 19 20 namespace mozilla { 21 22 namespace wr { 23 class DisplayListBuilder; 24 class WebRenderAPI; 25 } // namespace wr 26 27 namespace layers { 28 29 class CompositableHost; 30 class CompositorVsyncScheduler; 31 class WebRenderImageHost; 32 class WebRenderTextureHost; 33 34 class AsyncImagePipelineManager final { 35 public: 36 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager) 37 38 explicit AsyncImagePipelineManager(already_AddRefed<wr::WebRenderAPI>&& aApi); 39 40 protected: 41 ~AsyncImagePipelineManager(); 42 43 public: 44 void Destroy(); 45 46 void AddPipeline(const wr::PipelineId& aPipelineId); 47 void RemovePipeline(const wr::PipelineId& aPipelineId, 48 const wr::Epoch& aEpoch); 49 50 void HoldExternalImage(const wr::PipelineId& aPipelineId, 51 const wr::Epoch& aEpoch, 52 WebRenderTextureHost* aTexture); 53 void PipelineRendered(const wr::PipelineId& aPipelineId, 54 const wr::Epoch& aEpoch); 55 void PipelineRemoved(const wr::PipelineId& aPipelineId); 56 GetCompositionTime()57 TimeStamp GetCompositionTime() const { return mCompositionTime; } SetCompositionTime(TimeStamp aTimeStamp)58 void SetCompositionTime(TimeStamp aTimeStamp) { 59 mCompositionTime = aTimeStamp; 60 if (!mCompositionTime.IsNull() && !mCompositeUntilTime.IsNull() && 61 mCompositionTime >= mCompositeUntilTime) { 62 mCompositeUntilTime = TimeStamp(); 63 } 64 } CompositeUntil(TimeStamp aTimeStamp)65 void CompositeUntil(TimeStamp aTimeStamp) { 66 if (mCompositeUntilTime.IsNull() || mCompositeUntilTime < aTimeStamp) { 67 mCompositeUntilTime = aTimeStamp; 68 } 69 } GetCompositeUntilTime()70 TimeStamp GetCompositeUntilTime() const { return mCompositeUntilTime; } 71 72 void AddAsyncImagePipeline(const wr::PipelineId& aPipelineId, 73 WebRenderImageHost* aImageHost); 74 void RemoveAsyncImagePipeline(const wr::PipelineId& aPipelineId, 75 wr::TransactionBuilder& aTxn); 76 77 void UpdateAsyncImagePipeline(const wr::PipelineId& aPipelineId, 78 const LayoutDeviceRect& aScBounds, 79 const gfx::Matrix4x4& aScTransform, 80 const gfx::MaybeIntSize& aScaleToSize, 81 const wr::ImageRendering& aFilter, 82 const wr::MixBlendMode& aMixBlendMode); 83 void ApplyAsyncImages(); 84 AppendImageCompositeNotification(const ImageCompositeNotificationInfo & aNotification)85 void AppendImageCompositeNotification( 86 const ImageCompositeNotificationInfo& aNotification) { 87 mImageCompositeNotifications.AppendElement(aNotification); 88 } 89 FlushImageNotifications(nsTArray<ImageCompositeNotificationInfo> * aNotifications)90 void FlushImageNotifications( 91 nsTArray<ImageCompositeNotificationInfo>* aNotifications) { 92 aNotifications->AppendElements(Move(mImageCompositeNotifications)); 93 } 94 95 void SetWillGenerateFrame(); 96 bool GetAndResetWillGenerateFrame(); 97 98 private: GetNextResourceId()99 uint32_t GetNextResourceId() { return ++mResourceId; } GetNamespace()100 wr::IdNamespace GetNamespace() { return mIdNamespace; } GenerateImageKey()101 wr::ImageKey GenerateImageKey() { 102 wr::ImageKey key; 103 key.mNamespace = GetNamespace(); 104 key.mHandle = GetNextResourceId(); 105 return key; 106 } 107 108 struct ForwardingTextureHost { ForwardingTextureHostForwardingTextureHost109 ForwardingTextureHost(const wr::Epoch& aEpoch, TextureHost* aTexture) 110 : mEpoch(aEpoch), mTexture(aTexture) {} 111 wr::Epoch mEpoch; 112 CompositableTextureHostRef mTexture; 113 }; 114 115 struct PipelineTexturesHolder { 116 // Holds forwarding WebRenderTextureHosts. 117 std::queue<ForwardingTextureHost> mTextureHosts; 118 Maybe<wr::Epoch> mDestroyedEpoch; 119 }; 120 121 struct AsyncImagePipeline { 122 AsyncImagePipeline(); UpdateAsyncImagePipeline123 void Update(const LayoutDeviceRect& aScBounds, 124 const gfx::Matrix4x4& aScTransform, 125 const gfx::MaybeIntSize& aScaleToSize, 126 const wr::ImageRendering& aFilter, 127 const wr::MixBlendMode& aMixBlendMode) { 128 mIsChanged |= !mScBounds.IsEqualEdges(aScBounds) || 129 mScTransform != aScTransform || 130 mScaleToSize != aScaleToSize || mFilter != aFilter || 131 mMixBlendMode != aMixBlendMode; 132 mScBounds = aScBounds; 133 mScTransform = aScTransform; 134 mScaleToSize = aScaleToSize; 135 mFilter = aFilter; 136 mMixBlendMode = aMixBlendMode; 137 } 138 139 bool mInitialised; 140 bool mIsChanged; 141 bool mUseExternalImage; 142 LayoutDeviceRect mScBounds; 143 gfx::Matrix4x4 mScTransform; 144 gfx::MaybeIntSize mScaleToSize; 145 wr::ImageRendering mFilter; 146 wr::MixBlendMode mMixBlendMode; 147 RefPtr<WebRenderImageHost> mImageHost; 148 CompositableTextureHostRef mCurrentTexture; 149 nsTArray<wr::ImageKey> mKeys; 150 }; 151 152 Maybe<TextureHost::ResourceUpdateOp> UpdateImageKeys( 153 wr::TransactionBuilder& aResourceUpdates, AsyncImagePipeline* aPipeline, 154 nsTArray<wr::ImageKey>& aKeys); 155 Maybe<TextureHost::ResourceUpdateOp> UpdateWithoutExternalImage( 156 wr::TransactionBuilder& aResources, TextureHost* aTexture, 157 wr::ImageKey aKey, TextureHost::ResourceUpdateOp); 158 159 RefPtr<wr::WebRenderAPI> mApi; 160 wr::IdNamespace mIdNamespace; 161 uint32_t mResourceId; 162 163 nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder> 164 mPipelineTexturesHolders; 165 nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines; 166 uint32_t mAsyncImageEpoch; 167 bool mWillGenerateFrame; 168 bool mDestroyed; 169 170 // Render time for the current composition. 171 TimeStamp mCompositionTime; 172 173 // When nonnull, during rendering, some compositable indicated that it will 174 // change its rendering at this time. In order not to miss it, we composite 175 // on every vsync until this time occurs (this is the latest such time). 176 TimeStamp mCompositeUntilTime; 177 178 nsTArray<ImageCompositeNotificationInfo> mImageCompositeNotifications; 179 }; 180 181 } // namespace layers 182 } // namespace mozilla 183 184 #endif /* MOZILLA_GFX_WEBRENDERCOMPOSITABLE_HOLDER_H */ 185