0

Do not call EstablishGpuChannel if the gpu remote has been disconnected

The GPU channel cannot be established when gpu_remote is disconnected.
Stop calling RequestNewLayerTreeFrameSink because it's going to fail
again and it will be stuck in a forever loop of retries. This makes the
processes unable to be killed after Chrome is closed.

Bug: 336164423
Change-Id: Ie7db1df5531e178b2d06063c10c23ded917217b8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5676887
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Reviewed-by: Vasiliy Telezhnikov <vasilyt@chromium.org>
Commit-Queue: Maggie Chen <magchen@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1323390}
This commit is contained in:
Maggie Chen
2024-07-04 16:19:36 +00:00
committed by Chromium LUCI CQ
parent 434755046b
commit 40a628aad4
9 changed files with 43 additions and 6 deletions
content/renderer
services/viz/public/cpp/gpu
third_party/blink
public
platform
renderer
platform
exported
widget

@ -1413,6 +1413,9 @@ void RenderThreadImpl::CompositingModeFallbackToSoftware() {
is_gpu_compositing_disabled_ = true;
}
bool RenderThreadImpl::IsGpuRemoteDisconnected() {
return gpu_->gpu_remote_disconnected();
}
scoped_refptr<gpu::GpuChannelHost> RenderThreadImpl::EstablishGpuChannelSync() {
TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");

@ -212,6 +212,8 @@ class CONTENT_EXPORT RenderThreadImpl
// the appropriate mode.
bool IsGpuCompositingDisabled() const { return is_gpu_compositing_disabled_; }
bool IsGpuRemoteDisconnected();
// Synchronously establish a channel to the GPU plugin if not previously
// established or if it has been lost (for example if the GPU plugin crashed).
// If there is a pending asynchronous request, it will be completed by the

@ -529,6 +529,10 @@ RendererBlinkPlatformImpl::SharedCompositorWorkerContextProvider(
dark_mode_filter);
}
bool RendererBlinkPlatformImpl::IsGpuRemoteDisconnected() {
return RenderThreadImpl::current()->IsGpuRemoteDisconnected();
}
scoped_refptr<gpu::GpuChannelHost>
RendererBlinkPlatformImpl::EstablishGpuChannelSync() {
return RenderThreadImpl::current()->EstablishGpuChannelSync();

@ -144,6 +144,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl {
scoped_refptr<cc::RasterContextProviderWrapper>
SharedCompositorWorkerContextProvider(
cc::RasterDarkModeFilter* dark_mode_filter) override;
bool IsGpuRemoteDisconnected() override;
scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
void EstablishGpuChannel(EstablishGpuChannelCallback callback) override;
bool RTCSmoothnessAlgorithmEnabled() override;

@ -116,6 +116,8 @@ class Gpu::EstablishRequest
return gpu_channel_;
}
bool gpu_remote_disconnected() { return gpu_remote_disconnected_; }
// Sends EstablishGpuChannel() request using |gpu|. This must be called from
// the IO thread so that the response is handled on the IO thread.
void SendRequest(GpuPtrIO* gpu) {
@ -180,7 +182,8 @@ class Gpu::EstablishRequest
mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
const gpu::SharedImageCapabilities& shared_image_capabilities) {
const gpu::SharedImageCapabilities& shared_image_capabilities,
bool gpu_remote_disconnected) {
DCHECK(!main_task_runner_->BelongsToCurrentThread());
base::AutoLock lock(lock_);
@ -195,6 +198,7 @@ class Gpu::EstablishRequest
client_id, gpu_info, gpu_feature_info, shared_image_capabilities,
std::move(channel_handle));
}
gpu_remote_disconnected_ = gpu_remote_disconnected;
if (establish_event_) {
// Gpu::EstablishGpuChannelSync() was called. Unblock the main thread and
@ -224,6 +228,7 @@ class Gpu::EstablishRequest
bool finished_ = false;
scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
bool gpu_remote_disconnected_ = false;
};
void Gpu::GpuPtrIO::ConnectionError() {
@ -236,7 +241,7 @@ void Gpu::GpuPtrIO::ConnectionError() {
// forever after calling Gpu::EstablishGpuChannelSync().
establish_request_->OnEstablishedGpuChannel(
0, mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(), gpu::GpuFeatureInfo(),
gpu::SharedImageCapabilities());
gpu::SharedImageCapabilities(), /*gpu_remote_disconnected=*/true);
establish_request_.reset();
}
@ -251,7 +256,8 @@ void Gpu::GpuPtrIO::OnEstablishedGpuChannel(
establish_request_->OnEstablishedGpuChannel(
client_id, std::move(channel_handle), std::move(gpu_info),
std::move(gpu_feature_info), std::move(shared_image_capabilities));
std::move(gpu_feature_info), std::move(shared_image_capabilities),
/*gpu_remote_disconnected=*/false);
establish_request_.reset();
}
@ -417,6 +423,7 @@ void Gpu::OnEstablishedGpuChannel() {
DCHECK(!gpu_channel_);
gpu_channel_ = pending_request_->gpu_channel();
gpu_remote_disconnected_ = pending_request_->gpu_remote_disconnected();
pending_request_.reset();
std::vector<gpu::GpuChannelEstablishedCallback> callbacks;

@ -6,6 +6,9 @@
#define SERVICES_VIZ_PUBLIC_CPP_GPU_GPU_H_
#include <stdint.h>
#include <memory>
#include <string>
#include <vector>
#include "base/memory/scoped_refptr.h"
@ -60,6 +63,8 @@ class Gpu : public gpu::GpuChannelEstablishFactory {
scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync() override;
gpu::GpuMemoryBufferManager* GetGpuMemoryBufferManager() override;
bool gpu_remote_disconnected() { return gpu_remote_disconnected_; }
void LoseChannel();
scoped_refptr<gpu::GpuChannelHost> GetGpuChannel();
@ -87,6 +92,7 @@ class Gpu : public gpu::GpuChannelEstablishFactory {
std::unique_ptr<GpuPtrIO, base::OnTaskRunnerDeleter> gpu_;
scoped_refptr<EstablishRequest> pending_request_;
scoped_refptr<gpu::GpuChannelHost> gpu_channel_;
bool gpu_remote_disconnected_ = false;
std::vector<gpu::GpuChannelEstablishedCallback> establish_callbacks_;
};

@ -579,6 +579,9 @@ class BLINK_PLATFORM_EXPORT Platform {
// time this routine returns.
virtual scoped_refptr<gpu::GpuChannelHost> EstablishGpuChannelSync();
// Is mojo::Remote<mojom::Gpu> disconnected?
virtual bool IsGpuRemoteDisconnected();
// Same as above, but asynchronous.
using EstablishGpuChannelCallback =
base::OnceCallback<void(scoped_refptr<gpu::GpuChannelHost>)>;

@ -317,6 +317,10 @@ scoped_refptr<gpu::GpuChannelHost> Platform::EstablishGpuChannelSync() {
return nullptr;
}
bool Platform::IsGpuRemoteDisconnected() {
return false;
}
void Platform::EstablishGpuChannel(EstablishGpuChannelCallback callback) {
std::move(callback).Run(nullptr);
}

@ -369,9 +369,16 @@ void LayerTreeView::DidFailToInitializeLayerTreeFrameSink() {
}
frame_sink_state_ = FrameSinkState::kNoFrameSink;
layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink,
weak_factory_.GetWeakPtr()));
// The GPU channel cannot be established when gpu_remote is disconnected. Stop
// calling RequestNewLayerTreeFrameSink because it's going to fail again and
// it will be stuck in a forever loop of retries. This makes the processes
// unable to be killed after Chrome is closed.
// https://issues.chromium.org/336164423
if (!Platform::Current()->IsGpuRemoteDisconnected()) {
layer_tree_host_->GetTaskRunnerProvider()->MainThreadTaskRunner()->PostTask(
FROM_HERE, base::BindOnce(&LayerTreeView::RequestNewLayerTreeFrameSink,
weak_factory_.GetWeakPtr()));
}
}
void LayerTreeView::WillCommit(const cc::CommitState&) {