/* -*- 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 #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 mTexture; RefPtr mRTView; RefPtr mDepthBuffer; RefPtr mDepthStencilView; RefPtr mTextureSource; gfx::IntSize mSize; }; class MLGSwapChainD3D11 final : public MLGSwapChain { public: static RefPtr Create(MLGDeviceD3D11* aParent, ID3D11Device* aDevice, widget::CompositorWidget* aWidget); RefPtr 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 mParent; RefPtr mDevice; RefPtr mSwapChain; RefPtr mSwapChain1; RefPtr 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 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 mBuffer; MLGBufferType mType; size_t mSize; }; class MLGTextureD3D11 final : public MLGTexture, public MLGResourceD3D11 { public: explicit MLGTextureD3D11(ID3D11Texture2D* aTexture); static RefPtr 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 mTexture; RefPtr 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() const override; RefPtr 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 CreateDataTextureSource( TextureFlags aFlags) override; void SetRenderTarget(MLGRenderTarget* aRT) override; MLGRenderTarget* GetRenderTarget() override; void SetViewport(const gfx::IntRect& aViewport) override; void SetScissorRect(const Maybe& 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 CreateBuffer(MLGBufferType aType, uint32_t aSize, MLGUsage aUsage, const void* aInitialData) override; RefPtr CreateRenderTarget( const gfx::IntSize& aSize, MLGRenderTargetFlags aFlags) override; RefPtr CreateTexture(const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat, MLGUsage aUsage, MLGTextureFlags aFlags) override; RefPtr CreateTexture(TextureSource* aSource) override; void Clear(MLGRenderTarget* aRT, const gfx::Color& aColor) override; void ClearDepthBuffer(MLGRenderTarget* aRT) override; void ClearView(MLGRenderTarget* aRT, const gfx::Color& 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 mDevice; RefPtr mCtx; RefPtr mCtx1; UniquePtr mDiagnostics; typedef EnumeratedArray> PixelShaderArray; typedef EnumeratedArray> VertexShaderArray; typedef EnumeratedArray> InputLayoutArray; typedef EnumeratedArray> SamplerStateArray; typedef EnumeratedArray> BlendStateArray; typedef EnumeratedArray> DepthStencilStateArray; PixelShaderArray mPixelShaders; VertexShaderArray mVertexShaders; InputLayoutArray mInputLayouts; SamplerStateArray mSamplerStates; BlendStateArray mBlendStates; DepthStencilStateArray mDepthStencilStates; RefPtr mRasterizerStateNoScissor; RefPtr mRasterizerStateScissor; RefPtr mSyncObject; RefPtr mUnitQuadVB; RefPtr mUnitTriangleVB; RefPtr mCurrentVertexShader; RefPtr mCurrentInputLayout; RefPtr mCurrentPixelShader; RefPtr mCurrentBlendState; RefPtr mWaitForPresentQuery; RefPtr mNextWaitForPresentQuery; nsTHashtable> mLockedTextures; nsTHashtable> mLockAttemptedTextures; typedef EnumeratedArray LazyPixelShaderArray; LazyPixelShaderArray mLazyPixelShaders; typedef EnumeratedArray LazyVertexShaderArray; LazyVertexShaderArray mLazyVertexShaders; bool mScissored; }; } // namespace layers } // namespace mozilla struct ShaderBytes; #endif // mozilla_gfx_layers_d3d11_MLGDeviceD3D11_h