mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
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:
parent
979882e86f
commit
ec72f3a124
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user