diff options
Diffstat (limited to '')
-rw-r--r-- | gfx/layers/d3d11/MLGDeviceD3D11.h | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/gfx/layers/d3d11/MLGDeviceD3D11.h b/gfx/layers/d3d11/MLGDeviceD3D11.h new file mode 100644 index 0000000000..2a6aa8ffc7 --- /dev/null +++ b/gfx/layers/d3d11/MLGDeviceD3D11.h @@ -0,0 +1,326 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h +#define mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h + +#include <d3d11_1.h> + +#include "mozilla/layers/MLGDevice.h" +#include "mozilla/layers/SyncObject.h" +#include "mozilla/EnumeratedArray.h" +#include "nsTHashtable.h" +#include "nsPrintfCString.h" + +namespace mozilla { +namespace layers { + +struct GPUStats; +struct ShaderBytes; +class DiagnosticsD3D11; + +class MLGRenderTargetD3D11 final : public MLGRenderTarget { + public: + MLGRenderTargetD3D11(const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags); + + // Create with a new texture. + bool Initialize(ID3D11Device* aDevice); + + // Do not create a texture - use the given one provided, which may be null. + // The depth buffer is still initialized. + bool Initialize(ID3D11Device* aDevice, ID3D11Texture2D* aTexture); + + gfx::IntSize GetSize() const override; + MLGRenderTargetD3D11* AsD3D11() override { return this; } + MLGTexture* GetTexture() override; + + // This is exposed only for MLGSwapChainD3D11. + bool UpdateTexture(ID3D11Texture2D* aTexture); + + ID3D11DepthStencilView* GetDSV(); + ID3D11RenderTargetView* GetRenderTargetView(); + + private: + bool CreateDepthBuffer(ID3D11Device* aDevice); + void ForgetTexture(); + + private: + virtual ~MLGRenderTargetD3D11(); + + private: + RefPtr<ID3D11Texture2D> mTexture; + RefPtr<ID3D11RenderTargetView> mRTView; + RefPtr<ID3D11Texture2D> mDepthBuffer; + RefPtr<ID3D11DepthStencilView> mDepthStencilView; + RefPtr<MLGTexture> mTextureSource; + gfx::IntSize mSize; +}; + +class MLGSwapChainD3D11 final : public MLGSwapChain { + public: + static RefPtr<MLGSwapChainD3D11> Create(MLGDeviceD3D11* aParent, + ID3D11Device* aDevice, + widget::CompositorWidget* aWidget); + + RefPtr<MLGRenderTarget> AcquireBackBuffer() override; + gfx::IntSize GetSize() const override; + bool ResizeBuffers(const gfx::IntSize& aSize) override; + void CopyBackbuffer(gfx::DrawTarget* aTarget, + const gfx::IntRect& aBounds) override; + void Present() override; + void ForcePresent() override; + void Destroy() override; + + private: + MLGSwapChainD3D11(MLGDeviceD3D11* aParent, ID3D11Device* aDevice); + virtual ~MLGSwapChainD3D11(); + + bool Initialize(widget::CompositorWidget* aWidget); + void UpdateBackBufferContents(ID3D11Texture2D* aBack); + + private: + RefPtr<MLGDeviceD3D11> mParent; + RefPtr<ID3D11Device> mDevice; + RefPtr<IDXGISwapChain> mSwapChain; + RefPtr<IDXGISwapChain1> mSwapChain1; + RefPtr<MLGRenderTargetD3D11> mRT; + widget::CompositorWidget* mWidget; + gfx::IntSize mSize; + bool mCanUsePartialPresents; +}; + +class MLGResourceD3D11 { + public: + virtual ID3D11Resource* GetResource() const = 0; +}; + +class MLGBufferD3D11 final : public MLGBuffer, public MLGResourceD3D11 { + public: + static RefPtr<MLGBufferD3D11> Create(ID3D11Device* aDevice, + MLGBufferType aType, uint32_t aSize, + MLGUsage aUsage, + const void* aInitialData); + + MLGBufferD3D11* AsD3D11() override { return this; } + ID3D11Resource* GetResource() const override { return mBuffer; } + ID3D11Buffer* GetBuffer() const { return mBuffer; } + MLGResourceD3D11* AsResourceD3D11() override { return this; } + size_t GetSize() const override { return mSize; } + + protected: + MLGBufferD3D11(ID3D11Buffer* aBuffer, MLGBufferType aType, size_t aSize); + virtual ~MLGBufferD3D11(); + + private: + RefPtr<ID3D11Buffer> mBuffer; + MLGBufferType mType; + size_t mSize; +}; + +class MLGTextureD3D11 final : public MLGTexture, public MLGResourceD3D11 { + public: + explicit MLGTextureD3D11(ID3D11Texture2D* aTexture); + + static RefPtr<MLGTextureD3D11> Create(ID3D11Device* aDevice, + const gfx::IntSize& aSize, + gfx::SurfaceFormat aFormat, + MLGUsage aUsage, + MLGTextureFlags aFlags); + + MLGTextureD3D11* AsD3D11() override { return this; } + MLGResourceD3D11* AsResourceD3D11() override { return this; } + ID3D11Texture2D* GetTexture() const { return mTexture; } + ID3D11Resource* GetResource() const override { return mTexture; } + ID3D11ShaderResourceView* GetShaderResourceView(); + + private: + RefPtr<ID3D11Texture2D> mTexture; + RefPtr<ID3D11ShaderResourceView> mView; +}; + +class MLGDeviceD3D11 final : public MLGDevice { + public: + explicit MLGDeviceD3D11(ID3D11Device* aDevice); + virtual ~MLGDeviceD3D11(); + + bool Initialize() override; + + void StartDiagnostics(uint32_t aInvalidPixels) override; + void EndDiagnostics() override; + void GetDiagnostics(GPUStats* aStats) override; + + MLGDeviceD3D11* AsD3D11() override { return this; } + TextureFactoryIdentifier GetTextureFactoryIdentifier( + widget::CompositorWidget* aWidget) const override; + + RefPtr<MLGSwapChain> CreateSwapChainForWidget( + widget::CompositorWidget* aWidget) override; + + int32_t GetMaxTextureSize() const override; + LayersBackend GetLayersBackend() const override; + + void EndFrame() override; + + bool Map(MLGResource* aResource, MLGMapType aType, + MLGMappedResource* aMap) override; + void Unmap(MLGResource* aResource) override; + void UpdatePartialResource(MLGResource* aResource, const gfx::IntRect* aRect, + void* aData, uint32_t aStride) override; + void CopyTexture(MLGTexture* aDest, const gfx::IntPoint& aTarget, + MLGTexture* aSource, const gfx::IntRect& aRect) override; + + RefPtr<DataTextureSource> CreateDataTextureSource( + TextureFlags aFlags) override; + + void SetRenderTarget(MLGRenderTarget* aRT) override; + MLGRenderTarget* GetRenderTarget() override; + void SetViewport(const gfx::IntRect& aViewport) override; + void SetScissorRect(const Maybe<gfx::IntRect>& aScissorRect) override; + void SetVertexShader(VertexShaderID aVertexShader) override; + void SetPixelShader(PixelShaderID aPixelShader) override; + void SetSamplerMode(uint32_t aIndex, SamplerMode aSamplerMode) override; + void SetBlendState(MLGBlendState aBlendState) override; + void SetVertexBuffer(uint32_t aSlot, MLGBuffer* aBuffer, uint32_t aStride, + uint32_t aOffset) override; + void SetPSTextures(uint32_t aSlot, uint32_t aNumTextures, + TextureSource* const* aTextures) override; + void SetPSTexture(uint32_t aSlot, MLGTexture* aTexture) override; + void SetPSTexturesNV12(uint32_t aSlot, TextureSource* aTexture) override; + void SetPrimitiveTopology(MLGPrimitiveTopology aTopology) override; + void SetDepthTestMode(MLGDepthTestMode aMode) override; + + void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override; + void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer) override; + void SetVSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, + uint32_t aFirstConstant, + uint32_t aNumConstants) override; + void SetPSConstantBuffer(uint32_t aSlot, MLGBuffer* aBuffer, + uint32_t aFirstConstant, + uint32_t aNumConstants) override; + + RefPtr<MLGBuffer> CreateBuffer(MLGBufferType aType, uint32_t aSize, + MLGUsage aUsage, + const void* aInitialData) override; + + RefPtr<MLGRenderTarget> CreateRenderTarget( + const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) override; + + RefPtr<MLGTexture> CreateTexture(const gfx::IntSize& aSize, + gfx::SurfaceFormat aFormat, MLGUsage aUsage, + MLGTextureFlags aFlags) override; + + RefPtr<MLGTexture> CreateTexture(TextureSource* aSource) override; + + void Clear(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor) override; + void ClearDepthBuffer(MLGRenderTarget* aRT) override; + void ClearView(MLGRenderTarget* aRT, const gfx::DeviceColor& aColor, + const gfx::IntRect* aRects, size_t aNumRects) override; + void Draw(uint32_t aVertexCount, uint32_t aOffset) override; + void DrawInstanced(uint32_t aVertexCountPerInstance, uint32_t aInstanceCount, + uint32_t aVertexOffset, uint32_t aInstanceOffset) override; + void Flush() override; + + // This is exposed for TextureSourceProvider. + ID3D11Device* GetD3D11Device() const { return mDevice; } + + bool Synchronize() override; + void UnlockAllTextures() override; + + void InsertPresentWaitQuery(); + void WaitForPreviousPresentQuery(); + void HandleDeviceReset(const char* aWhere); + + private: + bool InitSyncObject(); + + void MaybeLockTexture(ID3D11Texture2D* aTexture); + + bool InitPixelShader(PixelShaderID aShaderID); + bool InitVertexShader(VertexShaderID aShaderID); + bool InitInputLayout(D3D11_INPUT_ELEMENT_DESC* aDesc, size_t aNumElements, + const ShaderBytes& aCode, VertexShaderID aShaderID); + bool InitRasterizerStates(); + bool InitSamplerStates(); + bool InitBlendStates(); + bool InitDepthStencilState(); + bool VerifyConstantBufferOffsetting() override; + + void SetInputLayout(ID3D11InputLayout* aLayout); + void SetVertexShader(ID3D11VertexShader* aShader); + + // Resolve a TextureSource to an ID3D11ShaderResourceView, locking the + // texture if needed. The lock is released at the end of the frame. + ID3D11ShaderResourceView* ResolveTextureSourceForShader( + TextureSource* aSource); + + private: + RefPtr<ID3D11Device> mDevice; + RefPtr<ID3D11DeviceContext> mCtx; + RefPtr<ID3D11DeviceContext1> mCtx1; + UniquePtr<DiagnosticsD3D11> mDiagnostics; + + typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders, + RefPtr<ID3D11PixelShader>> + PixelShaderArray; + typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders, + RefPtr<ID3D11VertexShader>> + VertexShaderArray; + typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders, + RefPtr<ID3D11InputLayout>> + InputLayoutArray; + typedef EnumeratedArray<SamplerMode, SamplerMode::MaxModes, + RefPtr<ID3D11SamplerState>> + SamplerStateArray; + typedef EnumeratedArray<MLGBlendState, MLGBlendState::MaxStates, + RefPtr<ID3D11BlendState>> + BlendStateArray; + typedef EnumeratedArray<MLGDepthTestMode, MLGDepthTestMode::MaxModes, + RefPtr<ID3D11DepthStencilState>> + DepthStencilStateArray; + + PixelShaderArray mPixelShaders; + VertexShaderArray mVertexShaders; + InputLayoutArray mInputLayouts; + SamplerStateArray mSamplerStates; + BlendStateArray mBlendStates; + DepthStencilStateArray mDepthStencilStates; + RefPtr<ID3D11RasterizerState> mRasterizerStateNoScissor; + RefPtr<ID3D11RasterizerState> mRasterizerStateScissor; + + RefPtr<SyncObjectHost> mSyncObject; + + RefPtr<MLGBuffer> mUnitQuadVB; + RefPtr<MLGBuffer> mUnitTriangleVB; + RefPtr<ID3D11VertexShader> mCurrentVertexShader; + RefPtr<ID3D11InputLayout> mCurrentInputLayout; + RefPtr<ID3D11PixelShader> mCurrentPixelShader; + RefPtr<ID3D11BlendState> mCurrentBlendState; + + RefPtr<ID3D11Query> mWaitForPresentQuery; + RefPtr<ID3D11Query> mNextWaitForPresentQuery; + + nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockedTextures; + nsTHashtable<nsRefPtrHashKey<IDXGIKeyedMutex>> mLockAttemptedTextures; + + typedef EnumeratedArray<PixelShaderID, PixelShaderID::MaxShaders, + const ShaderBytes*> + LazyPixelShaderArray; + LazyPixelShaderArray mLazyPixelShaders; + + typedef EnumeratedArray<VertexShaderID, VertexShaderID::MaxShaders, + const ShaderBytes*> + LazyVertexShaderArray; + LazyVertexShaderArray mLazyVertexShaders; + + bool mScissored; +}; + +} // namespace layers +} // namespace mozilla + +struct ShaderBytes; + +#endif // mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h |