DCLayerTree.h (23677B)
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_GFX_DCLAYER_TREE_H 8 #define MOZILLA_GFX_DCLAYER_TREE_H 9 10 #include <deque> 11 #include <dxgiformat.h> 12 #include <unordered_map> 13 #include <vector> 14 #include <windows.h> 15 16 #include "Colorspaces.h" 17 #include "GLTypes.h" 18 #include "mozilla/HashFunctions.h" 19 #include "mozilla/layers/OverlayInfo.h" 20 #include "mozilla/Maybe.h" 21 #include "mozilla/RefPtr.h" 22 #include "mozilla/StaticPtr.h" 23 #include "mozilla/UniquePtr.h" 24 #include "mozilla/webrender/WebRenderTypes.h" 25 26 struct ID3D11Device; 27 struct ID3D11DeviceContext; 28 struct ID3D11Texture2D; 29 struct ID3D11VideoDevice; 30 struct ID3D11VideoContext; 31 struct ID3D11VideoProcessor; 32 struct ID3D11VideoProcessorEnumerator; 33 struct ID3D11VideoProcessorOutputView; 34 struct IDCompositionColorMatrixEffect; 35 struct IDCompositionFilterEffect; 36 struct IDCompositionTableTransferEffect; 37 struct IDCompositionTexture; 38 struct IDCompositionDevice2; 39 struct IDCompositionDevice3; 40 struct IDCompositionSurface; 41 struct IDCompositionTarget; 42 struct IDCompositionVisual2; 43 struct IDXGIDecodeSwapChain; 44 struct IDXGIResource; 45 struct IDXGISwapChain1; 46 struct IDCompositionVirtualSurface; 47 struct IDCompositionRectangleClip; 48 49 namespace mozilla { 50 51 namespace gfx { 52 color::ColorProfileDesc QueryOutputColorProfile(); 53 } 54 55 namespace gl { 56 class GLContext; 57 } 58 59 namespace wr { 60 61 // The size of the virtual surface. This is large enough such that we 62 // will never render a surface larger than this. 63 #define VIRTUAL_SURFACE_SIZE (1024 * 1024) 64 65 class DCLayerSurface; 66 class DCTile; 67 class DCLayerDCompositionTexture; 68 class DCSurface; 69 class DCSwapChain; 70 class DCSurfaceDCompositionTextureOverlay; 71 class DCSurfaceVideo; 72 class DCSurfaceHandle; 73 class RenderTextureHost; 74 class RenderTextureHostUsageInfo; 75 class RenderDcompSurfaceTextureHost; 76 77 struct GpuOverlayInfo { 78 bool mSupportsOverlays = false; 79 bool mSupportsHardwareOverlays = false; 80 DXGI_FORMAT mOverlayFormatUsed = DXGI_FORMAT_B8G8R8A8_UNORM; 81 DXGI_FORMAT mOverlayFormatUsedHdr = DXGI_FORMAT_R16G16B16A16_FLOAT; 82 UINT mNv12OverlaySupportFlags = 0; 83 UINT mYuy2OverlaySupportFlags = 0; 84 UINT mBgra8OverlaySupportFlags = 0; 85 UINT mRgb10a2OverlaySupportFlags = 0; 86 UINT mRgba16fOverlaySupportFlags = 0; 87 88 bool mSupportsVpSuperResolution = false; 89 bool mSupportsVpAutoHDR = false; 90 bool mSupportsHDR = false; 91 }; 92 93 // - 94 95 struct ColorManagementChain { 96 RefPtr<IDCompositionColorMatrixEffect> srcRgbFromSrcYuv; 97 RefPtr<IDCompositionTableTransferEffect> srcLinearFromSrcTf; 98 RefPtr<IDCompositionColorMatrixEffect> dstLinearFromSrcLinear; 99 RefPtr<IDCompositionTableTransferEffect> dstTfFromDstLinear; 100 RefPtr<IDCompositionFilterEffect> last; 101 102 static ColorManagementChain From(IDCompositionDevice3& dcomp, 103 const color::ColorProfileConversionDesc&); 104 105 ~ColorManagementChain(); 106 }; 107 108 // - 109 110 enum class DCompOverlayTypes : uint8_t { 111 NO_OVERLAY = 0, 112 HARDWARE_DECODED_VIDEO = 1 << 0, 113 SOFTWARE_DECODED_VIDEO = 1 << 1, 114 }; 115 MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(DCompOverlayTypes) 116 117 // - 118 119 /** 120 * DCLayerTree manages direct composition layers. 121 * It does not manage gecko's layers::Layer. 122 */ 123 class DCLayerTree { 124 public: 125 static UniquePtr<DCLayerTree> Create(gl::GLContext* aGL, EGLConfig aEGLConfig, 126 ID3D11Device* aDevice, 127 ID3D11DeviceContext* aCtx, HWND aHwnd, 128 nsACString& aError); 129 130 static void Shutdown(); 131 132 explicit DCLayerTree(gl::GLContext* aGL, EGLConfig aEGLConfig, 133 ID3D11Device* aDevice, ID3D11DeviceContext* aCtx, 134 HWND aHwnd, IDCompositionDevice2* aCompositionDevice); 135 ~DCLayerTree(); 136 137 void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain); 138 void MaybeUpdateDebug(); 139 void MaybeCommit(); 140 void WaitForCommitCompletion(); 141 142 bool UseNativeCompositor() const; 143 bool UseLayerCompositor() const; 144 void DisableNativeCompositor(); 145 bool EnableAsyncScreenshot(); 146 bool GetAsyncScreenshotEnabled() const { return mEnableAsyncScreenshot; } 147 148 // Interface for wr::Compositor 149 void CompositorBeginFrame(); 150 void CompositorEndFrame(); 151 void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId, 152 wr::DeviceIntRect aDirtyRect, wr::DeviceIntRect aValidRect); 153 void Unbind(); 154 void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset, 155 wr::DeviceIntSize aTileSize, bool aIsOpaque); 156 void CreateSwapChainSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aSize, 157 bool aIsOpaque, bool aNeedsSyncDcompCommit); 158 void ResizeSwapChainSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aSize); 159 void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque); 160 void DestroySurface(NativeSurfaceId aId); 161 void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY); 162 void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY); 163 void AttachExternalImage(wr::NativeSurfaceId aId, 164 wr::ExternalImageId aExternalImage); 165 void AddSurface(wr::NativeSurfaceId aId, 166 const wr::CompositorSurfaceTransform& aTransform, 167 wr::DeviceIntRect aClipRect, 168 wr::ImageRendering aImageRendering, 169 wr::DeviceIntRect aRoundedClipRect, 170 wr::ClipRadius aClipRadius); 171 void BindSwapChain(wr::NativeSurfaceId aId, 172 const wr::DeviceIntRect* aDirtyRects, 173 size_t aNumDirtyRects); 174 void PresentSwapChain(wr::NativeSurfaceId aId, 175 const wr::DeviceIntRect* aDirtyRects, 176 size_t aNumDirtyRects); 177 178 gl::GLContext* GetGLContext() const { return mGL; } 179 EGLConfig GetEGLConfig() const { return mEGLConfig; } 180 ID3D11Device* GetDevice() const { return mDevice; } 181 ID3D11DeviceContext* GetDeviceContext() const { return mCtx; } 182 IDCompositionDevice2* GetCompositionDevice() const { 183 return mCompositionDevice; 184 } 185 ID3D11VideoDevice* GetVideoDevice() const { return mVideoDevice; } 186 ID3D11VideoContext* GetVideoContext() const { return mVideoContext; } 187 ID3D11VideoProcessor* GetVideoProcessor() const { return mVideoProcessor; } 188 ID3D11VideoProcessorEnumerator* GetVideoProcessorEnumerator() const { 189 return mVideoProcessorEnumerator; 190 } 191 bool EnsureVideoProcessor(const gfx::IntSize& aInputSize, 192 const gfx::IntSize& aOutputSize); 193 194 DCSurface* GetSurface(wr::NativeSurfaceId aId) const; 195 196 HWND GetHwnd() const { return mHwnd; } 197 198 // Get or create an FBO with depth buffer suitable for specified dimensions 199 GLuint GetOrCreateFbo(int aWidth, int aHeight); 200 201 bool SupportsHardwareOverlays(); 202 DXGI_FORMAT GetOverlayFormatForSDR(); 203 204 bool SupportsSwapChainTearing(); 205 bool UseDCLayerDCompositionTexture(); 206 207 void SetUsedOverlayTypeInFrame(DCompOverlayTypes aTypes); 208 209 int GetFrameId() { return mCurrentFrame; } 210 211 void SetPendingCommet() { mPendingCommit = true; } 212 213 protected: 214 bool Initialize(HWND aHwnd, nsACString& aError); 215 bool InitializeVideoOverlaySupport(); 216 bool MaybeUpdateDebugCounter(); 217 bool MaybeUpdateDebugVisualRedrawRegions(); 218 void DestroyEGLSurface(); 219 GLuint CreateEGLSurfaceForCompositionSurface( 220 wr::DeviceIntRect aDirtyRect, wr::DeviceIntPoint* aOffset, 221 RefPtr<IDCompositionSurface> aCompositionSurface, 222 wr::DeviceIntPoint aSurfaceOffset); 223 void ReleaseNativeCompositorResources(); 224 layers::OverlayInfo GetOverlayInfo(); 225 226 bool mUseNativeCompositor = true; 227 bool mEnableAsyncScreenshot = false; 228 bool mEnableAsyncScreenshotInNextFrame = false; 229 int mAsyncScreenshotLastFrameUsed = 0; 230 231 RefPtr<gl::GLContext> mGL; 232 EGLConfig mEGLConfig; 233 234 RefPtr<ID3D11Device> mDevice; 235 RefPtr<ID3D11DeviceContext> mCtx; 236 HWND mHwnd; 237 238 RefPtr<IDCompositionDevice2> mCompositionDevice; 239 RefPtr<IDCompositionTarget> mCompositionTarget; 240 RefPtr<IDCompositionVisual2> mRootVisual; 241 RefPtr<IDCompositionVisual2> mDefaultSwapChainVisual; 242 243 RefPtr<ID3D11VideoDevice> mVideoDevice; 244 RefPtr<ID3D11VideoContext> mVideoContext; 245 RefPtr<ID3D11VideoProcessor> mVideoProcessor; 246 RefPtr<ID3D11VideoProcessorEnumerator> mVideoProcessorEnumerator; 247 gfx::IntSize mVideoInputSize; 248 gfx::IntSize mVideoOutputSize; 249 250 bool mDebugCounter; 251 bool mDebugVisualRedrawRegions; 252 253 Maybe<RefPtr<IDCompositionSurface>> mCurrentSurface; 254 255 // The EGL image that is bound to the D3D texture provided by 256 // DirectComposition. 257 EGLImage mEGLImage; 258 259 // The GL render buffer ID that maps the EGLImage to an RBO for attaching to 260 // an FBO. 261 GLuint mColorRBO; 262 263 struct SurfaceIdHashFn { 264 std::size_t operator()(const wr::NativeSurfaceId& aId) const { 265 return HashGeneric(wr::AsUint64(aId)); 266 } 267 }; 268 269 std::unordered_map<wr::NativeSurfaceId, UniquePtr<DCSurface>, SurfaceIdHashFn> 270 mDCSurfaces; 271 272 // A list of layer IDs as they are added to the visual tree this frame. 273 std::vector<wr::NativeSurfaceId> mCurrentLayers; 274 275 // The previous frame's list of layer IDs in visual order. 276 std::vector<wr::NativeSurfaceId> mPrevLayers; 277 278 // Information about a cached FBO that is retained between frames. 279 struct CachedFrameBuffer { 280 int width; 281 int height; 282 GLuint fboId; 283 GLuint depthRboId; 284 int lastFrameUsed; 285 }; 286 287 // A cache of FBOs, containing a depth buffer allocated to a specific size. 288 // TODO(gw): Might be faster as a hashmap? The length is typically much less 289 // than 10. 290 nsTArray<CachedFrameBuffer> mFrameBuffers; 291 int mCurrentFrame = 0; 292 293 bool mPendingCommit; 294 295 mutable Maybe<color::ColorProfileDesc> mOutputColorProfile; 296 297 DCompOverlayTypes mUsedOverlayTypesInFrame = DCompOverlayTypes::NO_OVERLAY; 298 299 public: 300 const color::ColorProfileDesc& OutputColorProfile() const { 301 if (!mOutputColorProfile) { 302 mOutputColorProfile = Some(gfx::QueryOutputColorProfile()); 303 } 304 return *mOutputColorProfile; 305 } 306 307 protected: 308 static StaticAutoPtr<GpuOverlayInfo> sGpuOverlayInfo; 309 }; 310 311 /** 312 Represents a single picture cache slice. Each surface contains some 313 number of tiles. An implementation may choose to allocate individual 314 tiles to render in to (as the current impl does), or allocate a large 315 single virtual surface to draw into (e.g. the DirectComposition virtual 316 surface API in future). 317 */ 318 class DCSurface { 319 public: 320 const bool mIsVirtualSurface; 321 322 explicit DCSurface(wr::DeviceIntSize aTileSize, 323 wr::DeviceIntPoint aVirtualOffset, bool aIsVirtualSurface, 324 bool aIsOpaque, DCLayerTree* aDCLayerTree); 325 virtual ~DCSurface(); 326 327 virtual bool Initialize(); 328 void CreateTile(int32_t aX, int32_t aY); 329 void DestroyTile(int32_t aX, int32_t aY); 330 void SetClip(wr::DeviceIntRect aClipRect, wr::ClipRadius aClipRadius); 331 332 IDCompositionVisual2* GetContentVisual() const { return mContentVisual; } 333 IDCompositionVisual2* GetRootVisual() const { return mRootVisual; } 334 DCTile* GetTile(int32_t aX, int32_t aY) const; 335 336 struct TileKey { 337 TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {} 338 339 int32_t mX; 340 int32_t mY; 341 }; 342 343 wr::DeviceIntSize GetTileSize() const { return mTileSize; } 344 wr::DeviceIntPoint GetVirtualOffset() const { return mVirtualOffset; } 345 346 IDCompositionVirtualSurface* GetCompositionSurface() const { 347 return mVirtualSurface; 348 } 349 350 void UpdateAllocatedRect(); 351 void DirtyAllocatedRect(); 352 353 // Implement these if the inherited surface supports attaching external image. 354 virtual void AttachExternalImage(wr::ExternalImageId aExternalImage) { 355 MOZ_RELEASE_ASSERT(true, "Not support attaching external image"); 356 } 357 virtual void PresentExternalSurface(gfx::Matrix& aTransform) { 358 MOZ_RELEASE_ASSERT(true, "Not support presenting external surface"); 359 } 360 361 virtual DCSurfaceVideo* AsDCSurfaceVideo() { return nullptr; } 362 virtual DCSurfaceHandle* AsDCSurfaceHandle() { return nullptr; } 363 virtual DCLayerSurface* AsDCLayerSurface() { return nullptr; } 364 virtual DCSwapChain* AsDCSwapChain() { return nullptr; } 365 virtual DCLayerDCompositionTexture* AsDCLayerDCompositionTexture() { 366 return nullptr; 367 } 368 virtual DCSurfaceDCompositionTextureOverlay* 369 AsDCSurfaceDCompositionTextureOverlay() { 370 return nullptr; 371 } 372 373 bool IsUpdated(const wr::CompositorSurfaceTransform& aTransform, 374 const wr::DeviceIntRect& aClipRect, 375 const wr::ImageRendering aImageRendering, 376 const wr::DeviceIntRect& aRoundedClipRect, 377 const wr::ClipRadius& aClipRadius); 378 379 protected: 380 DCLayerTree* mDCLayerTree; 381 382 struct TileKeyHashFn { 383 std::size_t operator()(const TileKey& aId) const { 384 return HashGeneric(aId.mX, aId.mY); 385 } 386 }; 387 388 struct DCSurfaceData { 389 DCSurfaceData(const wr::CompositorSurfaceTransform& aTransform, 390 const wr::DeviceIntRect& aClipRect, 391 const wr::ImageRendering aImageRendering, 392 const wr::DeviceIntRect& aRoundedClipRect, 393 const wr::ClipRadius& aClipRadius) 394 : mTransform(aTransform), 395 mClipRect(aClipRect), 396 mImageRendering(aImageRendering), 397 mRoundedClipRect(aRoundedClipRect), 398 mClipRadius(aClipRadius) {} 399 400 wr::CompositorSurfaceTransform mTransform; 401 wr::DeviceIntRect mClipRect; 402 wr::ImageRendering mImageRendering; 403 wr::DeviceIntRect mRoundedClipRect; 404 wr::ClipRadius mClipRadius; 405 }; 406 407 // Each surface creates two visuals. The root is where it gets attached 408 // to parent visuals, the content is where surface (or child visuals) 409 // get attached. Most of the time, the root visual does nothing, but 410 // in the case of a complex clip, we attach the clip here. This allows 411 // us to implement the simple rectangle clip on the content, and apply 412 // the complex clip, if present, in a way that it's not affected by 413 // the transform of the content visual. 414 // 415 // When using a virtual surface, it is directly attached to this 416 // child visual and the tiles do not own visuals. 417 // 418 // Whether mIsVirtualSurface is enabled is decided at DCSurface creation 419 // time based on the pref gfx.webrender.dcomp-use-virtual-surfaces 420 RefPtr<IDCompositionVisual2> mRootVisual; 421 RefPtr<IDCompositionVisual2> mContentVisual; 422 RefPtr<IDCompositionRectangleClip> mClip; 423 424 wr::DeviceIntSize mTileSize; 425 bool mIsOpaque; 426 bool mAllocatedRectDirty; 427 std::unordered_map<TileKey, UniquePtr<DCTile>, TileKeyHashFn> mDCTiles; 428 wr::DeviceIntPoint mVirtualOffset; 429 RefPtr<IDCompositionVirtualSurface> mVirtualSurface; 430 Maybe<DCSurfaceData> mDCSurfaceData; 431 }; 432 433 class DCLayerSurface : public DCSurface { 434 public: 435 DCLayerSurface(bool aIsOpaque, DCLayerTree* aDCLayerTree) 436 : DCSurface(wr::DeviceIntSize{}, wr::DeviceIntPoint{}, false, aIsOpaque, 437 aDCLayerTree) {} 438 virtual ~DCLayerSurface() = default; 439 440 virtual void Bind(const wr::DeviceIntRect* aDirtyRects, 441 size_t aNumDirtyRects) = 0; 442 virtual bool Resize(wr::DeviceIntSize aSize) = 0; 443 virtual void Present(const wr::DeviceIntRect* aDirtyRects, 444 size_t aNumDirtyRects) = 0; 445 446 DCLayerSurface* AsDCLayerSurface() override { return this; } 447 }; 448 449 class DCLayerDCompositionTexture : public DCLayerSurface { 450 public: 451 DCLayerDCompositionTexture(wr::DeviceIntSize aSize, bool aIsOpaque, 452 DCLayerTree* aDCLayerTree); 453 virtual ~DCLayerDCompositionTexture(); 454 455 bool Initialize() override; 456 457 void Bind(const wr::DeviceIntRect* aDirtyRects, 458 size_t aNumDirtyRects) override; 459 bool Resize(wr::DeviceIntSize aSize) override; 460 void Present(const wr::DeviceIntRect* aDirtyRects, 461 size_t aNumDirtyRects) override; 462 463 DCLayerDCompositionTexture* AsDCLayerDCompositionTexture() override { 464 return this; 465 } 466 467 const size_t mSwapChainBufferCount; 468 469 private: 470 struct TextureHolder { 471 TextureHolder(ID3D11Texture2D* aTexture, 472 IDCompositionTexture* aDCompositionTexture, 473 EGLSurface aEGLSurface); 474 TextureHolder() = default; 475 476 RefPtr<ID3D11Texture2D> mTexture; 477 RefPtr<IDCompositionTexture> mDCompositionTexture; 478 EGLSurface mEGLSurface; 479 }; 480 481 bool AllocateTextures(); 482 void DestroyTextures(); 483 UniquePtr<TextureHolder> GetNextTexture(); 484 void UpdateCurrentTexture(); 485 486 wr::DeviceIntSize mSize; 487 std::deque<UniquePtr<TextureHolder>> mAvailableTextureHolders; 488 489 UniquePtr<TextureHolder> mCurrentTextureHolder; 490 UniquePtr<TextureHolder> mPresentingTextureHolder; 491 }; 492 493 class DCSwapChain : public DCLayerSurface { 494 public: 495 DCSwapChain(wr::DeviceIntSize aSize, bool aIsOpaque, 496 DCLayerTree* aDCLayerTree); 497 virtual ~DCSwapChain(); 498 499 bool Initialize() override; 500 501 void Bind(const wr::DeviceIntRect* aDirtyRects, 502 size_t aNumDirtyRects) override; 503 bool Resize(wr::DeviceIntSize aSize) override; 504 void Present(const wr::DeviceIntRect* aDirtyRects, 505 size_t aNumDirtyRects) override; 506 507 DCSwapChain* AsDCSwapChain() override { return this; } 508 509 const int mSwapChainBufferCount; 510 511 private: 512 wr::DeviceIntSize mSize; 513 RefPtr<IDXGISwapChain1> mSwapChain; 514 EGLSurface mEGLSurface; 515 bool mFirstPresent = true; 516 }; 517 518 class DCLayerCompositionSurface : public DCLayerSurface { 519 public: 520 DCLayerCompositionSurface(wr::DeviceIntSize aSize, bool aIsOpaque, 521 DCLayerTree* aDCLayerTree); 522 virtual ~DCLayerCompositionSurface(); 523 524 bool Initialize() override; 525 526 void Bind(const wr::DeviceIntRect* aDirtyRects, 527 size_t aNumDirtyRects) override; 528 bool Resize(wr::DeviceIntSize aSize) override; 529 void Present(const wr::DeviceIntRect* aDirtyRects, 530 size_t aNumDirtyRects) override; 531 532 private: 533 wr::DeviceIntSize mSize; 534 EGLSurface mEGLSurface = EGL_NO_SURFACE; 535 RefPtr<IDCompositionSurface> mCompositionSurface; 536 bool mFirstDraw = true; 537 }; 538 539 /** 540 * A wrapper surface which can contain either a DCVideo or a DCSurfaceHandle. 541 */ 542 class DCExternalSurfaceWrapper : public DCSurface { 543 public: 544 DCExternalSurfaceWrapper(bool aIsOpaque, DCLayerTree* aDCLayerTree) 545 : DCSurface(wr::DeviceIntSize{}, wr::DeviceIntPoint{}, 546 false /* virtual surface */, false /* opaque */, 547 aDCLayerTree), 548 mIsOpaque(aIsOpaque) {} 549 virtual ~DCExternalSurfaceWrapper() = default; 550 551 void AttachExternalImage(wr::ExternalImageId aExternalImage) override; 552 553 void PresentExternalSurface(gfx::Matrix& aTransform) override; 554 555 DCSurfaceVideo* AsDCSurfaceVideo() override { 556 return mSurface ? mSurface->AsDCSurfaceVideo() : nullptr; 557 } 558 559 DCSurfaceHandle* AsDCSurfaceHandle() override { 560 return mSurface ? mSurface->AsDCSurfaceHandle() : nullptr; 561 } 562 563 DCSurfaceDCompositionTextureOverlay* AsDCSurfaceDCompositionTextureOverlay() 564 override { 565 return mSurface ? mSurface->AsDCSurfaceDCompositionTextureOverlay() 566 : nullptr; 567 } 568 569 private: 570 DCSurface* EnsureSurfaceForExternalImage(wr::ExternalImageId aExternalImage); 571 572 UniquePtr<DCSurface> mSurface; 573 const bool mIsOpaque; 574 Maybe<ColorManagementChain> mCManageChain; 575 }; 576 577 class DCSurfaceDCompositionTextureOverlay : public DCSurface { 578 public: 579 DCSurfaceDCompositionTextureOverlay(bool aIsOpaque, 580 DCLayerTree* aDCLayerTree); 581 582 void AttachExternalImage(wr::ExternalImageId aExternalImage) override; 583 void Present(); 584 585 DCSurfaceDCompositionTextureOverlay* AsDCSurfaceDCompositionTextureOverlay() 586 override { 587 return this; 588 } 589 590 protected: 591 virtual ~DCSurfaceDCompositionTextureOverlay(); 592 593 RefPtr<RenderTextureHost> mRenderTextureHost; 594 RefPtr<RenderTextureHost> mPrevRenderTextureHost; 595 }; 596 597 class DCSurfaceVideo : public DCSurface { 598 public: 599 DCSurfaceVideo(bool aIsOpaque, DCLayerTree* aDCLayerTree); 600 601 void AttachExternalImage(wr::ExternalImageId aExternalImage) override; 602 bool CalculateSwapChainSize(gfx::Matrix& aTransform); 603 void PresentVideo(); 604 void OnCompositorEndFrame(int aFrameId, uint32_t aDurationMs); 605 606 DCSurfaceVideo* AsDCSurfaceVideo() override { return this; } 607 608 protected: 609 virtual ~DCSurfaceVideo(); 610 611 DXGI_FORMAT GetSwapChainFormat(bool aUseVpAutoHDR, bool aUseHDR); 612 bool CreateVideoSwapChain(DXGI_FORMAT aFormat); 613 bool CallVideoProcessorBlt(); 614 void ReleaseDecodeSwapChainResources(); 615 616 RefPtr<ID3D11VideoProcessorOutputView> mOutputView; 617 RefPtr<IDXGIResource> mDecodeResource; 618 RefPtr<IDXGISwapChain1> mVideoSwapChain; 619 RefPtr<IDXGIDecodeSwapChain> mDecodeSwapChain; 620 HANDLE mSwapChainSurfaceHandle = 0; 621 gfx::IntSize mVideoSize; 622 gfx::IntSize mSwapChainSize; 623 DXGI_FORMAT mSwapChainFormat = DXGI_FORMAT_B8G8R8A8_UNORM; 624 bool mIsDRM = false; 625 bool mFailedYuvSwapChain = false; 626 RefPtr<RenderTextureHost> mRenderTextureHost; 627 RefPtr<RenderTextureHost> mPrevTexture; 628 RefPtr<RenderTextureHostUsageInfo> mRenderTextureHostUsageInfo; 629 bool mFirstPresent = true; 630 const UINT mSwapChainBufferCount; 631 bool mUseVpAutoHDR = false; 632 bool mVpAutoHDRFailed = false; 633 bool mVpSuperResolutionFailed = false; 634 bool mContentIsHDR = false; 635 bool mUseHDR = false; 636 }; 637 638 /** 639 * A DC surface contains a IDCompositionSurface that is directly constructed by 640 * a handle. This is used by the Media Foundataion media engine, which would 641 * store the decoded video content in the surface. 642 */ 643 class DCSurfaceHandle : public DCSurface { 644 public: 645 DCSurfaceHandle(bool aIsOpaque, DCLayerTree* aDCLayerTree); 646 virtual ~DCSurfaceHandle() = default; 647 648 void AttachExternalImage(wr::ExternalImageId aExternalImage) override; 649 void PresentSurfaceHandle(); 650 651 DCSurfaceHandle* AsDCSurfaceHandle() override { return this; } 652 653 protected: 654 HANDLE GetSurfaceHandle() const; 655 IDCompositionSurface* EnsureSurface(); 656 657 RefPtr<RenderDcompSurfaceTextureHost> mDcompTextureHost; 658 }; 659 660 class DCTile { 661 public: 662 gfx::IntRect mValidRect; 663 664 DCLayerTree* mDCLayerTree; 665 // Indicates that when the first BeginDraw occurs on the surface it must be 666 // full size - required by dcomp on non-virtual surfaces. 667 bool mNeedsFullDraw; 668 669 explicit DCTile(DCLayerTree* aDCLayerTree); 670 ~DCTile(); 671 bool Initialize(int aX, int aY, wr::DeviceIntSize aSize, 672 bool aIsVirtualSurface, bool aIsOpaque, 673 RefPtr<IDCompositionVisual2> mSurfaceVisual); 674 RefPtr<IDCompositionSurface> Bind(wr::DeviceIntRect aValidRect); 675 IDCompositionVisual2* GetVisual() { return mVisual; } 676 677 protected: 678 // Size in pixels of this tile, some may be unused. Set by Initialize. 679 wr::DeviceIntSize mSize; 680 // Whether the tile is composited as opaque (ignores alpha) or transparent. 681 // Set by Initialize. 682 bool mIsOpaque; 683 // Some code paths differ based on whether parent surface is virtual. 684 bool mIsVirtualSurface; 685 // Visual that displays the composition surface, or NULL if the tile belongs 686 // to a virtual surface. 687 RefPtr<IDCompositionVisual2> mVisual; 688 // Surface for the visual, or NULL if the tile has not had its first Bind or 689 // belongs to a virtual surface. 690 RefPtr<IDCompositionSurface> mCompositionSurface; 691 692 RefPtr<IDCompositionSurface> CreateCompositionSurface(wr::DeviceIntSize aSize, 693 bool aIsOpaque); 694 }; 695 696 static inline bool operator==(const DCSurface::TileKey& a0, 697 const DCSurface::TileKey& a1) { 698 return a0.mX == a1.mX && a0.mY == a1.mY; 699 } 700 701 } // namespace wr 702 } // namespace mozilla 703 704 #endif