Bug 1200595 - D3D11 TextureData implementation. r=Bas

This commit is contained in:
Nicolas Silva 2015-10-15 17:53:37 +02:00
Родитель 94c7acf9ef
Коммит 943fe8686e
9 изменённых файлов: 796 добавлений и 710 удалений

Просмотреть файл

@ -129,7 +129,7 @@ D3D11ShareHandleImage::GetAsSourceSurface()
ID3D11Texture2D*
D3D11ShareHandleImage::GetTexture() const {
return mTextureClient->GetD3D11Texture();
return static_cast<D3D11TextureData*>(mTextureClient->GetInternalData())->GetD3D11Texture();
}
already_AddRefed<TextureClient>
@ -139,14 +139,12 @@ D3D11RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags,
TextureAllocationFlags aAllocFlags)
{
return TextureClientD3D11::Create(mSurfaceAllocator,
aFormat,
TextureFlags::DEFAULT,
mDevice,
aSize);
return CreateD3D11TextureClientWithDevice(aSize, aFormat,
aTextureFlags, aAllocFlags,
mDevice, mSurfaceAllocator);
}
already_AddRefed<TextureClientD3D11>
already_AddRefed<TextureClient>
D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
const gfx::IntSize& aSize)
{
@ -155,12 +153,7 @@ D3D11RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
aSize,
BackendSelector::Content,
layers::TextureFlags::DEFAULT);
if (!textureClient) {
return nullptr;
}
RefPtr<TextureClientD3D11> textureD3D11 = static_cast<TextureClientD3D11*>(textureClient.get());
return textureD3D11.forget();
return textureClient.forget();
}

Просмотреть файл

@ -26,7 +26,7 @@ public:
, mDevice(aDevice)
{}
already_AddRefed<TextureClientD3D11>
already_AddRefed<TextureClient>
CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
const gfx::IntSize& aSize);
@ -63,7 +63,7 @@ public:
private:
gfx::IntSize mSize;
gfx::IntRect mPictureRect;
RefPtr<TextureClientD3D11> mTextureClient;
RefPtr<TextureClient> mTextureClient;
};
} // namepace layers

Просмотреть файл

@ -204,17 +204,15 @@ IMFYCbCrImage::GetD3D9TextureClient(CompositableClient* aClient)
return nullptr;
}
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
TextureFlags::DEFAULT,
textureY,
textureCb,
textureCr,
shareHandleY,
shareHandleCb,
shareHandleCr,
GetSize(),
mData.mYSize,
mData.mCbCrSize);
mTextureClient = TextureClient::CreateWithData(
DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
TextureFlags::DEFAULT,
textureY, textureCb, textureCr,
shareHandleY, shareHandleCb, shareHandleCr,
GetSize(), mData.mYSize, mData.mCbCrSize),
TextureFlags::DEFAULT,
aClient->GetForwarder()
);
return mTextureClient;
}
@ -273,14 +271,14 @@ IMFYCbCrImage::GetTextureClient(CompositableClient* aClient)
mData.mCbCrStride, mData.mCbCrStride * mData.mCbCrSize.height);
}
mTextureClient = DXGIYCbCrTextureClient::Create(aClient->GetForwarder(),
TextureFlags::DEFAULT,
textureY,
textureCb,
textureCr,
GetSize(),
mData.mYSize,
mData.mCbCrSize);
mTextureClient = TextureClient::CreateWithData(
DXGIYCbCrTextureData::Create(aClient->GetForwarder(),
TextureFlags::DEFAULT,
textureY, textureCb, textureCr,
GetSize(), mData.mYSize, mData.mCbCrSize),
TextureFlags::DEFAULT,
aClient->GetForwarder()
);
return mTextureClient;
}

Просмотреть файл

@ -13,6 +13,7 @@
#include "nsDebug.h" // for NS_ERROR
#include "nsPoint.h" // for nsIntPoint
#include "nsRect.h" // for mozilla::gfx::IntRect
#include "base/basictypes.h"
using namespace mozilla::gfx;

Просмотреть файл

