tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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