WebRenderAPI.h (39568B)
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 <queue> 11 #include <stdint.h> 12 #include <vector> 13 #include <unordered_map> 14 15 #include "mozilla/AlreadyAddRefed.h" 16 #include "mozilla/gfx/CompositorHitTestInfo.h" 17 #include "mozilla/layers/AsyncImagePipelineOp.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" 30 #include "nsString.h" 31 #include "GLTypes.h" 32 #include "Units.h" 33 34 class gfxContext; 35 36 #undef None 37 38 namespace mozilla { 39 40 class nsDisplayItem; 41 class nsPaintedDisplayItem; 42 class nsDisplayTransform; 43 class nsDisplayListBuilder; 44 struct DisplayItemClipChain; 45 46 struct ActiveScrolledRoot; 47 48 namespace widget { 49 class CompositorWidget; 50 } 51 52 namespace layers { 53 class CompositorBridgeParent; 54 class DisplayItemCache; 55 class WebRenderBridgeParent; 56 class RenderRootStateManager; 57 class StackingContextHelper; 58 struct DisplayListData; 59 } // namespace layers 60 61 namespace layout { 62 class TextDrawTarget; 63 } 64 65 namespace wr { 66 67 class DisplayListBuilder; 68 class RendererOGL; 69 class RendererEvent; 70 class WebRenderAPI; 71 72 // This isn't part of WR's API, but we define it here to simplify layout's 73 // logic and data plumbing. 74 struct Line { 75 wr::LayoutRect bounds; 76 float wavyLineThickness; 77 wr::LineOrientation orientation; 78 wr::ColorF color; 79 wr::LineStyle style; 80 }; 81 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 84 /// frame building. 85 /// 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 { 90 public: 91 virtual void Notify(wr::Checkpoint aCheckpoint) = 0; 92 virtual ~NotificationHandler() = default; 93 }; 94 95 struct WrHitResult { 96 layers::LayersId mLayersId; 97 layers::ScrollableLayerGuid::ViewID mScrollId; 98 gfx::CompositorHitTestInfo mHitInfo; 99 SideBits mSideBits; 100 Maybe<uint64_t> mAnimationId; 101 }; 102 103 class TransactionBuilder final { 104 public: 105 explicit TransactionBuilder( 106 WebRenderAPI* aApi, bool aUseSceneBuilderThread = true, 107 layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler = nullptr, 108 layers::RemoteTextureTxnId aRemoteTextureTxnId = 0); 109 110 TransactionBuilder( 111 WebRenderAPI* aApi, Transaction* aTxn, bool aUseSceneBuilderThread, 112 bool aOwnsData, 113 layers::RemoteTextureTxnScheduler* aRemoteTextureTxnScheduler, 114 layers::RemoteTextureTxnId aRemoteTextureTxnId); 115 116 ~TransactionBuilder(); 117 118 void SetLowPriority(bool aIsLowPriority); 119 120 void UpdateEpoch(PipelineId aPipelineId, Epoch aEpoch); 121 122 void SetRootPipeline(PipelineId aPipelineId); 123 124 void RemovePipeline(PipelineId aPipelineId); 125 126 void SetDisplayList(Epoch aEpoch, wr::WrPipelineId pipeline_id, 127 wr::BuiltDisplayListDescriptor dl_descriptor, 128 wr::Vec<uint8_t>& dl_items_data, 129 wr::Vec<uint8_t>& dl_cache_data, 130 wr::Vec<uint8_t>& dl_spatial_tree); 131 132 void ClearDisplayList(Epoch aEpoch, wr::WrPipelineId aPipeline); 133 134 void GenerateFrame(const VsyncId& aVsyncId, bool aPresent, bool aTracked, 135 wr::RenderReasons aReasons); 136 137 void InvalidateRenderedFrame(wr::RenderReasons aReasons); 138 139 void SetDocumentView(const LayoutDeviceIntRect& aDocRect); 140 141 bool IsEmpty() const; 142 143 bool IsResourceUpdatesEmpty() const; 144 145 bool IsRenderedFrameInvalidated() const; 146 147 void AddImage(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, 148 wr::Vec<uint8_t>& aBytes); 149 150 void AddBlobImage(wr::BlobImageKey aKey, const ImageDescriptor& aDescriptor, 151 uint16_t aTileSize, wr::Vec<uint8_t>& aBytes, 152 const wr::DeviceIntRect& aVisibleRect); 153 154 void AddExternalImageBuffer(ImageKey key, const ImageDescriptor& aDescriptor, 155 ExternalImageId aHandle); 156 157 void AddExternalImage(ImageKey key, const ImageDescriptor& aDescriptor, 158 ExternalImageId aExtID, 159 wr::ExternalImageType aImageType, 160 uint8_t aChannelIndex = 0, bool aNormalizedUvs = false); 161 162 void UpdateImageBuffer(wr::ImageKey aKey, const ImageDescriptor& aDescriptor, 163 wr::Vec<uint8_t>& aBytes); 164 165 void UpdateBlobImage(wr::BlobImageKey aKey, 166 const ImageDescriptor& aDescriptor, 167 wr::Vec<uint8_t>& aBytes, 168 const wr::DeviceIntRect& aVisibleRect, 169 const wr::LayoutIntRect& aDirtyRect); 170 171 void UpdateExternalImage(ImageKey aKey, const ImageDescriptor& aDescriptor, 172 ExternalImageId aExtID, 173 wr::ExternalImageType aImageType, 174 uint8_t aChannelIndex = 0, 175 bool aNormalizedUvs = false); 176 177 void UpdateExternalImageWithDirtyRect( 178 ImageKey aKey, const ImageDescriptor& aDescriptor, ExternalImageId aExtID, 179 wr::ExternalImageType aImageType, const wr::DeviceIntRect& aDirtyRect, 180 uint8_t aChannelIndex = 0, bool aNormalizedUvs = false); 181 182 void SetBlobImageVisibleArea(BlobImageKey aKey, 183 const wr::DeviceIntRect& aArea); 184 185 void DeleteImage(wr::ImageKey aKey); 186 187 void DeleteBlobImage(wr::BlobImageKey aKey); 188 189 void AddSnapshotImage(wr::SnapshotImageKey aKey); 190 191 void DeleteSnapshotImage(wr::SnapshotImageKey aKey); 192 193 void AddRawFont(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, uint32_t aIndex); 194 195 void AddFontDescriptor(wr::FontKey aKey, wr::Vec<uint8_t>& aBytes, 196 uint32_t aIndex); 197 198 void DeleteFont(wr::FontKey aKey); 199 200 void AddFontInstance(wr::FontInstanceKey aKey, wr::FontKey aFontKey, 201 float aGlyphSize, 202 const wr::FontInstanceOptions* aOptions, 203 const wr::FontInstancePlatformOptions* aPlatformOptions, 204 wr::Vec<uint8_t>& aVariations); 205 206 void DeleteFontInstance(wr::FontInstanceKey aKey); 207 208 void UpdateQualitySettings(bool aForceSubpixelAAWherePossible); 209 210 void RenderOffscreen(wr::WrPipelineId aPipelineId); 211 212 void Notify(wr::Checkpoint aWhen, UniquePtr<NotificationHandler> aHandler); 213 214 void Clear(); 215 216 Transaction* Take(); 217 218 bool UseSceneBuilderThread() const { return mUseSceneBuilderThread; } 219 layers::WebRenderBackend GetBackendType() { return mApiBackend; } 220 Transaction* Raw() const { return mTxn; } 221 222 const RefPtr<layers::RemoteTextureTxnScheduler> mRemoteTextureTxnScheduler; 223 const layers::RemoteTextureTxnId mRemoteTextureTxnId; 224 225 protected: 226 Transaction* mTxn; 227 bool mUseSceneBuilderThread; 228 layers::WebRenderBackend mApiBackend; 229 bool mOwnsData; 230 }; 231 232 class TransactionWrapper final { 233 public: 234 explicit TransactionWrapper(Transaction* aTxn); 235 236 void AppendDynamicProperties( 237 const nsTArray<wr::WrOpacityProperty>& aOpacityArray, 238 const nsTArray<wr::WrTransformProperty>& aTransformArray, 239 const nsTArray<wr::WrColorProperty>& aColorArray); 240 void AppendTransformProperties( 241 const nsTArray<wr::WrTransformProperty>& aTransformArray); 242 void UpdateScrollPosition( 243 const wr::ExternalScrollId& aScrollId, 244 const nsTArray<wr::SampledScrollOffset>& aSampledOffsets); 245 void UpdateIsTransformAsyncZooming(uint64_t aAnimationId, bool aIsZooming); 246 void AddMinimapData(const wr::ExternalScrollId& aScrollId, 247 const MinimapData& aMinimapData); 248 249 private: 250 Transaction* mTxn; 251 }; 252 253 class WebRenderAPI final { 254 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebRenderAPI); 255 256 public: 257 /// This can be called on the compositor thread only. 258 static already_AddRefed<WebRenderAPI> Create( 259 layers::CompositorBridgeParent* aBridge, 260 RefPtr<widget::CompositorWidget>&& aWidget, 261 const wr::WrWindowId& aWindowId, LayoutDeviceIntSize aSize, 262 layers::WindowKind aWindowKind, nsACString& aError); 263 264 already_AddRefed<WebRenderAPI> Clone(); 265 266 void DestroyRenderer(); 267 268 wr::WindowId GetId() const { return mId; } 269 270 /// Do a non-blocking hit-testing query on a shared version of the hit 271 /// testing information. 272 std::vector<WrHitResult> HitTest(const wr::WorldPoint& aPoint); 273 274 void SendTransaction(TransactionBuilder& aTxn); 275 276 void SetFrameStartTime(const TimeStamp& aTime); 277 278 void RunOnRenderThread(UniquePtr<RendererEvent> aEvent); 279 280 void Readback(const TimeStamp& aStartTime, gfx::IntSize aSize, 281 const gfx::SurfaceFormat& aFormat, 282 const Range<uint8_t>& aBuffer, bool* aNeedsYFlip); 283 284 void ClearAllCaches(); 285 void EnableNativeCompositor(bool aEnable); 286 void SetBatchingLookback(uint32_t aCount); 287 void SetBool(wr::BoolParameter, bool value); 288 void SetInt(wr::IntParameter, int32_t value); 289 void SetFloat(wr::FloatParameter, float value); 290 291 void SetClearColor(const gfx::DeviceColor& aColor); 292 void SetProfilerUI(const nsACString& aUIString); 293 294 void Pause(); 295 bool Resume(); 296 297 void WakeSceneBuilder(); 298 void FlushSceneBuilder(); 299 300 void NotifyMemoryPressure(); 301 void AccumulateMemoryReport(wr::MemoryReport*); 302 303 wr::WrIdNamespace GetNamespace(); 304 layers::WebRenderBackend GetBackendType() { return mBackend; } 305 layers::WebRenderCompositor GetCompositorType() { return mCompositor; } 306 uint32_t GetMaxTextureSize() const { return mMaxTextureSize; } 307 bool GetUseANGLE() const { return mUseANGLE; } 308 bool GetUseDComp() const { return mUseDComp; } 309 bool GetUseLayerCompositor() const { return mUseLayerCompositor; } 310 bool GetUseTripleBuffering() const { return mUseTripleBuffering; } 311 bool SupportsExternalBufferTextures() const { 312 return mSupportsExternalBufferTextures; 313 } 314 layers::SyncHandle GetSyncHandle() const { return mSyncHandle; } 315 316 void Capture(); 317 318 void StartCaptureSequence(const nsACString& aPath, uint32_t aFlags); 319 void StopCaptureSequence(); 320 321 void BeginRecording(const TimeStamp& aRecordingStart, 322 wr::PipelineId aRootPipelineId); 323 324 typedef MozPromise<layers::FrameRecording, nsresult, true> 325 EndRecordingPromise; 326 327 RefPtr<EndRecordingPromise> EndRecording(); 328 329 layers::RemoteTextureInfoList* GetPendingRemoteTextureInfoList(); 330 layers::AsyncImagePipelineOps* GetPendingAsyncImagePipelineOps( 331 TransactionBuilder& aTxn); 332 333 void FlushPendingWrTransactionEventsWithoutWait(); 334 void FlushPendingWrTransactionEventsWithWait(); 335 336 wr::WebRenderAPI* GetRootAPI(); 337 338 protected: 339 WebRenderAPI(wr::DocumentHandle* aHandle, wr::WindowId aId, 340 layers::WebRenderBackend aBackend, 341 layers::WebRenderCompositor aCompositor, 342 uint32_t aMaxTextureSize, bool aUseANGLE, bool aUseDComp, 343 bool aUseLayerCompositor, bool aUseTripleBuffering, 344 bool aSupportsExternalBufferTextures, 345 layers::SyncHandle aSyncHandle, 346 wr::WebRenderAPI* aRootApi = nullptr, 347 wr::WebRenderAPI* aRootDocumentApi = nullptr); 348 349 ~WebRenderAPI(); 350 351 void WaitUntilPresentationFlushed(); 352 353 void UpdateDebugFlags(uint64_t aFlags); 354 bool CheckIsRemoteTextureReady(layers::RemoteTextureInfoList* aList, 355 const TimeStamp& aTimeStamp); 356 void WaitRemoteTextureReady(layers::RemoteTextureInfoList* aList); 357 358 enum class RemoteTextureWaitType : uint8_t { 359 AsyncWait = 0, 360 FlushWithWait = 1, 361 FlushWithoutWait = 2 362 }; 363 364 void HandleWrTransactionEvents(RemoteTextureWaitType aType); 365 366 class WrTransactionEvent { 367 public: 368 enum class Tag { 369 Transaction, 370 PendingRemoteTextures, 371 PendingAsyncImagePipelineOps, 372 }; 373 const Tag mTag; 374 const TimeStamp mTimeStamp; 375 376 private: 377 WrTransactionEvent(const Tag aTag, 378 UniquePtr<TransactionBuilder>&& aTransaction) 379 : mTag(aTag), 380 mTimeStamp(TimeStamp::Now()), 381 mTransaction(std::move(aTransaction)) { 382 MOZ_ASSERT(mTag == Tag::Transaction); 383 } 384 WrTransactionEvent( 385 const Tag aTag, 386 UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures) 387 : mTag(aTag), 388 mTimeStamp(TimeStamp::Now()), 389 mPendingRemoteTextures(std::move(aPendingRemoteTextures)) { 390 MOZ_ASSERT(mTag == Tag::PendingRemoteTextures); 391 } 392 WrTransactionEvent(const Tag aTag, 393 UniquePtr<layers::AsyncImagePipelineOps>&& 394 aPendingAsyncImagePipelineOps, 395 UniquePtr<TransactionBuilder>&& aTransaction) 396 : mTag(aTag), 397 mTimeStamp(TimeStamp::Now()), 398 mPendingAsyncImagePipelineOps( 399 std::move(aPendingAsyncImagePipelineOps)), 400 mTransaction(std::move(aTransaction)) { 401 MOZ_ASSERT(mTag == Tag::PendingAsyncImagePipelineOps); 402 } 403 404 UniquePtr<layers::RemoteTextureInfoList> mPendingRemoteTextures; 405 UniquePtr<layers::AsyncImagePipelineOps> mPendingAsyncImagePipelineOps; 406 UniquePtr<TransactionBuilder> mTransaction; 407 408 public: 409 static WrTransactionEvent Transaction(WebRenderAPI* aApi, 410 TransactionBuilder& aTxn) { 411 auto transaction = MakeUnique<TransactionBuilder>( 412 aApi, aTxn.Take(), aTxn.UseSceneBuilderThread(), /* aOwnsData */ true, 413 aTxn.mRemoteTextureTxnScheduler, aTxn.mRemoteTextureTxnId); 414 return WrTransactionEvent(Tag::Transaction, std::move(transaction)); 415 } 416 417 static WrTransactionEvent PendingRemoteTextures( 418 UniquePtr<layers::RemoteTextureInfoList>&& aPendingRemoteTextures) { 419 return WrTransactionEvent(Tag::PendingRemoteTextures, 420 std::move(aPendingRemoteTextures)); 421 } 422 423 static WrTransactionEvent PendingAsyncImagePipelineOps( 424 UniquePtr<layers::AsyncImagePipelineOps>&& 425 aPendingAsyncImagePipelineOps, 426 WebRenderAPI* aApi, const TransactionBuilder& aTxn) { 427 auto transaction = MakeUnique<TransactionBuilder>( 428 aApi, aTxn.Raw(), aTxn.UseSceneBuilderThread(), /* aOwnsData */ false, 429 aTxn.mRemoteTextureTxnScheduler, aTxn.mRemoteTextureTxnId); 430 return WrTransactionEvent(Tag::PendingAsyncImagePipelineOps, 431 std::move(aPendingAsyncImagePipelineOps), 432 std::move(transaction)); 433 } 434 435 wr::Transaction* RawTransaction() { 436 if (mTag == Tag::Transaction) { 437 return mTransaction->Raw(); 438 } 439 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 440 return nullptr; 441 } 442 443 TransactionBuilder* GetTransactionBuilder() { 444 if (mTag == Tag::Transaction || 445 mTag == Tag::PendingAsyncImagePipelineOps) { 446 return mTransaction.get(); 447 } 448 MOZ_CRASH("Should not be called"); 449 return nullptr; 450 } 451 452 bool UseSceneBuilderThread() { 453 if (mTag == Tag::Transaction) { 454 return mTransaction->UseSceneBuilderThread(); 455 } 456 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 457 return true; 458 } 459 460 layers::RemoteTextureInfoList* RemoteTextureInfoList() { 461 if (mTag == Tag::PendingRemoteTextures) { 462 MOZ_ASSERT(mPendingRemoteTextures); 463 return mPendingRemoteTextures.get(); 464 } 465 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 466 return nullptr; 467 } 468 469 layers::AsyncImagePipelineOps* AsyncImagePipelineOps() { 470 if (mTag == Tag::PendingAsyncImagePipelineOps) { 471 MOZ_ASSERT(mPendingAsyncImagePipelineOps); 472 return mPendingAsyncImagePipelineOps.get(); 473 } 474 MOZ_ASSERT_UNREACHABLE("unexpected to be called"); 475 return nullptr; 476 } 477 }; 478 479 wr::DocumentHandle* mDocHandle; 480 wr::WindowId mId; 481 layers::WebRenderBackend mBackend; 482 layers::WebRenderCompositor mCompositor; 483 int32_t mMaxTextureSize; 484 bool mUseANGLE; 485 bool mUseDComp; 486 bool mUseLayerCompositor; 487 bool mUseTripleBuffering; 488 bool mSupportsExternalBufferTextures; 489 bool mCaptureSequence; 490 layers::SyncHandle mSyncHandle; 491 bool mRendererDestroyed; 492 493 UniquePtr<layers::RemoteTextureInfoList> mPendingRemoteTextureInfoList; 494 UniquePtr<layers::AsyncImagePipelineOps> mPendingAsyncImagePipelineOps; 495 std::queue<WrTransactionEvent> mPendingWrTransactionEvents; 496 497 // We maintain alive the root api to know when to shut the render backend 498 // down, and the root api for the document to know when to delete the 499 // document. mRootApi is null for the api object that owns the channel (and is 500 // responsible for shutting it down), and mRootDocumentApi is null for the api 501 // object owning (and responsible for destroying) a given document. All api 502 // objects in the same window use the same channel, and some api objects write 503 // to the same document (but there is only one owner for each channel and for 504 // each document). 505 const RefPtr<wr::WebRenderAPI> mRootApi; 506 const RefPtr<wr::WebRenderAPI> mRootDocumentApi; 507 508 friend class DisplayListBuilder; 509 friend class layers::WebRenderBridgeParent; 510 }; 511 512 // This is a RAII class that automatically sends the transaction on 513 // destruction. This is useful for code that has multiple exit points and we 514 // want to ensure that the stuff accumulated in the transaction gets sent 515 // regardless of which exit we take. Note that if the caller explicitly calls 516 // mApi->SendTransaction() that's fine too because that empties out the 517 // TransactionBuilder and leaves it as a valid empty transaction, so calling 518 // SendTransaction on it again ends up being a no-op. 519 class MOZ_RAII AutoTransactionSender { 520 public: 521 AutoTransactionSender(WebRenderAPI* aApi, TransactionBuilder* aTxn) 522 : mApi(aApi), mTxn(aTxn) { 523 MOZ_RELEASE_ASSERT(mApi); 524 MOZ_RELEASE_ASSERT(aTxn); 525 } 526 527 ~AutoTransactionSender() { mApi->SendTransaction(*mTxn); } 528 529 private: 530 WebRenderAPI* mApi; 531 TransactionBuilder* mTxn; 532 }; 533 534 /** 535 * A set of optional parameters for stacking context creation. 536 */ 537 struct MOZ_STACK_CLASS StackingContextParams : public WrStackingContextParams { 538 StackingContextParams() 539 : WrStackingContextParams{ 540 WrStackingContextClip::None(), 541 nullptr, 542 nullptr, 543 nullptr, 544 nullptr, 545 wr::TransformStyle::Flat, 546 wr::WrReferenceFrameKind::Transform, 547 false, 548 false, 549 false, 550 nullptr, 551 /* prim_flags = */ wr::PrimitiveFlags::IS_BACKFACE_VISIBLE, 552 wr::MixBlendMode::Normal, 553 wr::StackingContextFlags{0}} {} 554 555 void SetPreserve3D(bool aPreserve) { 556 transform_style = 557 aPreserve ? wr::TransformStyle::Preserve3D : wr::TransformStyle::Flat; 558 } 559 560 // Fill this in only if this is for the root StackingContextHelper. 561 nsIFrame* mRootReferenceFrame = nullptr; 562 nsTArray<wr::FilterOp> mFilters; 563 nsTArray<wr::WrFilterData> mFilterDatas; 564 wr::LayoutRect mBounds = wr::ToLayoutRect(LayoutDeviceRect()); 565 const gfx::Matrix4x4* mBoundTransform = nullptr; 566 const wr::WrTransformInfo* mTransformPtr = nullptr; 567 nsDisplayTransform* mDeferredTransformItem = nullptr; 568 // Whether the stacking context is possibly animated. This alters how 569 // coordinates are transformed/snapped to invalidate less when transforms 570 // change frequently. 571 bool mAnimated = false; 572 // Whether items should be rasterized in a local space that is (mostly) 573 // invariant to transforms, i.e. disabling subpixel AA and screen space pixel 574 // snapping on text runs that would only make sense in screen space. 575 bool mRasterizeLocally = false; 576 }; 577 578 /// This is a simple C++ wrapper around WrState defined in the rust bindings. 579 /// We may want to turn this into a direct wrapper on top of 580 /// WebRenderFrameBuilder instead, so the interface may change a bit. 581 class DisplayListBuilder final { 582 public: 583 explicit DisplayListBuilder(wr::PipelineId aId, 584 layers::WebRenderBackend aBackend); 585 DisplayListBuilder(DisplayListBuilder&&) = default; 586 587 ~DisplayListBuilder(); 588 589 void Save(); 590 void Restore(); 591 void ClearSave(); 592 593 usize Dump(usize aIndent, const Maybe<usize>& aStart, 594 const Maybe<usize>& aEnd); 595 void DumpSerializedDisplayList(); 596 597 void Begin(layers::DisplayItemCache* aCache = nullptr); 598 void End(wr::BuiltDisplayList& aOutDisplayList); 599 void End(layers::DisplayListData& aOutTransaction); 600 601 Maybe<wr::WrSpatialId> PushStackingContext( 602 const StackingContextParams& aParams, const wr::LayoutRect& aBounds, 603 const wr::RasterSpace& aRasterSpace); 604 void PopStackingContext(bool aIsReferenceFrame); 605 606 wr::WrClipChainId DefineClipChain(Span<const wr::WrClipId> aClips, 607 const Maybe<wr::WrClipChainId>& aParent); 608 609 wr::WrClipId DefineImageMaskClip(const wr::ImageMask& aMask, 610 const nsTArray<wr::LayoutPoint>&, 611 wr::FillRule); 612 wr::WrClipId DefineRoundedRectClip(Maybe<wr::WrSpatialId> aSpace, 613 const wr::ComplexClipRegion& aComplex); 614 wr::WrClipId DefineRectClip(Maybe<wr::WrSpatialId> aSpace, 615 wr::LayoutRect aClipRect); 616 617 wr::WrSpatialId DefineStickyFrame( 618 const ActiveScrolledRoot* aStickyAsr, 619 Maybe<wr::WrSpatialId> aParentSpatialId, 620 const wr::LayoutRect& aContentRect, const float* aTopMargin, 621 const float* aRightMargin, const float* aBottomMargin, 622 const float* aLeftMargin, const StickyOffsetBounds& aVerticalBounds, 623 const StickyOffsetBounds& aHorizontalBounds, 624 const wr::LayoutVector2D& aAppliedOffset, wr::SpatialTreeItemKey aKey, 625 const WrAnimationProperty* aAnimation); 626 627 Maybe<wr::WrSpatialId> GetScrollIdForDefinedScrollLayer( 628 layers::ScrollableLayerGuid::ViewID aViewId) const; 629 Maybe<wr::WrSpatialId> GetSpatialIdForDefinedStickyLayer( 630 const ActiveScrolledRoot* aASR) const; 631 wr::WrSpatialId DefineScrollLayer( 632 const layers::ScrollableLayerGuid::ViewID& aViewId, 633 const Maybe<wr::WrSpatialId>& aParent, const wr::LayoutRect& aContentRect, 634 const wr::LayoutRect& aClipRect, const wr::LayoutVector2D& aScrollOffset, 635 wr::APZScrollGeneration aScrollOffsetGeneration, 636 wr::HasScrollLinkedEffect aHasScrollLinkedEffect, 637 wr::SpatialTreeItemKey aKey); 638 639 void PushRect(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 640 bool aIsBackfaceVisible, bool aForceAntiAliasing, 641 bool aIsCheckerboard, const wr::ColorF& aColor); 642 void PushRectWithAnimation(const wr::LayoutRect& aBounds, 643 const wr::LayoutRect& aClip, 644 bool aIsBackfaceVisible, const wr::ColorF& aColor, 645 const WrAnimationProperty* aAnimation); 646 void PushRoundedRect(const wr::LayoutRect& aBounds, 647 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 648 const wr::ColorF& aColor); 649 void PushHitTest(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 650 bool aIsBackfaceVisible, 651 const layers::ScrollableLayerGuid::ViewID& aScrollId, 652 const gfx::CompositorHitTestInfo& aHitInfo, 653 SideBits aSideBits); 654 655 void PushBackdropFilter(const wr::LayoutRect& aBounds, 656 const wr::ComplexClipRegion& aRegion, 657 const nsTArray<wr::FilterOp>& aFilters, 658 const nsTArray<wr::WrFilterData>& aFilterDatas, 659 bool aIsBackfaceVisible); 660 661 void PushLinearGradient(const wr::LayoutRect& aBounds, 662 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 663 const wr::LayoutPoint& aStartPoint, 664 const wr::LayoutPoint& aEndPoint, 665 const nsTArray<wr::GradientStop>& aStops, 666 wr::ExtendMode aExtendMode, 667 const wr::LayoutSize aTileSize, 668 const wr::LayoutSize aTileSpacing); 669 670 void PushRadialGradient(const wr::LayoutRect& aBounds, 671 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 672 const wr::LayoutPoint& aCenter, 673 const wr::LayoutSize& aRadius, 674 const nsTArray<wr::GradientStop>& aStops, 675 wr::ExtendMode aExtendMode, 676 const wr::LayoutSize aTileSize, 677 const wr::LayoutSize aTileSpacing); 678 679 void PushConicGradient(const wr::LayoutRect& aBounds, 680 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 681 const wr::LayoutPoint& aCenter, const float aAngle, 682 const nsTArray<wr::GradientStop>& aStops, 683 wr::ExtendMode aExtendMode, 684 const wr::LayoutSize aTileSize, 685 const wr::LayoutSize aTileSpacing); 686 687 void PushImage(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 688 bool aIsBackfaceVisible, bool aForceAntiAliasing, 689 wr::ImageRendering aFilter, wr::ImageKey aImage, 690 bool aPremultipliedAlpha = true, 691 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}, 692 bool aPreferCompositorSurface = false, 693 bool aSupportsExternalCompositing = false); 694 695 void PushRepeatingImage( 696 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 697 bool aIsBackfaceVisible, const wr::LayoutSize& aStretchSize, 698 const wr::LayoutSize& aTileSpacing, wr::ImageRendering aFilter, 699 wr::ImageKey aImage, bool aPremultipliedAlpha = true, 700 const wr::ColorF& aColor = wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f}); 701 702 void PushYCbCrPlanarImage( 703 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 704 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 705 wr::ImageKey aImageChannel1, wr::ImageKey aImageChannel2, 706 wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace, 707 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 708 bool aPreferCompositorSurface = false, 709 bool aSupportsExternalCompositing = false); 710 711 void PushNV12Image(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 712 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 713 wr::ImageKey aImageChannel1, wr::WrColorDepth aColorDepth, 714 wr::WrYuvColorSpace aColorSpace, 715 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 716 bool aPreferCompositorSurface = false, 717 bool aSupportsExternalCompositing = false); 718 719 void PushP010Image(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 720 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 721 wr::ImageKey aImageChannel1, wr::WrColorDepth aColorDepth, 722 wr::WrYuvColorSpace aColorSpace, 723 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 724 bool aPreferCompositorSurface = false, 725 bool aSupportsExternalCompositing = false); 726 727 void PushNV16Image(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 728 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 729 wr::ImageKey aImageChannel1, wr::WrColorDepth aColorDepth, 730 wr::WrYuvColorSpace aColorSpace, 731 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 732 bool aPreferCompositorSurface = false, 733 bool aSupportsExternalCompositing = false); 734 735 void PushYCbCrInterleavedImage( 736 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 737 bool aIsBackfaceVisible, wr::ImageKey aImageChannel0, 738 wr::WrColorDepth aColorDepth, wr::WrYuvColorSpace aColorSpace, 739 wr::WrColorRange aColorRange, wr::ImageRendering aFilter, 740 bool aPreferCompositorSurface = false, 741 bool aSupportsExternalCompositing = false); 742 743 void PushIFrame(const LayoutDeviceRect& aDevPxBounds, bool aIsBackfaceVisible, 744 wr::PipelineId aPipeline, bool aIgnoreMissingPipeline); 745 746 // XXX WrBorderSides are passed with Range. 747 // It is just to bypass compiler bug. See Bug 1357734. 748 void PushBorder(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 749 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, 750 const Range<const wr::BorderSide>& aSides, 751 const wr::BorderRadius& aRadius, 752 wr::AntialiasBorder = wr::AntialiasBorder::Yes); 753 754 void PushBorderImage(const wr::LayoutRect& aBounds, 755 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 756 const wr::WrBorderImage& aParams); 757 758 void PushBorderGradient(const wr::LayoutRect& aBounds, 759 const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 760 const wr::LayoutSideOffsets& aWidths, 761 const int32_t aWidth, const int32_t aHeight, 762 bool aFill, const wr::DeviceIntSideOffsets& aSlice, 763 const wr::LayoutPoint& aStartPoint, 764 const wr::LayoutPoint& aEndPoint, 765 const nsTArray<wr::GradientStop>& aStops, 766 wr::ExtendMode aExtendMode); 767 768 void PushBorderRadialGradient( 769 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 770 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill, 771 const wr::LayoutPoint& aCenter, const wr::LayoutSize& aRadius, 772 const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode); 773 774 void PushBorderConicGradient( 775 const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 776 bool aIsBackfaceVisible, const wr::LayoutSideOffsets& aWidths, bool aFill, 777 const wr::LayoutPoint& aCenter, const float aAngle, 778 const nsTArray<wr::GradientStop>& aStops, wr::ExtendMode aExtendMode); 779 780 void PushText(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 781 bool aIsBackfaceVisible, const wr::ColorF& aColor, 782 wr::FontInstanceKey aFontKey, 783 Range<const wr::GlyphInstance> aGlyphBuffer, 784 const wr::GlyphOptions* aGlyphOptions = nullptr); 785 786 void PushLine(const wr::LayoutRect& aClip, bool aIsBackfaceVisible, 787 const wr::Line& aLine); 788 789 void PushShadow(const wr::LayoutRect& aBounds, const wr::LayoutRect& aClip, 790 bool aIsBackfaceVisible, const wr::Shadow& aShadow, 791 bool aShouldInflate); 792 793 void PopAllShadows(); 794 795 void PushBoxShadow(const wr::LayoutRect& aRect, const wr::LayoutRect& aClip, 796 bool aIsBackfaceVisible, const wr::LayoutRect& aBoxBounds, 797 const wr::LayoutVector2D& aOffset, 798 const wr::ColorF& aColor, const float& aBlurRadius, 799 const float& aSpreadRadius, 800 const wr::BorderRadius& aBorderRadius, 801 const wr::BoxShadowClipMode& aClipMode); 802 803 void PushDebug(uint32_t aVal); 804 805 /** 806 * Notifies the DisplayListBuilder that it can group together WR display items 807 * that are pushed until |CancelGroup()| or |FinishGroup()| call. 808 */ 809 void StartGroup(nsPaintedDisplayItem* aItem); 810 811 /** 812 * Cancels grouping of the display items and discards all the display items 813 * pushed between the |StartGroup()| and |CancelGroup()| calls. 814 */ 815 void CancelGroup(const bool aDiscard = false); 816 817 /** 818 * Finishes the display item group. The group is stored in WebRender backend, 819 * and can be reused with |ReuseItem()|, if the Gecko display item is reused. 820 */ 821 void FinishGroup(); 822 823 /** 824 * Try to reuse the previously created WebRender display items for the given 825 * Gecko display item |aItem|. 826 * Returns true if the items were reused, otherwise returns false. 827 */ 828 bool ReuseItem(nsPaintedDisplayItem* aItem); 829 830 uint64_t CurrentClipChainId() const { 831 return mCurrentSpaceAndClipChain.clip_chain; 832 } 833 834 Maybe<wr::WrClipChainId> CurrentClipChainIdIfNotRoot() const { 835 return mCurrentSpaceAndClipChain.clip_chain != wr::ROOT_CLIP_CHAIN 836 ? Some(mCurrentSpaceAndClipChain.clip_chain) 837 : Nothing(); 838 } 839 840 const wr::WrSpaceAndClipChain& CurrentSpaceAndClipChain() const { 841 return mCurrentSpaceAndClipChain; 842 } 843 844 const wr::PipelineId& CurrentPipelineId() const { return mPipelineId; } 845 layers::WebRenderBackend GetBackendType() const { return mBackend; } 846 847 // Checks to see if the innermost enclosing fixed pos item has the same 848 // ASR. If so, it returns the scroll target for that fixed-pos item. 849 // Otherwise, it returns Nothing(). 850 Maybe<layers::ScrollableLayerGuid::ViewID> GetContainingFixedPosScrollTarget( 851 const ActiveScrolledRoot* aAsr); 852 853 Maybe<SideBits> GetContainingFixedPosSideBits(const ActiveScrolledRoot* aAsr); 854 855 gfxContext* GetTextContext(wr::IpcResourceUpdateQueue& aResources, 856 const layers::StackingContextHelper& aSc, 857 layers::RenderRootStateManager* aManager, 858 nsDisplayItem* aItem, nsRect& aBounds, 859 const gfx::Point& aDeviceOffset); 860 861 // Try to avoid using this when possible. 862 wr::WrState* Raw() { return mWrState; } 863 864 void SetClipChainLeaf(const Maybe<wr::LayoutRect>& aClipRect) { 865 mClipChainLeaf = aClipRect; 866 } 867 868 // Used for opacity flattening. When we flatten away an opacity item, 869 // we push the opacity value onto the builder. 870 // Descendant items should pull the inherited opacity during 871 // their CreateWebRenderCommands implementation. This can only happen if all 872 // descendant items reported supporting this functionality, via 873 // nsDisplayItem::CanApplyOpacity. 874 float GetInheritedOpacity() { return mInheritedOpacity; } 875 void SetInheritedOpacity(float aOpacity) { mInheritedOpacity = aOpacity; } 876 const DisplayItemClipChain* GetInheritedClipChain() { 877 return mInheritedClipChain; 878 } 879 void PushInheritedClipChain(nsDisplayListBuilder* aBuilder, 880 const DisplayItemClipChain* aClipChain); 881 void SetInheritedClipChain(const DisplayItemClipChain* aClipChain) { 882 mInheritedClipChain = aClipChain; 883 } 884 885 layers::DisplayItemCache* GetDisplayItemCache() { return mDisplayItemCache; } 886 887 // A chain of RAII objects, each holding a (ASR, ViewID, SideBits) tuple of 888 // data. The topmost object is pointed to by the mActiveFixedPosTracker 889 // pointer in the wr::DisplayListBuilder. 890 class MOZ_RAII FixedPosScrollTargetTracker final { 891 public: 892 FixedPosScrollTargetTracker(DisplayListBuilder& aBuilder, 893 const ActiveScrolledRoot* aAsr, 894 layers::ScrollableLayerGuid::ViewID aScrollId, 895 SideBits aSideBits); 896 ~FixedPosScrollTargetTracker(); 897 Maybe<layers::ScrollableLayerGuid::ViewID> GetScrollTargetForASR( 898 const ActiveScrolledRoot* aAsr); 899 Maybe<SideBits> GetSideBitsForASR(const ActiveScrolledRoot* aAsr); 900 901 private: 902 FixedPosScrollTargetTracker* mParentTracker; 903 DisplayListBuilder& mBuilder; 904 const ActiveScrolledRoot* mAsr; 905 layers::ScrollableLayerGuid::ViewID mScrollId; 906 SideBits mSideBits; 907 }; 908 909 protected: 910 wr::LayoutRect MergeClipLeaf(const wr::LayoutRect& aClip) { 911 if (mClipChainLeaf) { 912 return wr::IntersectLayoutRect(*mClipChainLeaf, aClip); 913 } 914 return aClip; 915 } 916 917 // See the implementation of PushShadow for details on these methods. 918 void SuspendClipLeafMerging(); 919 void ResumeClipLeafMerging(); 920 921 wr::WrState* mWrState; 922 923 // Track each scroll id that we encountered. We use this structure to 924 // ensure that we don't define a particular scroll layer multiple times, 925 // as that results in undefined behaviour in WR. 926 std::unordered_map<layers::ScrollableLayerGuid::ViewID, wr::WrSpatialId> 927 mScrollIds; 928 929 // Track spatial ids that we've created corresponding to ActiveScrolledRoot 930 // objects. Currently only used for sticky ASRs. 931 // FIXME(follow-up to bug 1730749): Use this for scroll ASRs as well, 932 // replacing mScrollIds. 933 std::unordered_map<const ActiveScrolledRoot*, wr::WrSpatialId> 934 mASRToSpatialIdMap; 935 936 wr::WrSpaceAndClipChain mCurrentSpaceAndClipChain; 937 938 // Contains the current leaf of the clip chain to be merged with the 939 // display item's clip rect when pushing an item. May be set to Nothing() if 940 // there is no clip rect to merge with. 941 Maybe<wr::LayoutRect> mClipChainLeaf; 942 943 // Versions of the above that are on hold while SuspendClipLeafMerging is on 944 // (see the implementation of PushShadow for details). 945 Maybe<wr::WrSpaceAndClipChain> mSuspendedSpaceAndClipChain; 946 Maybe<wr::LayoutRect> mSuspendedClipChainLeaf; 947 948 RefPtr<layout::TextDrawTarget> mCachedTextDT; 949 mozilla::UniquePtr<gfxContext> mCachedContext; 950 951 FixedPosScrollTargetTracker* mActiveFixedPosTracker; 952 953 wr::PipelineId mPipelineId; 954 layers::WebRenderBackend mBackend; 955 956 layers::DisplayItemCache* mDisplayItemCache; 957 Maybe<uint16_t> mCurrentCacheSlot; 958 float mInheritedOpacity = 1.0f; 959 const DisplayItemClipChain* mInheritedClipChain = nullptr; 960 961 friend class WebRenderAPI; 962 friend class SpaceAndClipChainHelper; 963 }; 964 965 // This is a RAII class that overrides the current Wr's SpatialId and 966 // ClipChainId. 967 class MOZ_RAII SpaceAndClipChainHelper final { 968 public: 969 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 970 wr::WrSpaceAndClipChain aSpaceAndClipChain) 971 : mBuilder(aBuilder), 972 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 973 aBuilder.mCurrentSpaceAndClipChain = aSpaceAndClipChain; 974 } 975 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 976 wr::WrSpatialId aSpatialId) 977 : mBuilder(aBuilder), 978 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 979 aBuilder.mCurrentSpaceAndClipChain.space = aSpatialId; 980 } 981 SpaceAndClipChainHelper(DisplayListBuilder& aBuilder, 982 wr::WrClipChainId aClipChainId) 983 : mBuilder(aBuilder), 984 mOldSpaceAndClipChain(aBuilder.mCurrentSpaceAndClipChain) { 985 aBuilder.mCurrentSpaceAndClipChain.clip_chain = aClipChainId.id; 986 } 987 988 ~SpaceAndClipChainHelper() { 989 mBuilder.mCurrentSpaceAndClipChain = mOldSpaceAndClipChain; 990 } 991 992 private: 993 SpaceAndClipChainHelper(const SpaceAndClipChainHelper&) = delete; 994 995 DisplayListBuilder& mBuilder; 996 wr::WrSpaceAndClipChain mOldSpaceAndClipChain; 997 }; 998 999 Maybe<wr::ImageFormat> SurfaceFormatToImageFormat(gfx::SurfaceFormat aFormat); 1000 1001 } // namespace wr 1002 } // namespace mozilla 1003 1004 #endif