diff --git a/gfx/layers/IMFYCbCrImage.cpp b/gfx/layers/IMFYCbCrImage.cpp index 9890fb1e68..25e2814174 100644 --- a/gfx/layers/IMFYCbCrImage.cpp +++ b/gfx/layers/IMFYCbCrImage.cpp @@ -194,12 +194,11 @@ IMFYCbCrImage::GetD3D9TextureClient(KnowsCompositor* aForwarder) return mTextureClient; } -TextureClient* -IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) +DXGIYCbCrTextureData* +IMFYCbCrImage::GetD3D11TextureData(Data aData, gfx::IntSize aSize) { - if (mTextureClient) { - return mTextureClient; - } + HRESULT hr; + RefPtr mt; RefPtr device = gfx::DeviceManagerDx::Get()->GetContentDevice(); @@ -207,21 +206,10 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); } - LayersBackend backend = aForwarder->GetCompositorBackendType(); - if (!device || backend != LayersBackend::LAYERS_D3D11) { - if (backend == LayersBackend::LAYERS_D3D9 || - backend == LayersBackend::LAYERS_D3D11) { - return GetD3D9TextureClient(aForwarder); - } - return nullptr; - } - if (!gfx::DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) { return nullptr; } - HRESULT hr; - RefPtr mt; hr = device->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt)); if (FAILED(hr)) { @@ -232,13 +220,13 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) return nullptr; } - if (mData.mYStride < 0 || mData.mCbCrStride < 0) { + if (aData.mYStride < 0 || aData.mCbCrStride < 0) { // D3D11 only supports unsigned stride values. return nullptr; } CD3D11_TEXTURE2D_DESC newDesc(DXGI_FORMAT_R8_UNORM, - mData.mYSize.width, mData.mYSize.height, 1, 1); + aData.mYSize.width, aData.mYSize.height, 1, 1); if (device == gfx::DeviceManagerDx::Get()->GetCompositorDevice()) { newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; @@ -250,8 +238,8 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureY)); NS_ENSURE_TRUE(SUCCEEDED(hr), nullptr); - newDesc.Width = mData.mCbCrSize.width; - newDesc.Height = mData.mCbCrSize.height; + newDesc.Width = aData.mCbCrSize.width; + newDesc.Height = aData.mCbCrSize.height; RefPtr textureCb; hr = device->CreateTexture2D(&newDesc, nullptr, getter_AddRefs(textureCb)); @@ -281,26 +269,59 @@ IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) D3D11_BOX box; box.front = box.top = box.left = 0; box.back = 1; - box.right = mData.mYSize.width; - box.bottom = mData.mYSize.height; - ctx->UpdateSubresource(textureY, 0, &box, mData.mYChannel, mData.mYStride, 0); + box.right = aData.mYSize.width; + box.bottom = aData.mYSize.height; + ctx->UpdateSubresource(textureY, 0, &box, aData.mYChannel, aData.mYStride, 0); - box.right = mData.mCbCrSize.width; - box.bottom = mData.mCbCrSize.height; - ctx->UpdateSubresource(textureCb, 0, &box, mData.mCbChannel, mData.mCbCrStride, 0); - ctx->UpdateSubresource(textureCr, 0, &box, mData.mCrChannel, mData.mCbCrStride, 0); + box.right = aData.mCbCrSize.width; + box.bottom = aData.mCbCrSize.height; + ctx->UpdateSubresource(textureCb, 0, &box, aData.mCbChannel, aData.mCbCrStride, 0); + ctx->UpdateSubresource(textureCr, 0, &box, aData.mCrChannel, aData.mCbCrStride, 0); + } + + return DXGIYCbCrTextureData::Create(textureY, textureCb, textureCr, + aSize, aData.mYSize, aData.mCbCrSize); +} + +TextureClient* +IMFYCbCrImage::GetD3D11TextureClient(KnowsCompositor* aForwarder) +{ + DXGIYCbCrTextureData* textureData = GetD3D11TextureData(mData, GetSize()); + + if (textureData == nullptr) { + return nullptr; } mTextureClient = TextureClient::CreateWithData( - DXGIYCbCrTextureData::Create(textureY, textureCb, textureCr, - aSize, aData.mYSize, aData.mCbCrSize); - - TextureFlags::DEFAULT, + textureData, TextureFlags::DEFAULT, aForwarder->GetTextureForwarder() ); return mTextureClient; } +TextureClient* +IMFYCbCrImage::GetTextureClient(KnowsCompositor* aForwarder) +{ + if (mTextureClient) { + return mTextureClient; + } + + RefPtr device = gfx::DeviceManagerDx::Get()->GetContentDevice(); + if (!device) { + device = gfx::DeviceManagerDx::Get()->GetCompositorDevice(); + } + + LayersBackend backend = aForwarder->GetCompositorBackendType(); + if (!device || backend != LayersBackend::LAYERS_D3D11) { + if (backend == LayersBackend::LAYERS_D3D9 || + backend == LayersBackend::LAYERS_D3D11) { + return GetD3D9TextureClient(aForwarder); + } + return nullptr; + } + return GetD3D11TextureClient(aForwarder); +} + } // namespace layers } // namespace mozilla diff --git a/gfx/layers/IMFYCbCrImage.h b/gfx/layers/IMFYCbCrImage.h index 9a42987279..6b4e90cf1f 100644 --- a/gfx/layers/IMFYCbCrImage.h +++ b/gfx/layers/IMFYCbCrImage.h @@ -6,6 +6,7 @@ #ifndef GFX_IMFYCBCRIMAGE_H #define GFX_IMFYCBCRIMAGE_H +#include "mozilla/layers/TextureD3D11.h" #include "mozilla/RefPtr.h" #include "ImageContainer.h" #include "mfidl.h" @@ -22,10 +23,15 @@ public: virtual TextureClient* GetTextureClient(KnowsCompositor* aForwarder) override; + static DXGIYCbCrTextureData* GetD3D11TextureData(Data aData, + gfx::IntSize aSize); + protected: TextureClient* GetD3D9TextureClient(KnowsCompositor* aForwarder); + TextureClient* GetD3D11TextureClient(KnowsCompositor* aForwarder); + ~IMFYCbCrImage(); RefPtr mBuffer; diff --git a/gfx/layers/client/TextureClient.h b/gfx/layers/client/TextureClient.h index ba521f8deb..9249394a5c 100644 --- a/gfx/layers/client/TextureClient.h +++ b/gfx/layers/client/TextureClient.h @@ -618,7 +618,7 @@ public: /** * Set last transaction id of CompositableForwarder. - * + * * Called when TextureClient has TextureFlags::RECYCLE flag. * When CompositableForwarder forwards the TextureClient with * TextureFlags::RECYCLE, it holds TextureClient's ref until host side @@ -644,7 +644,7 @@ public: private: static void TextureClientRecycleCallback(TextureClient* aClient, void* aClosure); - + // Internal helpers for creating texture clients using the actual forwarder instead // of KnowsCompositor. TextureClientPool uses these to let it cache texture clients // per-process instead of per ShadowLayerForwarder, but everyone else should @@ -659,7 +659,7 @@ private: BackendSelector aSelector, TextureFlags aTextureFlags, TextureAllocationFlags aAllocFlags = ALLOC_DEFAULT); - + static already_AddRefed CreateForRawBufferAccess(LayersIPCChannel* aAllocator, gfx::SurfaceFormat aFormat, @@ -735,6 +735,8 @@ protected: friend class TextureChild; friend void TestTextureClientSurface(TextureClient*, gfxImageSurface*); friend void TestTextureClientYCbCr(TextureClient*, PlanarYCbCrData&); + friend already_AddRefed CreateTextureHostWithBackend( + TextureClient*, LayersBackend&); #ifdef GFX_DEBUG_TRACK_CLIENTS_IN_POOL public: