tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Agfx/2d/SourceSurfaceD3D11.cpp | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Agfx/2d/SourceSurfaceD3D11.h | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mgfx/2d/Types.h | 1+
Mgfx/2d/moz.build | 2++
Mgfx/layers/d3d11/GpuProcessD3D11TextureMap.cpp | 19+++++++++++++++++++
Mgfx/layers/d3d11/GpuProcessD3D11TextureMap.h | 1+
Mgfx/layers/d3d11/TextureD3D11.cpp | 35++++++++++++++++++++++++++++++-----
Mgfx/layers/d3d11/TextureD3D11.h | 3+--
Mgfx/layers/ipc/CanvasTranslator.cpp | 15+--------------
Mgfx/layers/ipc/CanvasTranslator.h | 4----
Mmodules/libpref/init/StaticPrefList.yaml | 2+-
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