Bug 1673983 - Support using D3D11 textures as external compositor surfaces with D3D11 compositor. r=lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D95800
This commit is contained in:
Matt Woodrow 2020-11-06 00:01:54 +00:00
parent 979882e86f
commit ec72f3a124
8 changed files with 136 additions and 7 deletions

View File

@ -1060,6 +1060,11 @@ void DXGITextureHostD3D11::PushDisplayItems(
return;
}
bool supportsExternalCompositing = false;
if (gfx::gfxVars::UseSoftwareWebRender()) {
supportsExternalCompositing = true;
}
switch (GetFormat()) {
case gfx::SurfaceFormat::R8G8B8X8:
case gfx::SurfaceFormat::R8G8B8A8:
@ -1069,7 +1074,7 @@ void DXGITextureHostD3D11::PushDisplayItems(
aBuilder.PushImage(aBounds, aClip, true, aFilter, aImageKeys[0],
!(mFlags & TextureFlags::NON_PREMULTIPLIED),
wr::ColorF{1.0f, 1.0f, 1.0f, 1.0f},
preferCompositorSurface);
preferCompositorSurface, supportsExternalCompositing);
break;
}
case gfx::SurfaceFormat::P010:
@ -1251,7 +1256,7 @@ bool DXGIYCbCrTextureHostD3D11::BindTextureSource(
void DXGIYCbCrTextureHostD3D11::CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) {
RefPtr<wr::RenderTextureHost> texture = new wr::RenderDXGIYCbCrTextureHost(
mHandles, mYUVColorSpace, mColorDepth, mSizeY, mSizeCbCr);
mHandles, mYUVColorSpace, mColorDepth, mColorRange, mSizeY, mSizeCbCr);
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId),
texture.forget());
@ -1304,13 +1309,19 @@ void DXGIYCbCrTextureHostD3D11::PushDisplayItems(
return;
}
bool supportsExternalCompositing = false;
if (gfx::gfxVars::UseSoftwareWebRender()) {
supportsExternalCompositing = true;
}
MOZ_ASSERT(aImageKeys.length() == 3);
aBuilder.PushYCbCrPlanarImage(
aBounds, aClip, true, aImageKeys[0], aImageKeys[1], aImageKeys[2],
wr::ToWrColorDepth(mColorDepth), wr::ToWrYuvColorSpace(mYUVColorSpace),
wr::ToWrColorRange(mColorRange), aFilter,
aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE));
aFlags.contains(PushDisplayItemFlag::PREFER_COMPOSITOR_SURFACE),
supportsExternalCompositing);
}
bool DXGIYCbCrTextureHostD3D11::AcquireTextureSource(

View File

@ -10,6 +10,7 @@
#include "mozilla/widget/CompositorWidget.h"
#include "mozilla/layers/Effects.h"
#include "mozilla/webrender/RenderD3D11TextureHost.h"
namespace mozilla {
using namespace layers;
@ -95,6 +96,70 @@ void RenderCompositorD3D11SWGL::CompositorEndFrame() {
mCompositor->DrawQuad(drawRect, frameSurface.mClipRect, effect, 1.0,
frameSurface.mTransform, drawRect);
}
if (surface.mExternalImage) {
// We need to hold the texture source separately from the effect,
// since the effect doesn't hold a strong reference.
RefPtr<DataTextureSourceD3D11> layer;
RefPtr<TexturedEffect> texturedEffect;
gfx::IntSize size;
if (auto* host = surface.mExternalImage->AsRenderDXGITextureHost()) {
host->EnsureD3D11Texture2D(mCompositor->GetDevice());
layer = new DataTextureSourceD3D11(mCompositor->GetDevice(),
host->GetFormat(),
host->GetD3D11Texture2D());
if (host->GetFormat() == SurfaceFormat::NV12 ||
host->GetFormat() == SurfaceFormat::P010 ||
host->GetFormat() == SurfaceFormat::P016) {
texturedEffect = new EffectNV12(
layer, host->GetYUVColorSpace(), host->GetColorRange(),
host->GetColorDepth(), frameSurface.mFilter);
} else {
MOZ_ASSERT(host->GetFormat() == SurfaceFormat::B8G8R8X8 ||
host->GetFormat() == SurfaceFormat::B8G8R8A8);
texturedEffect = CreateTexturedEffect(host->GetFormat(), layer,
frameSurface.mFilter, true);
}
size = host->GetSize(0);
host->LockInternal();
} else if (auto* host =
surface.mExternalImage->AsRenderDXGIYCbCrTextureHost()) {
host->EnsureD3D11Texture2D(mCompositor->GetDevice());
layer = new DataTextureSourceD3D11(mCompositor->GetDevice(),
SurfaceFormat::A8,
host->GetD3D11Texture2D(0));
RefPtr<DataTextureSourceD3D11> u = new DataTextureSourceD3D11(
mCompositor->GetDevice(), SurfaceFormat::A8,
host->GetD3D11Texture2D(1));
layer->SetNextSibling(u);
RefPtr<DataTextureSourceD3D11> v = new DataTextureSourceD3D11(
mCompositor->GetDevice(), SurfaceFormat::A8,
host->GetD3D11Texture2D(2));
u->SetNextSibling(v);
texturedEffect = new EffectYCbCr(
layer, host->GetYUVColorSpace(), host->GetColorRange(),
host->GetColorDepth(), frameSurface.mFilter);
size = host->GetSize(0);
host->LockInternal();
}
gfx::Rect drawRect(0, 0, size.width, size.height);
EffectChain effect;
effect.mPrimaryEffect = texturedEffect;
mCompositor->DrawQuad(drawRect, frameSurface.mClipRect, effect, 1.0,
frameSurface.mTransform, drawRect);
if (auto* host = surface.mExternalImage->AsRenderDXGITextureHost()) {
host->Unlock();
} else if (auto* host =
surface.mExternalImage->AsRenderDXGIYCbCrTextureHost()) {
host->Unlock();
}
}
}
mFrameSurfaces.Clear();
}
@ -172,6 +237,14 @@ void RenderCompositorD3D11SWGL::CreateSurface(wr::NativeSurfaceId aId,
mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
}
void RenderCompositorD3D11SWGL::CreateExternalSurface(wr::NativeSurfaceId aId,
bool aIsOpaque) {
MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
Surface surface{wr::DeviceIntSize{}, aIsOpaque};
surface.mIsExternal = true;
mSurfaces.insert({aId, std::move(surface)});
}
void RenderCompositorD3D11SWGL::DestroySurface(NativeSurfaceId aId) {
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
@ -206,6 +279,23 @@ void RenderCompositorD3D11SWGL::DestroyTile(wr::NativeSurfaceId aId, int32_t aX,
surface.mTiles.erase(layerCursor);
}
void RenderCompositorD3D11SWGL::AttachExternalImage(
wr::NativeSurfaceId aId, wr::ExternalImageId aExternalImage) {
RenderTextureHost* image =
RenderThread::Get()->GetRenderTexture(aExternalImage);
MOZ_RELEASE_ASSERT(image);
MOZ_RELEASE_ASSERT(image->AsRenderDXGITextureHost() ||
image->AsRenderDXGIYCbCrTextureHost());
auto surfaceCursor = mSurfaces.find(aId);
MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
Surface& surface = surfaceCursor->second;
surface.mExternalImage = image;
MOZ_RELEASE_ASSERT(surface.mTiles.empty());
MOZ_RELEASE_ASSERT(surface.mIsExternal);
}
gfx::SamplingFilter ToSamplingFilter(wr::ImageRendering aImageRendering) {
if (aImageRendering == wr::ImageRendering::Auto) {
return gfx::SamplingFilter::LINEAR;

View File

@ -68,13 +68,12 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
void UnmapTile() override;
void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
wr::DeviceIntSize aTileSize, bool aIsOpaque) override;
void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override {
}
void CreateExternalSurface(wr::NativeSurfaceId aId, bool aIsOpaque) override;
void DestroySurface(NativeSurfaceId aId) override;
void CreateTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
void DestroyTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) override;
void AttachExternalImage(wr::NativeSurfaceId aId,
wr::ExternalImageId aExternalImage) override {}
wr::ExternalImageId aExternalImage) override;
void AddSurface(wr::NativeSurfaceId aId,
const wr::CompositorSurfaceTransform& aTransform,
wr::DeviceIntRect aClipRect,
@ -133,6 +132,7 @@ class RenderCompositorD3D11SWGL : public RenderCompositor {
bool mIsOpaque;
bool mIsExternal = false;
std::unordered_map<TileKey, Tile, Tile::KeyHashFn> mTiles;
RefPtr<RenderTextureHost> mExternalImage;
struct IdHashFn {
std::size_t operator()(const wr::NativeSurfaceId& aId) const {

View File

@ -415,13 +415,15 @@ gfx::IntSize RenderDXGITextureHost::GetSize(uint8_t aChannelIndex) const {
RenderDXGIYCbCrTextureHost::RenderDXGIYCbCrTextureHost(
WindowsHandle (&aHandles)[3], gfx::YUVColorSpace aYUVColorSpace,
gfx::ColorDepth aColorDepth, gfx::IntSize aSizeY, gfx::IntSize aSizeCbCr)
gfx::ColorDepth aColorDepth, gfx::ColorRange aColorRange,
gfx::IntSize aSizeY, gfx::IntSize aSizeCbCr)
: mHandles{aHandles[0], aHandles[1], aHandles[2]},
mSurfaces{0},
mStreams{0},
mTextureHandles{0},
mYUVColorSpace(aYUVColorSpace),
mColorDepth(aColorDepth),
mColorRange(aColorRange),
mSizeY(aSizeY),
mSizeCbCr(aSizeCbCr),
mLocked(false) {

View File

@ -102,9 +102,14 @@ class RenderDXGIYCbCrTextureHost final : public RenderTextureHostSWGL {
explicit RenderDXGIYCbCrTextureHost(WindowsHandle (&aHandles)[3],
gfx::YUVColorSpace aYUVColorSpace,
gfx::ColorDepth aColorDepth,
gfx::ColorRange aColorRange,
gfx::IntSize aSizeY,
gfx::IntSize aSizeCbCr);
RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() override {
return this;
}
wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL,
wr::ImageRendering aRendering) override;
void Unlock() override;
@ -115,6 +120,8 @@ class RenderDXGIYCbCrTextureHost final : public RenderTextureHostSWGL {
bool SyncObjectNeeded() override { return true; }
gfx::ColorRange GetColorRange() const { return mColorRange; }
// RenderTextureHostSWGL
gfx::SurfaceFormat GetFormat() const override {
return gfx::SurfaceFormat::YUV;
@ -131,6 +138,10 @@ class RenderDXGIYCbCrTextureHost final : public RenderTextureHostSWGL {
bool EnsureD3D11Texture2D(ID3D11Device* aDevice);
bool LockInternal();
ID3D11Texture2D* GetD3D11Texture2D(uint8_t aChannelIndex) {
return mTextures[aChannelIndex];
}
private:
virtual ~RenderDXGIYCbCrTextureHost();
@ -156,6 +167,7 @@ class RenderDXGIYCbCrTextureHost final : public RenderTextureHostSWGL {
gfx::YUVColorSpace mYUVColorSpace;
gfx::ColorDepth mColorDepth;
gfx::ColorRange mColorRange;
gfx::IntSize mSizeY;
gfx::IntSize mSizeCbCr;

View File

@ -25,6 +25,7 @@ namespace wr {
class RenderCompositor;
class RenderDXGITextureHost;
class RenderDXGIYCbCrTextureHost;
class RenderMacIOSurfaceTextureHost;
class RenderBufferTextureHost;
class RenderTextureHostSWGL;
@ -69,6 +70,9 @@ class RenderTextureHost {
virtual bool SyncObjectNeeded() { return false; }
virtual RenderDXGITextureHost* AsRenderDXGITextureHost() { return nullptr; }
virtual RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() {
return nullptr;
}
virtual RenderMacIOSurfaceTextureHost* AsRenderMacIOSurfaceTextureHost() {
return nullptr;

View File

@ -72,6 +72,15 @@ RenderDXGITextureHost* RenderTextureHostWrapper::AsRenderDXGITextureHost() {
return mTextureHost->AsRenderDXGITextureHost();
}
RenderDXGIYCbCrTextureHost*
RenderTextureHostWrapper::AsRenderDXGIYCbCrTextureHost() {
EnsureTextureHost();
if (!mTextureHost) {
return nullptr;
}
return mTextureHost->AsRenderDXGIYCbCrTextureHost();
}
RenderTextureHostSWGL* RenderTextureHostWrapper::EnsureRenderTextureHostSWGL()
const {
EnsureTextureHost();

View File

@ -35,6 +35,7 @@ class RenderTextureHostWrapper final : public RenderTextureHostSWGL {
void ClearCachedResources() override;
RenderMacIOSurfaceTextureHost* AsRenderMacIOSurfaceTextureHost() override;
RenderDXGITextureHost* AsRenderDXGITextureHost() override;
RenderDXGIYCbCrTextureHost* AsRenderDXGIYCbCrTextureHost() override;
// RenderTextureHostSWGL
size_t GetPlaneCount() const override;