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