0

[Windows] Disallow media service on dedicated thread with Ganesh.

When SkiaGraphite is not enabled, turning on dedicated media service
thread will introduce rendering performance regression on Windows. If
Ganesh is used or when dawn is not backed by either D3D11 or D3D12, we
run media service on GPU main to avoid turning on multi-thread
protection.

Bug: 375237130
Change-Id: Ic7cbffacb3d59ae202ba8232cb571845c6394ca2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5965653
Commit-Queue: Jianlin Qiu <jianlin.qiu@intel.com>
Reviewed-by: Dale Curtis <dalecurtis@chromium.org>
Reviewed-by: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1379393}
This commit is contained in:
Qiu Jianlin
2024-11-07 01:06:50 +00:00
committed by Chromium LUCI CQ
parent 66ea717c10
commit b518597f6a
3 changed files with 38 additions and 23 deletions

@ -51,12 +51,33 @@ GpuServiceFactory::~GpuServiceFactory() {}
void GpuServiceFactory::RunMediaService(
mojo::PendingReceiver<media::mojom::MediaService> receiver) {
#if BUILDFLAG(ENABLE_MOJO_MEDIA_IN_GPU_PROCESS)
// This service will host audio/video decoders, and if these decoding
// operations are blocked, user may hear audio glitch or see video
// freezing, hence "user blocking".
scoped_refptr<base::SequencedTaskRunner> task_runner = task_runner_;
if (media::IsDedicatedMediaServiceThreadEnabled(
gpu_info_.gl_implementation_parts.angle)) {
const bool use_dedicated_media_service_thread = [&]() {
#if BUILDFLAG(IS_WIN)
bool is_dawn_d3d_enabled = false;
// On Windows, check if we are using the Graphite D3D backend. There
// is rendering performance impact caused by lock contention on the
// D3D11 API lock, and Dawn mitigate this by batching API calls under
// the lock.
if (media_gpu_channel_manager_) {
if (auto shared_context_state =
media_gpu_channel_manager_->GetSharedContextState()) {
is_dawn_d3d_enabled = shared_context_state->IsGraphiteDawnD3D();
}
}
if (!is_dawn_d3d_enabled) {
return false;
}
#endif
return media::IsDedicatedMediaServiceThreadEnabled(
gpu_info_.gl_implementation_parts.angle);
}();
if (use_dedicated_media_service_thread) {
// This service will host audio/video decoders, and if these decoding
// operations are blocked, user may hear audio glitch or see video
// freezing, hence "user blocking".
if (base::FeatureList::IsEnabled(
media::kUseSequencedTaskRunnerForMediaService)) {
task_runner = base::ThreadPool::CreateSequencedTaskRunner(

@ -200,13 +200,14 @@ DefaultTexture2DWrapper::GpuResources::GpuResources(
gpu::SHARED_IMAGE_USAGE_GLES2_READ | gpu::SHARED_IMAGE_USAGE_RASTER_READ |
gpu::SHARED_IMAGE_USAGE_DISPLAY_READ | gpu::SHARED_IMAGE_USAGE_SCANOUT;
HRESULT hr = S_OK;
scoped_refptr<gpu::DXGISharedHandleState> dxgi_shared_handle_state;
D3D11_TEXTURE2D_DESC desc = {};
texture->GetDesc(&desc);
// Create shared handle for shareable output texture.
if (desc.MiscFlags & D3D11_RESOURCE_MISC_SHARED_NTHANDLE) {
ComDXGIResource1 dxgi_resource;
HRESULT hr = texture.As(&dxgi_resource);
hr = texture.As(&dxgi_resource);
if (FAILED(hr)) {
DLOG(ERROR) << "QueryInterface for IDXGIResource failed with error "
<< std::hex << hr;
@ -234,7 +235,16 @@ DefaultTexture2DWrapper::GpuResources::GpuResources(
->CreateAnonymousSharedHandleState(
base::win::ScopedHandle(shared_handle), texture);
}
Microsoft::WRL::ComPtr<ID3D11Multithread> multi_threaded;
hr = video_device.As(&multi_threaded);
CHECK_EQ(hr, S_OK);
// When |video_device| has multi-thread protection turned on, SkiaGraphite
// is ensured to be enabled. However we don't need to enable locking on the
// shared image if media service runs on main thread.
const bool is_thread_safe =
multi_threaded->GetMultithreadProtected() &&
IsDedicatedMediaServiceThreadEnabled(gl::ANGLEImplementation::kD3D11);
gpu::SharedImageInfo si_info{

@ -40,22 +40,7 @@ class GpuMojoMediaClientWin final : public GpuMojoMediaClient {
traits.media_gpu_channel_manager
? traits.media_gpu_channel_manager->GetSharedContextState()
: nullptr,
traits) {
// D3D11 multi-thread protection must be enabled before the device is used
// on other threads than the one it was created on.
// See https://crbugs.com/361718010 for more details.
if (!gpu_workarounds_.disable_d3d11_video_decoder) {
if (IsDedicatedMediaServiceThreadEnabled(
gpu_info_.gl_implementation_parts.angle) &&
d3d11_device_) {
Microsoft::WRL::ComPtr<ID3D11Multithread> multi_threaded;
auto hr = d3d11_device_->QueryInterface(IID_PPV_ARGS(&multi_threaded));
CHECK(SUCCEEDED(hr));
multi_threaded->SetMultithreadProtected(TRUE);
multithread_protected_ = true;
}
}
}
traits) {}
~GpuMojoMediaClientWin() final = default;
@ -183,7 +168,6 @@ class GpuMojoMediaClientWin final : public GpuMojoMediaClient {
d3d11_device_, d3d12_device_);
}
bool multithread_protected_ = false;
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
Microsoft::WRL::ComPtr<ID3D12Device> d3d12_device_;
};