@ -231,7 +231,9 @@ ClientTexture::Unlock()
MOZ_ASSERT(mBorrowedDrawTarget->refCount() <= mExpectedDtRefs);
if (mOpenMode & OpenMode::OPEN_WRITE) {
mBorrowedDrawTarget->Flush();
if (mReadbackSink) {
if (mReadbackSink && !mData->ReadBack(mReadbackSink)) {
// Fallback implementation for reading back, because mData does not
// have a backend-specific implementation and returned false.
RefPtr<SourceSurface> snapshot = mBorrowedDrawTarget->Snapshot();
RefPtr<DataSourceSurface> dataSurf = snapshot->GetDataSurface();
mReadbackSink->ProcessReadback(dataSurf);
@ -268,10 +270,6 @@ ClientTexture::GetFormat() const
ClientTexture::~ClientTexture()
{
// All the destruction code that may lead to virtual method calls must
// be in Finalize() which is called just before the destructor.
// TODO[nical] temporarily integrate this with FinalizeOnIPDLThred
if (ShouldDeallocateInDestructor()) {
mData->Deallocate(mAllocator);
} else {
@ -280,6 +278,12 @@ ClientTexture::~ClientTexture()
delete mData;
}
void
ClientTexture::FinalizeOnIPDLThread()
{
mData->FinalizeOnIPDLThread(this);
}
void
ClientTexture::UpdateFromSurface(gfx::SourceSurface* aSurface)
{
@ -336,6 +340,10 @@ ClientTexture::BorrowDrawTarget()
return nullptr;
}
if (!NS_IsMainThread()) {
return nullptr;
}
if (!mBorrowedDrawTarget) {
mBorrowedDrawTarget = mData->BorrowDrawTarget();
#ifdef DEBUG
@ -562,7 +570,10 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
aSize.width <= maxTextureSize &&
aSize.height <= maxTextureSize)
{
texture = new TextureClientD3D11(aAllocator, aFormat, aTextureFlags);
texture = CreateDXGITextureClient(aSize, aFormat, aTextureFlags, aAllocFlags, aAllocator);
if (texture) {
return texture.forget();
}
}
if (parentBackend == LayersBackend::LAYERS_D3D9 &&
moz2DBackend == gfx::BackendType::CAIRO &&
@ -921,6 +932,15 @@ SyncObject::CreateSyncObject(SyncHandle aHandle)
#endif
}
already_AddRefed<TextureClient>
TextureClient::CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator)
{
if (!aData) {
return nullptr;
}
return MakeAndAddRef<ClientTexture>(aData, aFlags, aAllocator);
}
bool
MappedYCbCrChannelData::CopyInto(MappedYCbCrChannelData& aDst)
{

Просмотреть файл

@ -195,6 +195,9 @@ public:
TextureFlags aFlags = TextureFlags::DEFAULT);
virtual ~TextureClient();
static already_AddRefed<TextureClient>
CreateWithData(TextureData* aData, TextureFlags aFlags, ISurfaceAllocator* aAllocator);
// Creates and allocates a TextureClient usable with Moz2D.
static already_AddRefed<TextureClient>
CreateForDrawing(CompositableForwarder* aAllocator,
@ -639,9 +642,16 @@ public:
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) { return false; };
virtual bool ReadBack(TextureReadbackSink* aReadbackSink) { return false; }
/// Ideally this should not be exposed and users of TextureClient would use Lock/Unlock
/// preoperly but that requires a few changes to SharedSurface and maybe gonk video.
virtual void WaitForFence(FenceHandle* aFence) {};
virtual void SyncWithObject(SyncObject* aFence) {};
/// Needed until the destruction sequence of TextureClient is revamped.
virtual void FinalizeOnIPDLThread(TextureClient*) {}
};
/// temporary class that will be merged back into TextureClient when all texture implementations
@ -687,11 +697,16 @@ public:
// TODO - we should be able to make this implicit and not expose the method.
virtual void WaitForBufferOwnership(bool aWaitReleaseFence = true) override;
virtual void SyncWithObject(SyncObject* aFence) override { mData->SyncWithObject(aFence); }
// by construction, ClientTexture cannot be created without successful allocation.
virtual bool IsAllocated() const override { return true; }
/// If you add new code that uses this method, you are probably doing something wrong.
virtual TextureData* GetInternalData() override { return mData; }
virtual void FinalizeOnIPDLThread() override;
protected:
TextureData* mData;
RefPtr<gfx::DrawTarget> mBorrowedDrawTarget;

Просмотреть файл

@ -5,7 +5,7 @@
#include "TextureClientPool.h"
#include "CompositableClient.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "gfxPrefs.h"

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -6,6 +6,7 @@
#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"
@ -20,101 +21,142 @@ namespace layers {
class CompositorD3D11;
/**
* A TextureClient to share a D3D10 texture with the compositor thread.
* The corresponding TextureHost is DXGITextureHostD3D11
*/
class TextureClientD3D11 : public TextureClient
class DXGITextureData : public TextureData
{
public:
TextureClientD3D11(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags);
virtual ~TextureClientD3D11();
// Creates a TextureClient and init width.
static already_AddRefed<TextureClientD3D11>
Create(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags,
ID3D11Texture2D* aTexture,
gfx::IntSize aSize);
static already_AddRefed<TextureClientD3D11>
Create(ISurfaceAllocator* aAllocator,
gfx::SurfaceFormat aFormat,
TextureFlags aFlags,
ID3D11Device* aDevice,
const gfx::IntSize& aSize);
// TextureClient
virtual bool IsAllocated() const override { return mTexture || mTexture10; }
virtual bool Lock(OpenMode aOpenMode) override;
virtual void Unlock() override;
virtual bool IsLocked() const override { return mIsLocked; }
virtual bool ImplementsLocking() const override { return true; }
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
virtual bool SupportsMoz2D() const override { return true; }
virtual bool HasInternalBuffer() const override { return false; }
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
virtual bool HasSynchronization() const override { return mHasSynchronization; }
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
static DXGITextureData*
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
virtual bool CanExposeDrawTarget() const override { return true; }
protected:
bool PrepareDrawTargetInLock(OpenMode aMode);
virtual gfx::DrawTarget* BorrowDrawTarget() override;
DXGITextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, bool aNeedsClear, bool aNeedsClearWhite);
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
virtual void GetDXGIResource(IDXGIResource** aOutResource) = 0;
virtual bool AllocateForSurface(gfx::IntSize aSize,
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
// 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;
};
virtual already_AddRefed<TextureClient>
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
already_AddRefed<TextureClient>
CreateDXGITextureClient(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags atextureFlags, TextureAllocationFlags aFlags,
ISurfaceAllocator* aAllocator);
virtual void SyncWithObject(SyncObject* aSyncObject) override;
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);
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
virtual void Unlock() override;
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const override;
// TODO - merge this with the FenceHandle API!
virtual void SyncWithObject(SyncObject* aSync) override;
ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
~D3D11TextureData();
protected:
bool AllocateD3D11Surface(ID3D11Device* aDevice, const gfx::IntSize& aSize);
D3D11TextureData(ID3D11Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite);
virtual void FinalizeOnIPDLThread() override;
virtual void FinalizeOnIPDLThread(TextureClient* aWrapper) override;
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
gfx::IntSize mSize;
RefPtr<ID3D10Texture2D> mTexture10;
RefPtr<ID3D11Texture2D> mTexture;
RefPtr<gfx::DrawTarget> mDrawTarget;
gfx::SurfaceFormat mFormat;
bool mIsLocked;
bool mNeedsClear;
bool mNeedsClearWhite;
};
class DXGIYCbCrTextureClient : public TextureClient
already_AddRefed<TextureClient>
CreateD3D11extureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
ID3D11Device* aDevice,
ISurfaceAllocator* aAllocator);
class D3D10TextureData : public DXGITextureData
{
public:
DXGIYCbCrTextureClient(ISurfaceAllocator* aAllocator,
TextureFlags aFlags);
static DXGITextureData*
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
virtual ~DXGIYCbCrTextureClient();
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
// Creates a TextureClient and init width.
static already_AddRefed<DXGIYCbCrTextureClient>
virtual void Unlock() override;
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
virtual TextureData*
CreateSimilar(ISurfaceAllocator* aAllocator,
TextureFlags aFlags,
TextureAllocationFlags aAllocFlags) const override;
// TODO - merge this with the FenceHandle API!
virtual void SyncWithObject(SyncObject* aSync) override;
virtual bool ReadBack(TextureReadbackSink* aReadbackSinc) override;
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
~D3D10TextureData();
protected:
D3D10TextureData(ID3D10Texture2D* aTexture,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
bool aNeedsClear, bool aNeedsClearWhite);
virtual void FinalizeOnIPDLThread(TextureClient*) override;
virtual void GetDXGIResource(IDXGIResource** aOutResource) override;
RefPtr<ID3D10Texture2D> mTexture;
};
class DXGIYCbCrTextureData : public TextureData
{
public:
static DXGIYCbCrTextureData*
Create(ISurfaceAllocator* aAllocator,
TextureFlags aFlags,
IDirect3DTexture9* aTextureY,
IDirect3DTexture9* aTextureCb,
IDirect3DTexture9* aTextureCr,
IUnknown* aTextureY,
IUnknown* aTextureCb,
IUnknown* aTextureCr,
HANDLE aHandleY,
HANDLE aHandleCb,
HANDLE aHandleCr,
@ -122,54 +164,53 @@ public:
const gfx::IntSize& aSizeY,
const gfx::IntSize& aSizeCbCr);
// Creates a TextureClient and init width.
static already_AddRefed<DXGIYCbCrTextureClient>
static DXGIYCbCrTextureData*
Create(ISurfaceAllocator* aAllocator,
TextureFlags aFlags,
ID3D11Texture2D* aTextureY,
ID3D11Texture2D* aTextureCb,
ID3D11Texture2D* aTextureY,
ID3D11Texture2D* aTextureCr,
const gfx::IntSize& aSize,
const gfx::IntSize& aSizeY,
const gfx::IntSize& aSizeCbCr);
// TextureClient
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
virtual bool IsAllocated() const override{ return !!mHoldRefs[0]; }
virtual void Unlock() override {}
virtual bool Lock(OpenMode aOpenMode) override;
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
virtual void Unlock() override;
// TODO - DXGIYCbCrTextureClient returned true but that looks like a mistake
virtual bool HasInternalBuffer() const override{ return false; }
virtual bool IsLocked() const override{ return mIsLocked; }
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
virtual gfx::SurfaceFormat GetFormat() const { return gfx::SurfaceFormat::YUV; }
virtual gfx::IntSize GetSize() const
{
return mSize;
}
virtual bool SupportsMoz2D() const { return false; }
virtual bool HasInternalBuffer() const override{ return true; }
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() { return nullptr; }
// This TextureClient should not be used in a context where we use CreateSimilar
// (ex. component alpha) because the underlying texture data is always created by
// an external producer.
virtual already_AddRefed<TextureClient>
CreateSimilar(TextureFlags, TextureAllocationFlags) const override{ return nullptr; }
// This TextureData should not be used in a context where we use CreateSimilar
// (ex. component alpha) because the underlying texture is always created by
// an external producer.
virtual DXGIYCbCrTextureData*
CreateSimilar(ISurfaceAllocator*, TextureFlags, TextureAllocationFlags) const override { return nullptr; }
private:
virtual void FinalizeOnIPDLThread() override;
virtual void Deallocate(ISurfaceAllocator* aAllocator) override;
RefPtr<IUnknown> mHoldRefs[3];
HANDLE mHandles[3];
gfx::IntSize mSize;
gfx::IntSize mSizeY;
gfx::IntSize mSizeCbCr;
bool mIsLocked;
virtual bool UpdateFromSurface(gfx::SourceSurface*) override { return false; }
protected:
virtual void FinalizeOnIPDLThread(TextureClient*) override;
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.
@ -267,6 +308,13 @@ protected:
};
already_AddRefed<TextureClient>
CreateD3D11TextureClientWithDevice(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags,
ID3D11Device* aDevice,
ISurfaceAllocator* aAllocator);
/**
* A TextureHost for shared D3D11 textures.
*/
@ -327,7 +375,7 @@ public:
virtual void Unlock() override;
virtual gfx::IntSize GetSize() const override{ return mSize; }
virtual gfx::IntSize GetSize() const override { return mSize; }
virtual already_AddRefed<gfx::DataSourceSurface> GetAsSurface() override
{