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/. */
7 #ifndef MOZILLA_LAYERS_WEBRENDERAPI_H
8 #define MOZILLA_LAYERS_WEBRENDERAPI_H
13 #include <unordered_map>
14 #include <unordered_set>
16 #include "mozilla/AlreadyAddRefed.h"
17 #include "mozilla/gfx/CompositorHitTestInfo.h"
18 #include "mozilla/layers/IpcResourceUpdateQueue.h"
19 #include "mozilla/layers/RemoteTextureMap.h"
20 #include "mozilla/layers/ScrollableLayerGuid.h"
21 #include "mozilla/layers/SyncObject.h"
22 #include "mozilla/layers/CompositionRecorder.h"
23 #include "mozilla/MozPromise.h"
24 #include "mozilla/Range.h"
25 #include "mozilla/TimeStamp.h"
26 #include "mozilla/UniquePtr.h"
27 #include "mozilla/VsyncDispatcher.h"
28 #include "mozilla/webrender/webrender_ffi.h"
29 #include "mozilla/webrender/WebRenderTypes.h"
41 class nsPaintedDisplayItem
;
42 class nsDisplayTransform
;
43 class nsDisplayListBuilder
;
44 struct DisplayItemClipChain
;
46 struct ActiveScrolledRoot
;
49 class CompositorWidget
;
53 class CompositorBridgeParent
;
54 class DisplayItemCache
;
55 class WebRenderBridgeParent
;
56 class RenderRootStateManager
;
57 class StackingContextHelper
;
58 struct DisplayListData
;
67 class DisplayListBuilder
;
72 // This isn't part of WR's API, but we define it here to simplify layout's
73 // logic and data plumbing.
75 wr::LayoutRect bounds
;
76 float wavyLineThickness
;
77 wr::LineOrientation orientation
;
82 /// A handler that can be bundled into a transaction and notified at specific
83 /// points in the rendering pipeline, such as after scene building or after
86 /// If for any reason the handler is dropped before reaching the requested
87 /// point, it is notified with the value Checkpoint::TransactionDropped.
88 /// So it is safe to assume that the handler will be notified "at some point".
89 class NotificationHandler
{
91 virtual void Notify(wr::Checkpoint aCheckpoint
) = 0;
92 virtual ~NotificationHandler() = default;
96 layers::LayersId mLayersId
;
97 layers::ScrollableLayerGuid::ViewID mScrollId
;
98 gfx::CompositorHitTestInfo mHitInfo
;
100 Maybe
<uint64_t> mAnimationId
;
103 class TransactionBuilder final
{
105 explicit TransactionBuilder(WebRenderAPI
* aApi
,
106 bool aUseSceneBuilderThread
= true);
108 ~TransactionBuilder();
110 void SetLowPriority(bool aIsLowPriority
);
112 void UpdateEpoch(PipelineId aPipelineId
, Epoch aEpoch
);
114 void SetRootPipeline(PipelineId aPipelineId
);
116 void RemovePipeline(PipelineId aPipelineId
);
118 void SetDisplayList(Epoch aEpoch
, wr::WrPipelineId pipeline_id
,
119 wr::BuiltDisplayListDescriptor dl_descriptor
,
120 wr::Vec
<uint8_t>& dl_items_data
,
121 wr::Vec
<uint8_t>& dl_cache_data
,
122 wr::Vec
<uint8_t>& dl_spatial_tree
);
124 void ClearDisplayList(Epoch aEpoch
, wr::WrPipelineId aPipeline
);
126 void GenerateFrame(const VsyncId
& aVsyncId
, wr::RenderReasons aReasons
);
128 void InvalidateRenderedFrame(wr::RenderReasons aReasons
);
130 void SetDocumentView(const LayoutDeviceIntRect
& aDocRect
);
132 bool IsEmpty() const;
134 bool IsResourceUpdatesEmpty() const;
136 bool IsRenderedFrameInvalidated() const;
138 void AddImage(wr::ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
139 wr::Vec
<uint8_t>& aBytes
);
141 void AddBlobImage(wr::BlobImageKey aKey
, const ImageDescriptor
& aDescriptor
,
142 uint16_t aTileSize
, wr::Vec
<uint8_t>& aBytes
,
143 const wr::DeviceIntRect
& aVisibleRect
);
145 void AddExternalImageBuffer(ImageKey key
, const ImageDescriptor
& aDescriptor
,
146 ExternalImageId aHandle
);
148 void AddExternalImage(ImageKey key
, const ImageDescriptor
& aDescriptor
,
149 ExternalImageId aExtID
,
150 wr::ExternalImageType aImageType
,
151 uint8_t aChannelIndex
= 0);
153 void UpdateImageBuffer(wr::ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
154 wr::Vec
<uint8_t>& aBytes
);
156 void UpdateBlobImage(wr::BlobImageKey aKey
,
157 const ImageDescriptor
& aDescriptor
,
158 wr::Vec
<uint8_t>& aBytes
,
159 const wr::DeviceIntRect
& aVisibleRect
,
160 const wr::LayoutIntRect
& aDirtyRect
);
162 void UpdateExternalImage(ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
163 ExternalImageId aExtID
,
164 wr::ExternalImageType aImageType
,
165 uint8_t aChannelIndex
= 0);
167 void UpdateExternalImageWithDirtyRect(ImageKey aKey
,
168 const ImageDescriptor
& aDescriptor
,
169 ExternalImageId aExtID
,
170 wr::ExternalImageType aImageType
,
171 const wr::DeviceIntRect
& aDirtyRect
,
172 uint8_t aChannelIndex
= 0);
174 void SetBlobImageVisibleArea(BlobImageKey aKey
,
175 const wr::DeviceIntRect
& aArea
);
177 void DeleteImage(wr::ImageKey aKey
);
179 void DeleteBlobImage(wr::BlobImageKey aKey
);
181 void AddRawFont(wr::FontKey aKey
, wr::Vec
<uint8_t>& aBytes
, uint32_t aIndex
);
183 void AddFontDescriptor(wr::FontKey aKey
, wr::Vec
<uint8_t>& aBytes
,
186 void DeleteFont(wr::FontKey aKey
);
188 void AddFontInstance(wr::FontInstanceKey aKey
, wr::FontKey aFontKey
,
190 const wr::FontInstanceOptions
* aOptions
,
191 const wr::FontInstancePlatformOptions
* aPlatformOptions
,
192 wr::Vec
<uint8_t>& aVariations
);
194 void DeleteFontInstance(wr::FontInstanceKey aKey
);
196 void UpdateQualitySettings(bool aForceSubpixelAAWherePossible
);
198 void Notify(wr::Checkpoint aWhen
, UniquePtr
<NotificationHandler
> aHandler
);
204 bool UseSceneBuilderThread() const { return mUseSceneBuilderThread
; }
205 layers::WebRenderBackend
GetBackendType() { return mApiBackend
; }
206 Transaction
* Raw() { return mTxn
; }
209 bool mUseSceneBuilderThread
;
210 layers::WebRenderBackend mApiBackend
;
214 class TransactionWrapper final
{
216 explicit TransactionWrapper(Transaction
* aTxn
);
218 void AppendDynamicProperties(
219 const nsTArray
<wr::WrOpacityProperty
>& aOpacityArray
,
220 const nsTArray
<wr::WrTransformProperty
>& aTransformArray
,
221 const nsTArray
<wr::WrColorProperty
>& aColorArray
);
222 void AppendTransformProperties(
223 const nsTArray
<wr::WrTransformProperty
>& aTransformArray
);
224 void UpdateScrollPosition(
225 const wr::WrPipelineId
& aPipelineId
,
226 const layers::ScrollableLayerGuid::ViewID
& aScrollId
,
227 const nsTArray
<wr::SampledScrollOffset
>& aSampledOffsets
);
228 void UpdateIsTransformAsyncZooming(uint64_t aAnimationId
, bool aIsZooming
);
234 class WebRenderAPI final
{
235 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderAPI
);
238 /// This can be called on the compositor thread only.
239 static already_AddRefed
<WebRenderAPI
> Create(
240 layers::CompositorBridgeParent
* aBridge
,
241 RefPtr
<widget::CompositorWidget
>&& aWidget
,
242 const wr::WrWindowId
& aWindowId
, LayoutDeviceIntSize aSize
,
243 layers::WindowKind aWindowKind
, nsACString
& aError
);
245 already_AddRefed
<WebRenderAPI
> Clone();
247 void DestroyRenderer();
249 wr::WindowId
GetId() const { return mId
; }
251 /// Do a non-blocking hit-testing query on a shared version of the hit
252 /// testing information.
253 std::vector
<WrHitResult
> HitTest(const wr::WorldPoint
& aPoint
);
255 void SendTransaction(TransactionBuilder
& aTxn
);
257 void SetFrameStartTime(const TimeStamp
& aTime
);
259 void RunOnRenderThread(UniquePtr
<RendererEvent
> aEvent
);
261 void Readback(const TimeStamp
& aStartTime
, gfx::IntSize aSize
,
262 const gfx::SurfaceFormat
& aFormat
,
263 const Range
<uint8_t>& aBuffer
, bool* aNeedsYFlip
);
265 void ClearAllCaches();
266 void EnableNativeCompositor(bool aEnable
);
267 void SetBatchingLookback(uint32_t aCount
);
268 void SetBool(wr::BoolParameter
, bool value
);
269 void SetInt(wr::IntParameter
, int32_t value
);
271 void SetClearColor(const gfx::DeviceColor
& aColor
);
272 void SetProfilerUI(const nsACString
& aUIString
);
277 void WakeSceneBuilder();
278 void FlushSceneBuilder();
280 void NotifyMemoryPressure();
281 void AccumulateMemoryReport(wr::MemoryReport
*);
283 wr::WrIdNamespace
GetNamespace();
284 layers::WebRenderBackend
GetBackendType() { return mBackend
; }
285 layers::WebRenderCompositor
GetCompositorType() { return mCompositor
; }
286 uint32_t GetMaxTextureSize() const { return mMaxTextureSize
; }
287 bool GetUseANGLE() const { return mUseANGLE
; }
288 bool GetUseDComp() const { return mUseDComp
; }
289 bool GetUseTripleBuffering() const { return mUseTripleBuffering
; }
290 bool SupportsExternalBufferTextures() const {
291 return mSupportsExternalBufferTextures
;
293 layers::SyncHandle
GetSyncHandle() const { return mSyncHandle
; }
297 void StartCaptureSequence(const nsACString
& aPath
, uint32_t aFlags
);
298 void StopCaptureSequence();
300 void BeginRecording(const TimeStamp
& aRecordingStart
,
301 wr::PipelineId aRootPipelineId
);
303 typedef MozPromise
<layers::FrameRecording
, nsresult
, true>
306 RefPtr
<EndRecordingPromise
> EndRecording();
308 layers::RemoteTextureInfoList
* GetPendingRemoteTextureInfoList();
310 void FlushPendingWrTransactionEventsWithoutWait();
311 void FlushPendingWrTransactionEventsWithWait();
314 WebRenderAPI(wr::DocumentHandle
* aHandle
, wr::WindowId aId
,
315 layers::WebRenderBackend aBackend
,
316 layers::WebRenderCompositor aCompositor
,
317 uint32_t aMaxTextureSize
, bool aUseANGLE
, bool aUseDComp
,
318 bool aUseTripleBuffering
, bool aSupportsExternalBufferTextures
,
319 layers::SyncHandle aSyncHandle
);
322 // Should be used only for shutdown handling
325 void UpdateDebugFlags(uint32_t aFlags
);
326 bool CheckIsRemoteTextureReady(layers::RemoteTextureInfoList
* aList
);
327 void WaitRemoteTextureReady(layers::RemoteTextureInfoList
* aList
);
329 enum class RemoteTextureWaitType
: uint8_t {
335 void HandleWrTransactionEvents(RemoteTextureWaitType aType
);
337 class WrTransactionEvent
{
341 PendingRemoteTextures
,
345 struct TransactionWrapper
{
346 TransactionWrapper(wr::Transaction
* aTxn
, bool aUseSceneBuilderThread
)
347 : mTxn(aTxn
), mUseSceneBuilderThread(aUseSceneBuilderThread
) {}
349 ~TransactionWrapper() {
351 wr_transaction_delete(mTxn
);
355 wr::Transaction
* mTxn
;
356 const bool mUseSceneBuilderThread
;
360 WrTransactionEvent(const Tag aTag
,
361 UniquePtr
<TransactionWrapper
>&& aTransaction
)
362 : mTag(aTag
), mTransaction(std::move(aTransaction
)) {
363 MOZ_ASSERT(mTag
== Tag::Transaction
);
367 UniquePtr
<layers::RemoteTextureInfoList
>&& aPendingRemoteTextures
)
369 mPendingRemoteTextures(std::move(aPendingRemoteTextures
)) {
370 MOZ_ASSERT(mTag
== Tag::PendingRemoteTextures
);
373 UniquePtr
<TransactionWrapper
> mTransaction
;
374 UniquePtr
<layers::RemoteTextureInfoList
> mPendingRemoteTextures
;
377 static WrTransactionEvent
Transaction(wr::Transaction
* aTxn
,
378 bool aUseSceneBuilderThread
) {
380 MakeUnique
<TransactionWrapper
>(aTxn
, aUseSceneBuilderThread
);
381 return WrTransactionEvent(Tag::Transaction
, std::move(transaction
));
384 static WrTransactionEvent
PendingRemoteTextures(
385 UniquePtr
<layers::RemoteTextureInfoList
>&& aPendingRemoteTextures
) {
386 return WrTransactionEvent(Tag::PendingRemoteTextures
,
387 std::move(aPendingRemoteTextures
));
390 wr::Transaction
* Transaction() {
391 if (mTag
== Tag::Transaction
) {
392 return mTransaction
->mTxn
;
394 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
398 bool UseSceneBuilderThread() {
399 if (mTag
== Tag::Transaction
) {
400 return mTransaction
->mUseSceneBuilderThread
;
402 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
406 layers::RemoteTextureInfoList
* RemoteTextureInfoList() {
407 if (mTag
== Tag::PendingRemoteTextures
) {
408 MOZ_ASSERT(mPendingRemoteTextures
);
409 return mPendingRemoteTextures
.get();
411 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
416 wr::DocumentHandle
* mDocHandle
;
418 layers::WebRenderBackend mBackend
;
419 layers::WebRenderCompositor mCompositor
;
420 int32_t mMaxTextureSize
;
423 bool mUseTripleBuffering
;
424 bool mSupportsExternalBufferTextures
;
425 bool mCaptureSequence
;
426 layers::SyncHandle mSyncHandle
;
427 bool mRendererDestroyed
;
429 UniquePtr
<layers::RemoteTextureInfoList
> mPendingRemoteTextureInfoList
;
430 std::queue
<WrTransactionEvent
> mPendingWrTransactionEvents
;
432 // We maintain alive the root api to know when to shut the render backend
433 // down, and the root api for the document to know when to delete the
434 // document. mRootApi is null for the api object that owns the channel (and is
435 // responsible for shutting it down), and mRootDocumentApi is null for the api
436 // object owning (and responsible for destroying) a given document. All api
437 // objects in the same window use the same channel, and some api objects write
438 // to the same document (but there is only one owner for each channel and for
440 RefPtr
<wr::WebRenderAPI
> mRootApi
;
441 RefPtr
<wr::WebRenderAPI
> mRootDocumentApi
;
443 friend class DisplayListBuilder
;
444 friend class layers::WebRenderBridgeParent
;
447 // This is a RAII class that automatically sends the transaction on
448 // destruction. This is useful for code that has multiple exit points and we
449 // want to ensure that the stuff accumulated in the transaction gets sent
450 // regardless of which exit we take. Note that if the caller explicitly calls
451 // mApi->SendTransaction() that's fine too because that empties out the
452 // TransactionBuilder and leaves it as a valid empty transaction, so calling
453 // SendTransaction on it again ends up being a no-op.
454 class MOZ_RAII AutoTransactionSender
{
456 AutoTransactionSender(WebRenderAPI
* aApi
, TransactionBuilder
* aTxn
)
457 : mApi(aApi
), mTxn(aTxn
) {
458 MOZ_RELEASE_ASSERT(mApi
);
459 MOZ_RELEASE_ASSERT(aTxn
);
462 ~AutoTransactionSender() { mApi
->SendTransaction(*mTxn
); }
466 TransactionBuilder
* mTxn
;
470 * A set of optional parameters for stacking context creation.
472 struct MOZ_STACK_CLASS StackingContextParams
: public WrStackingContextParams
{
473 StackingContextParams()
474 : WrStackingContextParams
{
475 WrStackingContextClip::None(),
479 wr::TransformStyle::Flat
,
480 wr::WrReferenceFrameKind::Transform
,
485 /* prim_flags = */ wr::PrimitiveFlags::IS_BACKFACE_VISIBLE
,
486 wr::MixBlendMode::Normal
,
487 wr::StackingContextFlags
{0}} {}
489 void SetPreserve3D(bool aPreserve
) {
491 aPreserve
? wr::TransformStyle::Preserve3D
: wr::TransformStyle::Flat
;
494 // Fill this in only if this is for the root StackingContextHelper.
495 nsIFrame
* mRootReferenceFrame
= nullptr;
496 nsTArray
<wr::FilterOp
> mFilters
;
497 nsTArray
<wr::WrFilterData
> mFilterDatas
;
498 wr::LayoutRect mBounds
= wr::ToLayoutRect(LayoutDeviceRect());
499 const gfx::Matrix4x4
* mBoundTransform
= nullptr;
500 const wr::WrTransformInfo
* mTransformPtr
= nullptr;
501 nsDisplayTransform
* mDeferredTransformItem
= nullptr;
502 // Whether the stacking context is possibly animated. This alters how
503 // coordinates are transformed/snapped to invalidate less when transforms
504 // change frequently.
505 bool mAnimated
= false;
506 // Whether items should be rasterized in a local space that is (mostly)
507 // invariant to transforms, i.e. disabling subpixel AA and screen space pixel
508 // snapping on text runs that would only make sense in screen space.
509 bool mRasterizeLocally
= false;
512 /// This is a simple C++ wrapper around WrState defined in the rust bindings.
513 /// We may want to turn this into a direct wrapper on top of
514 /// WebRenderFrameBuilder instead, so the interface may change a bit.
515 class DisplayListBuilder final
{
517 explicit DisplayListBuilder(wr::PipelineId aId
,
518 layers::WebRenderBackend aBackend
);
519 DisplayListBuilder(DisplayListBuilder
&&) = default;
521 ~DisplayListBuilder();
527 usize
Dump(usize aIndent
, const Maybe
<usize
>& aStart
,
528 const Maybe
<usize
>& aEnd
);
529 void DumpSerializedDisplayList();
531 void Begin(layers::DisplayItemCache
* aCache
= nullptr);
532 void End(wr::BuiltDisplayList
& aOutDisplayList
);
533 void End(layers::DisplayListData
& aOutTransaction
);
535 Maybe
<wr::WrSpatialId
> PushStackingContext(
536 const StackingContextParams
& aParams
, const wr::LayoutRect
& aBounds
,
537 const wr::RasterSpace
& aRasterSpace
);
538 void PopStackingContext(bool aIsReferenceFrame
);
540 wr::WrClipChainId
DefineClipChain(const nsTArray
<wr::WrClipId
>& aClips
,
541 bool aParentWithCurrentChain
= false);
543 wr::WrClipId
DefineImageMaskClip(const wr::ImageMask
& aMask
,
544 const nsTArray
<wr::LayoutPoint
>&,
546 wr::WrClipId
DefineRoundedRectClip(Maybe
<wr::WrSpatialId
> aSpace
,
547 const wr::ComplexClipRegion
& aComplex
);
548 wr::WrClipId
DefineRectClip(Maybe
<wr::WrSpatialId
> aSpace
,
549 wr::LayoutRect aClipRect
);
551 wr::WrSpatialId
DefineStickyFrame(
552 const wr::LayoutRect
& aContentRect
, const float* aTopMargin
,
553 const float* aRightMargin
, const float* aBottomMargin
,
554 const float* aLeftMargin
, const StickyOffsetBounds
& aVerticalBounds
,
555 const StickyOffsetBounds
& aHorizontalBounds
,
556 const wr::LayoutVector2D
& aAppliedOffset
, wr::SpatialTreeItemKey aKey
);
558 Maybe
<wr::WrSpatialId
> GetScrollIdForDefinedScrollLayer(
559 layers::ScrollableLayerGuid::ViewID aViewId
) const;
560 wr::WrSpatialId
DefineScrollLayer(
561 const layers::ScrollableLayerGuid::ViewID
& aViewId
,
562 const Maybe
<wr::WrSpatialId
>& aParent
, const wr::LayoutRect
& aContentRect
,
563 const wr::LayoutRect
& aClipRect
, const wr::LayoutVector2D
& aScrollOffset
,
564 wr::APZScrollGeneration aScrollOffsetGeneration
,
565 wr::HasScrollLinkedEffect aHasScrollLinkedEffect
,
566 wr::SpatialTreeItemKey aKey
);
568 void PushRect(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
569 bool aIsBackfaceVisible
, bool aForceAntiAliasing
,
570 bool aIsCheckerboard
, const wr::ColorF
& aColor
);
571 void PushRectWithAnimation(const wr::LayoutRect
& aBounds
,
572 const wr::LayoutRect
& aClip
,
573 bool aIsBackfaceVisible
, const wr::ColorF
& aColor
,
574 const WrAnimationProperty
* aAnimation
);
575 void PushRoundedRect(const wr::LayoutRect
& aBounds
,
576 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
577 const wr::ColorF
& aColor
);
578 void PushHitTest(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
579 bool aIsBackfaceVisible
,
580 const layers::ScrollableLayerGuid::ViewID
& aScrollId
,
581 const gfx::CompositorHitTestInfo
& aHitInfo
,
583 void PushClearRect(const wr::LayoutRect
& aBounds
);
585 void PushBackdropFilter(const wr::LayoutRect
& aBounds
,
586 const wr::ComplexClipRegion
& aRegion
,
587 const nsTArray
<wr::FilterOp
>& aFilters
,
588 const nsTArray
<wr::WrFilterData
>& aFilterDatas
,
589 bool aIsBackfaceVisible
);
591 void PushLinearGradient(const wr::LayoutRect
& aBounds
,
592 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
593 const wr::LayoutPoint
& aStartPoint
,
594 const wr::LayoutPoint
& aEndPoint
,
595 const nsTArray
<wr::GradientStop
>& aStops
,
596 wr::ExtendMode aExtendMode
,
597 const wr::LayoutSize aTileSize
,
598 const wr::LayoutSize aTileSpacing
);
600 void PushRadialGradient(const wr::LayoutRect
& aBounds
,
601 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
602 const wr::LayoutPoint
& aCenter
,
603 const wr::LayoutSize
& aRadius
,
604 const nsTArray
<wr::GradientStop
>& aStops
,
605 wr::ExtendMode aExtendMode
,
606 const wr::LayoutSize aTileSize
,
607 const wr::LayoutSize aTileSpacing
);
609 void PushConicGradient(const wr::LayoutRect
& aBounds
,
610 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
611 const wr::LayoutPoint
& aCenter
, const float aAngle
,
612 const nsTArray
<wr::GradientStop
>& aStops
,
613 wr::ExtendMode aExtendMode
,
614 const wr::LayoutSize aTileSize
,
615 const wr::LayoutSize aTileSpacing
);
617 void PushImage(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
618 bool aIsBackfaceVisible
, bool aForceAntiAliasing
,
619 wr::ImageRendering aFilter
, wr::ImageKey aImage
,
620 bool aPremultipliedAlpha
= true,
621 const wr::ColorF
& aColor
= wr::ColorF
{1.0f
, 1.0f
, 1.0f
, 1.0f
},
622 bool aPreferCompositorSurface
= false,
623 bool aSupportsExternalCompositing
= false);
625 void PushRepeatingImage(
626 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
627 bool aIsBackfaceVisible
, const wr::LayoutSize
& aStretchSize
,
628 const wr::LayoutSize
& aTileSpacing
, wr::ImageRendering aFilter
,
629 wr::ImageKey aImage
, bool aPremultipliedAlpha
= true,
630 const wr::ColorF
& aColor
= wr::ColorF
{1.0f
, 1.0f
, 1.0f
, 1.0f
});
632 void PushYCbCrPlanarImage(
633 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
634 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
635 wr::ImageKey aImageChannel1
, wr::ImageKey aImageChannel2
,
636 wr::WrColorDepth aColorDepth
, wr::WrYuvColorSpace aColorSpace
,
637 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
638 bool aPreferCompositorSurface
= false,
639 bool aSupportsExternalCompositing
= false);
641 void PushNV12Image(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
642 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
643 wr::ImageKey aImageChannel1
, wr::WrColorDepth aColorDepth
,
644 wr::WrYuvColorSpace aColorSpace
,
645 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
646 bool aPreferCompositorSurface
= false,
647 bool aSupportsExternalCompositing
= false);
649 void PushP010Image(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
650 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
651 wr::ImageKey aImageChannel1
, wr::WrColorDepth aColorDepth
,
652 wr::WrYuvColorSpace aColorSpace
,
653 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
654 bool aPreferCompositorSurface
= false,
655 bool aSupportsExternalCompositing
= false);
657 void PushYCbCrInterleavedImage(
658 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
659 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
660 wr::WrColorDepth aColorDepth
, wr::WrYuvColorSpace aColorSpace
,
661 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
662 bool aPreferCompositorSurface
= false,
663 bool aSupportsExternalCompositing
= false);
665 void PushIFrame(const LayoutDeviceRect
& aDevPxBounds
, bool aIsBackfaceVisible
,
666 wr::PipelineId aPipeline
, bool aIgnoreMissingPipeline
);
668 // XXX WrBorderSides are passed with Range.
669 // It is just to bypass compiler bug. See Bug 1357734.
670 void PushBorder(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
671 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
,
672 const Range
<const wr::BorderSide
>& aSides
,
673 const wr::BorderRadius
& aRadius
,
674 wr::AntialiasBorder
= wr::AntialiasBorder::Yes
);
676 void PushBorderImage(const wr::LayoutRect
& aBounds
,
677 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
678 const wr::WrBorderImage
& aParams
);
680 void PushBorderGradient(const wr::LayoutRect
& aBounds
,
681 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
682 const wr::LayoutSideOffsets
& aWidths
,
683 const int32_t aWidth
, const int32_t aHeight
,
684 bool aFill
, const wr::DeviceIntSideOffsets
& aSlice
,
685 const wr::LayoutPoint
& aStartPoint
,
686 const wr::LayoutPoint
& aEndPoint
,
687 const nsTArray
<wr::GradientStop
>& aStops
,
688 wr::ExtendMode aExtendMode
);
690 void PushBorderRadialGradient(
691 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
692 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
, bool aFill
,
693 const wr::LayoutPoint
& aCenter
, const wr::LayoutSize
& aRadius
,
694 const nsTArray
<wr::GradientStop
>& aStops
, wr::ExtendMode aExtendMode
);
696 void PushBorderConicGradient(
697 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
698 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
, bool aFill
,
699 const wr::LayoutPoint
& aCenter
, const float aAngle
,
700 const nsTArray
<wr::GradientStop
>& aStops
, wr::ExtendMode aExtendMode
);
702 void PushText(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
703 bool aIsBackfaceVisible
, const wr::ColorF
& aColor
,
704 wr::FontInstanceKey aFontKey
,
705 Range
<const wr::GlyphInstance
> aGlyphBuffer
,
706 const wr::GlyphOptions
* aGlyphOptions
= nullptr);
708 void PushLine(const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
709 const wr::Line
& aLine
);
711 void PushShadow(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
712 bool aIsBackfaceVisible
, const wr::Shadow
& aShadow
,
713 bool aShouldInflate
);
715 void PopAllShadows();
717 void PushBoxShadow(const wr::LayoutRect
& aRect
, const wr::LayoutRect
& aClip
,
718 bool aIsBackfaceVisible
, const wr::LayoutRect
& aBoxBounds
,
719 const wr::LayoutVector2D
& aOffset
,
720 const wr::ColorF
& aColor
, const float& aBlurRadius
,
721 const float& aSpreadRadius
,
722 const wr::BorderRadius
& aBorderRadius
,
723 const wr::BoxShadowClipMode
& aClipMode
);
726 * Notifies the DisplayListBuilder that it can group together WR display items
727 * that are pushed until |CancelGroup()| or |FinishGroup()| call.
729 void StartGroup(nsPaintedDisplayItem
* aItem
);
732 * Cancels grouping of the display items and discards all the display items
733 * pushed between the |StartGroup()| and |CancelGroup()| calls.
735 void CancelGroup(const bool aDiscard
= false);
738 * Finishes the display item group. The group is stored in WebRender backend,
739 * and can be reused with |ReuseItem()|, if the Gecko display item is reused.
744 * Try to reuse the previously created WebRender display items for the given
745 * Gecko display item |aItem|.
746 * Returns true if the items were reused, otherwise returns false.
748 bool ReuseItem(nsPaintedDisplayItem
* aItem
);
750 uint64_t CurrentClipChainId() const {
751 return mCurrentSpaceAndClipChain
.clip_chain
;
754 const wr::WrSpaceAndClipChain
& CurrentSpaceAndClipChain() const {
755 return mCurrentSpaceAndClipChain
;
758 const wr::PipelineId
& CurrentPipelineId() const { return mPipelineId
; }
759 layers::WebRenderBackend
GetBackendType() const { return mBackend
; }
761 // Checks to see if the innermost enclosing fixed pos item has the same
762 // ASR. If so, it returns the scroll target for that fixed-pos item.
763 // Otherwise, it returns Nothing().
764 Maybe
<layers::ScrollableLayerGuid::ViewID
> GetContainingFixedPosScrollTarget(
765 const ActiveScrolledRoot
* aAsr
);
767 Maybe
<SideBits
> GetContainingFixedPosSideBits(const ActiveScrolledRoot
* aAsr
);
769 gfxContext
* GetTextContext(wr::IpcResourceUpdateQueue
& aResources
,
770 const layers::StackingContextHelper
& aSc
,
771 layers::RenderRootStateManager
* aManager
,
772 nsDisplayItem
* aItem
, nsRect
& aBounds
,
773 const gfx::Point
& aDeviceOffset
);
775 // Try to avoid using this when possible.
776 wr::WrState
* Raw() { return mWrState
; }
778 void SetClipChainLeaf(const Maybe
<wr::LayoutRect
>& aClipRect
) {
779 mClipChainLeaf
= aClipRect
;
782 // Used for opacity flattening. When we flatten away an opacity item,
783 // we push the opacity value onto the builder.
784 // Descendant items should pull the inherited opacity during
785 // their CreateWebRenderCommands implementation. This can only happen if all
786 // descendant items reported supporting this functionality, via
787 // nsDisplayItem::CanApplyOpacity.
788 float GetInheritedOpacity() { return mInheritedOpacity
; }
789 void SetInheritedOpacity(float aOpacity
) { mInheritedOpacity
= aOpacity
; }
790 const DisplayItemClipChain
* GetInheritedClipChain() {
791 return mInheritedClipChain
;
793 void PushInheritedClipChain(nsDisplayListBuilder
* aBuilder
,
794 const DisplayItemClipChain
* aClipChain
);
795 void SetInheritedClipChain(const DisplayItemClipChain
* aClipChain
) {
796 mInheritedClipChain
= aClipChain
;
799 layers::DisplayItemCache
* GetDisplayItemCache() { return mDisplayItemCache
; }
801 // A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of
802 // data. The topmost object is pointed to by the mActiveFixedPosTracker
803 // pointer in the wr::DisplayListBuilder.
804 class MOZ_RAII FixedPosScrollTargetTracker final
{
806 FixedPosScrollTargetTracker(DisplayListBuilder
& aBuilder
,
807 const ActiveScrolledRoot
* aAsr
,
808 layers::ScrollableLayerGuid::ViewID aScrollId
,
810 ~FixedPosScrollTargetTracker();
811 Maybe
<layers::ScrollableLayerGuid::ViewID
> GetScrollTargetForASR(
812 const ActiveScrolledRoot
* aAsr
);
813 Maybe
<SideBits
> GetSideBitsForASR(const ActiveScrolledRoot
* aAsr
);
816 FixedPosScrollTargetTracker
* mParentTracker
;
817 DisplayListBuilder
& mBuilder
;
818 const ActiveScrolledRoot
* mAsr
;
819 layers::ScrollableLayerGuid::ViewID mScrollId
;
824 wr::LayoutRect
MergeClipLeaf(const wr::LayoutRect
& aClip
) {
825 if (mClipChainLeaf
) {
826 return wr::IntersectLayoutRect(*mClipChainLeaf
, aClip
);
831 // See the implementation of PushShadow for details on these methods.
832 void SuspendClipLeafMerging();
833 void ResumeClipLeafMerging();
835 wr::WrState
* mWrState
;
837 // Track each scroll id that we encountered. We use this structure to
838 // ensure that we don't define a particular scroll layer multiple times,
839 // as that results in undefined behaviour in WR.
840 std::unordered_map
<layers::ScrollableLayerGuid::ViewID
, wr::WrSpatialId
>
843 wr::WrSpaceAndClipChain mCurrentSpaceAndClipChain
;
845 // Contains the current leaf of the clip chain to be merged with the
846 // display item's clip rect when pushing an item. May be set to Nothing() if
847 // there is no clip rect to merge with.
848 Maybe
<wr::LayoutRect
> mClipChainLeaf
;
850 // Versions of the above that are on hold while SuspendClipLeafMerging is on
851 // (see the implementation of PushShadow for details).
852 Maybe
<wr::WrSpaceAndClipChain
> mSuspendedSpaceAndClipChain
;
853 Maybe
<wr::LayoutRect
> mSuspendedClipChainLeaf
;
855 RefPtr
<layout::TextDrawTarget
> mCachedTextDT
;
856 mozilla::UniquePtr
<gfxContext
> mCachedContext
;
858 FixedPosScrollTargetTracker
* mActiveFixedPosTracker
;
860 wr::PipelineId mPipelineId
;
861 layers::WebRenderBackend mBackend
;
863 nsTArray
<wr::PipelineId
> mRemotePipelineIds
;
865 layers::DisplayItemCache
* mDisplayItemCache
;
866 Maybe
<uint16_t> mCurrentCacheSlot
;
867 float mInheritedOpacity
= 1.0f
;
868 const DisplayItemClipChain
* mInheritedClipChain
= nullptr;
870 friend class WebRenderAPI
;
871 friend class SpaceAndClipChainHelper
;
874 // This is a RAII class that overrides the current Wr's SpatialId and
876 class MOZ_RAII SpaceAndClipChainHelper final
{
878 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
879 wr::WrSpaceAndClipChain aSpaceAndClipChain
)
880 : mBuilder(aBuilder
),
881 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
882 aBuilder
.mCurrentSpaceAndClipChain
= aSpaceAndClipChain
;
884 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
885 wr::WrSpatialId aSpatialId
)
886 : mBuilder(aBuilder
),
887 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
888 aBuilder
.mCurrentSpaceAndClipChain
.space
= aSpatialId
;
890 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
891 wr::WrClipChainId aClipChainId
)
892 : mBuilder(aBuilder
),
893 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
894 aBuilder
.mCurrentSpaceAndClipChain
.clip_chain
= aClipChainId
.id
;
897 ~SpaceAndClipChainHelper() {
898 mBuilder
.mCurrentSpaceAndClipChain
= mOldSpaceAndClipChain
;
902 SpaceAndClipChainHelper(const SpaceAndClipChainHelper
&) = delete;
904 DisplayListBuilder
& mBuilder
;
905 wr::WrSpaceAndClipChain mOldSpaceAndClipChain
;
908 Maybe
<wr::ImageFormat
> SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat
);
911 } // namespace mozilla