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_layers_d3d11_MLGDeviceD3D11_h
8 #define mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h
9 
10 #include <d3d11_1.h>
11 
12 #include "mozilla/layers/MLGDevice.h"
13 #include "mozilla/layers/SyncObject.h"
14 #include "mozilla/EnumeratedArray.h"
15 #include "nsTHashtable.h"
16 #include "nsPrintfCString.h"
17 
18 namespace mozilla {
19 namespace layers {
20 
21 struct GPUStats;
22 struct ShaderBytes;
23 class DiagnosticsD3D11;
24 
25 class MLGRenderTargetD3D11 final : public MLGRenderTarget {
26  public:
27   MLGRenderTargetD3D11(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags);
28 
29   // Create with a new texture.
30   bool Initialize(ID3D11Device* aDevice);
31 
32   // Do not create a texture - use the given one provided, which may be null.
33   // The depth buffer is still initialized.
34   bool Initialize(ID3D11Device* aDevice, ID3D11Texture2D* aTexture);
35 
36   gfx::IntSize GetSize() const override;
AsD3D11()37   MLGRenderTargetD3D11* AsD3D11() override { return this; }
38   MLGTexture* GetTexture() override;
39 
40   // This is exposed only for MLGSwapChainD3D11.
41   bool UpdateTexture(ID3D11Texture2D* aTexture);
42 
43   ID3D11DepthStencilView* GetDSV();
44   ID3D11RenderTargetView* GetRenderTargetView();
45 
46  private:
47   bool CreateDepthBuffer(ID3D11Device* aDevice);
48   void ForgetTexture();
49 
50  private:
51   virtual ~MLGRenderTargetD3D11();
52 
53  private:
54   RefPtr<ID3D11Texture2D> mTexture;
55   RefPtr<ID3D11RenderTargetView> mRTView;
56   RefPtr<ID3D11Texture2D> mDepthBuffer;
57   RefPtr<ID3D11DepthStencilView> mDepthStencilView;
58   RefPtr<MLGTexture> mTextureSource;
59   gfx::IntSize mSize;
60 };
61 
62 class MLGSwapChainD3D11 final : public MLGSwapChain {
63  public:
64   static RefPtr<MLGSwapChainD3D11> Create(MLGDeviceD3D11* aParent,
65                                           ID3D11Device* aDevice,
66                                           widget::CompositorWidget* aWidget);
67 
68   RefPtr<MLGRenderTarget> AcquireBackBuffer() override;
69   gfx::IntSize GetSize() const override;
70   bool ResizeBuffers(const gfx::IntSize& aSize) override;
71   void CopyBackbuffer(gfx::DrawTarget* aTarget,
72                       const gfx::IntRect& aBounds) override;
73   void Present() override;
74   void ForcePresent() override;
75   void Destroy() override;
76 
77  private:
78   MLGSwapChainD3D11(MLGDeviceD3D11* aParent, ID3D11Device* aDevice);
79   virtual ~MLGSwapChainD3D11();
80 
81   bool Initialize(widget::CompositorWidget* aWidget);
82   void UpdateBackBufferContents(ID3D11Texture2D* aBack);
83 
84  private:
85   RefPtr<MLGDeviceD3D11> mParent;
86   RefPtr<ID3D11Device> mDevice;
87   RefPtr<IDXGISwapChain> mSwapChain;
88   RefPtr<IDXGISwapChain1> mSwapChain1;
89   RefPtr<MLGRenderTargetD3D11> mRT;
90   widget::CompositorWidget* mWidget;
91   gfx::IntSize mSize;
92   bool mCanUsePartialPresents;
93 };
94 
95 class MLGResourceD3D11 {
96  public:
97   virtual ID3D11Resource* GetResource() const = 0;
98 };
99 
100 class MLGBufferD3D11 final : public MLGBuffer, public MLGResourceD3D11 {
101  public:
102   static RefPtr<MLGBufferD3D11> Create(ID3D11Device* aDevice,
103                                        MLGBufferType aType, uint32_t aSize,
104                                        MLGUsage aUsage,
105                                        const void* aInitialData);
106 
AsD3D11()107   MLGBufferD3D11* AsD3D11() override { return this; }
GetResource()108   ID3D11Resource* GetResource() const override { return mBuffer; }
GetBuffer()109   ID3D11Buffer* GetBuffer() const { return mBuffer; }
AsResourceD3D11()110   MLGResourceD3D11* AsResourceD3D11() override { return this; }
GetSize()111   size_t GetSize() const override { return mSize; }
112 
113  protected:
114   MLGBufferD3D11(ID3D11Buffer* aBuffer, MLGBufferType aType, size_t aSize);
115   virtual ~MLGBufferD3D11();
116 
117  private:
118   RefPtr<ID3D11Buffer> mBuffer;
119   MLGBufferType mType;
120   size_t mSize;
121 };
122 
123 class MLGTextureD3D11 final : public MLGTexture, public MLGResourceD3D11 {
124  public:
125   explicit MLGTextureD3D11(ID3D11Texture2D* aTexture);
126 
127   static RefPtr<MLGTextureD3D11> Create(ID3D11Device* aDevice,
128                                         const gfx::IntSize& aSize,
129                                         gfx::SurfaceFormat aFormat,
130                                         MLGUsage aUsage,
131                                         MLGTextureFlags aFlags);
132 
AsD3D11()133   MLGTextureD3D11* AsD3D11() override { return this; }
AsResourceD3D11()134   MLGResourceD3D11* AsResourceD3D11() override { return this; }
GetTexture()135   ID3D11Texture2D* GetTexture() const { return mTexture; }
GetResource()136   ID3D11Resource* GetResource() const override { return mTexture; }
137   ID3D11ShaderResourceView* GetShaderResourceView();
138 
139  private:
140   RefPtr<ID3D11Texture2D> mTexture;
141   RefPtr<ID3D11ShaderResourceView> mView;
142 };
143 
144 class MLGDeviceD3D11 final : public MLGDevice {
145  public:
146   explicit MLGDeviceD3D11(ID3D11Device* aDevice);
147   virtual ~MLGDeviceD3D11();
148 
149   bool Initialize() override;
150 
151   void StartDiagnostics(uint32_t aInvalidPixels) override;
152   void EndDiagnostics() override;
153   void GetDiagnostics(GPUStats* aStats) override;
154 
AsD3D11()155   MLGDeviceD3D11* AsD3D11() override { return this; }
156   TextureFactoryIdentifier GetTextureFactoryIdentifier(
157       widget::CompositorWidget* aWidget) const override;
158 
159   RefPtr<MLGSwapChain> CreateSwapChainForWidget(
160       widget::CompositorWidget* aWidget) override;
161 
162   int32_t GetMaxTextureSize() const override;
163   LayersBackend GetLayersBackend() const override;
164 
165   void EndFrame() override;
166 
167   bool Map(MLGResource* aResource, MLGMapType aType,
168            MLGMappedResource* aMap) override;
169   void Unmap(MLGResource* aResource) override;
170   void UpdatePartialResource(MLGResource* aResource, const gfx::IntRect* aRect,
171                              void* aData, uint32_t aStride) override;
172   void CopyTexture(MLGTexture* aDest, const gfx::IntPoint& aTarget,
173                    MLGTexture* aSource, const gfx::IntRect& aRect) override;
174 
175   RefPtr<DataTextureSource> CreateDataTextureSource(
176       TextureFlags aFlags) override;
177 
178   void SetRenderTarget(MLGRenderTarget* aRT) override;
179   MLGRenderTarget* GetRenderTarget() override;
180   void SetViewport(const gfx::IntRect& aViewport) override;
181   void SetScissorRect(const Maybe<gfx::IntRect>& aScissorRect) override;
182   void SetVertexShader(VertexShaderID aVertexShader) override;
183   void SetPixelShader(PixelShaderID aPixelShader) override;
184   void SetSamplerMode(uint32_t aIndex, SamplerMode aSamplerMode) override;
185   void SetBlendState(MLGBlendState aBlendState) override;
186   void SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride,
187                        uint32_t aOffset) override;
188   void SetPSTextures(uint32_t aSlot, uint32_t aNumTextures,
189                      TextureSource* const* aTextures) override;
190   void SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) override;
191   void SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) override;
192   void SetPrimitiveTopology(MLGPrimitiveTopology aTopology) override;
193   void SetDepthTestMode(MLGDepthTestMode aMode) override;
194 
195   void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override;
196   void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override;
197   void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer,
198                            uint32_t aFirstConstant,
199                            uint32_t aNumConstants) override;
200   void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer,
201                            uint32_t aFirstConstant,
202                            uint32_t aNumConstants) override;
203 
204   RefPtr<MLGBuffer> CreateBuffer(MLGBufferType aType, uint32_t aSize,
205                                  MLGUsage aUsage,
206                                  const void* aInitialData) override;
207 
208   RefPtr<MLGRenderTarget> CreateRenderTarget(
209       const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) override;
210 
211   RefPtr<MLGTexture> CreateTexture(const gfx::IntSize& aSize,
212                                    gfx::SurfaceFormat aFormat, MLGUsage aUsage,
213                                    MLGTextureFlags aFlags) override;
214 
215   RefPtr<MLGTexture> CreateTexture(TextureSource* aSource) override;
216 
217   void Clear(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor) override;
218   void ClearDepthBuffer(MLGRenderTarget* aRT) override;
219   void ClearView(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor,
220                  const gfx::IntRect* aRects, size_t aNumRects) override;
221   void Draw(uint32_t aVertexCount, uint32_t aOffset) override;
222   void DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount,
223                      uint32_t aVertexOffset, uint32_t aInstanceOffset) override;
224   void Flush() override;
225 
226   // This is exposed for TextureSourceProvider.
GetD3D11Device()227   ID3D11Device* GetD3D11Device() const { return mDevice; }
228 
229   bool Synchronize() override;
230   void UnlockAllTextures() override;
231 
232   void InsertPresentWaitQuery();
233   void WaitForPreviousPresentQuery();
234   void HandleDeviceReset(const char* aWhere);
235 
236  private:
237   bool InitSyncObject();
238 
239   void MaybeLockTexture(ID3D11Texture2D* aTexture);
240 
241   bool InitPixelShader(PixelShaderID aShaderID);
242   bool InitVertexShader(VertexShaderID aShaderID);
243   bool InitInputLayout(D3D11_INPUT_ELEMENT_DESC* aDesc, size_t aNumElements,
244                        const ShaderBytes& aCode, VertexShaderID aShaderID);
245   bool InitRasterizerStates();
246   bool InitSamplerStates();
247   bool InitBlendStates();
248   bool InitDepthStencilState();
249   bool VerifyConstantBufferOffsetting() override;
250 
251   void SetInputLayout(ID3D11InputLayout* aLayout);
252   void SetVertexShader(ID3D11VertexShader* aShader);
253 
254   // Resolve a TextureSource to an ID3D11ShaderResourceView, locking the
255   // texture if needed. The lock is released at the end of the frame.
256   ID3D11ShaderResourceView* ResolveTextureSourceForShader(
257       TextureSource* aSource);
258 
259  private:
260   RefPtr<ID3D11Device> mDevice;
261   RefPtr<ID3D11DeviceContext> mCtx;
262   RefPtr<ID3D11DeviceContext1> mCtx1;
263   UniquePtr<DiagnosticsD3D11> mDiagnostics;
264 
265   typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders,
266                           RefPtr<ID3D11PixelShader>>
267       PixelShaderArray;
268   typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
269                           RefPtr<ID3D11VertexShader>>
270       VertexShaderArray;
271   typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
272                           RefPtr<ID3D11InputLayout>>
273       InputLayoutArray;
274   typedef EnumeratedArray<SamplerMode, SamplerMode::MaxModes,
275                           RefPtr<ID3D11SamplerState>>
276       SamplerStateArray;
277   typedef EnumeratedArray<MLGBlendState, MLGBlendState::MaxStates,
278                           RefPtr<ID3D11BlendState>>
279       BlendStateArray;
280   typedef EnumeratedArray<MLGDepthTestMode, MLGDepthTestMode::MaxModes,
281                           RefPtr<ID3D11DepthStencilState>>
282       DepthStencilStateArray;
283 
284   PixelShaderArray mPixelShaders;
285   VertexShaderArray mVertexShaders;
286   InputLayoutArray mInputLayouts;
287   SamplerStateArray mSamplerStates;
288   BlendStateArray mBlendStates;
289   DepthStencilStateArray mDepthStencilStates;
290   RefPtr<ID3D11RasterizerState> mRasterizerStateNoScissor;
291   RefPtr<ID3D11RasterizerState> mRasterizerStateScissor;
292 
293   RefPtr<SyncObjectHost> mSyncObject;
294 
295   RefPtr<MLGBuffer> mUnitQuadVB;
296   RefPtr<MLGBuffer> mUnitTriangleVB;
297   RefPtr<ID3D11VertexShader> mCurrentVertexShader;
298   RefPtr<ID3D11InputLayout> mCurrentInputLayout;
299   RefPtr<ID3D11PixelShader> mCurrentPixelShader;
300   RefPtr<ID3D11BlendState> mCurrentBlendState;
301 
302   RefPtr<ID3D11Query> mWaitForPresentQuery;
303   RefPtr<ID3D11Query> mNextWaitForPresentQuery;
304 
305   nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockedTextures;
306   nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockAttemptedTextures;
307 
308   typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders,
309                           const ShaderBytes*>
310       LazyPixelShaderArray;
311   LazyPixelShaderArray mLazyPixelShaders;
312 
313   typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders,
314                           const ShaderBytes*>
315       LazyVertexShaderArray;
316   LazyVertexShaderArray mLazyVertexShaders;
317 
318   bool mScissored;
319 };
320 
321 }  // namespace layers
322 }  // namespace mozilla
323 
324 struct ShaderBytes;
325 
326 #endif  // mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h
327