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 GFX_WEBRENDERCOMMANDBUILDER_H 8 #define GFX_WEBRENDERCOMMANDBUILDER_H 9 10 #include "mozilla/webrender/WebRenderAPI.h" 11 #include "mozilla/layers/ClipManager.h" 12 #include "mozilla/layers/HitTestInfoManager.h" 13 #include "mozilla/layers/WebRenderMessages.h" 14 #include "mozilla/layers/WebRenderScrollData.h" 15 #include "mozilla/layers/WebRenderUserData.h" 16 #include "mozilla/SVGIntegrationUtils.h" // for WrFiltersHolder 17 #include "nsDisplayList.h" 18 #include "nsIFrame.h" 19 #include "nsTHashSet.h" 20 #include "DisplayItemCache.h" 21 #include "ImgDrawResult.h" 22 23 namespace mozilla { 24 25 namespace image { 26 class WebRenderImageProvider; 27 } 28 29 namespace layers { 30 31 class ImageClient; 32 class ImageContainer; 33 class WebRenderBridgeChild; 34 class WebRenderCanvasData; 35 class WebRenderCanvasRendererAsync; 36 class WebRenderImageData; 37 class WebRenderFallbackData; 38 class WebRenderParentCommand; 39 class WebRenderUserData; 40 41 class WebRenderCommandBuilder final { 42 typedef nsTHashSet<RefPtr<WebRenderUserData>> WebRenderUserDataRefTable; 43 typedef nsTHashSet<RefPtr<WebRenderCanvasData>> CanvasDataSet; 44 45 public: 46 explicit WebRenderCommandBuilder(WebRenderLayerManager* aManager); 47 48 void Destroy(); 49 50 void EmptyTransaction(); 51 52 bool NeedsEmptyTransaction(); 53 54 void BuildWebRenderCommands(wr::DisplayListBuilder& aBuilder, 55 wr::IpcResourceUpdateQueue& aResourceUpdates, 56 nsDisplayList* aDisplayList, 57 nsDisplayListBuilder* aDisplayListBuilder, 58 WebRenderScrollData& aScrollData, 59 WrFiltersHolder&& aFilters); 60 61 void PushOverrideForASR(const ActiveScrolledRoot* aASR, 62 const wr::WrSpatialId& aSpatialId); 63 void PopOverrideForASR(const ActiveScrolledRoot* aASR); 64 65 Maybe<wr::ImageKey> CreateImageKey( 66 nsDisplayItem* aItem, ImageContainer* aContainer, 67 mozilla::wr::DisplayListBuilder& aBuilder, 68 mozilla::wr::IpcResourceUpdateQueue& aResources, 69 mozilla::wr::ImageRendering aRendering, const StackingContextHelper& aSc, 70 gfx::IntSize& aSize, const Maybe<LayoutDeviceRect>& aAsyncImageBounds); 71 72 Maybe<wr::ImageKey> CreateImageProviderKey( 73 nsDisplayItem* aItem, image::WebRenderImageProvider* aProvider, 74 image::ImgDrawResult aDrawResult, 75 mozilla::wr::IpcResourceUpdateQueue& aResources); 76 GetWebRenderUserDataTable()77 WebRenderUserDataRefTable* GetWebRenderUserDataTable() { 78 return &mWebRenderUserDatas; 79 } 80 81 bool PushImage(nsDisplayItem* aItem, ImageContainer* aContainer, 82 mozilla::wr::DisplayListBuilder& aBuilder, 83 mozilla::wr::IpcResourceUpdateQueue& aResources, 84 const StackingContextHelper& aSc, 85 const LayoutDeviceRect& aRect, const LayoutDeviceRect& aClip); 86 87 bool PushImageProvider(nsDisplayItem* aItem, 88 image::WebRenderImageProvider* aProvider, 89 image::ImgDrawResult aDrawResult, 90 mozilla::wr::DisplayListBuilder& aBuilder, 91 mozilla::wr::IpcResourceUpdateQueue& aResources, 92 const LayoutDeviceRect& aRect, 93 const LayoutDeviceRect& aClip); 94 95 void PushInProcessImage(nsDisplayItem* aItem, 96 const CompositableHandle& aHandle, 97 mozilla::wr::DisplayListBuilder& aBuilder, 98 mozilla::wr::IpcResourceUpdateQueue& aResources, 99 const StackingContextHelper& aSc, 100 const LayoutDeviceRect& aAsyncImageBounds); 101 102 Maybe<wr::ImageMask> BuildWrMaskImage( 103 nsDisplayMasksAndClipPaths* aMaskItem, wr::DisplayListBuilder& aBuilder, 104 wr::IpcResourceUpdateQueue& aResources, const StackingContextHelper& aSc, 105 nsDisplayListBuilder* aDisplayListBuilder, 106 const LayoutDeviceRect& aBounds); 107 108 bool PushItemAsImage(nsDisplayItem* aItem, wr::DisplayListBuilder& aBuilder, 109 wr::IpcResourceUpdateQueue& aResources, 110 const StackingContextHelper& aSc, 111 nsDisplayListBuilder* aDisplayListBuilder); 112 113 void CreateWebRenderCommandsFromDisplayList( 114 nsDisplayList* aDisplayList, nsDisplayItem* aWrappingItem, 115 nsDisplayListBuilder* aDisplayListBuilder, 116 const StackingContextHelper& aSc, wr::DisplayListBuilder& aBuilder, 117 wr::IpcResourceUpdateQueue& aResources, bool aNewClipList = true); 118 119 // aWrappingItem has to be non-null. 120 void DoGroupingForDisplayList(nsDisplayList* aDisplayList, 121 nsDisplayItem* aWrappingItem, 122 nsDisplayListBuilder* aDisplayListBuilder, 123 const StackingContextHelper& aSc, 124 wr::DisplayListBuilder& aBuilder, 125 wr::IpcResourceUpdateQueue& aResources); 126 127 already_AddRefed<WebRenderFallbackData> GenerateFallbackData( 128 nsDisplayItem* aItem, wr::DisplayListBuilder& aBuilder, 129 wr::IpcResourceUpdateQueue& aResources, const StackingContextHelper& aSc, 130 nsDisplayListBuilder* aDisplayListBuilder, LayoutDeviceRect& aImageRect); 131 132 void RemoveUnusedAndResetWebRenderUserData(); 133 void ClearCachedResources(); 134 135 bool ShouldDumpDisplayList(nsDisplayListBuilder* aBuilder); GetBuilderDumpIndex()136 wr::usize GetBuilderDumpIndex() const { return mBuilderDumpIndex; } 137 GetContainsSVGGroup()138 bool GetContainsSVGGroup() { return mContainsSVGGroup; } 139 140 // Those are data that we kept between transactions. We used to cache some 141 // data in the layer. But in layers free mode, we don't have layer which 142 // means we need some other place to cached the data between transaction. 143 // We store the data in frame's property. 144 template <class T> 145 already_AddRefed<T> CreateOrRecycleWebRenderUserData( 146 nsDisplayItem* aItem, bool* aOutIsRecycled = nullptr) { 147 MOZ_ASSERT(aItem); 148 nsIFrame* frame = aItem->Frame(); 149 if (aOutIsRecycled) { 150 *aOutIsRecycled = true; 151 } 152 153 WebRenderUserDataTable* userDataTable = 154 frame->GetProperty(WebRenderUserDataProperty::Key()); 155 156 if (!userDataTable) { 157 userDataTable = new WebRenderUserDataTable(); 158 frame->AddProperty(WebRenderUserDataProperty::Key(), userDataTable); 159 } 160 161 RefPtr<WebRenderUserData>& data = userDataTable->LookupOrInsertWith( 162 WebRenderUserDataKey(aItem->GetPerFrameKey(), T::Type()), [&] { 163 auto data = MakeRefPtr<T>(GetRenderRootStateManager(), aItem); 164 mWebRenderUserDatas.Insert(data); 165 if (aOutIsRecycled) { 166 *aOutIsRecycled = false; 167 } 168 return data; 169 }); 170 171 MOZ_ASSERT(data); 172 MOZ_ASSERT(data->GetType() == T::Type()); 173 174 // Mark the data as being used. We will remove unused user data in the end 175 // of EndTransaction. 176 data->SetUsed(true); 177 178 switch (T::Type()) { 179 case WebRenderUserData::UserDataType::eCanvas: 180 mLastCanvasDatas.Insert(data->AsCanvasData()); 181 break; 182 default: 183 break; 184 } 185 186 RefPtr<T> res = static_cast<T*>(data.get()); 187 return res.forget(); 188 } 189 190 WebRenderLayerManager* mManager; 191 192 private: 193 RenderRootStateManager* GetRenderRootStateManager(); 194 void CreateWebRenderCommands(nsDisplayItem* aItem, 195 mozilla::wr::DisplayListBuilder& aBuilder, 196 mozilla::wr::IpcResourceUpdateQueue& aResources, 197 const StackingContextHelper& aSc, 198 nsDisplayListBuilder* aDisplayListBuilder); 199 200 bool ComputeInvalidationForDisplayItem(nsDisplayListBuilder* aBuilder, 201 const nsPoint& aShift, 202 nsDisplayItem* aItem); 203 bool ComputeInvalidationForDisplayList(nsDisplayListBuilder* aBuilder, 204 const nsPoint& aShift, 205 nsDisplayList* aList); 206 207 ClipManager mClipManager; 208 HitTestInfoManager mHitTestInfoManager; 209 210 // We use this as a temporary data structure while building the mScrollData 211 // inside a layers-free transaction. 212 std::vector<WebRenderLayerScrollData> mLayerScrollData; 213 // We use this as a temporary data structure to track the current display 214 // item's ASR as we recurse in CreateWebRenderCommandsFromDisplayList. We 215 // need this so that WebRenderLayerScrollData items that deeper in the 216 // tree don't duplicate scroll metadata that their ancestors already have. 217 std::vector<const ActiveScrolledRoot*> mAsrStack; 218 const ActiveScrolledRoot* mLastAsr; 219 220 WebRenderUserDataRefTable mWebRenderUserDatas; 221 222 // Store of WebRenderCanvasData objects for use in empty transactions 223 CanvasDataSet mLastCanvasDatas; 224 225 wr::usize mBuilderDumpIndex; 226 wr::usize mDumpIndent; 227 228 public: 229 // Whether consecutive inactive display items should be grouped into one 230 // blob image. 231 bool mDoGrouping; 232 233 // True if the most recently build display list contained an svg that 234 // we did grouping for. 235 bool mContainsSVGGroup; 236 }; 237 238 } // namespace layers 239 } // namespace mozilla 240 241 #endif /* GFX_WEBRENDERCOMMANDBUILDER_H */ 242