diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index b1fb1afd2c99..51ff3c6c502f 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -11,7 +11,9 @@ #include "gfx2DGlue.h" #include "gfxPrefs.h" #include "ReadbackManagerD3D11.h" +#include "mozilla/gfx/DataSurfaceHelpers.h" #include "mozilla/gfx/DeviceManagerDx.h" +#include "mozilla/gfx/gfxVars.h" #include "mozilla/gfx/Logging.h" #include "mozilla/layers/CompositorBridgeChild.h" #include "mozilla/webrender/WebRenderAPI.h" @@ -855,6 +857,68 @@ DXGITextureHostD3D11::LockInternal() return mIsLocked; } +already_AddRefed +DXGITextureHostD3D11::GetAsSurface() +{ + if (!gfxVars::UseWebRender()) { + return nullptr; + } + + switch (GetFormat()) { + case gfx::SurfaceFormat::R8G8B8X8: + case gfx::SurfaceFormat::R8G8B8A8: + case gfx::SurfaceFormat::B8G8R8A8: + case gfx::SurfaceFormat::B8G8R8X8: + break; + default: { + MOZ_ASSERT_UNREACHABLE("DXGITextureHostD3D11: unsupported format!"); + return nullptr; + } + } + + AutoLockTextureHostWithoutCompositor autoLock(this); + if (autoLock.Failed()) { + NS_WARNING("Failed to lock the D3DTexture"); + return nullptr; + } + + RefPtr device; + mTexture->GetDevice(getter_AddRefs(device)); + + D3D11_TEXTURE2D_DESC textureDesc = {0}; + mTexture->GetDesc(&textureDesc); + + RefPtr context; + device->GetImmediateContext(getter_AddRefs(context)); + + textureDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + textureDesc.Usage = D3D11_USAGE_STAGING; + textureDesc.BindFlags = 0; + textureDesc.MiscFlags = 0; + textureDesc.MipLevels = 1; + RefPtr cpuTexture; + HRESULT hr = device->CreateTexture2D(&textureDesc, nullptr, getter_AddRefs(cpuTexture)); + if (FAILED(hr)) { + return nullptr; + } + + context->CopyResource(cpuTexture, mTexture); + + D3D11_MAPPED_SUBRESOURCE mappedSubresource; + hr = context->Map(cpuTexture, 0, D3D11_MAP_READ, 0, &mappedSubresource); + if (FAILED(hr)) { + return nullptr; + } + + RefPtr surf = + gfx::CreateDataSourceSurfaceFromData(IntSize(textureDesc.Width, textureDesc.Height), + GetFormat(), + (uint8_t*)mappedSubresource.pData, + mappedSubresource.RowPitch); + context->Unmap(cpuTexture, 0); + return surf.forget(); +} + bool DXGITextureHostD3D11::EnsureTextureSource() { diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h index 8c31b9717e90..c7b36a36e5f9 100644 --- a/gfx/layers/d3d11/TextureD3D11.h +++ b/gfx/layers/d3d11/TextureD3D11.h @@ -321,10 +321,7 @@ public: virtual gfx::IntSize GetSize() const override { return mSize; } - virtual already_AddRefed GetAsSurface() override - { - return nullptr; - } + virtual already_AddRefed GetAsSurface() override; virtual void GetWRImageKeys(nsTArray& aImageKeys, const std::function& aImageKeyAllocator) override;