summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d11/TextureD3D11.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/d3d11/TextureD3D11.h')
-rw-r--r--gfx/layers/d3d11/TextureD3D11.h455
1 files changed, 455 insertions, 0 deletions
diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h
new file mode 100644
index 000000000..831342aa2
--- /dev/null
+++ b/gfx/layers/d3d11/TextureD3D11.h
@@ -0,0 +1,455 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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_TEXTURED3D11_H
+#define MOZILLA_GFX_TEXTURED3D11_H
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/layers/Compositor.h"
+#include "mozilla/layers/TextureClient.h"
+#include "mozilla/layers/TextureHost.h"
+#include "gfxWindowsPlatform.h"
+#include "mozilla/GfxMessageUtils.h"
+#include <d3d11.h>
+#include "d3d9.h"
+#include <vector>
+
+namespace mozilla {
+namespace layers {
+
+class MOZ_RAII AutoTextureLock
+{
+public:
+ AutoTextureLock(IDXGIKeyedMutex* aMutex, HRESULT& aResult,
+ uint32_t aTimeout = 0);
+ ~AutoTextureLock();
+
+private:
+ RefPtr<IDXGIKeyedMutex> mMutex;
+ HRESULT mResult;
+};
+
+class CompositorD3D11;
+
+class DXGITextureData : public TextureData
+{
+public:
+ virtual void FillInfo(TextureData::Info& aInfo) const override;
+
+ virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
+
+ static DXGITextureData*
+ Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
+
+protected:
+ bool PrepareDrawTargetInLock(OpenMode aMode);
+
+ DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ bool aNeedsClear, bool aNeedsClearWhite,
+ bool aIsForOutOfBandContent);
+
+ virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
+
+ // Hold on to the DrawTarget because it is expensive to create one each ::Lock.
+ RefPtr<gfx::DrawTarget> mDrawTarget;
+ gfx::IntSize mSize;
+ gfx::SurfaceFormat mFormat;
+ bool mNeedsClear;
+ bool mNeedsClearWhite;
+ bool mHasSynchronization;
+ bool mIsForOutOfBandContent;
+};
+
+class D3D11TextureData : public DXGITextureData
+{
+public:
+ // If aDevice is null, use one provided by gfxWindowsPlatform.
+ static DXGITextureData*
+ Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ TextureAllocationFlags aAllocFlags,
+ ID3D11Device* aDevice = nullptr);
+ static DXGITextureData*
+ Create(gfx::SourceSurface* aSurface,
+ TextureAllocationFlags aAllocFlags,
+ ID3D11Device* aDevice = nullptr);
+
+ virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+
+ virtual bool Lock(OpenMode aMode) override;
+
+ virtual void Unlock() override;
+
+ virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
+
+ virtual TextureData*
+ CreateSimilar(LayersIPCChannel* aAllocator,
+ LayersBackend aLayersBackend,
+ TextureFlags aFlags,
+ TextureAllocationFlags aAllocFlags) const override;
+
+ virtual void SyncWithObject(SyncObject* aSync) override;
+
+ ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
+
+ virtual void Deallocate(LayersIPCChannel* aAllocator) override;
+
+ D3D11TextureData* AsD3D11TextureData() override {
+ return this;
+ }
+
+ ~D3D11TextureData();
+protected:
+ D3D11TextureData(ID3D11Texture2D* aTexture,
+ gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ bool aNeedsClear, bool aNeedsClearWhite,
+ bool aIsForOutOfBandContent);
+
+ virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
+
+ static DXGITextureData*
+ Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ gfx::SourceSurface* aSurface,
+ TextureAllocationFlags aAllocFlags,
+ ID3D11Device* aDevice = nullptr);
+
+ RefPtr<ID3D11Texture2D> mTexture;
+};
+
+already_AddRefed<TextureClient>
+CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
+ ID3D11Device* aDevice,
+ LayersIPCChannel* aAllocator);
+
+class DXGIYCbCrTextureData : public TextureData
+{
+public:
+ static DXGIYCbCrTextureData*
+ Create(TextureFlags aFlags,
+ IUnknown* aTextureY,
+ IUnknown* aTextureCb,
+ IUnknown* aTextureCr,
+ HANDLE aHandleY,
+ HANDLE aHandleCb,
+ HANDLE aHandleCr,
+ const gfx::IntSize& aSize,
+ const gfx::IntSize& aSizeY,
+ const gfx::IntSize& aSizeCbCr);
+
+ static DXGIYCbCrTextureData*
+ Create(TextureFlags aFlags,
+ ID3D11Texture2D* aTextureCb,
+ ID3D11Texture2D* aTextureY,
+ ID3D11Texture2D* aTextureCr,
+ const gfx::IntSize& aSize,
+ const gfx::IntSize& aSizeY,
+ const gfx::IntSize& aSizeCbCr);
+
+ virtual bool Lock(OpenMode) override { return true; }
+
+ virtual void Unlock() override {}
+
+ virtual void FillInfo(TextureData::Info& aInfo) const override;
+
+ virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+
+ virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override { return nullptr; }
+
+ virtual void Deallocate(LayersIPCChannel* aAllocator) override;
+
+ virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
+
+ virtual TextureFlags GetTextureFlags() const override
+ {
+ return TextureFlags::DEALLOCATE_MAIN_THREAD;
+ }
+
+protected:
+ RefPtr<IUnknown> mHoldRefs[3];
+ HANDLE mHandles[3];
+ gfx::IntSize mSize;
+ gfx::IntSize mSizeY;
+ gfx::IntSize mSizeCbCr;
+};
+
+/**
+ * TextureSource that provides with the necessary APIs to be composited by a
+ * CompositorD3D11.
+ */
+class TextureSourceD3D11
+{
+public:
+ TextureSourceD3D11() : mFormatOverride(DXGI_FORMAT_UNKNOWN) {}
+ virtual ~TextureSourceD3D11() {}
+
+ virtual ID3D11Texture2D* GetD3D11Texture() const { return mTexture; }
+ virtual ID3D11ShaderResourceView* GetShaderResourceView();
+protected:
+ virtual gfx::IntSize GetSize() const { return mSize; }
+
+ gfx::IntSize mSize;
+ RefPtr<ID3D11Texture2D> mTexture;
+ RefPtr<ID3D11ShaderResourceView> mSRV;
+ DXGI_FORMAT mFormatOverride;
+};
+
+/**
+ * A TextureSource that implements the DataTextureSource interface.
+ * it can be used without a TextureHost and is able to upload texture data
+ * from a gfx::DataSourceSurface.
+ */
+class DataTextureSourceD3D11 : public DataTextureSource
+ , public TextureSourceD3D11
+ , public BigImageIterator
+{
+public:
+ /// Constructor allowing the texture to perform texture uploads.
+ ///
+ /// The texture can be used as an actual DataTextureSource.
+ DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
+ TextureFlags aFlags);
+
+ /// Constructor for textures created around DXGI shared handles, disallowing
+ /// texture uploads.
+ ///
+ /// The texture CANNOT be used as a DataTextureSource.
+ DataTextureSourceD3D11(gfx::SurfaceFormat aFormat, CompositorD3D11* aCompositor,
+ ID3D11Texture2D* aTexture);
+
+ virtual ~DataTextureSourceD3D11();
+
+ virtual const char* Name() const override { return "DataTextureSourceD3D11"; }
+
+ // DataTextureSource
+
+ virtual bool Update(gfx::DataSourceSurface* aSurface,
+ nsIntRegion* aDestRegion = nullptr,
+ gfx::IntPoint* aSrcOffset = nullptr) override;
+
+ // TextureSource
+
+ virtual TextureSourceD3D11* AsSourceD3D11() override { return this; }
+
+ virtual ID3D11Texture2D* GetD3D11Texture() const override;
+
+ virtual ID3D11ShaderResourceView* GetShaderResourceView() override;
+
+ // Returns nullptr if this texture was created by a DXGI TextureHost.
+ virtual DataTextureSource* AsDataTextureSource() override { return mAllowTextureUploads ? this : false; }
+
+ virtual void DeallocateDeviceData() override { mTexture = nullptr; }
+
+ virtual gfx::IntSize GetSize() const override { return mSize; }
+
+ virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
+
+ virtual void SetCompositor(Compositor* aCompositor) override;
+
+ // BigImageIterator
+
+ virtual BigImageIterator* AsBigImageIterator() override { return mIsTiled ? this : nullptr; }
+
+ virtual size_t GetTileCount() override { return mTileTextures.size(); }
+
+ virtual bool NextTile() override { return (++mCurrentTile < mTileTextures.size()); }
+
+ virtual gfx::IntRect GetTileRect() override;
+
+ virtual void EndBigImageIteration() override { mIterating = false; }
+
+ virtual void BeginBigImageIteration() override
+ {
+ mIterating = true;
+ mCurrentTile = 0;
+ }
+
+protected:
+ gfx::IntRect GetTileRect(uint32_t aIndex) const;
+
+ void Reset();
+
+ std::vector< RefPtr<ID3D11Texture2D> > mTileTextures;
+ std::vector< RefPtr<ID3D11ShaderResourceView> > mTileSRVs;
+ RefPtr<CompositorD3D11> mCompositor;
+ gfx::SurfaceFormat mFormat;
+ TextureFlags mFlags;
+ uint32_t mCurrentTile;
+ bool mIsTiled;
+ bool mIterating;
+ // Sadly, the code was originally organized so that this class is used both in
+ // the cases where we want to perform texture uploads through the DataTextureSource
+ // interface, and the cases where we wrap the texture around an existing DXGI
+ // handle in which case we should not use it as a DataTextureSource.
+ // This member differentiates the two scenarios. When it is false the texture
+ // "pretends" to not be a DataTextureSource.
+ bool mAllowTextureUploads;
+};
+
+already_AddRefed<TextureClient>
+CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
+ ID3D11Device* aDevice,
+ LayersIPCChannel* aAllocator);
+
+
+/**
+ * A TextureHost for shared D3D11 textures.
+ */
+class DXGITextureHostD3D11 : public TextureHost
+{
+public:
+ DXGITextureHostD3D11(TextureFlags aFlags,
+ const SurfaceDescriptorD3D10& aDescriptor);
+
+ virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
+
+ virtual void DeallocateDeviceData() override {}
+
+ virtual void SetCompositor(Compositor* aCompositor) override;
+
+ virtual Compositor* GetCompositor() override;
+
+ virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
+
+ virtual bool Lock() override;
+ virtual void Unlock() override;
+
+ virtual bool LockWithoutCompositor() override;
+ virtual void UnlockWithoutCompositor() override;
+
+ virtual gfx::IntSize GetSize() const override { return mSize; }
+
+ virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
+ {
+ return nullptr;
+ }
+
+protected:
+ bool LockInternal();
+ void UnlockInternal();
+
+ RefPtr<ID3D11Device> GetDevice();
+
+ bool OpenSharedHandle();
+
+ RefPtr<ID3D11Texture2D> mTexture;
+ RefPtr<DataTextureSourceD3D11> mTextureSource;
+ RefPtr<CompositorD3D11> mCompositor;
+ gfx::IntSize mSize;
+ WindowsHandle mHandle;
+ gfx::SurfaceFormat mFormat;
+ bool mIsLocked;
+};
+
+class DXGIYCbCrTextureHostD3D11 : public TextureHost
+{
+public:
+ DXGIYCbCrTextureHostD3D11(TextureFlags aFlags,
+ const SurfaceDescriptorDXGIYCbCr& aDescriptor);
+
+ virtual bool BindTextureSource(CompositableTextureSourceRef& aTexture) override;
+
+ virtual void DeallocateDeviceData() override{}
+
+ virtual void SetCompositor(Compositor* aCompositor) override;
+
+ virtual Compositor* GetCompositor() override;
+
+ virtual gfx::SurfaceFormat GetFormat() const override{ return gfx::SurfaceFormat::YUV; }
+
+ // Bug 1305906 fixes YUVColorSpace handling
+ virtual YUVColorSpace GetYUVColorSpace() const override { return YUVColorSpace::BT601; }
+
+ virtual bool Lock() override;
+
+ virtual void Unlock() override;
+
+ virtual gfx::IntSize GetSize() const override { return mSize; }
+
+ virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
+ {
+ return nullptr;
+ }
+
+protected:
+ RefPtr<ID3D11Device> GetDevice();
+
+ bool OpenSharedHandle();
+
+ RefPtr<ID3D11Texture2D> mTextures[3];
+ RefPtr<DataTextureSourceD3D11> mTextureSources[3];
+
+ RefPtr<CompositorD3D11> mCompositor;
+ gfx::IntSize mSize;
+ WindowsHandle mHandles[3];
+ bool mIsLocked;
+};
+
+class CompositingRenderTargetD3D11 : public CompositingRenderTarget,
+ public TextureSourceD3D11
+{
+public:
+ CompositingRenderTargetD3D11(ID3D11Texture2D* aTexture,
+ const gfx::IntPoint& aOrigin,
+ DXGI_FORMAT aFormatOverride = DXGI_FORMAT_UNKNOWN);
+
+ virtual const char* Name() const override { return "CompositingRenderTargetD3D11"; }
+
+ virtual TextureSourceD3D11* AsSourceD3D11() override { return this; }
+
+ void BindRenderTarget(ID3D11DeviceContext* aContext);
+
+ virtual gfx::IntSize GetSize() const override;
+
+ void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
+
+private:
+ friend class CompositorD3D11;
+ RefPtr<ID3D11RenderTargetView> mRTView;
+};
+
+class SyncObjectD3D11 : public SyncObject
+{
+public:
+ SyncObjectD3D11(SyncHandle aSyncHandle);
+ virtual void FinalizeFrame();
+ virtual bool IsSyncObjectValid();
+
+ virtual SyncType GetSyncType() { return SyncType::D3D11; }
+
+ void RegisterTexture(ID3D11Texture2D* aTexture);
+
+private:
+ RefPtr<ID3D11Texture2D> mD3D11Texture;
+ RefPtr<ID3D11Device> mD3D11Device;
+ std::vector<ID3D11Texture2D*> mD3D11SyncedTextures;
+ SyncHandle mHandle;
+};
+
+inline uint32_t GetMaxTextureSizeForFeatureLevel(D3D_FEATURE_LEVEL aFeatureLevel)
+{
+ int32_t maxTextureSize;
+ switch (aFeatureLevel) {
+ case D3D_FEATURE_LEVEL_11_1:
+ case D3D_FEATURE_LEVEL_11_0:
+ maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ break;
+ case D3D_FEATURE_LEVEL_10_1:
+ case D3D_FEATURE_LEVEL_10_0:
+ maxTextureSize = D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ break;
+ case D3D_FEATURE_LEVEL_9_3:
+ maxTextureSize = D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ break;
+ default:
+ maxTextureSize = D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION;
+ }
+ return maxTextureSize;
+}
+
+}
+}
+
+#endif /* MOZILLA_GFX_TEXTURED3D11_H */