Bug 1959856 - Add FenceD3D11 handling to hardware decoded video r=gfx-reviewers,lsalzman

Differential Revision: https://phabricator.services.mozilla.com/D245202
This commit is contained in:
sotaro
2025-04-15 10:49:16 +00:00
parent 382b3ed472
commit 397e2d4830
8 changed files with 199 additions and 44 deletions

View File

@@ -28,8 +28,10 @@
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/glean/DomMediaPlatformsWmfMetrics.h"
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/D3D11ZeroCopyTextureImage.h"
#include "mozilla/layers/FenceD3D11.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/TextureD3D11.h"
#include "mozilla/layers/TextureForwarder.h"
@@ -424,6 +426,7 @@ class D3D11DXVA2Manager : public DXVA2Manager {
std::list<ThreadSafeWeakPtr<layers::IMFSampleWrapper>> mIMFSampleWrappers;
RefPtr<layers::ZeroCopyUsageInfo> mZeroCopyUsageInfo;
uint32_t mVendorID = 0;
RefPtr<layers::FenceD3D11> mWriteFence;
};
bool D3D11DXVA2Manager::SupportsConfig(const VideoInfo& aInfo,
@@ -666,6 +669,13 @@ D3D11DXVA2Manager::InitInternal(layers::KnowsCompositor* aKnowsCompositor,
}
}
auto* fencesHolderMap = layers::CompositeProcessD3D11FencesHolderMap::Get();
const bool useFence =
fencesHolderMap && layers::FenceD3D11::IsSupported(mDevice);
if (useFence) {
mWriteFence = layers::FenceD3D11::Create(mDevice);
}
RefPtr<ID3D10Multithread> mt;
hr = mDevice->QueryInterface((ID3D10Multithread**)getter_AddRefs(mt));
NS_ENSURE_TRUE(SUCCEEDED(hr) && mt, hr);
@@ -851,7 +861,8 @@ HRESULT D3D11DXVA2Manager::WrapTextureWithImage(IMFSample* aVideoSample,
RefPtr<D3D11TextureIMFSampleImage> image = new D3D11TextureIMFSampleImage(
aVideoSample, texture, arrayIndex, gfx::IntSize(mWidth, mHeight), aRegion,
ToColorSpace2(mYUVColorSpace), mColorRange, mColorDepth);
image->AllocateTextureClient(mKnowsCompositor, mZeroCopyUsageInfo);
image->AllocateTextureClient(mKnowsCompositor, mZeroCopyUsageInfo,
mWriteFence);
RefPtr<IMFSampleWrapper> wrapper = image->GetIMFSampleWrapper();
ThreadSafeWeakPtr<IMFSampleWrapper> weak(wrapper);
@@ -869,7 +880,8 @@ HRESULT D3D11DXVA2Manager::WrapTextureWithImage(
RefPtr<D3D11TextureAVFrameImage> image = new D3D11TextureAVFrameImage(
aTextureWrapper, gfx::IntSize(mWidth, mHeight), aRegion,
ToColorSpace2(mYUVColorSpace), mColorRange, mColorDepth);
image->AllocateTextureClient(mKnowsCompositor, mZeroCopyUsageInfo);
image->AllocateTextureClient(mKnowsCompositor, mZeroCopyUsageInfo,
mWriteFence);
image.forget(aOutImage);
return S_OK;
}
@@ -1207,8 +1219,16 @@ HRESULT D3D11DXVA2Manager::CopyTextureToImage(
perfRecorder.Record();
}
if (!mutex && mDevice != DeviceManagerDx::Get()->GetCompositorDevice() &&
mSyncObject) {
auto* textureData = client->GetInternalData()->AsD3D11TextureData();
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
MOZ_ASSERT(textureData);
const bool useFence =
textureData && textureData->mFencesHolderId.isSome() && fencesHolderMap;
if (useFence) {
textureData->IncrementAndSignalWriteFence();
} else if (!mutex &&
mDevice != DeviceManagerDx::Get()->GetCompositorDevice() &&
mSyncObject) {
static StaticMutex sMutex MOZ_UNANNOTATED;
// Ensure that we only ever attempt to synchronise via the sync object
// serially as when using the same D3D11 device for multiple video decoders

View File

@@ -14,6 +14,7 @@
#include "GPUVideoImage.h"
#include "ScopedGLHelpers.h"
#include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
#include "mozilla/layers/D3D11ShareHandleImage.h"
#include "mozilla/layers/D3D11ZeroCopyTextureImage.h"
#include "mozilla/layers/D3D11YCbCrImage.h"
@@ -228,6 +229,7 @@ bool GLBlitHelper::BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
const auto srcOrigin = OriginPos::BottomLeft;
const gfx::IntRect clipRect(0, 0, clipSize.width, clipSize.height);
const auto colorSpace = desc.colorSpace();
const auto fencesHolderId = desc.fencesHolderId();
if (format != gfx::SurfaceFormat::NV12 &&
format != gfx::SurfaceFormat::P010 &&
@@ -255,6 +257,13 @@ bool GLBlitHelper::BlitDescriptor(const layers::SurfaceDescriptorD3D10& desc,
MOZ_GL_ASSERT(mGL, false); // Get a nullptr from OpenSharedResource1.
return false;
}
auto* fencesHolderMap = layers::CompositeProcessD3D11FencesHolderMap::Get();
MOZ_ASSERT(fencesHolderMap);
if (fencesHolderMap && fencesHolderId.isSome()) {
fencesHolderMap->WaitWriteFence(fencesHolderId.ref(), d3d);
}
const RefPtr<ID3D11Texture2D> texList[2] = {tex, tex};
const EGLAttrib postAttribs0[] = {LOCAL_EGL_NATIVE_BUFFER_PLANE_OFFSET_IMG, 0,
LOCAL_EGL_D3D_TEXTURE_SUBRESOURCE_ID_ANGLE,

View File

@@ -16,6 +16,8 @@
#include "mozilla/gfx/DeviceManagerDx.h"
#include "mozilla/layers/CompositableClient.h"
#include "mozilla/layers/CompositableForwarder.h"
#include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
#include "mozilla/layers/FenceD3D11.h"
#include "mozilla/layers/TextureClient.h"
#include "mozilla/layers/TextureD3D11.h"
@@ -187,9 +189,12 @@ already_AddRefed<TextureClient> D3D11RecycleAllocator::CreateOrRecycleClient(
}
mImageDevice = device;
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
const bool useFence =
fencesHolderMap && FenceD3D11::IsSupported(mImageDevice);
TextureAllocationFlags allocFlags = TextureAllocationFlags::ALLOC_DEFAULT;
if (StaticPrefs::media_wmf_use_sync_texture_AtStartup() ||
mDevice == DeviceManagerDx::Get()->GetCompositorDevice()) {
if (!useFence && (StaticPrefs::media_wmf_use_sync_texture_AtStartup() ||
mDevice == DeviceManagerDx::Get()->GetCompositorDevice())) {
// If our device is the compositor device, we don't need any synchronization
// in practice.
allocFlags = TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION;
@@ -201,6 +206,17 @@ already_AddRefed<TextureClient> D3D11RecycleAllocator::CreateOrRecycleClient(
RefPtr<TextureClient> textureClient =
CreateOrRecycle(helper).unwrapOr(nullptr);
if (textureClient) {
auto* textureData = textureClient->GetInternalData()->AsD3D11TextureData();
MOZ_ASSERT(textureData);
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
if (textureData && textureData->mFencesHolderId.isSome() &&
fencesHolderMap) {
fencesHolderMap->WaitAllFencesAndForget(
textureData->mFencesHolderId.ref(), mDevice);
}
}
return textureClient.forget();
}

View File

@@ -12,6 +12,7 @@
#include "D3D11TextureWrapper.h"
#include "WMF.h"
#include "mozilla/gfx/SourceSurfaceRawData.h"
#include "mozilla/layers/FenceD3D11.h"
#include "mozilla/layers/KnowsCompositor.h"
#include "mozilla/layers/TextureForwarder.h"
@@ -48,11 +49,19 @@ D3D11ZeroCopyTextureImage::D3D11ZeroCopyTextureImage(
MOZ_ASSERT(XRE_IsGPUProcess());
}
D3D11ZeroCopyTextureImage::~D3D11ZeroCopyTextureImage() {
// XXX add shutdown check for fence?
}
void D3D11ZeroCopyTextureImage::AllocateTextureClient(
KnowsCompositor* aKnowsCompositor, RefPtr<ZeroCopyUsageInfo> aUsageInfo) {
KnowsCompositor* aKnowsCompositor, RefPtr<ZeroCopyUsageInfo> aUsageInfo,
const RefPtr<FenceD3D11> aWriteFence) {
if (aWriteFence) {
aWriteFence->IncrementAndSignal();
}
mTextureClient = D3D11TextureData::CreateTextureClient(
mTexture, mArrayIndex, mSize, gfx::SurfaceFormat::NV12, mColorSpace,
mColorRange, aKnowsCompositor, aUsageInfo);
mColorRange, aKnowsCompositor, aUsageInfo, aWriteFence);
MOZ_ASSERT(mTextureClient);
}

View File

@@ -26,6 +26,8 @@ class GLBlitHelper;
}
namespace layers {
class FenceD3D11;
class ZeroCopyUsageInfo final {
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(ZeroCopyUsageInfo)
@@ -51,10 +53,11 @@ class D3D11ZeroCopyTextureImage : public Image {
gfx::ColorSpace2 aColorSpace,
gfx::ColorRange aColorRange,
gfx::ColorDepth aColorDepth);
virtual ~D3D11ZeroCopyTextureImage() = default;
virtual ~D3D11ZeroCopyTextureImage();
void AllocateTextureClient(KnowsCompositor* aKnowsCompositor,
RefPtr<ZeroCopyUsageInfo> aUsageInfo);
RefPtr<ZeroCopyUsageInfo> aUsageInfo,
const RefPtr<FenceD3D11> aWriteFence);
gfx::IntSize GetSize() const override;
already_AddRefed<gfx::SourceSurface> GetAsSourceSurface() override;

View File

@@ -312,16 +312,18 @@ static void UnlockD3DTexture(
}
}
D3D11TextureData::D3D11TextureData(ID3D11Texture2D* aTexture,
uint32_t aArrayIndex,
RefPtr<gfx::FileHandleWrapper> aSharedHandle,
gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
TextureAllocationFlags aFlags)
D3D11TextureData::D3D11TextureData(
ID3D11Device* aDevice, ID3D11Texture2D* aTexture, uint32_t aArrayIndex,
RefPtr<gfx::FileHandleWrapper> aSharedHandle, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat,
const Maybe<CompositeProcessFencesHolderId> aFencesHolderId,
const RefPtr<FenceD3D11> aWriteFence, TextureAllocationFlags aFlags)
: mSize(aSize),
mFormat(aFormat),
mNeedsClear(aFlags & ALLOC_CLEAR_BUFFER),
mHasKeyedMutex(HasKeyedMutex(aTexture)),
mFencesHolderId(aFencesHolderId),
mWriteFence(aWriteFence),
mNeedsClear(aFlags & ALLOC_CLEAR_BUFFER),
mTexture(aTexture),
mSharedHandle(std::move(aSharedHandle)),
mArrayIndex(aArrayIndex),
@@ -356,9 +358,22 @@ D3D11TextureData::~D3D11TextureData() {
gfxCriticalNoteOnce << "GpuProcessD3D11TextureMap does not exist";
}
}
if (mFencesHolderId.isSome()) {
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
if (fencesHolderMap) {
fencesHolderMap->Unregister(mFencesHolderId.ref());
gfxCriticalNoteOnce
<< "CompositeProcessD3D11FencesHolderMap does not exist";
}
}
}
bool D3D11TextureData::Lock(OpenMode aMode) {
if (mFencesHolderId.isSome()) {
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
fencesHolderMap->WaitAllFencesAndForget(mFencesHolderId.ref(), mDevice);
}
if (mHasKeyedMutex &&
!LockD3DTexture(mTexture.get(), SerializeWithMoz2D::Yes)) {
return false;
@@ -396,6 +411,10 @@ bool D3D11TextureData::PrepareDrawTargetInLock(OpenMode aMode) {
}
void D3D11TextureData::Unlock() {
if (mFencesHolderId.isSome()) {
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
fencesHolderMap->SetWriteFence(mFencesHolderId.ref(), mWriteFence);
}
if (mHasKeyedMutex) {
UnlockD3DTexture(mTexture.get(), SerializeWithMoz2D::Yes);
}
@@ -424,8 +443,7 @@ bool D3D11TextureData::SerializeSpecific(
SurfaceDescriptorD3D10* const aOutDesc) {
*aOutDesc = SurfaceDescriptorD3D10(
mSharedHandle, mGpuProcessTextureId, mArrayIndex, mFormat, mSize,
mColorSpace, mColorRange, /* hasKeyedMutex */ mHasKeyedMutex,
/* fencesHolderId */ Nothing());
mColorSpace, mColorRange, mHasKeyedMutex, mFencesHolderId);
return true;
}
@@ -450,10 +468,25 @@ already_AddRefed<TextureClient> D3D11TextureData::CreateTextureClient(
ID3D11Texture2D* aTexture, uint32_t aIndex, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat, gfx::ColorSpace2 aColorSpace,
gfx::ColorRange aColorRange, KnowsCompositor* aKnowsCompositor,
RefPtr<ZeroCopyUsageInfo> aUsageInfo) {
RefPtr<ZeroCopyUsageInfo> aUsageInfo,
const RefPtr<FenceD3D11> aWriteFence) {
MOZ_ASSERT(aTexture);
RefPtr<ID3D11Device> device;
aTexture->GetDevice(getter_AddRefs(device));
Maybe<CompositeProcessFencesHolderId> fencesHolderId;
if (aWriteFence) {
auto* fencesHolderMap = layers::CompositeProcessD3D11FencesHolderMap::Get();
fencesHolderId = Some(CompositeProcessFencesHolderId::GetNext());
fencesHolderMap->Register(fencesHolderId.ref());
} else {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
}
D3D11TextureData* data = new D3D11TextureData(
aTexture, aIndex, nullptr, aSize, aFormat,
TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
device, aTexture, aIndex, nullptr, aSize, aFormat, fencesHolderId,
aWriteFence, TextureAllocationFlags::ALLOC_MANUAL_SYNCHRONIZATION);
data->mColorSpace = aColorSpace;
data->SetColorRange(aColorRange);
@@ -519,16 +552,31 @@ D3D11TextureData* D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat,
newDesc.MiscFlags =
D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED;
bool useFence = false;
bool useKeyedMutex = false;
if (!NS_IsMainThread()) {
// On the main thread we use the syncobject to handle synchronization.
if (!(aFlags & ALLOC_MANUAL_SYNCHRONIZATION)) {
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
useKeyedMutex = true;
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
useFence = fencesHolderMap && FenceD3D11::IsSupported(device);
if (!useFence) {
newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED_NTHANDLE |
D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;
useKeyedMutex = true;
}
}
}
Maybe<CompositeProcessFencesHolderId> fencesHolderId;
RefPtr<FenceD3D11> fence;
if (useFence) {
fence = FenceD3D11::Create(device);
if (!fence) {
return nullptr;
}
fencesHolderId = Some(CompositeProcessFencesHolderId::GetNext());
}
if (aSurface && useKeyedMutex &&
!DeviceManagerDx::Get()->CanInitializeKeyedMutexTextures()) {
return nullptr;
@@ -621,8 +669,14 @@ D3D11TextureData* D3D11TextureData::Create(IntSize aSize, SurfaceFormat aFormat,
RefPtr<gfx::FileHandleWrapper> handle =
new gfx::FileHandleWrapper(UniqueFileHandle(sharedHandle));
if (useFence) {
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
fencesHolderMap->Register(fencesHolderId.ref());
}
D3D11TextureData* data =
new D3D11TextureData(texture11, 0, handle, aSize, aFormat, aFlags);
new D3D11TextureData(device, texture11, 0, handle, aSize, aFormat,
fencesHolderId, fence, aFlags);
texture11->GetDevice(getter_AddRefs(device));
if (XRE_IsGPUProcess() &&
@@ -659,6 +713,20 @@ TextureFlags D3D11TextureData::GetTextureFlags() const {
return TextureFlags::WAIT_HOST_USAGE_END;
}
void D3D11TextureData::IncrementAndSignalWriteFence() {
if (!mFencesHolderId.isNothing() || !mWriteFence) {
return;
}
auto* fencesHolderMap = CompositeProcessD3D11FencesHolderMap::Get();
if (!fencesHolderMap) {
MOZ_ASSERT_UNREACHABLE("unexpected to be called");
return;
}
mWriteFence->IncrementAndSignal();
fencesHolderMap->SetWriteFence(mFencesHolderId.ref(), mWriteFence);
}
DXGIYCbCrTextureData* DXGIYCbCrTextureData::Create(
ID3D11Texture2D* aTextureY, ID3D11Texture2D* aTextureCb,
ID3D11Texture2D* aTextureCr, const gfx::IntSize& aSize,
@@ -898,7 +966,7 @@ static RefPtr<ID3D11Texture2D> OpenSharedD3D11Texture(
RefPtr<ID3D11Texture2D> texture;
if (gpuProcessTextureId.isSome()) {
auto* textureMap = layers::GpuProcessD3D11TextureMap::Get();
auto* textureMap = GpuProcessD3D11TextureMap::Get();
if (textureMap) {
texture = textureMap->GetTexture(gpuProcessTextureId.ref());
}
@@ -1010,13 +1078,33 @@ DXGITextureHostD3D11::GetAsSurfaceWithDevice(
return nullptr;
}
bool isLocked = LockD3DTexture(d3dTexture.get());
if (!isLocked) {
RefPtr<ID3D11Device> device;
d3dTexture->GetDevice(getter_AddRefs(device));
if (!device) {
gfxCriticalNoteOnce << "Failed to get D3D11 device from source texture";
return nullptr;
}
const auto onExit =
mozilla::MakeScopeExit([&]() { UnlockD3DTexture(d3dTexture.get()); });
if (mFencesHolderId.isSome()) {
auto* fencesHolderMap = layers::CompositeProcessD3D11FencesHolderMap::Get();
MOZ_ASSERT(fencesHolderMap);
if (!fencesHolderMap) {
return nullptr;
}
fencesHolderMap->WaitWriteFence(mFencesHolderId.ref(), device);
} else {
bool isLocked = LockD3DTexture(d3dTexture.get());
if (!isLocked) {
return nullptr;
}
}
const auto onExit = mozilla::MakeScopeExit([&]() {
if (mFencesHolderId.isSome()) {
return;
}
UnlockD3DTexture(d3dTexture.get());
});
bool isRGB = [&]() {
switch (mFormat) {
@@ -1055,13 +1143,6 @@ DXGITextureHostD3D11::GetAsSurfaceWithDevice(
return nullptr;
}
RefPtr<ID3D11Device> device;
d3dTexture->GetDevice(getter_AddRefs(device));
if (!device) {
gfxCriticalNoteOnce << "Failed to get D3D11 device from source texture";
return nullptr;
}
RefPtr<ID3D11DeviceContext> context;
device->GetImmediateContext(getter_AddRefs(context));

View File

@@ -72,7 +72,8 @@ class D3D11TextureData final : public TextureData {
ID3D11Texture2D* aTexture, uint32_t aIndex, gfx::IntSize aSize,
gfx::SurfaceFormat aFormat, gfx::ColorSpace2 aColorSpace,
gfx::ColorRange aColorRange, KnowsCompositor* aKnowsCompositor,
RefPtr<ZeroCopyUsageInfo> aUsageInfo);
RefPtr<ZeroCopyUsageInfo> aUsageInfo,
const RefPtr<FenceD3D11> aWriteFence);
virtual ~D3D11TextureData();
@@ -123,10 +124,15 @@ class D3D11TextureData final : public TextureData {
return mGpuProcessTextureId;
}
void IncrementAndSignalWriteFence();
private:
D3D11TextureData(ID3D11Texture2D* aTexture, uint32_t aArrayIndex,
D3D11TextureData(ID3D11Device* aDevice, ID3D11Texture2D* aTexture,
uint32_t aArrayIndex,
RefPtr<gfx::FileHandleWrapper> aSharedHandle,
gfx::IntSize aSize, gfx::SurfaceFormat aFormat,
const Maybe<CompositeProcessFencesHolderId> aFencesHolderId,
const RefPtr<FenceD3D11> aWriteFence,
TextureAllocationFlags aFlags);
bool PrepareDrawTargetInLock(OpenMode aMode);
@@ -143,17 +149,20 @@ class D3D11TextureData final : public TextureData {
// Hold on to the DrawTarget because it is expensive to create one each
// ::Lock.
RefPtr<gfx::DrawTarget> mDrawTarget;
const gfx::IntSize mSize;
const gfx::SurfaceFormat mFormat;
public:
const gfx::IntSize mSize;
const gfx::SurfaceFormat mFormat;
const bool mHasKeyedMutex;
const Maybe<CompositeProcessFencesHolderId> mFencesHolderId;
const RefPtr<FenceD3D11> mWriteFence;
gfx::ColorSpace2 mColorSpace = gfx::ColorSpace2::SRGB;
private:
gfx::ColorRange mColorRange = gfx::ColorRange::LIMITED;
bool mNeedsClear = false;
const bool mHasKeyedMutex;
const RefPtr<ID3D11Device> mDevice;
RefPtr<ID3D11Texture2D> mTexture;
const RefPtr<gfx::FileHandleWrapper> mSharedHandle;
Maybe<GpuProcessTextureId> mGpuProcessTextureId;
@@ -397,7 +406,7 @@ class DXGITextureHostD3D11 : public TextureHost {
const gfx::IntSize mSize;
const gfx::SurfaceFormat mFormat;
const bool mHasKeyedMutex;
const Maybe<layers::CompositeProcessFencesHolderId> mFencesHolderId;
const Maybe<CompositeProcessFencesHolderId> mFencesHolderId;
const gfx::ColorSpace2 mColorSpace;
const gfx::ColorRange mColorRange;
};

View File

@@ -23,6 +23,7 @@
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/gfx/Matrix.h"
#include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
#include "mozilla/StaticPrefs_gfx.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/webrender/RenderD3D11TextureHost.h"
@@ -2035,6 +2036,7 @@ bool DCSurfaceVideo::CallVideoProcessorBlt() {
MOZ_ASSERT(mRenderTextureHost);
HRESULT hr;
const auto device = mDCLayerTree->GetDevice();
const auto videoDevice = mDCLayerTree->GetVideoDevice();
const auto videoContext = mDCLayerTree->GetVideoContext();
const auto texture = mRenderTextureHost->AsRenderDXGITextureHost();
@@ -2056,6 +2058,12 @@ bool DCSurfaceVideo::CallVideoProcessorBlt() {
return false;
}
if (texture->mFencesHolderId.isSome()) {
auto* fencesHolderMap = layers::CompositeProcessD3D11FencesHolderMap::Get();
MOZ_ASSERT(fencesHolderMap);
fencesHolderMap->WaitWriteFence(texture->mFencesHolderId.ref(), device);
}
RefPtr<IDXGISwapChain3> swapChain3;
mVideoSwapChain->QueryInterface(
(IDXGISwapChain3**)getter_AddRefs(swapChain3));