зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1200595 - D3D9 TextureData implementation. r=Bas
This commit is contained in:
Родитель
2eea103a37
Коммит
51dd6c34c2
|
@ -56,14 +56,15 @@ D3D9SurfaceImage::AllocateAndCopy(D3D9RecycleAllocator* aAllocator,
|
|||
// DXVA surfaces aren't created sharable, so we need to copy the surface
|
||||
// to a sharable texture to that it's accessible to the layer manager's
|
||||
// device.
|
||||
RefPtr<SharedTextureClientD3D9> textureClient =
|
||||
RefPtr<TextureClient> textureClient =
|
||||
aAllocator->CreateOrRecycleClient(gfx::SurfaceFormat::B8G8R8X8, aRegion.Size());
|
||||
if (!textureClient) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
// Copy the image onto the texture, preforming YUV -> RGB conversion if necessary.
|
||||
RefPtr<IDirect3DSurface9> textureSurface = textureClient->GetD3D9Surface();
|
||||
RefPtr<IDirect3DSurface9> textureSurface = static_cast<DXGID3D9TextureData*>(
|
||||
textureClient->GetInternalData())->GetD3D9Surface();
|
||||
if (!textureSurface) {
|
||||
return E_FAIL;
|
||||
}
|
||||
|
@ -121,7 +122,7 @@ D3D9SurfaceImage::EnsureSynchronized()
|
|||
const D3DSURFACE_DESC&
|
||||
D3D9SurfaceImage::GetDesc() const
|
||||
{
|
||||
return mTextureClient->GetDesc();
|
||||
return static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData())->GetDesc();
|
||||
}
|
||||
|
||||
gfx::IntSize
|
||||
|
@ -142,7 +143,9 @@ D3D9SurfaceImage::GetTextureClient(CompositableClient* aClient)
|
|||
already_AddRefed<gfx::SourceSurface>
|
||||
D3D9SurfaceImage::GetAsSourceSurface()
|
||||
{
|
||||
NS_ENSURE_TRUE(mTextureClient, nullptr);
|
||||
if (!mTextureClient) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
HRESULT hr;
|
||||
RefPtr<gfx::DataSourceSurface> surface = gfx::Factory::CreateDataSourceSurface(mSize, gfx::SurfaceFormat::B8G8R8X8);
|
||||
|
@ -153,14 +156,15 @@ D3D9SurfaceImage::GetAsSourceSurface()
|
|||
// Ensure that the texture is ready to be used.
|
||||
EnsureSynchronized();
|
||||
|
||||
DXGID3D9TextureData* texData = static_cast<DXGID3D9TextureData*>(mTextureClient->GetInternalData());
|
||||
// Readback the texture from GPU memory into system memory, so that
|
||||
// we can copy it into the Cairo image. This is expensive.
|
||||
RefPtr<IDirect3DSurface9> textureSurface = mTextureClient->GetD3D9Surface();
|
||||
RefPtr<IDirect3DSurface9> textureSurface = texData->GetD3D9Surface();
|
||||
if (!textureSurface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDirect3DDevice9> device = mTextureClient->GetD3D9Device();
|
||||
RefPtr<IDirect3DDevice9> device = texData->GetD3D9Device();
|
||||
if (!device) {
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -208,28 +212,20 @@ D3D9RecycleAllocator::Allocate(gfx::SurfaceFormat aFormat,
|
|||
TextureFlags aTextureFlags,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
return SharedTextureClientD3D9::Create(mSurfaceAllocator,
|
||||
aFormat,
|
||||
aTextureFlags,
|
||||
mDevice,
|
||||
aSize);
|
||||
}
|
||||
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
D3D9RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
RefPtr<TextureClient> textureClient =
|
||||
CreateOrRecycle(aFormat,
|
||||
aSize,
|
||||
BackendSelector::Content,
|
||||
layers::TextureFlags::DEFAULT);
|
||||
if (!textureClient) {
|
||||
TextureData* data = DXGID3D9TextureData::Create(aSize, aFormat, aTextureFlags, mDevice);
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SharedTextureClientD3D9> textureD3D9 = static_cast<SharedTextureClientD3D9*>(textureClient.get());
|
||||
return textureD3D9.forget();
|
||||
return MakeAndAddRef<ClientTexture>(data, aTextureFlags, mSurfaceAllocator);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
D3D9RecycleAllocator::CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize)
|
||||
{
|
||||
return CreateOrRecycle(aFormat, aSize, BackendSelector::Content,
|
||||
TextureFlags::DEFAULT);
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class SharedTextureClientD3D9;
|
||||
class TextureClient;
|
||||
|
||||
class D3D9RecycleAllocator : public TextureClientRecycleAllocator
|
||||
{
|
||||
|
@ -26,7 +26,7 @@ public:
|
|||
, mDevice(aDevice)
|
||||
{}
|
||||
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
already_AddRefed<TextureClient>
|
||||
CreateOrRecycleClient(gfx::SurfaceFormat aFormat,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
|
@ -73,7 +73,7 @@ private:
|
|||
|
||||
gfx::IntSize mSize;
|
||||
RefPtr<IDirect3DQuery9> mQuery;
|
||||
RefPtr<SharedTextureClientD3D9> mTextureClient;
|
||||
RefPtr<TextureClient> mTextureClient;
|
||||
bool mValid;
|
||||
bool mIsFirstFrame;
|
||||
};
|
||||
|
|
|
@ -582,7 +582,10 @@ TextureClient::CreateForDrawing(CompositableForwarder* aAllocator,
|
|||
aSize.height <= maxTextureSize &&
|
||||
NS_IsMainThread()) {
|
||||
if (gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
|
||||
texture = new TextureClientD3D9(aAllocator, aFormat, aTextureFlags);
|
||||
TextureData* data = D3D9TextureData::Create(aSize, aFormat, aAllocFlags);
|
||||
if (data) {
|
||||
return MakeAndAddRef<ClientTexture>(data, aTextureFlags, aAllocator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -442,45 +442,62 @@ DataTextureSourceD3D9::GetTileRect()
|
|||
return GetTileRect(mCurrentTile);
|
||||
}
|
||||
|
||||
TextureClientD3D9::TextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mFormat(aFormat)
|
||||
, mIsLocked(false)
|
||||
, mNeedsClear(false)
|
||||
, mNeedsClearWhite(false)
|
||||
, mLockRect(false)
|
||||
|
||||
D3D9TextureData::D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture)
|
||||
: mTexture(aTexture)
|
||||
, mSize(aSize)
|
||||
, mFormat(aFormat)
|
||||
, mNeedsClear(false)
|
||||
, mNeedsClearWhite(false)
|
||||
{
|
||||
MOZ_COUNT_CTOR(TextureClientD3D9);
|
||||
MOZ_COUNT_CTOR(D3D9TextureData);
|
||||
}
|
||||
|
||||
TextureClientD3D9::~TextureClientD3D9()
|
||||
D3D9TextureData::~D3D9TextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(TextureClientD3D9);
|
||||
MOZ_COUNT_DTOR(D3D9TextureData);
|
||||
}
|
||||
|
||||
already_AddRefed<TextureClient>
|
||||
TextureClientD3D9::CreateSimilar(TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
|
||||
D3D9TextureData*
|
||||
D3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureAllocationFlags aAllocFlags)
|
||||
{
|
||||
RefPtr<TextureClient> tex = new TextureClientD3D9(mAllocator, mFormat,
|
||||
mFlags | aFlags);
|
||||
|
||||
if (!tex->AllocateForSurface(mSize, aAllocFlags)) {
|
||||
_D3DFORMAT format = SurfaceFormatToD3D9Format(aFormat);
|
||||
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
|
||||
RefPtr<IDirect3DTexture9> d3d9Texture = deviceManager ? deviceManager->CreateTexture(aSize, format,
|
||||
D3DPOOL_SYSTEMMEM,
|
||||
nullptr)
|
||||
: nullptr;
|
||||
if (!d3d9Texture) {
|
||||
NS_WARNING("Could not create a d3d9 texture");
|
||||
return nullptr;
|
||||
}
|
||||
D3D9TextureData* data = new D3D9TextureData(aSize, aFormat, d3d9Texture);
|
||||
|
||||
return tex.forget();
|
||||
data->mNeedsClear = aAllocFlags & ALLOC_CLEAR_BUFFER;
|
||||
data->mNeedsClearWhite = aAllocFlags & ALLOC_CLEAR_BUFFER_WHITE;
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
TextureData*
|
||||
D3D9TextureData::CreateSimilar(ISurfaceAllocator*, TextureFlags aFlags, TextureAllocationFlags aAllocFlags) const
|
||||
{
|
||||
return D3D9TextureData::Create(mSize, mFormat, aAllocFlags);
|
||||
}
|
||||
|
||||
void
|
||||
D3D9TextureData::FinalizeOnIPDLThread(TextureClient* aWrapper)
|
||||
{
|
||||
if (mTexture) {
|
||||
aWrapper->KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientD3D9::Lock(OpenMode aMode)
|
||||
D3D9TextureData::Lock(OpenMode aMode, FenceHandle*)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid() || !IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!gfxWindowsPlatform::GetPlatform()->GetD3D9Device()) {
|
||||
// If the device has failed then we should not lock the surface,
|
||||
// even if we could.
|
||||
|
@ -495,71 +512,44 @@ TextureClientD3D9::Lock(OpenMode aMode)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mIsLocked = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D9::Unlock()
|
||||
D3D9TextureData::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked, "Unlocked called while the texture is not locked!");
|
||||
if (!mIsLocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
mDrawTarget->Flush();
|
||||
mDrawTarget = nullptr;
|
||||
}
|
||||
|
||||
if (mLockRect) {
|
||||
mD3D9Surface->UnlockRect();
|
||||
mLockRect = false;
|
||||
}
|
||||
|
||||
mIsLocked = false;
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
D3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mTexture->AddRef(); // Release in TextureHostD3D9::TextureHostD3D9
|
||||
aOutDescriptor = SurfaceDescriptorD3D9(reinterpret_cast<uintptr_t>(mTexture.get()));
|
||||
return true;
|
||||
}
|
||||
|
||||
gfx::DrawTarget*
|
||||
TextureClientD3D9::BorrowDrawTarget()
|
||||
already_AddRefed<gfx::DrawTarget>
|
||||
D3D9TextureData::BorrowDrawTarget()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked && mD3D9Surface);
|
||||
if (!mIsLocked || !mD3D9Surface) {
|
||||
NS_WARNING("Calling BorrowDrawTarget on an Unlocked TextureClient");
|
||||
gfxCriticalNote << "BorrowDrawTarget on an Unlocked TextureClient";
|
||||
MOZ_ASSERT(mD3D9Surface);
|
||||
if (!mD3D9Surface) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (mDrawTarget) {
|
||||
return mDrawTarget;
|
||||
}
|
||||
|
||||
RefPtr<DrawTarget> dt;
|
||||
if (ContentForFormat(mFormat) == gfxContentType::COLOR) {
|
||||
RefPtr<gfxASurface> surface = new gfxWindowsSurface(mD3D9Surface);
|
||||
if (!surface || surface->CairoStatus()) {
|
||||
NS_WARNING("Could not create surface for d3d9 surface");
|
||||
gfxCriticalNote << "Failed creation on D3D9";
|
||||
NS_WARNING("Could not create gfxASurface for d3d9 surface");
|
||||
return nullptr;
|
||||
}
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "Bad draw target creation for surface D3D9 " << mSize;
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(surface, mSize);
|
||||
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
}
|
||||
} else {
|
||||
// gfxWindowsSurface don't support transparency so we can't use the d3d9
|
||||
|
@ -571,31 +561,31 @@ TextureClientD3D9::BorrowDrawTarget()
|
|||
gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
|
||||
return nullptr;
|
||||
}
|
||||
mDrawTarget =
|
||||
gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
|
||||
rect.Pitch, mFormat);
|
||||
if (!mDrawTarget) {
|
||||
gfxCriticalNote << "Bad draw target creation for data D3D9 " << mSize << ", " << (int)mFormat;
|
||||
dt = gfxPlatform::GetPlatform()->CreateDrawTargetForData((uint8_t*)rect.pBits, mSize,
|
||||
rect.Pitch, mFormat);
|
||||
if (!dt) {
|
||||
return nullptr;
|
||||
}
|
||||
mLockRect = true;
|
||||
|
||||
mLockRect = true;
|
||||
}
|
||||
|
||||
if (mNeedsClear) {
|
||||
mDrawTarget->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
|
||||
dt->ClearRect(Rect(0, 0, GetSize().width, GetSize().height));
|
||||
mNeedsClear = false;
|
||||
}
|
||||
if (mNeedsClearWhite) {
|
||||
mDrawTarget->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
dt->FillRect(Rect(0, 0, GetSize().width, GetSize().height), ColorPattern(Color(1.0, 1.0, 1.0, 1.0)));
|
||||
mNeedsClearWhite = false;
|
||||
}
|
||||
|
||||
return mDrawTarget;
|
||||
return dt.forget();
|
||||
}
|
||||
|
||||
void
|
||||
TextureClientD3D9::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
bool
|
||||
D3D9TextureData::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked && mD3D9Surface);
|
||||
MOZ_ASSERT(mD3D9Surface);
|
||||
|
||||
// gfxWindowsSurface don't support transparency so we can't use the d3d9
|
||||
// windows surface optimization.
|
||||
|
@ -604,25 +594,21 @@ TextureClientD3D9::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
HRESULT hr = mD3D9Surface->LockRect(&rect, nullptr, 0);
|
||||
if (FAILED(hr) || !rect.pBits) {
|
||||
gfxCriticalError() << "Failed to lock rect borrowing the target in D3D9 " << hexa(hr);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
RefPtr<DataSourceSurface> srcSurf = aSurface->GetDataSurface();
|
||||
|
||||
if (!srcSurf) {
|
||||
gfxCriticalError() << "Failed to GetDataSurface in UpdateFromSurface.";
|
||||
return;
|
||||
}
|
||||
|
||||
if (mSize != srcSurf->GetSize() || mFormat != srcSurf->GetFormat()) {
|
||||
gfxCriticalError() << "Attempt to update texture client from a surface with a different size or format! This: " << mSize << " " << mFormat << " Other: " << srcSurf->GetSize() << " " << srcSurf->GetFormat();
|
||||
return;
|
||||
mD3D9Surface->UnlockRect();
|
||||
return false;
|
||||
}
|
||||
|
||||
DataSourceSurface::MappedSurface sourceMap;
|
||||
if (!srcSurf->Map(DataSourceSurface::READ, &sourceMap)) {
|
||||
gfxCriticalError() << "Failed to map source surface for UpdateFromSurface.";
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int y = 0; y < srcSurf->GetSize().height; y++) {
|
||||
|
@ -633,94 +619,65 @@ TextureClientD3D9::UpdateFromSurface(gfx::SourceSurface* aSurface)
|
|||
|
||||
srcSurf->Unmap();
|
||||
mD3D9Surface->UnlockRect();
|
||||
}
|
||||
|
||||
bool
|
||||
TextureClientD3D9::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags)
|
||||
{
|
||||
MOZ_ASSERT(!IsAllocated());
|
||||
mSize = aSize;
|
||||
_D3DFORMAT format = SurfaceFormatToD3D9Format(mFormat);
|
||||
|
||||
DeviceManagerD3D9* deviceManager = gfxWindowsPlatform::GetPlatform()->GetD3D9DeviceManager();
|
||||
if (!deviceManager ||
|
||||
!(mTexture = deviceManager->CreateTexture(mSize, format, D3DPOOL_SYSTEMMEM, nullptr))) {
|
||||
NS_WARNING("Could not create d3d9 texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
mNeedsClear = aFlags & ALLOC_CLEAR_BUFFER;
|
||||
mNeedsClearWhite = aFlags & ALLOC_CLEAR_BUFFER_WHITE;
|
||||
|
||||
MOZ_ASSERT(mTexture);
|
||||
return true;
|
||||
}
|
||||
|
||||
SharedTextureClientD3D9::SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags)
|
||||
: TextureClient(aAllocator, aFlags)
|
||||
, mFormat(aFormat)
|
||||
, mHandle(0)
|
||||
, mIsLocked(false)
|
||||
DXGID3D9TextureData::DXGID3D9TextureData(gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture, HANDLE aHandle,
|
||||
IDirect3DDevice9* aDevice)
|
||||
: mFormat(aFormat)
|
||||
, mTexture(aTexture)
|
||||
, mHandle(aHandle)
|
||||
, mDevice(aDevice)
|
||||
{
|
||||
MOZ_COUNT_CTOR(SharedTextureClientD3D9);
|
||||
MOZ_COUNT_CTOR(DXGID3D9TextureData);
|
||||
}
|
||||
|
||||
SharedTextureClientD3D9::~SharedTextureClientD3D9()
|
||||
DXGID3D9TextureData::~DXGID3D9TextureData()
|
||||
{
|
||||
MOZ_COUNT_DTOR(SharedTextureClientD3D9);
|
||||
if (mTexture) {
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SharedTextureClientD3D9::FinalizeOnIPDLThread()
|
||||
{
|
||||
if (mTexture && mActor) {
|
||||
KeepUntilFullDeallocation(MakeUnique<TKeepAlive<IDirect3DTexture9>>(mTexture));
|
||||
}
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed -= mDesc.Width * mDesc.Height * 4;
|
||||
MOZ_COUNT_DTOR(DXGID3D9TextureData);
|
||||
}
|
||||
|
||||
// static
|
||||
already_AddRefed<SharedTextureClientD3D9>
|
||||
SharedTextureClientD3D9::Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice,
|
||||
const gfx::IntSize& aSize)
|
||||
DXGID3D9TextureData*
|
||||
DXGID3D9TextureData::Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice)
|
||||
{
|
||||
MOZ_ASSERT(aFormat == gfx::SurfaceFormat::B8G8R8X8);
|
||||
if (aFormat != gfx::SurfaceFormat::B8G8R8X8) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<IDirect3DTexture9> texture;
|
||||
HANDLE shareHandle = nullptr;
|
||||
HRESULT hr = aDevice->CreateTexture(aSize.width,
|
||||
aSize.height,
|
||||
HRESULT hr = aDevice->CreateTexture(aSize.width, aSize.height,
|
||||
1,
|
||||
D3DUSAGE_RENDERTARGET,
|
||||
D3DFMT_X8R8G8B8,
|
||||
D3DPOOL_DEFAULT,
|
||||
getter_AddRefs(texture),
|
||||
&shareHandle);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr) && shareHandle, nullptr);
|
||||
if (FAILED(hr) || !shareHandle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
RefPtr<SharedTextureClientD3D9> client =
|
||||
new SharedTextureClientD3D9(aAllocator,
|
||||
aFormat,
|
||||
aFlags);
|
||||
|
||||
client->mDevice = aDevice;
|
||||
client->mTexture = texture;
|
||||
client->mHandle = shareHandle;
|
||||
texture->GetLevelDesc(0, &client->mDesc);
|
||||
D3DSURFACE_DESC surfaceDesc;
|
||||
hr = texture->GetLevelDesc(0, &surfaceDesc);
|
||||
if (FAILED(hr)) {
|
||||
return nullptr;
|
||||
}
|
||||
DXGID3D9TextureData* data = new DXGID3D9TextureData(aFormat, texture, shareHandle, aDevice);
|
||||
data->mDesc = surfaceDesc;
|
||||
|
||||
gfxWindowsPlatform::sD3D9SharedTextureUsed += aSize.width * aSize.height * 4;
|
||||
return client.forget();
|
||||
return data;
|
||||
}
|
||||
|
||||
already_AddRefed<IDirect3DSurface9>
|
||||
SharedTextureClientD3D9::GetD3D9Surface() const
|
||||
DXGID3D9TextureData::GetD3D9Surface() const
|
||||
{
|
||||
RefPtr<IDirect3DSurface9> textureSurface;
|
||||
HRESULT hr = mTexture->GetSurfaceLevel(0, getter_AddRefs(textureSurface));
|
||||
|
@ -730,34 +687,13 @@ SharedTextureClientD3D9::GetD3D9Surface() const
|
|||
}
|
||||
|
||||
bool
|
||||
SharedTextureClientD3D9::Lock(OpenMode)
|
||||
DXGID3D9TextureData::Serialize(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(!mIsLocked);
|
||||
if (!IsValid()) {
|
||||
return false;
|
||||
}
|
||||
mIsLocked = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
SharedTextureClientD3D9::Unlock()
|
||||
{
|
||||
MOZ_ASSERT(mIsLocked, "Unlock called while the texture is not locked!");
|
||||
}
|
||||
|
||||
bool
|
||||
SharedTextureClientD3D9::ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor)
|
||||
{
|
||||
MOZ_ASSERT(IsValid());
|
||||
if (!IsAllocated()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aOutDescriptor = SurfaceDescriptorD3D10((WindowsHandle)(mHandle), mFormat, GetSize());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TextureHostD3D9::TextureHostD3D9(TextureFlags aFlags,
|
||||
const SurfaceDescriptorD3D9& aDescriptor)
|
||||
: TextureHost(aFlags)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#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>
|
||||
|
@ -174,52 +175,49 @@ protected:
|
|||
* Needs a D3D9 context on the client side.
|
||||
* The corresponding TextureHost is TextureHostD3D9.
|
||||
*/
|
||||
class TextureClientD3D9 : public TextureClient
|
||||
class D3D9TextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
TextureClientD3D9(ISurfaceAllocator* aAllocator, gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
~D3D9TextureData();
|
||||
|
||||
virtual ~TextureClientD3D9();
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return !!mTexture; }
|
||||
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual gfx::IntSize GetSize() const { return mSize; }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const { return mFormat; }
|
||||
|
||||
virtual bool CanExposeDrawTarget() const override { return true; }
|
||||
|
||||
virtual gfx::DrawTarget* BorrowDrawTarget() override;
|
||||
|
||||
virtual void UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual bool AllocateForSurface(gfx::IntSize aSize,
|
||||
TextureAllocationFlags aFlags = ALLOC_DEFAULT) override;
|
||||
virtual bool SupportsMoz2D() const override { return true; }
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
virtual already_AddRefed<TextureClient>
|
||||
CreateSimilar(TextureFlags aFlags = TextureFlags::DEFAULT,
|
||||
TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT) const override;
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescrptor) override;
|
||||
|
||||
virtual bool Lock(OpenMode aMode, FenceHandle*) override;
|
||||
|
||||
virtual void Unlock() override;
|
||||
|
||||
virtual already_AddRefed<gfx::DrawTarget> BorrowDrawTarget() override;
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const override { return mSize; }
|
||||
|
||||
virtual bool UpdateFromSurface(gfx::SourceSurface* aSurface) override;
|
||||
|
||||
virtual TextureData*
|
||||
CreateSimilar(ISurfaceAllocator* aAllocator,
|
||||
TextureFlags aFlags,
|
||||
TextureAllocationFlags aAllocFlags) const override;
|
||||
|
||||
static D3D9TextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureAllocationFlags aFlags);
|
||||
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
|
||||
|
||||
protected:
|
||||
virtual void FinalizeOnIPDLThread(TextureClient* aWrapper) override;
|
||||
|
||||
D3D9TextureData(gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
|
||||
IDirect3DTexture9* aTexture);
|
||||
|
||||
private:
|
||||
RefPtr<IDirect3DTexture9> mTexture;
|
||||
RefPtr<IDirect3DSurface9> mD3D9Surface;
|
||||
RefPtr<gfx::DrawTarget> mDrawTarget;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat;
|
||||
bool mIsLocked;
|
||||
bool mNeedsClear;
|
||||
bool mNeedsClearWhite;
|
||||
bool mLockRect;
|
||||
|
@ -230,49 +228,27 @@ private:
|
|||
* At the moment it is only used with D3D11 compositing, and the corresponding
|
||||
* TextureHost is DXGITextureHostD3D11.
|
||||
*/
|
||||
class SharedTextureClientD3D9 : public TextureClient
|
||||
class DXGID3D9TextureData : public TextureData
|
||||
{
|
||||
public:
|
||||
SharedTextureClientD3D9(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags);
|
||||
static DXGID3D9TextureData*
|
||||
Create(gfx::IntSize aSize, gfx::SurfaceFormat aFormat, TextureFlags aFlags, IDirect3DDevice9* aDevice);
|
||||
|
||||
virtual ~SharedTextureClientD3D9();
|
||||
~DXGID3D9TextureData();
|
||||
|
||||
// Creates a TextureClient and init width.
|
||||
static already_AddRefed<SharedTextureClientD3D9>
|
||||
Create(ISurfaceAllocator* aAllocator,
|
||||
gfx::SurfaceFormat aFormat,
|
||||
TextureFlags aFlags,
|
||||
IDirect3DDevice9* aDevice,
|
||||
const gfx::IntSize& aSize);
|
||||
|
||||
// TextureClient
|
||||
|
||||
virtual bool IsAllocated() const override { return !!mTexture; }
|
||||
virtual gfx::IntSize GetSize() const { return gfx::IntSize(mDesc.Width, mDesc.Height); }
|
||||
|
||||
virtual gfx::SurfaceFormat GetFormat() const override { return mFormat; }
|
||||
|
||||
virtual bool Lock(OpenMode aOpenMode) override;
|
||||
virtual bool Lock(OpenMode, FenceHandle*) override { return true; }
|
||||
|
||||
virtual void Unlock() override;
|
||||
virtual void Unlock() override {}
|
||||
|
||||
virtual bool IsLocked() const override { return mIsLocked; }
|
||||
virtual bool Serialize(SurfaceDescriptor& aOutDescriptor) override;
|
||||
|
||||
virtual bool ToSurfaceDescriptor(SurfaceDescriptor& aOutDescriptor) override;
|
||||
virtual bool HasInternalBuffer() const override { return false; }
|
||||
|
||||
virtual gfx::IntSize GetSize() const
|
||||
{
|
||||
return gfx::IntSize(mDesc.Width, mDesc.Height);
|
||||
}
|
||||
|
||||
virtual bool HasInternalBuffer() const override { return true; }
|
||||
|
||||
// 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; }
|
||||
virtual void Deallocate(ISurfaceAllocator* aAllocator) {}
|
||||
|
||||
IDirect3DDevice9* GetD3D9Device() { return mDevice; }
|
||||
IDirect3DTexture9* GetD3D9Texture() { return mTexture; }
|
||||
|
@ -284,15 +260,16 @@ public:
|
|||
return mDesc;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void FinalizeOnIPDLThread() override;
|
||||
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;
|
||||
bool mIsLocked;
|
||||
};
|
||||
|
||||
class TextureHostD3D9 : public TextureHost
|
||||
|
|
Загрузка…
Ссылка в новой задаче