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_GFX_DCLAYER_TREE_H
8 #define MOZILLA_GFX_DCLAYER_TREE_H
10 #include <unordered_map>
15 #include "mozilla/HashFunctions.h"
16 #include "mozilla/Maybe.h"
17 #include "mozilla/RefPtr.h"
18 #include "mozilla/UniquePtr.h"
19 #include "mozilla/webrender/WebRenderTypes.h"
22 struct ID3D11DeviceContext
;
23 struct ID3D11VideoDevice
;
24 struct ID3D11VideoContext
;
25 struct ID3D11VideoProcessor
;
26 struct ID3D11VideoProcessorEnumerator
;
27 struct ID3D11VideoProcessorOutputView
;
28 struct IDCompositionDevice2
;
29 struct IDCompositionSurface
;
30 struct IDCompositionTarget
;
31 struct IDCompositionVisual2
;
32 struct IDXGIDecodeSwapChain
;
34 struct IDXGISwapChain1
;
35 struct IDCompositionVirtualSurface
;
45 // The size of the virtual surface. This is large enough such that we
46 // will never render a surface larger than this.
47 #define VIRTUAL_SURFACE_SIZE (1024 * 1024)
52 class RenderTextureHost
;
55 * DCLayerTree manages direct composition layers.
56 * It does not manage gecko's layers::Layer.
60 static UniquePtr
<DCLayerTree
> Create(gl::GLContext
* aGL
, EGLConfig aEGLConfig
,
61 ID3D11Device
* aDevice
,
62 ID3D11DeviceContext
* aCtx
, HWND aHwnd
,
64 explicit DCLayerTree(gl::GLContext
* aGL
, EGLConfig aEGLConfig
,
65 ID3D11Device
* aDevice
, ID3D11DeviceContext
* aCtx
,
66 IDCompositionDevice2
* aCompositionDevice
);
69 void SetDefaultSwapChain(IDXGISwapChain1
* aSwapChain
);
70 void MaybeUpdateDebug();
72 void WaitForCommitCompletion();
73 void DisableNativeCompositor();
75 // Interface for wr::Compositor
76 void CompositorBeginFrame();
77 void CompositorEndFrame();
78 void Bind(wr::NativeTileId aId
, wr::DeviceIntPoint
* aOffset
, uint32_t* aFboId
,
79 wr::DeviceIntRect aDirtyRect
, wr::DeviceIntRect aValidRect
);
81 void CreateSurface(wr::NativeSurfaceId aId
, wr::DeviceIntPoint aVirtualOffset
,
82 wr::DeviceIntSize aTileSize
, bool aIsOpaque
);
83 void CreateExternalSurface(wr::NativeSurfaceId aId
, bool aIsOpaque
);
84 void DestroySurface(NativeSurfaceId aId
);
85 void CreateTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
);
86 void DestroyTile(wr::NativeSurfaceId aId
, int32_t aX
, int32_t aY
);
87 void AttachExternalImage(wr::NativeSurfaceId aId
,
88 wr::ExternalImageId aExternalImage
);
89 void AddSurface(wr::NativeSurfaceId aId
,
90 const wr::CompositorSurfaceTransform
& aTransform
,
91 wr::DeviceIntRect aClipRect
,
92 wr::ImageRendering aImageRendering
);
94 gl::GLContext
* GetGLContext() const { return mGL
; }
95 EGLConfig
GetEGLConfig() const { return mEGLConfig
; }
96 ID3D11Device
* GetDevice() const { return mDevice
; }
97 IDCompositionDevice2
* GetCompositionDevice() const {
98 return mCompositionDevice
;
100 ID3D11VideoDevice
* GetVideoDevice() const { return mVideoDevice
; }
101 ID3D11VideoContext
* GetVideoContext() const { return mVideoContext
; }
102 ID3D11VideoProcessor
* GetVideoProcessor() const { return mVideoProcessor
; }
103 ID3D11VideoProcessorEnumerator
* GetVideoProcessorEnumerator() const {
104 return mVideoProcessorEnumerator
;
106 bool EnsureVideoProcessor(const gfx::IntSize
& aVideoSize
);
108 DCSurface
* GetSurface(wr::NativeSurfaceId aId
) const;
110 // Get or create an FBO with depth buffer suitable for specified dimensions
111 GLuint
GetOrCreateFbo(int aWidth
, int aHeight
);
114 bool Initialize(HWND aHwnd
, nsACString
& aError
);
115 bool InitializeVideoOverlaySupport();
116 bool MaybeUpdateDebugCounter();
117 bool MaybeUpdateDebugVisualRedrawRegions();
118 void DestroyEGLSurface();
119 GLuint
CreateEGLSurfaceForCompositionSurface(
120 wr::DeviceIntRect aDirtyRect
, wr::DeviceIntPoint
* aOffset
,
121 RefPtr
<IDCompositionSurface
> aCompositionSurface
,
122 wr::DeviceIntPoint aSurfaceOffset
);
123 void ReleaseNativeCompositorResources();
125 RefPtr
<gl::GLContext
> mGL
;
126 EGLConfig mEGLConfig
;
128 RefPtr
<ID3D11Device
> mDevice
;
129 RefPtr
<ID3D11DeviceContext
> mCtx
;
131 RefPtr
<IDCompositionDevice2
> mCompositionDevice
;
132 RefPtr
<IDCompositionTarget
> mCompositionTarget
;
133 RefPtr
<IDCompositionVisual2
> mRootVisual
;
134 RefPtr
<IDCompositionVisual2
> mDefaultSwapChainVisual
;
136 RefPtr
<ID3D11VideoDevice
> mVideoDevice
;
137 RefPtr
<ID3D11VideoContext
> mVideoContext
;
138 RefPtr
<ID3D11VideoProcessor
> mVideoProcessor
;
139 RefPtr
<ID3D11VideoProcessorEnumerator
> mVideoProcessorEnumerator
;
140 gfx::IntSize mVideoSize
;
142 bool mVideoOverlaySupported
;
145 bool mDebugVisualRedrawRegions
;
147 Maybe
<RefPtr
<IDCompositionSurface
>> mCurrentSurface
;
149 // The EGL image that is bound to the D3D texture provided by
150 // DirectComposition.
153 // The GL render buffer ID that maps the EGLImage to an RBO for attaching to
157 struct SurfaceIdHashFn
{
158 std::size_t operator()(const wr::NativeSurfaceId
& aId
) const {
159 return HashGeneric(wr::AsUint64(aId
));
163 std::unordered_map
<wr::NativeSurfaceId
, UniquePtr
<DCSurface
>, SurfaceIdHashFn
>
166 // A list of layer IDs as they are added to the visual tree this frame.
167 std::vector
<wr::NativeSurfaceId
> mCurrentLayers
;
169 // The previous frame's list of layer IDs in visual order.
170 std::vector
<wr::NativeSurfaceId
> mPrevLayers
;
172 // Information about a cached FBO that is retained between frames.
173 struct CachedFrameBuffer
{
181 // A cache of FBOs, containing a depth buffer allocated to a specific size.
182 // TODO(gw): Might be faster as a hashmap? The length is typically much less
184 nsTArray
<CachedFrameBuffer
> mFrameBuffers
;
185 int mCurrentFrame
= 0;
191 Represents a single picture cache slice. Each surface contains some
192 number of tiles. An implementation may choose to allocate individual
193 tiles to render in to (as the current impl does), or allocate a large
194 single virtual surface to draw into (e.g. the DirectComposition virtual
195 surface API in future).
199 explicit DCSurface(wr::DeviceIntSize aTileSize
,
200 wr::DeviceIntPoint aVirtualOffset
, bool aIsOpaque
,
201 DCLayerTree
* aDCLayerTree
);
202 virtual ~DCSurface();
205 void CreateTile(int32_t aX
, int32_t aY
);
206 void DestroyTile(int32_t aX
, int32_t aY
);
208 IDCompositionVisual2
* GetVisual() const { return mVisual
; }
209 DCTile
* GetTile(int32_t aX
, int32_t aY
) const;
212 TileKey(int32_t aX
, int32_t aY
) : mX(aX
), mY(aY
) {}
218 wr::DeviceIntSize
GetTileSize() const { return mTileSize
; }
219 wr::DeviceIntPoint
GetVirtualOffset() const { return mVirtualOffset
; }
221 IDCompositionVirtualSurface
* GetCompositionSurface() const {
222 return mVirtualSurface
;
225 void UpdateAllocatedRect();
226 void DirtyAllocatedRect();
228 virtual DCSurfaceVideo
* AsDCSurfaceVideo() { return nullptr; }
231 DCLayerTree
* mDCLayerTree
;
233 struct TileKeyHashFn
{
234 std::size_t operator()(const TileKey
& aId
) const {
235 return HashGeneric(aId
.mX
, aId
.mY
);
239 // The visual for this surface. No content is attached to here, but tiles
240 // that belong to this surface are added as children. In this way, we can
241 // set the clip and scroll offset once, on this visual, to affect all
243 RefPtr
<IDCompositionVisual2
> mVisual
;
245 wr::DeviceIntSize mTileSize
;
247 bool mAllocatedRectDirty
;
248 std::unordered_map
<TileKey
, UniquePtr
<DCTile
>, TileKeyHashFn
> mDCTiles
;
249 wr::DeviceIntPoint mVirtualOffset
;
250 RefPtr
<IDCompositionVirtualSurface
> mVirtualSurface
;
253 class DCSurfaceVideo
: public DCSurface
{
255 DCSurfaceVideo(bool aIsOpaque
, DCLayerTree
* aDCLayerTree
);
257 void AttachExternalImage(wr::ExternalImageId aExternalImage
);
259 DCSurfaceVideo
* AsDCSurfaceVideo() override
{ return this; }
262 bool CreateVideoSwapChain(RenderTextureHost
* aTexture
);
263 bool CallVideoProcessorBlt(RenderTextureHost
* aTexture
);
264 void ReleaseDecodeSwapChainResources();
266 RefPtr
<ID3D11VideoProcessorOutputView
> mOutputView
;
267 RefPtr
<IDXGIResource
> mDecodeResource
;
268 RefPtr
<IDXGISwapChain1
> mVideoSwapChain
;
269 RefPtr
<IDXGIDecodeSwapChain
> mDecodeSwapChain
;
270 HANDLE mSwapChainSurfaceHandle
;
271 gfx::IntSize mSwapChainSize
;
272 RefPtr
<RenderTextureHost
> mPrevTexture
;
277 explicit DCTile(DCLayerTree
* aDCLayerTree
);
279 bool Initialize(int aX
, int aY
, wr::DeviceIntSize aSize
, bool aIsOpaque
);
281 gfx::IntRect mValidRect
;
283 DCLayerTree
* mDCLayerTree
;
286 static inline bool operator==(const DCSurface::TileKey
& a0
,
287 const DCSurface::TileKey
& a1
) {
288 return a0
.mX
== a1
.mX
&& a0
.mY
== a1
.mY
;
292 } // namespace mozilla