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/AsyncImagePipelineOp.h"
19 #include "mozilla/layers/IpcResourceUpdateQueue.h"
20 #include "mozilla/layers/RemoteTextureMap.h"
21 #include "mozilla/layers/ScrollableLayerGuid.h"
22 #include "mozilla/layers/SyncObject.h"
23 #include "mozilla/layers/CompositionRecorder.h"
24 #include "mozilla/MozPromise.h"
25 #include "mozilla/Range.h"
26 #include "mozilla/TimeStamp.h"
27 #include "mozilla/UniquePtr.h"
28 #include "mozilla/VsyncDispatcher.h"
29 #include "mozilla/webrender/webrender_ffi.h"
30 #include "mozilla/webrender/WebRenderTypes.h"
42 class nsPaintedDisplayItem
;
43 class nsDisplayTransform
;
44 class nsDisplayListBuilder
;
45 struct DisplayItemClipChain
;
47 struct ActiveScrolledRoot
;
50 class CompositorWidget
;
54 class CompositorBridgeParent
;
55 class DisplayItemCache
;
56 class WebRenderBridgeParent
;
57 class RenderRootStateManager
;
58 class StackingContextHelper
;
59 struct DisplayListData
;
68 class DisplayListBuilder
;
73 // This isn't part of WR's API, but we define it here to simplify layout's
74 // logic and data plumbing.
76 wr::LayoutRect bounds
;
77 float wavyLineThickness
;
78 wr::LineOrientation orientation
;
83 /// A handler that can be bundled into a transaction and notified at specific
84 /// points in the rendering pipeline, such as after scene building or after
87 /// If for any reason the handler is dropped before reaching the requested
88 /// point, it is notified with the value Checkpoint::TransactionDropped.
89 /// So it is safe to assume that the handler will be notified "at some point".
90 class NotificationHandler
{
92 virtual void Notify(wr::Checkpoint aCheckpoint
) = 0;
93 virtual ~NotificationHandler() = default;
97 layers::LayersId mLayersId
;
98 layers::ScrollableLayerGuid::ViewID mScrollId
;
99 gfx::CompositorHitTestInfo mHitInfo
;
101 Maybe
<uint64_t> mAnimationId
;
104 class TransactionBuilder final
{
106 explicit TransactionBuilder(WebRenderAPI
* aApi
,
107 bool aUseSceneBuilderThread
= true);
109 TransactionBuilder(WebRenderAPI
* aApi
, Transaction
* aTxn
,
110 bool aUseSceneBuilderThread
, bool aOwnsData
);
112 ~TransactionBuilder();
114 void SetLowPriority(bool aIsLowPriority
);
116 void UpdateEpoch(PipelineId aPipelineId
, Epoch aEpoch
);
118 void SetRootPipeline(PipelineId aPipelineId
);
120 void RemovePipeline(PipelineId aPipelineId
);
122 void SetDisplayList(Epoch aEpoch
, wr::WrPipelineId pipeline_id
,
123 wr::BuiltDisplayListDescriptor dl_descriptor
,
124 wr::Vec
<uint8_t>& dl_items_data
,
125 wr::Vec
<uint8_t>& dl_cache_data
,
126 wr::Vec
<uint8_t>& dl_spatial_tree
);
128 void ClearDisplayList(Epoch aEpoch
, wr::WrPipelineId aPipeline
);
130 void GenerateFrame(const VsyncId
& aVsyncId
, wr::RenderReasons aReasons
);
132 void InvalidateRenderedFrame(wr::RenderReasons aReasons
);
134 void SetDocumentView(const LayoutDeviceIntRect
& aDocRect
);
136 bool IsEmpty() const;
138 bool IsResourceUpdatesEmpty() const;
140 bool IsRenderedFrameInvalidated() const;
142 void AddImage(wr::ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
143 wr::Vec
<uint8_t>& aBytes
);
145 void AddBlobImage(wr::BlobImageKey aKey
, const ImageDescriptor
& aDescriptor
,
146 uint16_t aTileSize
, wr::Vec
<uint8_t>& aBytes
,
147 const wr::DeviceIntRect
& aVisibleRect
);
149 void AddExternalImageBuffer(ImageKey key
, const ImageDescriptor
& aDescriptor
,
150 ExternalImageId aHandle
);
152 void AddExternalImage(ImageKey key
, const ImageDescriptor
& aDescriptor
,
153 ExternalImageId aExtID
,
154 wr::ExternalImageType aImageType
,
155 uint8_t aChannelIndex
= 0);
157 void UpdateImageBuffer(wr::ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
158 wr::Vec
<uint8_t>& aBytes
);
160 void UpdateBlobImage(wr::BlobImageKey aKey
,
161 const ImageDescriptor
& aDescriptor
,
162 wr::Vec
<uint8_t>& aBytes
,
163 const wr::DeviceIntRect
& aVisibleRect
,
164 const wr::LayoutIntRect
& aDirtyRect
);
166 void UpdateExternalImage(ImageKey aKey
, const ImageDescriptor
& aDescriptor
,
167 ExternalImageId aExtID
,
168 wr::ExternalImageType aImageType
,
169 uint8_t aChannelIndex
= 0);
171 void UpdateExternalImageWithDirtyRect(ImageKey aKey
,
172 const ImageDescriptor
& aDescriptor
,
173 ExternalImageId aExtID
,
174 wr::ExternalImageType aImageType
,
175 const wr::DeviceIntRect
& aDirtyRect
,
176 uint8_t aChannelIndex
= 0);
178 void SetBlobImageVisibleArea(BlobImageKey aKey
,
179 const wr::DeviceIntRect
& aArea
);
181 void DeleteImage(wr::ImageKey aKey
);
183 void DeleteBlobImage(wr::BlobImageKey aKey
);
185 void AddRawFont(wr::FontKey aKey
, wr::Vec
<uint8_t>& aBytes
, uint32_t aIndex
);
187 void AddFontDescriptor(wr::FontKey aKey
, wr::Vec
<uint8_t>& aBytes
,
190 void DeleteFont(wr::FontKey aKey
);
192 void AddFontInstance(wr::FontInstanceKey aKey
, wr::FontKey aFontKey
,
194 const wr::FontInstanceOptions
* aOptions
,
195 const wr::FontInstancePlatformOptions
* aPlatformOptions
,
196 wr::Vec
<uint8_t>& aVariations
);
198 void DeleteFontInstance(wr::FontInstanceKey aKey
);
200 void UpdateQualitySettings(bool aForceSubpixelAAWherePossible
);
202 void Notify(wr::Checkpoint aWhen
, UniquePtr
<NotificationHandler
> aHandler
);
208 bool UseSceneBuilderThread() const { return mUseSceneBuilderThread
; }
209 layers::WebRenderBackend
GetBackendType() { return mApiBackend
; }
210 Transaction
* Raw() { return mTxn
; }
214 bool mUseSceneBuilderThread
;
215 layers::WebRenderBackend mApiBackend
;
219 class TransactionWrapper final
{
221 explicit TransactionWrapper(Transaction
* aTxn
);
223 void AppendDynamicProperties(
224 const nsTArray
<wr::WrOpacityProperty
>& aOpacityArray
,
225 const nsTArray
<wr::WrTransformProperty
>& aTransformArray
,
226 const nsTArray
<wr::WrColorProperty
>& aColorArray
);
227 void AppendTransformProperties(
228 const nsTArray
<wr::WrTransformProperty
>& aTransformArray
);
229 void UpdateScrollPosition(
230 const wr::ExternalScrollId
& aScrollId
,
231 const nsTArray
<wr::SampledScrollOffset
>& aSampledOffsets
);
232 void UpdateIsTransformAsyncZooming(uint64_t aAnimationId
, bool aIsZooming
);
233 void AddMinimapData(const wr::ExternalScrollId
& aScrollId
,
234 const MinimapData
& aMinimapData
);
240 class WebRenderAPI final
{
241 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderAPI
);
244 /// This can be called on the compositor thread only.
245 static already_AddRefed
<WebRenderAPI
> Create(
246 layers::CompositorBridgeParent
* aBridge
,
247 RefPtr
<widget::CompositorWidget
>&& aWidget
,
248 const wr::WrWindowId
& aWindowId
, LayoutDeviceIntSize aSize
,
249 layers::WindowKind aWindowKind
, nsACString
& aError
);
251 already_AddRefed
<WebRenderAPI
> Clone();
253 void DestroyRenderer();
255 wr::WindowId
GetId() const { return mId
; }
257 /// Do a non-blocking hit-testing query on a shared version of the hit
258 /// testing information.
259 std::vector
<WrHitResult
> HitTest(const wr::WorldPoint
& aPoint
);
261 void SendTransaction(TransactionBuilder
& aTxn
);
263 void SetFrameStartTime(const TimeStamp
& aTime
);
265 void RunOnRenderThread(UniquePtr
<RendererEvent
> aEvent
);
267 void Readback(const TimeStamp
& aStartTime
, gfx::IntSize aSize
,
268 const gfx::SurfaceFormat
& aFormat
,
269 const Range
<uint8_t>& aBuffer
, bool* aNeedsYFlip
);
271 void ClearAllCaches();
272 void EnableNativeCompositor(bool aEnable
);
273 void SetBatchingLookback(uint32_t aCount
);
274 void SetBool(wr::BoolParameter
, bool value
);
275 void SetInt(wr::IntParameter
, int32_t value
);
277 void SetClearColor(const gfx::DeviceColor
& aColor
);
278 void SetProfilerUI(const nsACString
& aUIString
);
283 void WakeSceneBuilder();
284 void FlushSceneBuilder();
286 void NotifyMemoryPressure();
287 void AccumulateMemoryReport(wr::MemoryReport
*);
289 wr::WrIdNamespace
GetNamespace();
290 layers::WebRenderBackend
GetBackendType() { return mBackend
; }
291 layers::WebRenderCompositor
GetCompositorType() { return mCompositor
; }
292 uint32_t GetMaxTextureSize() const { return mMaxTextureSize
; }
293 bool GetUseANGLE() const { return mUseANGLE
; }
294 bool GetUseDComp() const { return mUseDComp
; }
295 bool GetUseTripleBuffering() const { return mUseTripleBuffering
; }
296 bool SupportsExternalBufferTextures() const {
297 return mSupportsExternalBufferTextures
;
299 layers::SyncHandle
GetSyncHandle() const { return mSyncHandle
; }
303 void StartCaptureSequence(const nsACString
& aPath
, uint32_t aFlags
);
304 void StopCaptureSequence();
306 void BeginRecording(const TimeStamp
& aRecordingStart
,
307 wr::PipelineId aRootPipelineId
);
309 typedef MozPromise
<layers::FrameRecording
, nsresult
, true>
312 RefPtr
<EndRecordingPromise
> EndRecording();
314 layers::RemoteTextureInfoList
* GetPendingRemoteTextureInfoList();
315 layers::AsyncImagePipelineOps
* GetPendingAsyncImagePipelineOps(
316 TransactionBuilder
& aTxn
);
318 void FlushPendingWrTransactionEventsWithoutWait();
319 void FlushPendingWrTransactionEventsWithWait();
321 wr::WebRenderAPI
* GetRootAPI();
324 WebRenderAPI(wr::DocumentHandle
* aHandle
, wr::WindowId aId
,
325 layers::WebRenderBackend aBackend
,
326 layers::WebRenderCompositor aCompositor
,
327 uint32_t aMaxTextureSize
, bool aUseANGLE
, bool aUseDComp
,
328 bool aUseTripleBuffering
, bool aSupportsExternalBufferTextures
,
329 layers::SyncHandle aSyncHandle
,
330 wr::WebRenderAPI
* aRootApi
= nullptr,
331 wr::WebRenderAPI
* aRootDocumentApi
= nullptr);
334 // Should be used only for shutdown handling
337 void UpdateDebugFlags(uint32_t aFlags
);
338 bool CheckIsRemoteTextureReady(layers::RemoteTextureInfoList
* aList
,
339 const TimeStamp
& aTimeStamp
);
340 void WaitRemoteTextureReady(layers::RemoteTextureInfoList
* aList
);
342 enum class RemoteTextureWaitType
: uint8_t {
348 void HandleWrTransactionEvents(RemoteTextureWaitType aType
);
350 class WrTransactionEvent
{
354 PendingRemoteTextures
,
355 PendingAsyncImagePipelineOps
,
358 const TimeStamp mTimeStamp
;
361 WrTransactionEvent(const Tag aTag
,
362 UniquePtr
<TransactionBuilder
>&& aTransaction
)
364 mTimeStamp(TimeStamp::Now()),
365 mTransaction(std::move(aTransaction
)) {
366 MOZ_ASSERT(mTag
== Tag::Transaction
);
370 UniquePtr
<layers::RemoteTextureInfoList
>&& aPendingRemoteTextures
)
372 mTimeStamp(TimeStamp::Now()),
373 mPendingRemoteTextures(std::move(aPendingRemoteTextures
)) {
374 MOZ_ASSERT(mTag
== Tag::PendingRemoteTextures
);
376 WrTransactionEvent(const Tag aTag
,
377 UniquePtr
<layers::AsyncImagePipelineOps
>&&
378 aPendingAsyncImagePipelineOps
,
379 UniquePtr
<TransactionBuilder
>&& aTransaction
)
381 mTimeStamp(TimeStamp::Now()),
382 mPendingAsyncImagePipelineOps(
383 std::move(aPendingAsyncImagePipelineOps
)),
384 mTransaction(std::move(aTransaction
)) {
385 MOZ_ASSERT(mTag
== Tag::PendingAsyncImagePipelineOps
);
388 UniquePtr
<layers::RemoteTextureInfoList
> mPendingRemoteTextures
;
389 UniquePtr
<layers::AsyncImagePipelineOps
> mPendingAsyncImagePipelineOps
;
390 UniquePtr
<TransactionBuilder
> mTransaction
;
393 static WrTransactionEvent
Transaction(WebRenderAPI
* aApi
,
394 wr::Transaction
* aTxn
,
395 bool aUseSceneBuilderThread
) {
396 auto transaction
= MakeUnique
<TransactionBuilder
>(
397 aApi
, aTxn
, aUseSceneBuilderThread
, /* aOwnsData */ true);
398 return WrTransactionEvent(Tag::Transaction
, std::move(transaction
));
401 static WrTransactionEvent
PendingRemoteTextures(
402 UniquePtr
<layers::RemoteTextureInfoList
>&& aPendingRemoteTextures
) {
403 return WrTransactionEvent(Tag::PendingRemoteTextures
,
404 std::move(aPendingRemoteTextures
));
407 static WrTransactionEvent
PendingAsyncImagePipelineOps(
408 UniquePtr
<layers::AsyncImagePipelineOps
>&&
409 aPendingAsyncImagePipelineOps
,
410 WebRenderAPI
* aApi
, wr::Transaction
* aTxn
,
411 bool aUseSceneBuilderThread
) {
412 auto transaction
= MakeUnique
<TransactionBuilder
>(
413 aApi
, aTxn
, aUseSceneBuilderThread
, /* aOwnsData */ false);
414 return WrTransactionEvent(Tag::PendingAsyncImagePipelineOps
,
415 std::move(aPendingAsyncImagePipelineOps
),
416 std::move(transaction
));
419 wr::Transaction
* RawTransaction() {
420 if (mTag
== Tag::Transaction
) {
421 return mTransaction
->Raw();
423 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
427 TransactionBuilder
* GetTransactionBuilder() {
428 if (mTag
== Tag::PendingAsyncImagePipelineOps
) {
429 return mTransaction
.get();
431 MOZ_CRASH("Should not be called");
435 bool UseSceneBuilderThread() {
436 if (mTag
== Tag::Transaction
) {
437 return mTransaction
->UseSceneBuilderThread();
439 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
443 layers::RemoteTextureInfoList
* RemoteTextureInfoList() {
444 if (mTag
== Tag::PendingRemoteTextures
) {
445 MOZ_ASSERT(mPendingRemoteTextures
);
446 return mPendingRemoteTextures
.get();
448 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
452 layers::AsyncImagePipelineOps
* AsyncImagePipelineOps() {
453 if (mTag
== Tag::PendingAsyncImagePipelineOps
) {
454 MOZ_ASSERT(mPendingAsyncImagePipelineOps
);
455 return mPendingAsyncImagePipelineOps
.get();
457 MOZ_ASSERT_UNREACHABLE("unexpected to be called");
462 wr::DocumentHandle
* mDocHandle
;
464 layers::WebRenderBackend mBackend
;
465 layers::WebRenderCompositor mCompositor
;
466 int32_t mMaxTextureSize
;
469 bool mUseTripleBuffering
;
470 bool mSupportsExternalBufferTextures
;
471 bool mCaptureSequence
;
472 layers::SyncHandle mSyncHandle
;
473 bool mRendererDestroyed
;
475 UniquePtr
<layers::RemoteTextureInfoList
> mPendingRemoteTextureInfoList
;
476 UniquePtr
<layers::AsyncImagePipelineOps
> mPendingAsyncImagePipelineOps
;
477 std::queue
<WrTransactionEvent
> mPendingWrTransactionEvents
;
479 // We maintain alive the root api to know when to shut the render backend
480 // down, and the root api for the document to know when to delete the
481 // document. mRootApi is null for the api object that owns the channel (and is
482 // responsible for shutting it down), and mRootDocumentApi is null for the api
483 // object owning (and responsible for destroying) a given document. All api
484 // objects in the same window use the same channel, and some api objects write
485 // to the same document (but there is only one owner for each channel and for
487 const RefPtr
<wr::WebRenderAPI
> mRootApi
;
488 const RefPtr
<wr::WebRenderAPI
> mRootDocumentApi
;
490 friend class DisplayListBuilder
;
491 friend class layers::WebRenderBridgeParent
;
494 // This is a RAII class that automatically sends the transaction on
495 // destruction. This is useful for code that has multiple exit points and we
496 // want to ensure that the stuff accumulated in the transaction gets sent
497 // regardless of which exit we take. Note that if the caller explicitly calls
498 // mApi->SendTransaction() that's fine too because that empties out the
499 // TransactionBuilder and leaves it as a valid empty transaction, so calling
500 // SendTransaction on it again ends up being a no-op.
501 class MOZ_RAII AutoTransactionSender
{
503 AutoTransactionSender(WebRenderAPI
* aApi
, TransactionBuilder
* aTxn
)
504 : mApi(aApi
), mTxn(aTxn
) {
505 MOZ_RELEASE_ASSERT(mApi
);
506 MOZ_RELEASE_ASSERT(aTxn
);
509 ~AutoTransactionSender() { mApi
->SendTransaction(*mTxn
); }
513 TransactionBuilder
* mTxn
;
517 * A set of optional parameters for stacking context creation.
519 struct MOZ_STACK_CLASS StackingContextParams
: public WrStackingContextParams
{
520 StackingContextParams()
521 : WrStackingContextParams
{
522 WrStackingContextClip::None(),
526 wr::TransformStyle::Flat
,
527 wr::WrReferenceFrameKind::Transform
,
532 /* prim_flags = */ wr::PrimitiveFlags::IS_BACKFACE_VISIBLE
,
533 wr::MixBlendMode::Normal
,
534 wr::StackingContextFlags
{0}} {}
536 void SetPreserve3D(bool aPreserve
) {
538 aPreserve
? wr::TransformStyle::Preserve3D
: wr::TransformStyle::Flat
;
541 // Fill this in only if this is for the root StackingContextHelper.
542 nsIFrame
* mRootReferenceFrame
= nullptr;
543 nsTArray
<wr::FilterOp
> mFilters
;
544 nsTArray
<wr::WrFilterData
> mFilterDatas
;
545 wr::LayoutRect mBounds
= wr::ToLayoutRect(LayoutDeviceRect());
546 const gfx::Matrix4x4
* mBoundTransform
= nullptr;
547 const wr::WrTransformInfo
* mTransformPtr
= nullptr;
548 nsDisplayTransform
* mDeferredTransformItem
= nullptr;
549 // Whether the stacking context is possibly animated. This alters how
550 // coordinates are transformed/snapped to invalidate less when transforms
551 // change frequently.
552 bool mAnimated
= false;
553 // Whether items should be rasterized in a local space that is (mostly)
554 // invariant to transforms, i.e. disabling subpixel AA and screen space pixel
555 // snapping on text runs that would only make sense in screen space.
556 bool mRasterizeLocally
= false;
559 /// This is a simple C++ wrapper around WrState defined in the rust bindings.
560 /// We may want to turn this into a direct wrapper on top of
561 /// WebRenderFrameBuilder instead, so the interface may change a bit.
562 class DisplayListBuilder final
{
564 explicit DisplayListBuilder(wr::PipelineId aId
,
565 layers::WebRenderBackend aBackend
);
566 DisplayListBuilder(DisplayListBuilder
&&) = default;
568 ~DisplayListBuilder();
574 usize
Dump(usize aIndent
, const Maybe
<usize
>& aStart
,
575 const Maybe
<usize
>& aEnd
);
576 void DumpSerializedDisplayList();
578 void Begin(layers::DisplayItemCache
* aCache
= nullptr);
579 void End(wr::BuiltDisplayList
& aOutDisplayList
);
580 void End(layers::DisplayListData
& aOutTransaction
);
582 Maybe
<wr::WrSpatialId
> PushStackingContext(
583 const StackingContextParams
& aParams
, const wr::LayoutRect
& aBounds
,
584 const wr::RasterSpace
& aRasterSpace
);
585 void PopStackingContext(bool aIsReferenceFrame
);
587 wr::WrClipChainId
DefineClipChain(const nsTArray
<wr::WrClipId
>& aClips
,
588 bool aParentWithCurrentChain
= false);
590 wr::WrClipId
DefineImageMaskClip(const wr::ImageMask
& aMask
,
591 const nsTArray
<wr::LayoutPoint
>&,
593 wr::WrClipId
DefineRoundedRectClip(Maybe
<wr::WrSpatialId
> aSpace
,
594 const wr::ComplexClipRegion
& aComplex
);
595 wr::WrClipId
DefineRectClip(Maybe
<wr::WrSpatialId
> aSpace
,
596 wr::LayoutRect aClipRect
);
598 wr::WrSpatialId
DefineStickyFrame(
599 const wr::LayoutRect
& aContentRect
, const float* aTopMargin
,
600 const float* aRightMargin
, const float* aBottomMargin
,
601 const float* aLeftMargin
, const StickyOffsetBounds
& aVerticalBounds
,
602 const StickyOffsetBounds
& aHorizontalBounds
,
603 const wr::LayoutVector2D
& aAppliedOffset
, wr::SpatialTreeItemKey aKey
);
605 Maybe
<wr::WrSpatialId
> GetScrollIdForDefinedScrollLayer(
606 layers::ScrollableLayerGuid::ViewID aViewId
) const;
607 wr::WrSpatialId
DefineScrollLayer(
608 const layers::ScrollableLayerGuid::ViewID
& aViewId
,
609 const Maybe
<wr::WrSpatialId
>& aParent
, const wr::LayoutRect
& aContentRect
,
610 const wr::LayoutRect
& aClipRect
, const wr::LayoutVector2D
& aScrollOffset
,
611 wr::APZScrollGeneration aScrollOffsetGeneration
,
612 wr::HasScrollLinkedEffect aHasScrollLinkedEffect
,
613 wr::SpatialTreeItemKey aKey
);
615 void PushRect(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
616 bool aIsBackfaceVisible
, bool aForceAntiAliasing
,
617 bool aIsCheckerboard
, const wr::ColorF
& aColor
);
618 void PushRectWithAnimation(const wr::LayoutRect
& aBounds
,
619 const wr::LayoutRect
& aClip
,
620 bool aIsBackfaceVisible
, const wr::ColorF
& aColor
,
621 const WrAnimationProperty
* aAnimation
);
622 void PushRoundedRect(const wr::LayoutRect
& aBounds
,
623 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
624 const wr::ColorF
& aColor
);
625 void PushHitTest(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
626 bool aIsBackfaceVisible
,
627 const layers::ScrollableLayerGuid::ViewID
& aScrollId
,
628 const gfx::CompositorHitTestInfo
& aHitInfo
,
630 void PushClearRect(const wr::LayoutRect
& aBounds
);
632 void PushBackdropFilter(const wr::LayoutRect
& aBounds
,
633 const wr::ComplexClipRegion
& aRegion
,
634 const nsTArray
<wr::FilterOp
>& aFilters
,
635 const nsTArray
<wr::WrFilterData
>& aFilterDatas
,
636 bool aIsBackfaceVisible
);
638 void PushLinearGradient(const wr::LayoutRect
& aBounds
,
639 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
640 const wr::LayoutPoint
& aStartPoint
,
641 const wr::LayoutPoint
& aEndPoint
,
642 const nsTArray
<wr::GradientStop
>& aStops
,
643 wr::ExtendMode aExtendMode
,
644 const wr::LayoutSize aTileSize
,
645 const wr::LayoutSize aTileSpacing
);
647 void PushRadialGradient(const wr::LayoutRect
& aBounds
,
648 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
649 const wr::LayoutPoint
& aCenter
,
650 const wr::LayoutSize
& aRadius
,
651 const nsTArray
<wr::GradientStop
>& aStops
,
652 wr::ExtendMode aExtendMode
,
653 const wr::LayoutSize aTileSize
,
654 const wr::LayoutSize aTileSpacing
);
656 void PushConicGradient(const wr::LayoutRect
& aBounds
,
657 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
658 const wr::LayoutPoint
& aCenter
, const float aAngle
,
659 const nsTArray
<wr::GradientStop
>& aStops
,
660 wr::ExtendMode aExtendMode
,
661 const wr::LayoutSize aTileSize
,
662 const wr::LayoutSize aTileSpacing
);
664 void PushImage(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
665 bool aIsBackfaceVisible
, bool aForceAntiAliasing
,
666 wr::ImageRendering aFilter
, wr::ImageKey aImage
,
667 bool aPremultipliedAlpha
= true,
668 const wr::ColorF
& aColor
= wr::ColorF
{1.0f
, 1.0f
, 1.0f
, 1.0f
},
669 bool aPreferCompositorSurface
= false,
670 bool aSupportsExternalCompositing
= false);
672 void PushRepeatingImage(
673 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
674 bool aIsBackfaceVisible
, const wr::LayoutSize
& aStretchSize
,
675 const wr::LayoutSize
& aTileSpacing
, wr::ImageRendering aFilter
,
676 wr::ImageKey aImage
, bool aPremultipliedAlpha
= true,
677 const wr::ColorF
& aColor
= wr::ColorF
{1.0f
, 1.0f
, 1.0f
, 1.0f
});
679 void PushYCbCrPlanarImage(
680 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
681 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
682 wr::ImageKey aImageChannel1
, wr::ImageKey aImageChannel2
,
683 wr::WrColorDepth aColorDepth
, wr::WrYuvColorSpace aColorSpace
,
684 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
685 bool aPreferCompositorSurface
= false,
686 bool aSupportsExternalCompositing
= false);
688 void PushNV12Image(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
689 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
690 wr::ImageKey aImageChannel1
, wr::WrColorDepth aColorDepth
,
691 wr::WrYuvColorSpace aColorSpace
,
692 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
693 bool aPreferCompositorSurface
= false,
694 bool aSupportsExternalCompositing
= false);
696 void PushP010Image(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
697 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
698 wr::ImageKey aImageChannel1
, wr::WrColorDepth aColorDepth
,
699 wr::WrYuvColorSpace aColorSpace
,
700 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
701 bool aPreferCompositorSurface
= false,
702 bool aSupportsExternalCompositing
= false);
704 void PushYCbCrInterleavedImage(
705 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
706 bool aIsBackfaceVisible
, wr::ImageKey aImageChannel0
,
707 wr::WrColorDepth aColorDepth
, wr::WrYuvColorSpace aColorSpace
,
708 wr::WrColorRange aColorRange
, wr::ImageRendering aFilter
,
709 bool aPreferCompositorSurface
= false,
710 bool aSupportsExternalCompositing
= false);
712 void PushIFrame(const LayoutDeviceRect
& aDevPxBounds
, bool aIsBackfaceVisible
,
713 wr::PipelineId aPipeline
, bool aIgnoreMissingPipeline
);
715 // XXX WrBorderSides are passed with Range.
716 // It is just to bypass compiler bug. See Bug 1357734.
717 void PushBorder(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
718 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
,
719 const Range
<const wr::BorderSide
>& aSides
,
720 const wr::BorderRadius
& aRadius
,
721 wr::AntialiasBorder
= wr::AntialiasBorder::Yes
);
723 void PushBorderImage(const wr::LayoutRect
& aBounds
,
724 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
725 const wr::WrBorderImage
& aParams
);
727 void PushBorderGradient(const wr::LayoutRect
& aBounds
,
728 const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
729 const wr::LayoutSideOffsets
& aWidths
,
730 const int32_t aWidth
, const int32_t aHeight
,
731 bool aFill
, const wr::DeviceIntSideOffsets
& aSlice
,
732 const wr::LayoutPoint
& aStartPoint
,
733 const wr::LayoutPoint
& aEndPoint
,
734 const nsTArray
<wr::GradientStop
>& aStops
,
735 wr::ExtendMode aExtendMode
);
737 void PushBorderRadialGradient(
738 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
739 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
, bool aFill
,
740 const wr::LayoutPoint
& aCenter
, const wr::LayoutSize
& aRadius
,
741 const nsTArray
<wr::GradientStop
>& aStops
, wr::ExtendMode aExtendMode
);
743 void PushBorderConicGradient(
744 const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
745 bool aIsBackfaceVisible
, const wr::LayoutSideOffsets
& aWidths
, bool aFill
,
746 const wr::LayoutPoint
& aCenter
, const float aAngle
,
747 const nsTArray
<wr::GradientStop
>& aStops
, wr::ExtendMode aExtendMode
);
749 void PushText(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
750 bool aIsBackfaceVisible
, const wr::ColorF
& aColor
,
751 wr::FontInstanceKey aFontKey
,
752 Range
<const wr::GlyphInstance
> aGlyphBuffer
,
753 const wr::GlyphOptions
* aGlyphOptions
= nullptr);
755 void PushLine(const wr::LayoutRect
& aClip
, bool aIsBackfaceVisible
,
756 const wr::Line
& aLine
);
758 void PushShadow(const wr::LayoutRect
& aBounds
, const wr::LayoutRect
& aClip
,
759 bool aIsBackfaceVisible
, const wr::Shadow
& aShadow
,
760 bool aShouldInflate
);
762 void PopAllShadows();
764 void PushBoxShadow(const wr::LayoutRect
& aRect
, const wr::LayoutRect
& aClip
,
765 bool aIsBackfaceVisible
, const wr::LayoutRect
& aBoxBounds
,
766 const wr::LayoutVector2D
& aOffset
,
767 const wr::ColorF
& aColor
, const float& aBlurRadius
,
768 const float& aSpreadRadius
,
769 const wr::BorderRadius
& aBorderRadius
,
770 const wr::BoxShadowClipMode
& aClipMode
);
773 * Notifies the DisplayListBuilder that it can group together WR display items
774 * that are pushed until |CancelGroup()| or |FinishGroup()| call.
776 void StartGroup(nsPaintedDisplayItem
* aItem
);
779 * Cancels grouping of the display items and discards all the display items
780 * pushed between the |StartGroup()| and |CancelGroup()| calls.
782 void CancelGroup(const bool aDiscard
= false);
785 * Finishes the display item group. The group is stored in WebRender backend,
786 * and can be reused with |ReuseItem()|, if the Gecko display item is reused.
791 * Try to reuse the previously created WebRender display items for the given
792 * Gecko display item |aItem|.
793 * Returns true if the items were reused, otherwise returns false.
795 bool ReuseItem(nsPaintedDisplayItem
* aItem
);
797 uint64_t CurrentClipChainId() const {
798 return mCurrentSpaceAndClipChain
.clip_chain
;
801 const wr::WrSpaceAndClipChain
& CurrentSpaceAndClipChain() const {
802 return mCurrentSpaceAndClipChain
;
805 const wr::PipelineId
& CurrentPipelineId() const { return mPipelineId
; }
806 layers::WebRenderBackend
GetBackendType() const { return mBackend
; }
808 // Checks to see if the innermost enclosing fixed pos item has the same
809 // ASR. If so, it returns the scroll target for that fixed-pos item.
810 // Otherwise, it returns Nothing().
811 Maybe
<layers::ScrollableLayerGuid::ViewID
> GetContainingFixedPosScrollTarget(
812 const ActiveScrolledRoot
* aAsr
);
814 Maybe
<SideBits
> GetContainingFixedPosSideBits(const ActiveScrolledRoot
* aAsr
);
816 gfxContext
* GetTextContext(wr::IpcResourceUpdateQueue
& aResources
,
817 const layers::StackingContextHelper
& aSc
,
818 layers::RenderRootStateManager
* aManager
,
819 nsDisplayItem
* aItem
, nsRect
& aBounds
,
820 const gfx::Point
& aDeviceOffset
);
822 // Try to avoid using this when possible.
823 wr::WrState
* Raw() { return mWrState
; }
825 void SetClipChainLeaf(const Maybe
<wr::LayoutRect
>& aClipRect
) {
826 mClipChainLeaf
= aClipRect
;
829 // Used for opacity flattening. When we flatten away an opacity item,
830 // we push the opacity value onto the builder.
831 // Descendant items should pull the inherited opacity during
832 // their CreateWebRenderCommands implementation. This can only happen if all
833 // descendant items reported supporting this functionality, via
834 // nsDisplayItem::CanApplyOpacity.
835 float GetInheritedOpacity() { return mInheritedOpacity
; }
836 void SetInheritedOpacity(float aOpacity
) { mInheritedOpacity
= aOpacity
; }
837 const DisplayItemClipChain
* GetInheritedClipChain() {
838 return mInheritedClipChain
;
840 void PushInheritedClipChain(nsDisplayListBuilder
* aBuilder
,
841 const DisplayItemClipChain
* aClipChain
);
842 void SetInheritedClipChain(const DisplayItemClipChain
* aClipChain
) {
843 mInheritedClipChain
= aClipChain
;
846 layers::DisplayItemCache
* GetDisplayItemCache() { return mDisplayItemCache
; }
848 // A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of
849 // data. The topmost object is pointed to by the mActiveFixedPosTracker
850 // pointer in the wr::DisplayListBuilder.
851 class MOZ_RAII FixedPosScrollTargetTracker final
{
853 FixedPosScrollTargetTracker(DisplayListBuilder
& aBuilder
,
854 const ActiveScrolledRoot
* aAsr
,
855 layers::ScrollableLayerGuid::ViewID aScrollId
,
857 ~FixedPosScrollTargetTracker();
858 Maybe
<layers::ScrollableLayerGuid::ViewID
> GetScrollTargetForASR(
859 const ActiveScrolledRoot
* aAsr
);
860 Maybe
<SideBits
> GetSideBitsForASR(const ActiveScrolledRoot
* aAsr
);
863 FixedPosScrollTargetTracker
* mParentTracker
;
864 DisplayListBuilder
& mBuilder
;
865 const ActiveScrolledRoot
* mAsr
;
866 layers::ScrollableLayerGuid::ViewID mScrollId
;
871 wr::LayoutRect
MergeClipLeaf(const wr::LayoutRect
& aClip
) {
872 if (mClipChainLeaf
) {
873 return wr::IntersectLayoutRect(*mClipChainLeaf
, aClip
);
878 // See the implementation of PushShadow for details on these methods.
879 void SuspendClipLeafMerging();
880 void ResumeClipLeafMerging();
882 wr::WrState
* mWrState
;
884 // Track each scroll id that we encountered. We use this structure to
885 // ensure that we don't define a particular scroll layer multiple times,
886 // as that results in undefined behaviour in WR.
887 std::unordered_map
<layers::ScrollableLayerGuid::ViewID
, wr::WrSpatialId
>
890 wr::WrSpaceAndClipChain mCurrentSpaceAndClipChain
;
892 // Contains the current leaf of the clip chain to be merged with the
893 // display item's clip rect when pushing an item. May be set to Nothing() if
894 // there is no clip rect to merge with.
895 Maybe
<wr::LayoutRect
> mClipChainLeaf
;
897 // Versions of the above that are on hold while SuspendClipLeafMerging is on
898 // (see the implementation of PushShadow for details).
899 Maybe
<wr::WrSpaceAndClipChain
> mSuspendedSpaceAndClipChain
;
900 Maybe
<wr::LayoutRect
> mSuspendedClipChainLeaf
;
902 RefPtr
<layout::TextDrawTarget
> mCachedTextDT
;
903 mozilla::UniquePtr
<gfxContext
> mCachedContext
;
905 FixedPosScrollTargetTracker
* mActiveFixedPosTracker
;
907 wr::PipelineId mPipelineId
;
908 layers::WebRenderBackend mBackend
;
910 layers::DisplayItemCache
* mDisplayItemCache
;
911 Maybe
<uint16_t> mCurrentCacheSlot
;
912 float mInheritedOpacity
= 1.0f
;
913 const DisplayItemClipChain
* mInheritedClipChain
= nullptr;
915 friend class WebRenderAPI
;
916 friend class SpaceAndClipChainHelper
;
919 // This is a RAII class that overrides the current Wr's SpatialId and
921 class MOZ_RAII SpaceAndClipChainHelper final
{
923 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
924 wr::WrSpaceAndClipChain aSpaceAndClipChain
)
925 : mBuilder(aBuilder
),
926 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
927 aBuilder
.mCurrentSpaceAndClipChain
= aSpaceAndClipChain
;
929 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
930 wr::WrSpatialId aSpatialId
)
931 : mBuilder(aBuilder
),
932 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
933 aBuilder
.mCurrentSpaceAndClipChain
.space
= aSpatialId
;
935 SpaceAndClipChainHelper(DisplayListBuilder
& aBuilder
,
936 wr::WrClipChainId aClipChainId
)
937 : mBuilder(aBuilder
),
938 mOldSpaceAndClipChain(aBuilder
.mCurrentSpaceAndClipChain
) {
939 aBuilder
.mCurrentSpaceAndClipChain
.clip_chain
= aClipChainId
.id
;
942 ~SpaceAndClipChainHelper() {
943 mBuilder
.mCurrentSpaceAndClipChain
= mOldSpaceAndClipChain
;
947 SpaceAndClipChainHelper(const SpaceAndClipChainHelper
&) = delete;
949 DisplayListBuilder
& mBuilder
;
950 wr::WrSpaceAndClipChain mOldSpaceAndClipChain
;
953 Maybe
<wr::ImageFormat
> SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat
);
956 } // namespace mozilla