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_LAYERS_WEBRENDERAPI_H 8 #define MOZILLA_LAYERS_WEBRENDERAPI_H 9 10 #include <vector> 11 #include <unordered_map> 12 #include <unordered_set> 13 14 #include "mozilla/AlreadyAddRefed.h" 15 #include "mozilla/gfx/CompositorHitTestInfo.h" 16 #include "mozilla/layers/IpcResourceUpdateQueue.h" 17 #include "mozilla/layers/ScrollableLayerGuid.h" 18 #include "mozilla/layers/SyncObject.h" 19 #include "mozilla/layers/WebRenderCompositionRecorder.h" 20 #include "mozilla/Range.h" 21 #include "mozilla/TimeStamp.h" 22 #include "mozilla/webrender/webrender_ffi.h" 23 #include "mozilla/webrender/WebRenderTypes.h" 24 #include "GLTypes.h" 25 #include "Units.h" 26 27 class nsDisplayItem; 28 class nsPaintedDisplayItem; 29 class nsDisplayTransform; 30 31 #undef None 32 33 namespace mozilla { 34 35 struct ActiveScrolledRoot; 36 37 namespace widget { 38 class CompositorWidget; 39 } 40 41 namespace layers { 42 class CompositorBridgeParent; 43 class DisplayItemCache; 44 class WebRenderBridgeParent; 45 class RenderRootStateManager; 46 struct DisplayListData; 47 } // namespace layers 48 49 namespace layout { 50 class TextDrawTarget; 51 } 52 53 namespace wr { 54 55 class DisplayListBuilder; 56 class RendererOGL; 57 class RendererEvent; 58 59 // This isn't part of WR's API, but we define it here to simplify layout's 60 // logic and data plumbing. 61 struct Line { 62 wr::LayoutRect bounds; 63 float wavyLineThickness; 64 wr::LineOrientation orientation; 65 wr::ColorF color; 66 wr::LineStyle style; 67 }; 68 69 /// A handler that can be bundled into a transaction and notified at specific 70 /// points in the rendering pipeline, such as after scene building or after 71 /// frame building. 72 /// 73 /// If for any reason the handler is dropped before reaching the requested 74 /// point, it is notified with the value Checkpoint::TransactionDropped. 75 /// So it is safe to assume that the handler will be notified "at some point". 76 class NotificationHandler { 77 public: 78 virtual void Notify(wr::Checkpoint aCheckpoint) = 0; 79 virtual ~NotificationHandler() = default; 80 }; 81 82 struct WrHitResult { 83 layers::LayersId mLayersId; 84 layers::ScrollableLayerGuid::ViewID mScrollId; 85 gfx::CompositorHitTestInfo mHitInfo; 86 SideBits mSideBits; 87 }; 88 89 class TransactionBuilder final { 90 public: 91 explicit TransactionBuilder(bool aUseSceneBuilderThread = true); 92 93 ~TransactionBuilder(); 94 95 void SetLowPriority(bool aIsLowPriority); 96 97 void UpdateEpoch(PipelineId aPipelineId, Epoch aEpoch); 98 99 void SetRootPipeline(PipelineId aPipelineId); 100 101 void RemovePipeline(PipelineId aPipelineId); 102 103 void SetDisplayList(const gfx::DeviceColor& aBgColor, Epoch aEpoch, 104 const wr::LayoutSize& aViewportSize, 105 wr::WrPipelineId pipeline_id, 106 const wr::LayoutSize& content_size, 107 wr::BuiltDisplayListDescriptor dl_descriptor, 108 wr::Vec<uint8_t>& dl_data); 109 110 void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipeline); 111 112 void GenerateFrame(); 113 114 void InvalidateRenderedFrame(); 115 116 void UpdateDynamicProperties( 117 const nsTArray<wr::WrOpacityProperty>& aOpacityArray, 118 const nsTArray<wr::WrTransformProperty>& aTransformArray, 119 const nsTArray<wr::WrColorProperty>& aColorArray); 120 121 void SetDocumentView(const LayoutDeviceIntRect& aDocRect); 122 123 void UpdateScrollPosition( 124 const wr::WrPipelineId& aPipelineId, 125 const layers::ScrollableLayerGuid::ViewID& aScrollId, 126 const wr::LayoutPoint& aScrollPosition); 127 128 bool IsEmpty() const; 129 130 bool IsResourceUpdatesEmpty() const; 131 132 bool IsRenderedFrameInvalidated() const; 133 134 void AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, 135 wr::Vec<uint8_t>& aBytes); 136 137 void AddBlobImage(wr::BlobImageKey aKey, const ImageDescriptor& aDescriptor, 138 wr::Vec<uint8_t>& aBytes, 139 const wr::DeviceIntRect& aVisibleRect); 140 141 void AddExternalImageBuffer(ImageKey key, const ImageDescriptor& aDescriptor, 142 ExternalImageId aHandle); 143 144 void AddExternalImage(ImageKey key, const ImageDescriptor& aDescriptor, 145 ExternalImageId aExtID, 146 wr::ExternalImageType aImageType, 147 uint8_t aChannelIndex = 0); 148 149 void UpdateImageBuffer(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, 150 wr::Vec<uint8_t>& aBytes); 151 152 void UpdateBlobImage(wr::BlobImageKey aKey, 153 const ImageDescriptor& aDescriptor, 154 wr::Vec<uint8_t>& aBytes, 155 const wr::DeviceIntRect& aVisibleRect, 156 const wr::LayoutIntRect& aDirtyRect); 157 158 void UpdateExternalImage(ImageKey aKey, const ImageDescriptor& aDescriptor, 159 ExternalImageId aExtID, 160 wr::ExternalImageType aImageType, 161 uint8_t aChannelIndex = 0); 162 163 void UpdateExternalImageWithDirtyRect(ImageKey aKey, 164 const ImageDescriptor& aDescriptor, 165 ExternalImageId aExtID, 166 wr::ExternalImageType aImageType, 167 const wr::DeviceIntRect& aDirtyRect, 168 uint8_t aChannelIndex = 0); 169 170 void SetBlobImageVisibleArea(BlobImageKey aKey, 171 const wr::DeviceIntRect& aArea); 172 173 void DeleteImage(wr::ImageKey aKey); 174 175 void DeleteBlobImage(wr::BlobImageKey aKey); 176 177 void AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex); 178 179 void AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, 180 uint32_t aIndex); 181 182 void DeleteFont(wr::FontKey aKey); 183 184 void AddFontInstance(wr::FontInstanceKey aKey, wr::FontKey aFontKey, 185 float aGlyphSize, 186 const wr::FontInstanceOptions* aOptions, 187 const wr::FontInstancePlatformOptions* aPlatformOptions, 188 wr::Vec<uint8_t>& aVariations); 189 190 void DeleteFontInstance(wr::FontInstanceKey aKey); 191 192 void UpdateQualitySettings(bool aForceSubpixelAAWherePossible); 193 194 void Notify(wr::Checkpoint aWhen, UniquePtr<NotificationHandler> aHandler); 195 196 void Clear(); 197 UseSceneBuilderThread()198 bool UseSceneBuilderThread() const { return mUseSceneBuilderThread; } Raw()199 Transaction* Raw() { return mTxn; } 200 201 protected: 202 bool mUseSceneBuilderThread; 203 Transaction* mTxn; 204 }; 205 206 class TransactionWrapper final { 207 public: 208 explicit TransactionWrapper(Transaction* aTxn); 209 210 void AppendTransformProperties( 211 const nsTArray<wr::WrTransformProperty>& aTransformArray); 212 void UpdateScrollPosition( 213 const wr::WrPipelineId& aPipelineId, 214 const layers::ScrollableLayerGuid::ViewID& aScrollId, 215 const wr::LayoutPoint& aScrollPosition); 216 void UpdatePinchZoom(float aZoom); 217 void UpdateIsTransformAsyncZooming(uint64_t aAnimationId, bool aIsZooming); 218 219 private: 220 Transaction* mTxn; 221 }; 222 223 class WebRenderAPI final { 224 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderAPI); 225 226 public: 227 /// This can be called on the compositor thread only. 228 static already_AddRefed<WebRenderAPI> Create( 229 layers::CompositorBridgeParent* aBridge, 230 RefPtr<widget::CompositorWidget>&& aWidget, 231 const wr::WrWindowId& aWindowId, LayoutDeviceIntSize aSize); 232 233 already_AddRefed<WebRenderAPI> Clone(); 234 GetId()235 wr::WindowId GetId() const { return mId; } 236 237 /// Do a non-blocking hit-testing query on a shared version of the hit 238 /// testing information. 239 std::vector<WrHitResult> HitTest(const wr::WorldPoint& aPoint); 240 241 void SendTransaction(TransactionBuilder& aTxn); 242 243 void SetFrameStartTime(const TimeStamp& aTime); 244 245 void RunOnRenderThread(UniquePtr<RendererEvent> aEvent); 246 247 void Readback(const TimeStamp& aStartTime, gfx::IntSize aSize, 248 const gfx::SurfaceFormat& aFormat, 249 const Range<uint8_t>& aBuffer); 250 251 void ClearAllCaches(); 252 void EnableNativeCompositor(bool aEnable); 253 void EnableMultithreading(bool aEnable); 254 void SetBatchingLookback(uint32_t aCount); 255 256 void Pause(); 257 bool Resume(); 258 259 void WakeSceneBuilder(); 260 void FlushSceneBuilder(); 261 262 void NotifyMemoryPressure(); 263 void AccumulateMemoryReport(wr::MemoryReport*); 264 265 wr::WrIdNamespace GetNamespace(); GetMaxTextureSize()266 uint32_t GetMaxTextureSize() const { return mMaxTextureSize; } GetUseANGLE()267 bool GetUseANGLE() const { return mUseANGLE; } GetUseDComp()268 bool GetUseDComp() const { return mUseDComp; } GetUseTripleBuffering()269 bool GetUseTripleBuffering() const { return mUseTripleBuffering; } GetSyncHandle()270 layers::SyncHandle GetSyncHandle() const { return mSyncHandle; } 271 272 void Capture(); 273 274 void ToggleCaptureSequence(); 275 276 void SetCompositionRecorder( 277 UniquePtr<layers::WebRenderCompositionRecorder> aRecorder); 278 279 typedef MozPromise<bool, nsresult, true> WriteCollectedFramesPromise; 280 typedef MozPromise<layers::CollectedFrames, nsresult, true> 281 GetCollectedFramesPromise; 282 283 /** 284 * Write the frames collected by the |WebRenderCompositionRecorder| to disk. 285 * 286 * If there is not currently a recorder, this is a no-op. 287 */ 288 RefPtr<WriteCollectedFramesPromise> WriteCollectedFrames(); 289 290 /** 291 * Return the frames collected by the |WebRenderCompositionRecorder| encoded 292 * as data URIs. 293 * 294 * If there is not currently a recorder, this is a no-op and the promise will 295 * be rejected. 296 */ 297 RefPtr<GetCollectedFramesPromise> GetCollectedFrames(); 298 299 protected: 300 WebRenderAPI(wr::DocumentHandle* aHandle, wr::WindowId aId, 301 uint32_t aMaxTextureSize, bool aUseANGLE, bool aUseDComp, 302 bool aUseTripleBuffering, layers::SyncHandle aSyncHandle); 303 304 ~WebRenderAPI(); 305 // Should be used only for shutdown handling 306 void WaitFlushed(); 307 308 void UpdateDebugFlags(uint32_t aFlags); 309 310 wr::DocumentHandle* mDocHandle; 311 wr::WindowId mId; 312 int32_t mMaxTextureSize; 313 bool mUseANGLE; 314 bool mUseDComp; 315 bool mUseTripleBuffering; 316 bool mCaptureSequence; 317 layers::SyncHandle mSyncHandle; 318 319 // We maintain alive the root api to know when to shut the render backend 320 // down, and the root api for the document to know when to delete the 321 // document. mRootApi is null for the api object that owns the channel (and is 322 // responsible for shutting it down), and mRootDocumentApi is null for the api 323 // object owning (and responsible for destroying) a given document. All api 324 // objects in the same window use the same channel, and some api objects write 325 // to the same document (but there is only one owner for each channel and for 326 // each document). 327 RefPtr<wr::WebRenderAPI> mRootApi; 328 RefPtr<wr::WebRenderAPI> mRootDocumentApi; 329 330 friend class DisplayListBuilder; 331 friend class layers::WebRenderBridgeParent; 332 }; 333 334 // This is a RAII class that automatically sends the transaction on 335 // destruction. This is useful for code that has multiple exit points and we 336 // want to ensure that the stuff accumulated in the transaction gets sent 337 // regardless of which exit we take. Note that if the caller explicitly calls 338 // mApi->SendTransaction() that's fine too because that empties out the 339 // TransactionBuilder and leaves it as a valid empty transaction, so calling 340 // SendTransaction on it again ends up being a no-op. 341 class MOZ_RAII AutoTransactionSender { 342 public: AutoTransactionSender(WebRenderAPI * aApi,TransactionBuilder * aTxn)343 AutoTransactionSender(WebRenderAPI* aApi, TransactionBuilder* aTxn) 344 : mApi(aApi), mTxn(aTxn) {} 345 ~AutoTransactionSender()346 ~AutoTransactionSender() { mApi->SendTransaction(*mTxn); } 347 348 private: 349 WebRenderAPI* mApi; 350 TransactionBuilder* mTxn; 351 }; 352 353 /** 354 * A set of optional parameters for stacking context creation. 355 */ 356 struct MOZ_STACK_CLASS StackingContextParams : public WrStackingContextParams { StackingContextParamsStackingContextParams357 StackingContextParams() 358 : WrStackingContextParams{ 359 WrStackingContextClip::None(), 360 nullptr, 361 nullptr, 362 wr::TransformStyle::Flat, 363 wr::WrReferenceFrameKind::Transform, 364 nullptr, 365 /* prim_flags = */ wr::PrimitiveFlags::IS_BACKFACE_VISIBLE, 366 wr::MixBlendMode::Normal, 367 wr::StackingContextFlags{0}} {} 368 SetPreserve3DStackingContextParams369 void SetPreserve3D(bool aPreserve) { 370 transform_style = 371 aPreserve ? wr::TransformStyle::Preserve3D : wr::TransformStyle::Flat; 372 } 373 374 nsTArray<wr::FilterOp> mFilters; 375 nsTArray<wr::WrFilterData> mFilterDatas; 376 wr::LayoutRect mBounds = wr::ToLayoutRect(LayoutDeviceRect()); 377 const gfx::Matrix4x4* mBoundTransform = nullptr; 378 const gfx::Matrix4x4* mTransformPtr = nullptr; 379 Maybe<nsDisplayTransform*> mDeferredTransformItem; 380 // Whether the stacking context is possibly animated. This alters how 381 // coordinates are transformed/snapped to invalidate less when transforms 382 // change frequently. 383 bool mAnimated = false; 384 // Whether items should be rasterized in a local space that is (mostly) 385 // invariant to transforms, i.e. disabling subpixel AA and screen space pixel 386 // snapping on text runs that would only make sense in screen space. 387 bool mRasterizeLocally = false; 388 }; 389 390 /// This is a simple C++ wrapper around WrState defined in the rust bindings. 391 /// We may want to turn this into a direct wrapper on top of 392 /// WebRenderFrameBuilder instead, so the interface may change a bit. 393 class DisplayListBuilder final { 394 public: 395 DisplayListBuilder(wr::PipelineId aId, const wr::LayoutSize& aContentSize, 396 size_t aCapacity = 0, 397 layers::DisplayItemCache* aCache = nullptr); 398 DisplayListBuilder(DisplayListBuilder&&) = default; 399 400 ~DisplayListBuilder(); 401 402 void Save(); 403 void Restore(); 404 void ClearSave(); 405 406 usize Dump(usize aIndent, const Maybe<usize>& aStart, 407 const Maybe<usize>& aEnd); 408 void DumpSerializedDisplayList(); 409 410 void Finalize(wr::LayoutSize& aOutContentSizes, 411 wr::BuiltDisplayList& aOutDisplayList); 412 void Finalize(layers::DisplayListData& aOutTransaction); 413 414 Maybe<wr::WrSpatialId> PushStackingContext( 415 const StackingContextParams& aParams, const wr::LayoutRect& aBounds, 416 const wr::RasterSpace& aRasterSpace); 417 void PopStackingContext(bool aIsReferenceFrame); 418 419 wr::WrClipChainId DefineClipChain(const nsTArray<wr::WrClipId>& aClips, 420 bool aParentWithCurrentChain = false); 421 422 wr::WrClipId DefineClip( 423 const Maybe<wr::WrSpaceAndClip>& aParent, const wr::LayoutRect& aClipRect, 424 const nsTArray<wr::ComplexClipRegion>* aComplex = nullptr); 425 426 wr::WrClipId DefineImageMaskClip(const wr::ImageMask& aMask); 427 wr::WrClipId DefineRoundedRectClip(const wr::ComplexClipRegion& aComplex); 428 wr::WrClipId DefineRectClip(wr::LayoutRect aClipRect); 429 430 wr::WrSpatialId DefineStickyFrame(const wr::LayoutRect& aContentRect, 431 const float* aTopMargin, 432 const float* aRightMargin, 433 const float* aBottomMargin, 434 const float* aLeftMargin, 435 const StickyOffsetBounds& aVerticalBounds, 436 const StickyOffsetBounds& aHorizontalBounds, 437 const wr::LayoutVector2D& aAppliedOffset); 438 439 Maybe<wr::WrSpaceAndClip> GetScrollIdForDefinedScrollLayer( 440 layers::ScrollableLayerGuid::ViewID aViewId) const; 441 wr::WrSpaceAndClip DefineScrollLayer( 442 const layers::ScrollableLayerGuid::ViewID& aViewId, 443 const Maybe<wr::WrSpaceAndClip>& aParent, 444 const wr::LayoutRect& aContentRect, const wr::LayoutRect& aClipRect, 445 const wr::LayoutPoint& aScrollOffset); 446 447 void PushRect(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 448 bool aIsBackfaceVisible, const wr::ColorF& aColor); 449 void PushRectWithAnimation(const wr::LayoutRect& aBounds, 450 const wr::LayoutRect& aClip, 451 bool aIsBackfaceVisible, const wr::ColorF& aColor, 452 const WrAnimationProperty* aAnimation); 453 void PushRoundedRect(const wr::LayoutRect& aBounds, 454 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 455 const wr::ColorF& aColor); 456 void PushHitTest(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 457 bool aIsBackfaceVisible); 458 void PushClearRect(const wr::LayoutRect& aBounds); 459 void PushClearRectWithComplexRegion(const wr::LayoutRect& aBounds, 460 const wr::ComplexClipRegion& aRegion); 461 462 void PushBackdropFilter(const wr::LayoutRect& aBounds, 463 const wr::ComplexClipRegion& aRegion, 464 const nsTArray<wr::FilterOp>& aFilters, 465 const nsTArray<wr::WrFilterData>& aFilterDatas, 466 bool aIsBackfaceVisible); 467 468 void PushLinearGradient(const wr::LayoutRect& aBounds, 469 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 470 const wr::LayoutPoint& aStartPoint, 471 const wr::LayoutPoint& aEndPoint, 472 const nsTArray<wr::GradientStop>& aStops, 473 wr::ExtendMode aExtendMode, 474 const wr::LayoutSize aTileSize, 475 const wr::LayoutSize aTileSpacing); 476 477 void PushRadialGradient(const wr::LayoutRect& aBounds, 478 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 479 const wr::LayoutPoint& aCenter, 480 const wr::LayoutSize& aRadius, 481 const nsTArray<wr::GradientStop>& aStops, 482 wr::ExtendMode aExtendMode, 483 const wr::LayoutSize aTileSize, 484 const wr::LayoutSize aTileSpacing); 485 486 void PushConicGradient(const wr::LayoutRect& aBounds, 487 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 488 const wr::LayoutPoint& aCenter, const float aAngle, 489 const nsTArray<wr::GradientStop>& aStops, 490 wr::ExtendMode aExtendMode, 491 const wr::LayoutSize aTileSize, 492 const wr::LayoutSize aTileSpacing); 493 494 void PushImage(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 495 bool aIsBackfaceVisible, wr::ImageRendering aFilter, 496 wr::ImageKey aImage, bool aPremultipliedAlpha = true, 497 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, 498 bool aPreferCompositorSurface = false); 499 500 void PushRepeatingImage( 501 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 502 bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize, 503 const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter, 504 wr::ImageKey aImage, bool aPremultipliedAlpha = true, 505 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}); 506 507 void PushYCbCrPlanarImage( 508 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 509 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 510 wr::ImageKey aImageChannel1, wr::ImageKey aImageChannel2, 511 wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace, 512 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 513 bool aPreferCompositorSurface = false); 514 515 void PushNV12Image(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 516 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 517 wr::ImageKey aImageChannel1, wr::WrColorDepth aColorDepth, 518 wr::WrYuvColorSpace aColorSpace, 519 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 520 bool aPreferCompositorSurface = false); 521 522 void PushYCbCrInterleavedImage( 523 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 524 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 525 wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace, 526 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 527 bool aPreferCompositorSurface = false); 528 529 void PushIFrame(const wr::LayoutRect& aBounds, bool aIsBackfaceVisible, 530 wr::PipelineId aPipeline, bool aIgnoreMissingPipeline); 531 532 // XXX WrBorderSides are passed with Range. 533 // It is just to bypass compiler bug. See Bug 1357734. 534 void PushBorder(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 535 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, 536 const Range<const wr::BorderSide>& aSides, 537 const wr::BorderRadius& aRadius, 538 wr::AntialiasBorder = wr::AntialiasBorder::Yes); 539 540 void PushBorderImage(const wr::LayoutRect& aBounds, 541 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 542 const wr::WrBorderImage& aParams); 543 544 void PushBorderGradient(const wr::LayoutRect& aBounds, 545 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 546 const wr::LayoutSideOffsets& aWidths, 547 const int32_t aWidth, const int32_t aHeight, 548 bool aFill, const wr::DeviceIntSideOffsets& aSlice, 549 const wr::LayoutPoint& aStartPoint, 550 const wr::LayoutPoint& aEndPoint, 551 const nsTArray<wr::GradientStop>& aStops, 552 wr::ExtendMode aExtendMode, 553 const wr::LayoutSideOffsets& aOutset); 554 555 void PushBorderRadialGradient( 556 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 557 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill, 558 const wr::LayoutPoint& aCenter, const wr::LayoutSize& aRadius, 559 const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode, 560 const wr::LayoutSideOffsets& aOutset); 561 562 void PushBorderConicGradient( 563 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 564 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill, 565 const wr::LayoutPoint& aCenter, const float aAngle, 566 const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode, 567 const wr::LayoutSideOffsets& aOutset); 568 569 void PushText(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 570 bool aIsBackfaceVisible, const wr::ColorF& aColor, 571 wr::FontInstanceKey aFontKey, 572 Range<const wr::GlyphInstance> aGlyphBuffer, 573 const wr::GlyphOptions* aGlyphOptions = nullptr); 574 575 void PushLine(const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 576 const wr::Line& aLine); 577 578 void PushShadow(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 579 bool aIsBackfaceVisible, const wr::Shadow& aShadow, 580 bool aShouldInflate); 581 582 void PopAllShadows(); 583 584 void PushBoxShadow(const wr::LayoutRect& aRect, const wr::LayoutRect& aClip, 585 bool aIsBackfaceVisible, const wr::LayoutRect& aBoxBounds, 586 const wr::LayoutVector2D& aOffset, 587 const wr::ColorF& aColor, const float& aBlurRadius, 588 const float& aSpreadRadius, 589 const wr::BorderRadius& aBorderRadius, 590 const wr::BoxShadowClipMode& aClipMode); 591 592 /** 593 * Notifies the DisplayListBuilder that it can group together WR display items 594 * that are pushed until |CancelGroup()| or |FinishGroup()| call. 595 */ 596 void StartGroup(nsPaintedDisplayItem* aItem); 597 598 /** 599 * Cancels grouping of the display items and discards all the display items 600 * pushed between the |StartGroup()| and |CancelGroup()| calls. 601 */ 602 void CancelGroup(const bool aDiscard = false); 603 604 /** 605 * Finishes the display item group. The group is stored in WebRender backend, 606 * and can be reused with |ReuseItem()|, if the Gecko display item is reused. 607 */ 608 void FinishGroup(); 609 610 /** 611 * Try to reuse the previously created WebRender display items for the given 612 * Gecko display item |aItem|. 613 * Returns true if the items were reused, otherwise returns false. 614 */ 615 bool ReuseItem(nsPaintedDisplayItem* aItem); 616 CurrentClipChainId()617 uint64_t CurrentClipChainId() const { 618 return mCurrentSpaceAndClipChain.clip_chain; 619 } 620 CurrentSpaceAndClipChain()621 const wr::WrSpaceAndClipChain& CurrentSpaceAndClipChain() const { 622 return mCurrentSpaceAndClipChain; 623 } 624 CurrentPipelineId()625 const wr::PipelineId& CurrentPipelineId() const { return mPipelineId; } 626 627 // Checks to see if the innermost enclosing fixed pos item has the same 628 // ASR. If so, it returns the scroll target for that fixed-pos item. 629 // Otherwise, it returns Nothing(). 630 Maybe<layers::ScrollableLayerGuid::ViewID> GetContainingFixedPosScrollTarget( 631 const ActiveScrolledRoot* aAsr); 632 633 Maybe<SideBits> GetContainingFixedPosSideBits(const ActiveScrolledRoot* aAsr); 634 635 // Set the hit-test info to be used for all display items until the next call 636 // to SetHitTestInfo or ClearHitTestInfo. 637 void SetHitTestInfo(const layers::ScrollableLayerGuid::ViewID& aScrollId, 638 gfx::CompositorHitTestInfo aHitInfo, SideBits aSideBits); 639 // Clears the hit-test info so that subsequent display items will not have it. 640 void ClearHitTestInfo(); 641 642 already_AddRefed<gfxContext> GetTextContext( 643 wr::IpcResourceUpdateQueue& aResources, 644 const layers::StackingContextHelper& aSc, 645 layers::RenderRootStateManager* aManager, nsDisplayItem* aItem, 646 nsRect& aBounds, const gfx::Point& aDeviceOffset); 647 648 // Try to avoid using this when possible. Raw()649 wr::WrState* Raw() { return mWrState; } 650 SetClipChainLeaf(const Maybe<wr::LayoutRect> & aClipRect)651 void SetClipChainLeaf(const Maybe<wr::LayoutRect>& aClipRect) { 652 mClipChainLeaf = aClipRect; 653 } 654 655 // A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of 656 // data. The topmost object is pointed to by the mActiveFixedPosTracker 657 // pointer in the wr::DisplayListBuilder. 658 class MOZ_RAII FixedPosScrollTargetTracker final { 659 public: 660 FixedPosScrollTargetTracker(DisplayListBuilder& aBuilder, 661 const ActiveScrolledRoot* aAsr, 662 layers::ScrollableLayerGuid::ViewID aScrollId, 663 SideBits aSideBits); 664 ~FixedPosScrollTargetTracker(); 665 Maybe<layers::ScrollableLayerGuid::ViewID> GetScrollTargetForASR( 666 const ActiveScrolledRoot* aAsr); 667 Maybe<SideBits> GetSideBitsForASR(const ActiveScrolledRoot* aAsr); 668 669 private: 670 FixedPosScrollTargetTracker* mParentTracker; 671 DisplayListBuilder& mBuilder; 672 const ActiveScrolledRoot* mAsr; 673 layers::ScrollableLayerGuid::ViewID mScrollId; 674 SideBits mSideBits; 675 }; 676 677 protected: MergeClipLeaf(const wr::LayoutRect & aClip)678 wr::LayoutRect MergeClipLeaf(const wr::LayoutRect& aClip) { 679 if (mClipChainLeaf) { 680 return wr::IntersectLayoutRect(*mClipChainLeaf, aClip); 681 } 682 return aClip; 683 } 684 685 // See the implementation of PushShadow for details on these methods. 686 void SuspendClipLeafMerging(); 687 void ResumeClipLeafMerging(); 688 689 wr::WrState* mWrState; 690 691 // Track each scroll id that we encountered. We use this structure to 692 // ensure that we don't define a particular scroll layer multiple times, 693 // as that results in undefined behaviour in WR. 694 std::unordered_map<layers::ScrollableLayerGuid::ViewID, wr::WrSpaceAndClip> 695 mScrollIds; 696 697 wr::WrSpaceAndClipChain mCurrentSpaceAndClipChain; 698 699 // Contains the current leaf of the clip chain to be merged with the 700 // display item's clip rect when pushing an item. May be set to Nothing() if 701 // there is no clip rect to merge with. 702 Maybe<wr::LayoutRect> mClipChainLeaf; 703 704 // Versions of the above that are on hold while SuspendClipLeafMerging is on 705 // (see the implementation of PushShadow for details). 706 Maybe<wr::WrSpaceAndClipChain> mSuspendedSpaceAndClipChain; 707 Maybe<wr::LayoutRect> mSuspendedClipChainLeaf; 708 709 RefPtr<layout::TextDrawTarget> mCachedTextDT; 710 RefPtr<gfxContext> mCachedContext; 711 712 FixedPosScrollTargetTracker* mActiveFixedPosTracker; 713 714 wr::PipelineId mPipelineId; 715 wr::LayoutSize mContentSize; 716 717 nsTArray<wr::PipelineId> mRemotePipelineIds; 718 719 layers::DisplayItemCache* mDisplayItemCache; 720 Maybe<uint16_t> mCurrentCacheSlot; 721 722 friend class WebRenderAPI; 723 friend class SpaceAndClipChainHelper; 724 }; 725 726 // This is a RAII class that overrides the current Wr's SpatialId and 727 // ClipChainId. 728 class MOZ_RAII SpaceAndClipChainHelper final { 729 public: SpaceAndClipChainHelper(DisplayListBuilder & aBuilder,wr::WrSpaceAndClipChain aSpaceAndClipChain MOZ_GUARD_OBJECT_NOTIFIER_PARAM)730 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 731 wr::WrSpaceAndClipChain aSpaceAndClipChain 732 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 733 : mBuilder(aBuilder), 734 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 735 aBuilder.mCurrentSpaceAndClipChain = aSpaceAndClipChain; 736 MOZ_GUARD_OBJECT_NOTIFIER_INIT; 737 } SpaceAndClipChainHelper(DisplayListBuilder & aBuilder,wr::WrSpatialId aSpatialId MOZ_GUARD_OBJECT_NOTIFIER_PARAM)738 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 739 wr::WrSpatialId aSpatialId 740 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 741 : mBuilder(aBuilder), 742 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 743 aBuilder.mCurrentSpaceAndClipChain.space = aSpatialId; 744 MOZ_GUARD_OBJECT_NOTIFIER_INIT; 745 } SpaceAndClipChainHelper(DisplayListBuilder & aBuilder,wr::WrClipChainId aClipChainId MOZ_GUARD_OBJECT_NOTIFIER_PARAM)746 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 747 wr::WrClipChainId aClipChainId 748 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) 749 : mBuilder(aBuilder), 750 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 751 aBuilder.mCurrentSpaceAndClipChain.clip_chain = aClipChainId.id; 752 MOZ_GUARD_OBJECT_NOTIFIER_INIT; 753 } 754 ~SpaceAndClipChainHelper()755 ~SpaceAndClipChainHelper() { 756 mBuilder.mCurrentSpaceAndClipChain = mOldSpaceAndClipChain; 757 } 758 759 private: 760 SpaceAndClipChainHelper(const SpaceAndClipChainHelper&) = delete; 761 762 DisplayListBuilder& mBuilder; 763 wr::WrSpaceAndClipChain mOldSpaceAndClipChain; 764 MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER 765 }; 766 767 Maybe<wr::ImageFormat> SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat); 768 769 } // namespace wr 770 } // namespace mozilla 771 772 #endif 773