commit e242af0af55078242b4ee6616b500334188587a9
parent f5b90a54c0aeae46aa5234d39bf1a2a081d6d24b
Author: Sotaro Ikeda <sotaro.ikeda.g@gmail.com>
Date: Thu, 30 Oct 2025 13:12:41 +0000
Bug 1997248 - Revive DXGITextureHostD3D11::GetAsSurfaceWithDevice() and canvas2d video rendering fast path on Windows r=gfx-reviewers,nical
DXGITextureHostD3D11::GetAsSurfaceWithDevice() implementation was removed by Bug 1996124. It also caused to disable canvas2d video rendering fast path.
Differential Revision: https://phabricator.services.mozilla.com/D270637
Diffstat:
11 files changed, 173 insertions(+), 26 deletions(-)
diff --git a/gfx/2d/SourceSurfaceD3D11.cpp b/gfx/2d/SourceSurfaceD3D11.cpp
@@ -0,0 +1,63 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "SourceSurfaceD3D11.h"
+
+namespace mozilla {
+namespace gfx {
+
+/* static */
+RefPtr<SourceSurfaceD3D11> SourceSurfaceD3D11::Create(
+ ID3D11Texture2D* aTexture, const uint32_t aArrayIndex,
+ const gfx::ColorSpace2 aColorSpace, const gfx::ColorRange aColorRange,
+ const Maybe<layers::CompositeProcessFencesHolderId> aFencesHolderId) {
+ MOZ_ASSERT(aTexture);
+
+ if (!aTexture) {
+ return nullptr;
+ }
+
+ CD3D11_TEXTURE2D_DESC desc;
+ aTexture->GetDesc(&desc);
+
+ if (desc.Format != DXGI_FORMAT_B8G8R8A8_UNORM &&
+ desc.Format != DXGI_FORMAT_NV12 && desc.Format != DXGI_FORMAT_P010 &&
+ desc.Format != DXGI_FORMAT_P016) {
+ MOZ_ASSERT_UNREACHABLE("unexpected to be called");
+ return nullptr;
+ }
+
+ return MakeAndAddRef<SourceSurfaceD3D11>(
+ SurfaceFormat::B8G8R8A8, IntSize(desc.Width, desc.Height), aTexture,
+ aArrayIndex, aColorSpace, aColorRange, aFencesHolderId);
+}
+
+SourceSurfaceD3D11::SourceSurfaceD3D11(
+ const SurfaceFormat aFormat, const IntSize aSize, ID3D11Texture2D* aTexture,
+ const uint32_t aArrayIndex, const gfx::ColorSpace2 aColorSpace,
+ const gfx::ColorRange aColorRange,
+ const Maybe<layers::CompositeProcessFencesHolderId> aFencesHolderId)
+ : mFormat(aFormat),
+ mSize(aSize),
+ mTexture(aTexture),
+ mArrayIndex(aArrayIndex),
+ mColorSpace(aColorSpace),
+ mColorRange(aColorRange),
+ mFencesHolderId(aFencesHolderId) {}
+
+SourceSurfaceD3D11::~SourceSurfaceD3D11() {}
+
+bool SourceSurfaceD3D11::IsValid() const { return true; }
+
+already_AddRefed<DataSourceSurface> SourceSurfaceD3D11::GetDataSurface() {
+ RefPtr<DataSourceSurface> src =
+ Factory::CreateBGRA8DataSourceSurfaceForD3D11Texture(
+ mTexture, mArrayIndex, mColorSpace, mColorRange);
+ return src.forget();
+}
+
+} // namespace gfx
+} // namespace mozilla
diff --git a/gfx/2d/SourceSurfaceD3D11.h b/gfx/2d/SourceSurfaceD3D11.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef MOZILLA_GFX_SourceSurfaceD3D11_H_
+#define MOZILLA_GFX_SourceSurfaceD3D11_H_
+
+#include <d3d11.h>
+
+#include "mozilla/gfx/2D.h"
+#include "mozilla/layers/LayersTypes.h"
+
+namespace mozilla {
+namespace gfx {
+
+class SourceSurfaceD3D11 : public SourceSurface {
+ public:
+ MOZ_DECLARE_REFCOUNTED_VIRTUAL_TYPENAME(SourceSurfaceD3D11, override)
+
+ static RefPtr<SourceSurfaceD3D11> Create(
+ ID3D11Texture2D* aTexture, const uint32_t aArrayIndex,
+ const gfx::ColorSpace2 aColorSpace, const gfx::ColorRange aColorRange,
+ const Maybe<layers::CompositeProcessFencesHolderId> aFencesHolderId);
+
+ SourceSurfaceD3D11(
+ const SurfaceFormat aFormat, const IntSize aSize,
+ ID3D11Texture2D* aTexture, const uint32_t aArrayIndex,
+ const gfx::ColorSpace2 aColorSpace, const gfx::ColorRange aColorRange,
+ const Maybe<layers::CompositeProcessFencesHolderId> aFencesHolderId);
+ ~SourceSurfaceD3D11();
+
+ SurfaceType GetType() const override { return SurfaceType::D3D11_TEXTURE; }
+ IntSize GetSize() const override { return mSize; }
+ SurfaceFormat GetFormat() const override { return mFormat; }
+ bool IsValid() const override;
+ already_AddRefed<DataSourceSurface> GetDataSurface() override;
+
+ ID3D11Texture2D* GetD3D11Texture() { return mTexture; }
+
+ const SurfaceFormat mFormat;
+ const IntSize mSize;
+ const RefPtr<ID3D11Texture2D> mTexture;
+ const uint32_t mArrayIndex;
+ const ColorSpace2 mColorSpace;
+ const ColorRange mColorRange;
+ const Maybe<layers::CompositeProcessFencesHolderId> mFencesHolderId;
+};
+
+} // namespace gfx
+} // namespace mozilla
+
+#endif /* MOZILLA_GFX_SourceSurfaceD3D11_H_ */
diff --git a/gfx/2d/Types.h b/gfx/2d/Types.h
@@ -40,6 +40,7 @@ enum class SurfaceType : int8_t {
BLOB_IMAGE, /* Recorded blob image */
DATA_MAPPED, /* Data surface wrapping a ScopedMap */
WEBGL, /* Surface wrapping a DrawTargetWebgl texture */
+ D3D11_TEXTURE, /* Surface wrapping a D3D11Texture */
};
enum class SurfaceFormat : int8_t {
diff --git a/gfx/2d/moz.build b/gfx/2d/moz.build
@@ -80,6 +80,7 @@ if CONFIG["MOZ_WIDGET_TOOLKIT"] in ("cocoa", "uikit"):
elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
EXPORTS.mozilla.gfx += [
"DWriteSettings.h",
+ "SourceSurfaceD3D11.h",
"UnscaledFontDWrite.h",
"UnscaledFontGDI.h",
]
@@ -89,6 +90,7 @@ elif CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows":
"NativeFontResourceGDI.cpp",
"ScaledFontDWrite.cpp",
"ScaledFontWin.cpp",
+ "SourceSurfaceD3D11.cpp",
]
DEFINES["WIN32"] = True
diff --git a/gfx/layers/d3d11/GpuProcessD3D11TextureMap.cpp b/gfx/layers/d3d11/GpuProcessD3D11TextureMap.cpp
@@ -207,6 +207,25 @@ Maybe<HANDLE> GpuProcessD3D11TextureMap::GetSharedHandle(
return Some(handle->GetHandle());
}
+void GpuProcessD3D11TextureMap::DisableZeroCopyNV12Texture(
+ GpuProcessTextureId aTextureId) {
+ MonitorAutoLock lock(mMonitor);
+
+ auto it = mD3D11TexturesById.find(aTextureId);
+ if (it == mD3D11TexturesById.end()) {
+ MOZ_ASSERT_UNREACHABLE("unexpected to be called");
+ return;
+ }
+
+ if (!it->second.mZeroCopyUsageInfo) {
+ return;
+ }
+
+ // Disable no video copy for future decoded video frames. Since
+ // Get SharedHandle of copied Texture() is slow.
+ it->second.mZeroCopyUsageInfo->DisableZeroCopyNV12Texture();
+}
+
size_t GpuProcessD3D11TextureMap::GetWaitingTextureCount() const {
MonitorAutoLock lock(mMonitor);
return mWaitingTextures.size();
diff --git a/gfx/layers/d3d11/GpuProcessD3D11TextureMap.h b/gfx/layers/d3d11/GpuProcessD3D11TextureMap.h
@@ -53,6 +53,7 @@ class GpuProcessD3D11TextureMap {
RefPtr<ID3D11Texture2D> GetTexture(GpuProcessTextureId aTextureId);
Maybe<HANDLE> GetSharedHandle(GpuProcessTextureId aTextureId);
+ void DisableZeroCopyNV12Texture(GpuProcessTextureId aTextureId);
size_t GetWaitingTextureCount() const;
diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp
@@ -20,6 +20,7 @@
#include "mozilla/gfx/FileHandleWrapper.h"
#include "mozilla/gfx/Logging.h"
#include "mozilla/gfx/gfxVars.h"
+#include "mozilla/gfx/SourceSurfaceD3D11.h"
#include "mozilla/ipc/FileDescriptor.h"
#include "mozilla/layers/CompositorBridgeChild.h"
#include "mozilla/layers/D3D11ZeroCopyTextureImage.h"
@@ -27,7 +28,6 @@
#include "mozilla/layers/CompositeProcessD3D11FencesHolderMap.h"
#include "mozilla/layers/GpuProcessD3D11TextureMap.h"
#include "mozilla/layers/HelpersD3D11.h"
-#include "mozilla/layers/VideoProcessorD3D11.h"
#include "mozilla/webrender/RenderD3D11TextureHost.h"
#include "mozilla/webrender/RenderThread.h"
#include "mozilla/webrender/WebRenderAPI.h"
@@ -1023,10 +1023,35 @@ already_AddRefed<gfx::DataSourceSurface> DXGITextureHostD3D11::GetAsSurface(
}
already_AddRefed<gfx::DataSourceSurface>
-DXGITextureHostD3D11::GetAsSurfaceWithDevice(
- ID3D11Device* const aDevice,
- DataMutex<RefPtr<VideoProcessorD3D11>>& aVideoProcessorD3D11) {
- return nullptr;
+DXGITextureHostD3D11::GetAsSurfaceWithDevice(ID3D11Device* const aDevice) {
+ if (!aDevice) {
+ return nullptr;
+ }
+
+ RefPtr<ID3D11Texture2D> d3dTexture = OpenSharedD3D11Texture(this, aDevice);
+ if (!d3dTexture) {
+ return nullptr;
+ }
+
+ if (mGpuProcessTextureId.isSome()) {
+ auto* textureMap = layers::GpuProcessD3D11TextureMap::Get();
+ if (textureMap) {
+ textureMap->DisableZeroCopyNV12Texture(mGpuProcessTextureId.ref());
+ }
+ }
+
+ RefPtr<gfx::SourceSurface> sourceSurface = gfx::SourceSurfaceD3D11::Create(
+ d3dTexture, mArrayIndex, mColorSpace, mColorRange, mFencesHolderId);
+ if (!sourceSurface) {
+ return nullptr;
+ }
+
+ RefPtr<DataSourceSurface> dataSurface = sourceSurface->GetDataSurface();
+ if (!dataSurface) {
+ return nullptr;
+ }
+
+ return dataSurface.forget();
}
void DXGITextureHostD3D11::CreateRenderTexture(
diff --git a/gfx/layers/d3d11/TextureD3D11.h b/gfx/layers/d3d11/TextureD3D11.h
@@ -372,8 +372,7 @@ class DXGITextureHostD3D11 : public TextureHost {
// Return DataSourceSurface using aDevice withou readback to CPU.
already_AddRefed<gfx::DataSourceSurface> GetAsSurfaceWithDevice(
- ID3D11Device* const aDevice,
- DataMutex<RefPtr<VideoProcessorD3D11>>& aVideoProcessorD3D11);
+ ID3D11Device* const aDevice);
void CreateRenderTexture(
const wr::ExternalImageId& aExternalImageId) override;
diff --git a/gfx/layers/ipc/CanvasTranslator.cpp b/gfx/layers/ipc/CanvasTranslator.cpp
@@ -38,7 +38,6 @@
#if defined(XP_WIN)
# include "mozilla/gfx/DeviceManagerDx.h"
# include "mozilla/layers/TextureD3D11.h"
-# include "mozilla/layers/VideoProcessorD3D11.h"
#endif
namespace mozilla {
@@ -69,9 +68,6 @@ CanvasTranslator::CanvasTranslator(
layers::SharedSurfacesHolder* aSharedSurfacesHolder,
const dom::ContentParentId& aContentId, uint32_t aManagerId)
: mSharedSurfacesHolder(aSharedSurfacesHolder),
-#if defined(XP_WIN)
- mVideoProcessorD3D11("CanvasTranslator::mVideoProcessorD3D11"),
-#endif
mMaxSpinCount(StaticPrefs::gfx_canvas_remote_max_spin_count()),
mContentId(aContentId),
mManagerId(aManagerId),
@@ -468,14 +464,6 @@ void CanvasTranslator::ActorDestroy(ActorDestroyReason why) {
mPendingCanvasTranslatorEvents.clear();
}
-#if defined(XP_WIN)
- {
- auto lock = mVideoProcessorD3D11.Lock();
- auto& videoProcessor = lock.ref();
- videoProcessor = nullptr;
- }
-#endif
-
DispatchToTaskQueue(NewRunnableMethod("CanvasTranslator::ClearTextureInfo",
this,
&CanvasTranslator::ClearTextureInfo));
@@ -1544,8 +1532,7 @@ CanvasTranslator::LookupSourceSurfaceFromSurfaceDescriptor(
if (RefPtr<ID3D11Device> device =
gfx::DeviceManagerDx::Get()->GetCanvasDevice()) {
- usedSurf = textureHostD3D11->GetAsSurfaceWithDevice(device,
- mVideoProcessorD3D11);
+ usedSurf = textureHostD3D11->GetAsSurfaceWithDevice(device);
} else {
usedSurf = nullptr;
}
diff --git a/gfx/layers/ipc/CanvasTranslator.h b/gfx/layers/ipc/CanvasTranslator.h
@@ -49,7 +49,6 @@ namespace layers {
class SharedSurfacesHolder;
class TextureData;
class TextureHost;
-class VideoProcessorD3D11;
class CanvasTranslator final : public gfx::InlineTranslator,
public PCanvasParent {
@@ -474,9 +473,6 @@ class CanvasTranslator final : public gfx::InlineTranslator,
void NotifyTextureDestruction(const RemoteTextureOwnerId aTextureOwnerId);
const RefPtr<SharedSurfacesHolder> mSharedSurfacesHolder;
-#if defined(XP_WIN)
- DataMutex<RefPtr<VideoProcessorD3D11>> mVideoProcessorD3D11;
-#endif
static StaticRefPtr<gfx::SharedContextWebgl> sSharedContext;
RefPtr<gfx::SharedContextWebgl> mSharedContext;
RefPtr<RemoteTextureOwnerClient> mRemoteTextureOwner;
diff --git a/modules/libpref/init/StaticPrefList.yaml b/modules/libpref/init/StaticPrefList.yaml
@@ -6837,7 +6837,7 @@
- name: gfx.canvas.remote.use-draw-image-fast-path-d3d
type: RelaxedAtomicBool
- value: false
+ value: true
mirror: always
- name: gfx.canvas.remote.recycle-used-data-surface