summaryrefslogtreecommitdiffstats
path: root/gfx/layers/d3d9/TextureD3D9.h
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/layers/d3d9/TextureD3D9.h')
-rw-r--r--gfx/layers/d3d9/TextureD3D9.h433
1 files changed, 433 insertions, 0 deletions
diff --git a/gfx/layers/d3d9/TextureD3D9.h b/gfx/layers/d3d9/TextureD3D9.h
new file mode 100644
index 000000000..67d7a13a6
--- /dev/null
+++ b/gfx/layers/d3d9/TextureD3D9.h
@@ -0,0 +1,433 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * 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_TEXTURED3D9_H
+#define MOZILLA_GFX_TEXTURED3D9_H
+
+#include "mozilla/layers/Compositor.h"
+#include "mozilla/layers/TextureClient.h"
+#include "mozilla/layers/TextureHost.h"
+#include "mozilla/GfxMessageUtils.h"
+#include "mozilla/gfx/2D.h"
+#include "gfxWindowsPlatform.h"
+#include "d3d9.h"
+#include <vector>
+#include "DeviceManagerD3D9.h"
+
+namespace mozilla {
+namespace layers {
+
+class CompositorD3D9;
+
+class TextureSourceD3D9
+{
+ friend class DeviceManagerD3D9;
+
+public:
+ TextureSourceD3D9()
+ : mPreviousHost(nullptr)
+ , mNextHost(nullptr)
+ , mCreatingDeviceManager(nullptr)
+ {}
+ virtual ~TextureSourceD3D9();
+
+ virtual IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
+
+ StereoMode GetStereoMode() const { return mStereoMode; };
+
+ // Release all texture memory resources held by the texture host.
+ virtual void ReleaseTextureResources()
+ {
+ mTexture = nullptr;
+ }
+
+protected:
+ virtual gfx::IntSize GetSize() const { return mSize; }
+ void SetSize(const gfx::IntSize& aSize) { mSize = aSize; }
+
+ // Helper methods for creating and copying textures.
+ already_AddRefed<IDirect3DTexture9> InitTextures(
+ DeviceManagerD3D9* aDeviceManager,
+ const gfx::IntSize &aSize,
+ _D3DFORMAT aFormat,
+ RefPtr<IDirect3DSurface9>& aSurface,
+ D3DLOCKED_RECT& aLockedRect);
+
+ already_AddRefed<IDirect3DTexture9> DataToTexture(
+ DeviceManagerD3D9* aDeviceManager,
+ unsigned char *aData,
+ int aStride,
+ const gfx::IntSize &aSize,
+ _D3DFORMAT aFormat,
+ uint32_t aBPP);
+
+ // aTexture should be in SYSTEMMEM, returns a texture in the default
+ // pool (that is, in video memory).
+ already_AddRefed<IDirect3DTexture9> TextureToTexture(
+ DeviceManagerD3D9* aDeviceManager,
+ IDirect3DTexture9* aTexture,
+ const gfx::IntSize& aSize,
+ _D3DFORMAT aFormat);
+
+ gfx::IntSize mSize;
+
+ // Linked list of all objects holding d3d9 textures.
+ TextureSourceD3D9* mPreviousHost;
+ TextureSourceD3D9* mNextHost;
+ // The device manager that created our textures.
+ RefPtr<DeviceManagerD3D9> mCreatingDeviceManager;
+
+ StereoMode mStereoMode;
+ RefPtr<IDirect3DTexture9> mTexture;
+};
+
+/**
+ * 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 DataTextureSourceD3D9 : public DataTextureSource
+ , public TextureSourceD3D9
+ , public BigImageIterator
+{
+public:
+ /// Constructor allowing the texture to perform texture uploads.
+ ///
+ /// The texture can be used as an actual DataTextureSource.
+ DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
+ CompositorD3D9* aCompositor,
+ TextureFlags aFlags = TextureFlags::DEFAULT,
+ StereoMode aStereoMode = StereoMode::MONO);
+
+ /// Constructor for textures created around DXGI shared handles, disallowing
+ /// texture uploads.
+ ///
+ /// The texture CANNOT be used as a DataTextureSource.
+ DataTextureSourceD3D9(gfx::SurfaceFormat aFormat,
+ gfx::IntSize aSize,
+ CompositorD3D9* aCompositor,
+ IDirect3DTexture9* aTexture,
+ TextureFlags aFlags = TextureFlags::DEFAULT);
+
+ virtual ~DataTextureSourceD3D9();
+
+ virtual const char* Name() const override { return "DataTextureSourceD3D9"; }
+
+ // DataTextureSource
+
+ virtual bool Update(gfx::DataSourceSurface* aSurface,
+ nsIntRegion* aDestRegion = nullptr,
+ gfx::IntPoint* aSrcOffset = nullptr) override;
+
+ // TextureSource
+
+ virtual TextureSourceD3D9* AsSourceD3D9() override { return this; }
+
+ virtual IDirect3DTexture9* GetD3D9Texture() override;
+
+ // Returns nullptr if this texture was created by a DXGI TextureHost.
+ virtual DataTextureSource* AsDataTextureSource() override { return mAllowTextureUploads ? this : nullptr; }
+
+ 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;
+ }
+
+ /**
+ * Copy the content of aTexture using the GPU.
+ */
+ bool UpdateFromTexture(IDirect3DTexture9* aTexture, const nsIntRegion* aRegion);
+
+protected:
+ gfx::IntRect GetTileRect(uint32_t aTileIndex) const;
+
+ void Reset();
+
+ std::vector< RefPtr<IDirect3DTexture9> > mTileTextures;
+ RefPtr<CompositorD3D9> mCompositor;
+ gfx::SurfaceFormat mFormat;
+ uint32_t mCurrentTile;
+ TextureFlags mFlags;
+ bool mIsTiled;
+ bool mIterating;
+ bool mAllowTextureUploads;
+};
+
+/**
+ * Needs a D3D9 context on the client side.
+ * The corresponding TextureHost is TextureHostD3D9.
+ */
+class D3D9TextureData : public TextureData
+{
+public:
+ ~D3D9TextureData();
+
+ virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
+
+ virtual bool Lock(OpenMode aMode) override;
+
+ virtual void Unlock() override;
+
+ virtual void FillInfo(TextureData::Info& aInfo) const override;
+
+ virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
+
+ virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
+
+ virtual TextureData*
+ CreateSimilar(LayersIPCChannel* aAllocator,
+ LayersBackend aLayersBackend,
+ TextureFlags aFlags,
+ TextureAllocationFlags aAllocFlags) const override;
+
+ static D3D9TextureData*
+ Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
+
+ virtual void Deallocate(LayersIPCChannel* aAllocator) override {}
+
+protected:
+ D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
+ IDirect3DTexture9* aTexture);
+
+ RefPtr<IDirect3DTexture9> mTexture;
+ RefPtr<IDirect3DSurface9> mD3D9Surface;
+ gfx::IntSize mSize;
+ gfx::SurfaceFormat mFormat;
+ bool mNeedsClear;
+ bool mNeedsClearWhite;
+ bool mLockRect;
+};
+
+/**
+ * Wraps a D3D9 texture, shared with the compositor though DXGI.
+ * At the moment it is only used with D3D11 compositing, and the corresponding
+ * TextureHost is DXGITextureHostD3D11.
+ */
+class DXGID3D9TextureData : public TextureData
+{
+public:
+ static DXGID3D9TextureData*
+ Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureFlags aFlags, IDirect3DDevice9* aDevice);
+
+ ~DXGID3D9TextureData();
+
+ virtual void FillInfo(TextureData::Info& aInfo) const override;
+
+ virtual bool Lock(OpenMode) override { return true; }
+
+ virtual void Unlock() override {}
+
+ virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
+
+ virtual void Deallocate(LayersIPCChannel* aAllocator) override {}
+
+ IDirect3DDevice9* GetD3D9Device() { return mDevice; }
+ IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
+ HANDLE GetShareHandle() const { return mHandle; }
+ already_AddRefed<IDirect3DSurface9> GetD3D9Surface() const;
+
+ const D3DSURFACE_DESC& GetDesc() const
+ {
+ return mDesc;
+ }
+
+ gfx::IntSize GetSize() const { return gfx::IntSize(mDesc.Width, mDesc.Height); }
+
+protected:
+ DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
+ IDirect3DTexture9* aTexture, HANDLE aHandle,
+ IDirect3DDevice9* aDevice);
+
+ RefPtr<IDirect3DDevice9> mDevice;
+ RefPtr<IDirect3DTexture9> mTexture;
+ gfx::SurfaceFormat mFormat;
+ HANDLE mHandle;
+ D3DSURFACE_DESC mDesc;
+};
+
+class TextureHostD3D9 : public TextureHost
+{
+public:
+ TextureHostD3D9(TextureFlags aFlags,
+ const SurfaceDescriptorD3D9& 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 gfx::IntSize GetSize() const override { return mSize; }
+
+ virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
+ {
+ return nullptr;
+ }
+
+ virtual bool HasIntermediateBuffer() const override { return true; }
+
+protected:
+ TextureHostD3D9(TextureFlags aFlags);
+ IDirect3DDevice9* GetDevice();
+
+ virtual void UpdatedInternal(const nsIntRegion* aRegion) override;
+
+ RefPtr<DataTextureSourceD3D9> mTextureSource;
+ RefPtr<IDirect3DTexture9> mTexture;
+ RefPtr<CompositorD3D9> mCompositor;
+ gfx::IntSize mSize;
+ gfx::SurfaceFormat mFormat;
+ bool mIsLocked;
+};
+
+class DXGITextureHostD3D9 : public TextureHost
+{
+public:
+ DXGITextureHostD3D9(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 gfx::IntSize GetSize() const override { return mSize; }
+
+ virtual bool Lock() override;
+
+ virtual void Unlock() override;
+
+ virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
+ {
+ return nullptr; // TODO: cf bug 872568
+ }
+
+protected:
+ void OpenSharedHandle();
+ IDirect3DDevice9* GetDevice();
+
+ RefPtr<DataTextureSourceD3D9> mTextureSource;
+ RefPtr<CompositorD3D9> mCompositor;
+ WindowsHandle mHandle;
+ gfx::SurfaceFormat mFormat;
+ gfx::IntSize mSize;
+ bool mIsLocked;
+};
+
+class DXGIYCbCrTextureHostD3D9 : public TextureHost
+{
+public:
+ DXGIYCbCrTextureHostD3D9(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:
+ IDirect3DDevice9* GetDevice();
+
+ HANDLE mHandles[3];
+ RefPtr<IDirect3DTexture9> mTextures[3];
+ RefPtr<DataTextureSourceD3D9> mTextureSources[3];
+
+ RefPtr<CompositorD3D9> mCompositor;
+ gfx::IntSize mSize;
+ gfx::IntSize mSizeY;
+ gfx::IntSize mSizeCbCr;
+ bool mIsLocked;
+ };
+
+class CompositingRenderTargetD3D9 : public CompositingRenderTarget,
+ public TextureSourceD3D9
+{
+public:
+ CompositingRenderTargetD3D9(IDirect3DTexture9* aTexture,
+ SurfaceInitMode aInit,
+ const gfx::IntRect& aRect);
+ // use for rendering to the main window, cannot be rendered as a texture
+ CompositingRenderTargetD3D9(IDirect3DSurface9* aSurface,
+ SurfaceInitMode aInit,
+ const gfx::IntRect& aRect);
+ virtual ~CompositingRenderTargetD3D9();
+
+ virtual const char* Name() const override { return "CompositingRenderTargetD3D9"; }
+
+ virtual TextureSourceD3D9* AsSourceD3D9() override
+ {
+ MOZ_ASSERT(mTexture,
+ "No texture, can't be indirectly rendered. Is this the screen backbuffer?");
+ return this;
+ }
+
+ virtual gfx::IntSize GetSize() const override;
+
+ void BindRenderTarget(IDirect3DDevice9* aDevice);
+
+ IDirect3DSurface9* GetD3D9Surface() const { return mSurface; }
+
+private:
+ friend class CompositorD3D9;
+
+ RefPtr<IDirect3DSurface9> mSurface;
+ SurfaceInitMode mInitMode;
+};
+
+}
+}
+
+#endif /* MOZILLA_GFX_TEXTURED3D9_H */