Bug 1472338: part 1) Add Chrome tests for the async Clipboard API. r=NeilDeakin
[gecko.git] / gfx / webrender_bindings / DCLayerTree.h
blobf8ef5d895f7e0dc9e49f9e795bce3202c29a3d2a
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 <dxgiformat.h>
11 #include <unordered_map>
12 #include <vector>
13 #include <windows.h>
15 #include "GLTypes.h"
16 #include "mozilla/HashFunctions.h"
17 #include "mozilla/Maybe.h"
18 #include "mozilla/RefPtr.h"
19 #include "mozilla/UniquePtr.h"
20 #include "mozilla/webrender/WebRenderTypes.h"
22 struct ID3D11Device;
23 struct ID3D11DeviceContext;
24 struct ID3D11VideoDevice;
25 struct ID3D11VideoContext;
26 struct ID3D11VideoProcessor;
27 struct ID3D11VideoProcessorEnumerator;
28 struct ID3D11VideoProcessorOutputView;
29 struct IDCompositionDevice2;
30 struct IDCompositionSurface;
31 struct IDCompositionTarget;
32 struct IDCompositionVisual2;
33 struct IDXGIDecodeSwapChain;
34 struct IDXGIResource;
35 struct IDXGISwapChain1;
36 struct IDCompositionVirtualSurface;
38 namespace mozilla {
40 namespace gl {
41 class GLContext;
44 namespace wr {
46 // The size of the virtual surface. This is large enough such that we
47 // will never render a surface larger than this.
48 #define VIRTUAL_SURFACE_SIZE (1024 * 1024)
50 class DCTile;
51 class DCSurface;
52 class DCSurfaceVideo;
53 class RenderTextureHost;
55 struct GpuOverlayInfo {
56 bool mSupportsOverlays = false;
57 bool mSupportsHardwareOverlays = false;
58 DXGI_FORMAT mOverlayFormatUsed = DXGI_FORMAT_B8G8R8A8_UNORM;
59 DXGI_FORMAT mOverlayFormatUsedHdr = DXGI_FORMAT_R10G10B10A2_UNORM;
60 UINT mNv12OverlaySupportFlags = 0;
61 UINT mYuy2OverlaySupportFlags = 0;
62 UINT mRgb10a2OverlaySupportFlags = 0;
65 /**
66 * DCLayerTree manages direct composition layers.
67 * It does not manage gecko's layers::Layer.
69 class DCLayerTree {
70 public:
71 static UniquePtr<DCLayerTree> Create(gl::GLContext* aGL, EGLConfig aEGLConfig,
72 ID3D11Device* aDevice,
73 ID3D11DeviceContext* aCtx, HWND aHwnd,
74 nsACString& aError);
76 static void Shutdown();
78 explicit DCLayerTree(gl::GLContext* aGL, EGLConfig aEGLConfig,
79 ID3D11Device* aDevice, ID3D11DeviceContext* aCtx,
80 IDCompositionDevice2* aCompositionDevice);
81 ~DCLayerTree();
83 void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain);
84 void MaybeUpdateDebug();
85 void MaybeCommit();
86 void WaitForCommitCompletion();
87 void DisableNativeCompositor();
89 // Interface for wr::Compositor
90 void CompositorBeginFrame();
91 void CompositorEndFrame();
92 void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
93 wr::DeviceIntRect aDirtyRect, wr::DeviceIntRect aValidRect);
94 void Unbind();
95 void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
96 wr::DeviceIntSize aTileSize, bool aIsOpaque);
97 void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque);
98 void DestroySurface(NativeSurfaceId aId);
99 void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY);
100 void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY);
101 void AttachExternalImage(wr::NativeSurfaceId aId,
102 wr::ExternalImageId aExternalImage);
103 void AddSurface(wr::NativeSurfaceId aId,
104 const wr::CompositorSurfaceTransform& aTransform,
105 wr::DeviceIntRect aClipRect,
106 wr::ImageRendering aImageRendering);
108 gl::GLContext* GetGLContext() const { return mGL; }
109 EGLConfig GetEGLConfig() const { return mEGLConfig; }
110 ID3D11Device* GetDevice() const { return mDevice; }
111 IDCompositionDevice2* GetCompositionDevice() const {
112 return mCompositionDevice;
114 ID3D11VideoDevice* GetVideoDevice() const { return mVideoDevice; }
115 ID3D11VideoContext* GetVideoContext() const { return mVideoContext; }
116 ID3D11VideoProcessor* GetVideoProcessor() const { return mVideoProcessor; }
117 ID3D11VideoProcessorEnumerator* GetVideoProcessorEnumerator() const {
118 return mVideoProcessorEnumerator;
120 bool EnsureVideoProcessor(const gfx::IntSize& aVideoSize);
122 DCSurface* GetSurface(wr::NativeSurfaceId aId) const;
124 // Get or create an FBO with depth buffer suitable for specified dimensions
125 GLuint GetOrCreateFbo(int aWidth, int aHeight);
127 bool SupportsHardwareOverlays();
128 DXGI_FORMAT GetOverlayFormatForSDR();
130 protected:
131 bool Initialize(HWND aHwnd, nsACString& aError);
132 bool InitializeVideoOverlaySupport();
133 bool MaybeUpdateDebugCounter();
134 bool MaybeUpdateDebugVisualRedrawRegions();
135 void DestroyEGLSurface();
136 GLuint CreateEGLSurfaceForCompositionSurface(
137 wr::DeviceIntRect aDirtyRect, wr::DeviceIntPoint* aOffset,
138 RefPtr<IDCompositionSurface> aCompositionSurface,
139 wr::DeviceIntPoint aSurfaceOffset);
140 void ReleaseNativeCompositorResources();
142 RefPtr<gl::GLContext> mGL;
143 EGLConfig mEGLConfig;
145 RefPtr<ID3D11Device> mDevice;
146 RefPtr<ID3D11DeviceContext> mCtx;
148 RefPtr<IDCompositionDevice2> mCompositionDevice;
149 RefPtr<IDCompositionTarget> mCompositionTarget;
150 RefPtr<IDCompositionVisual2> mRootVisual;
151 RefPtr<IDCompositionVisual2> mDefaultSwapChainVisual;
153 RefPtr<ID3D11VideoDevice> mVideoDevice;
154 RefPtr<ID3D11VideoContext> mVideoContext;
155 RefPtr<ID3D11VideoProcessor> mVideoProcessor;
156 RefPtr<ID3D11VideoProcessorEnumerator> mVideoProcessorEnumerator;
157 gfx::IntSize mVideoSize;
159 bool mDebugCounter;
160 bool mDebugVisualRedrawRegions;
162 Maybe<RefPtr<IDCompositionSurface>> mCurrentSurface;
164 // The EGL image that is bound to the D3D texture provided by
165 // DirectComposition.
166 EGLImage mEGLImage;
168 // The GL render buffer ID that maps the EGLImage to an RBO for attaching to
169 // an FBO.
170 GLuint mColorRBO;
172 struct SurfaceIdHashFn {
173 std::size_t operator()(const wr::NativeSurfaceId& aId) const {
174 return HashGeneric(wr::AsUint64(aId));
178 std::unordered_map<wr::NativeSurfaceId, UniquePtr<DCSurface>, SurfaceIdHashFn>
179 mDCSurfaces;
181 // A list of layer IDs as they are added to the visual tree this frame.
182 std::vector<wr::NativeSurfaceId> mCurrentLayers;
184 // The previous frame's list of layer IDs in visual order.
185 std::vector<wr::NativeSurfaceId> mPrevLayers;
187 // Information about a cached FBO that is retained between frames.
188 struct CachedFrameBuffer {
189 int width;
190 int height;
191 GLuint fboId;
192 GLuint depthRboId;
193 int lastFrameUsed;
196 // A cache of FBOs, containing a depth buffer allocated to a specific size.
197 // TODO(gw): Might be faster as a hashmap? The length is typically much less
198 // than 10.
199 nsTArray<CachedFrameBuffer> mFrameBuffers;
200 int mCurrentFrame = 0;
202 bool mPendingCommit;
204 static UniquePtr<GpuOverlayInfo> sGpuOverlayInfo;
208 Represents a single picture cache slice. Each surface contains some
209 number of tiles. An implementation may choose to allocate individual
210 tiles to render in to (as the current impl does), or allocate a large
211 single virtual surface to draw into (e.g. the DirectComposition virtual
212 surface API in future).
214 class DCSurface {
215 public:
216 explicit DCSurface(wr::DeviceIntSize aTileSize,
217 wr::DeviceIntPoint aVirtualOffset, bool aIsOpaque,
218 DCLayerTree* aDCLayerTree);
219 virtual ~DCSurface();
221 bool Initialize();
222 void CreateTile(int32_t aX, int32_t aY);
223 void DestroyTile(int32_t aX, int32_t aY);
225 IDCompositionVisual2* GetVisual() const { return mVisual; }
226 DCTile* GetTile(int32_t aX, int32_t aY) const;
228 struct TileKey {
229 TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
231 int32_t mX;
232 int32_t mY;
235 wr::DeviceIntSize GetTileSize() const { return mTileSize; }
236 wr::DeviceIntPoint GetVirtualOffset() const { return mVirtualOffset; }
238 IDCompositionVirtualSurface* GetCompositionSurface() const {
239 return mVirtualSurface;
242 void UpdateAllocatedRect();
243 void DirtyAllocatedRect();
245 virtual DCSurfaceVideo* AsDCSurfaceVideo() { return nullptr; }
247 protected:
248 DCLayerTree* mDCLayerTree;
250 struct TileKeyHashFn {
251 std::size_t operator()(const TileKey& aId) const {
252 return HashGeneric(aId.mX, aId.mY);
256 // The visual for this surface. No content is attached to here, but tiles
257 // that belong to this surface are added as children. In this way, we can
258 // set the clip and scroll offset once, on this visual, to affect all
259 // children.
260 RefPtr<IDCompositionVisual2> mVisual;
262 wr::DeviceIntSize mTileSize;
263 bool mIsOpaque;
264 bool mAllocatedRectDirty;
265 std::unordered_map<TileKey, UniquePtr<DCTile>, TileKeyHashFn> mDCTiles;
266 wr::DeviceIntPoint mVirtualOffset;
267 RefPtr<IDCompositionVirtualSurface> mVirtualSurface;
270 class DCSurfaceVideo : public DCSurface {
271 public:
272 DCSurfaceVideo(bool aIsOpaque, DCLayerTree* aDCLayerTree);
274 void AttachExternalImage(wr::ExternalImageId aExternalImage);
276 DCSurfaceVideo* AsDCSurfaceVideo() override { return this; }
278 protected:
279 DXGI_FORMAT GetSwapChainFormat();
280 bool CreateVideoSwapChain(RenderTextureHost* aTexture);
281 bool CallVideoProcessorBlt(RenderTextureHost* aTexture);
282 void ReleaseDecodeSwapChainResources();
284 RefPtr<ID3D11VideoProcessorOutputView> mOutputView;
285 RefPtr<IDXGIResource> mDecodeResource;
286 RefPtr<IDXGISwapChain1> mVideoSwapChain;
287 RefPtr<IDXGIDecodeSwapChain> mDecodeSwapChain;
288 HANDLE mSwapChainSurfaceHandle;
289 gfx::IntSize mSwapChainSize;
290 DXGI_FORMAT mSwapChainFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
291 bool mFailedToCreateYuvSwapChain = false;
292 RefPtr<RenderTextureHost> mPrevTexture;
295 class DCTile {
296 public:
297 explicit DCTile(DCLayerTree* aDCLayerTree);
298 ~DCTile();
299 bool Initialize(int aX, int aY, wr::DeviceIntSize aSize, bool aIsOpaque);
301 gfx::IntRect mValidRect;
303 DCLayerTree* mDCLayerTree;
306 static inline bool operator==(const DCSurface::TileKey& a0,
307 const DCSurface::TileKey& a1) {
308 return a0.mX == a1.mX && a0.mY == a1.mY;
311 } // namespace wr
312 } // namespace mozilla
314 #endif