Skip to content

Commit

Permalink
PreEstablish a GPU channel in RenderProcessHostImpl before renderer a…
Browse files Browse the repository at this point in the history
…sks for one.

BUG=783512
TEST=bots
R=piman@chromium.org

Change-Id: I331bc073ebb2fb77aaffd074fd97e979b057ee44
Reviewed-on: https://chromium-review.googlesource.com/773538
Reviewed-by: Sadrul Chowdhury <sadrul@chromium.org>
Reviewed-by: Antoine Labour <piman@chromium.org>
Commit-Queue: Zhenyao Mo <zmo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520456}
  • Loading branch information
zhenyao authored and Commit Bot committed Nov 30, 2017
1 parent a8d2219 commit b5dec6f
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 22 deletions.
71 changes: 61 additions & 10 deletions content/browser/gpu/gpu_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ GpuClient::GpuClient(int render_process_id)
}

GpuClient::~GpuClient() {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
bindings_.CloseAllBindings();
OnError();
}
Expand All @@ -30,6 +31,7 @@ void GpuClient::Add(ui::mojom::GpuRequest request) {
}

void GpuClient::OnError() {
callback_.Reset();
if (!bindings_.empty())
return;
BrowserGpuMemoryBufferManager* gpu_memory_buffer_manager =
Expand All @@ -38,21 +40,43 @@ void GpuClient::OnError() {
gpu_memory_buffer_manager->ProcessRemoved(render_process_id_);
}

void GpuClient::PreEstablishGpuChannel() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
BrowserThread::PostTask(
BrowserThread::IO, FROM_HERE,
base::BindOnce(&GpuClient::EstablishGpuChannel, base::Unretained(this),
EstablishGpuChannelCallback()));
}

void GpuClient::OnEstablishGpuChannel(
const EstablishGpuChannelCallback& callback,
mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status) {
DCHECK_EQ(channel_handle.is_valid(),
status == GpuProcessHost::EstablishChannelStatus::SUCCESS);
gpu_channel_requested_ = false;
EstablishGpuChannelCallback callback = std::move(callback_);
DCHECK(!callback_);

if (status == GpuProcessHost::EstablishChannelStatus::GPU_HOST_INVALID) {
// GPU process may have crashed or been killed. Try again.
EstablishGpuChannel(callback);
return;
}
callback.Run(render_process_id_, std::move(channel_handle), gpu_info,
gpu_feature_info);
if (callback) {
// A request is waiting.
callback.Run(render_process_id_, std::move(channel_handle), gpu_info,
gpu_feature_info);
return;
}
if (status == GpuProcessHost::EstablishChannelStatus::SUCCESS) {
// This is the case we pre-establish a channel before a request arrives.
// Cache the channel for a future request.
channel_handle_ = std::move(channel_handle);
gpu_info_ = gpu_info;
gpu_feature_info_ = gpu_feature_info;
}
}

void GpuClient::OnCreateGpuMemoryBuffer(
Expand All @@ -61,17 +85,44 @@ void GpuClient::OnCreateGpuMemoryBuffer(
callback.Run(handle);
}

void GpuClient::ClearCallback() {
if (!callback_)
return;
EstablishGpuChannelCallback callback = std::move(callback_);
callback.Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
gpu::GPUInfo(), gpu::GpuFeatureInfo());
DCHECK(!callback_);
}

void GpuClient::EstablishGpuChannel(
const EstablishGpuChannelCallback& callback) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
// At most one channel should be requested. So clear previous request first.
ClearCallback();
if (channel_handle_.is_valid()) {
// If a channel has been pre-established and cached,
// 1) if callback is valid, return it right away.
// 2) if callback is empty, it's PreEstablishGpyChannel() being called
// more than once, no need to do anything.
if (callback) {
callback.Run(render_process_id_, std::move(channel_handle_), gpu_info_,
gpu_feature_info_);
DCHECK(!channel_handle_.is_valid());
}
return;
}
GpuProcessHost* host = GpuProcessHost::Get();
if (!host) {
OnEstablishGpuChannel(
callback, mojo::ScopedMessagePipeHandle(), gpu::GPUInfo(),
gpu::GpuFeatureInfo(),
GpuProcessHost::EstablishChannelStatus::GPU_ACCESS_DENIED);
if (callback) {
callback.Run(render_process_id_, mojo::ScopedMessagePipeHandle(),
gpu::GPUInfo(), gpu::GpuFeatureInfo());
}
return;
}

callback_ = callback;
if (gpu_channel_requested_)
return;
gpu_channel_requested_ = true;
bool preempts = false;
bool allow_view_command_buffers = false;
bool allow_real_time_streams = false;
Expand All @@ -80,8 +131,8 @@ void GpuClient::EstablishGpuChannel(
ChildProcessHostImpl::ChildProcessUniqueIdToTracingProcessId(
render_process_id_),
preempts, allow_view_command_buffers, allow_real_time_streams,
base::Bind(&GpuClient::OnEstablishGpuChannel, weak_factory_.GetWeakPtr(),
callback));
base::Bind(&GpuClient::OnEstablishGpuChannel,
weak_factory_.GetWeakPtr()));
}

void GpuClient::CreateJpegDecodeAccelerator(
Expand Down
11 changes: 9 additions & 2 deletions content/browser/gpu/gpu_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ class GpuClient : public ui::mojom::Gpu {

void Add(ui::mojom::GpuRequest request);

void PreEstablishGpuChannel();

private:
void OnError();
void OnEstablishGpuChannel(const EstablishGpuChannelCallback& callback,
mojo::ScopedMessagePipeHandle channel_handle,
void OnEstablishGpuChannel(mojo::ScopedMessagePipeHandle channel_handle,
const gpu::GPUInfo& gpu_info,
const gpu::GpuFeatureInfo& gpu_feature_info,
GpuProcessHost::EstablishChannelStatus status);
void OnCreateGpuMemoryBuffer(const CreateGpuMemoryBufferCallback& callback,
const gfx::GpuMemoryBufferHandle& handle);
void ClearCallback();

// ui::mojom::Gpu overrides:
void EstablishGpuChannel(
Expand All @@ -48,6 +50,11 @@ class GpuClient : public ui::mojom::Gpu {

const int render_process_id_;
mojo::BindingSet<ui::mojom::Gpu> bindings_;
bool gpu_channel_requested_ = false;
EstablishGpuChannelCallback callback_;
mojo::ScopedMessagePipeHandle channel_handle_;
gpu::GPUInfo gpu_info_;
gpu::GpuFeatureInfo gpu_feature_info_;
base::WeakPtrFactory<GpuClient> weak_factory_;

DISALLOW_COPY_AND_ASSIGN(GpuClient);
Expand Down
22 changes: 13 additions & 9 deletions content/browser/renderer_host/render_process_host_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@
#include "third_party/WebKit/public/public_features.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/ui_base_switches.h"
#include "ui/base/ui_base_switches_util.h"
#include "ui/display/display_switches.h"
#include "ui/gl/gl_switches.h"
#include "ui/gl/gpu_switching_manager.h"
Expand Down Expand Up @@ -1353,6 +1354,9 @@ RenderProcessHostImpl::RenderProcessHostImpl(
AddObserver(indexed_db_factory_.get());

InitializeChannelProxy();

if (!switches::IsMusHostingViz())
gpu_client_.reset(new GpuClient(GetID()));
}

// static
Expand Down Expand Up @@ -1447,6 +1451,9 @@ bool RenderProcessHostImpl::Init() {
if (renderer_path.empty())
return false;

if (gpu_client_)
gpu_client_->PreEstablishGpuChannel();

sent_render_process_ready_ = false;

// We may reach Init() during process death notification (e.g.
Expand Down Expand Up @@ -1882,8 +1889,12 @@ void RenderProcessHostImpl::RegisterMojoInterfaces() {
base::WrapRefCounted(
storage_partition_impl_->GetBackgroundFetchContext())));

registry->AddInterface(base::Bind(&RenderProcessHostImpl::CreateMusGpuRequest,
base::Unretained(this)));
if (gpu_client_) {
// |gpu_client_| outlives the registry, because its destruction is posted to
// IO thread from the destructor of |this|.
registry->AddInterface(
base::Bind(&GpuClient::Add, base::Unretained(gpu_client_.get())));
}

registry->AddInterface(
base::Bind(
Expand Down Expand Up @@ -1990,13 +2001,6 @@ void RenderProcessHostImpl::GetBlobURLLoaderFactory(
std::move(request));
}

void RenderProcessHostImpl::CreateMusGpuRequest(ui::mojom::GpuRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (!gpu_client_)
gpu_client_.reset(new GpuClient(GetID()));
gpu_client_->Add(std::move(request));
}

void RenderProcessHostImpl::CreateOffscreenCanvasProvider(
blink::mojom::OffscreenCanvasProviderRequest request) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
Expand Down
1 change: 0 additions & 1 deletion content/browser/renderer_host/render_process_host_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,6 @@ class CONTENT_EXPORT RenderProcessHostImpl

void BindRouteProvider(mojom::RouteProviderAssociatedRequest request);

void CreateMusGpuRequest(ui::mojom::GpuRequest request);
void CreateOffscreenCanvasProvider(
blink::mojom::OffscreenCanvasProviderRequest request);
void BindFrameSinkProvider(mojom::FrameSinkProviderRequest request);
Expand Down
2 changes: 2 additions & 0 deletions services/ui/public/cpp/gpu/gpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "base/message_loop/message_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "gpu/command_buffer/common/scheduling_priority.h"
#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
Expand Down Expand Up @@ -236,6 +237,7 @@ void Gpu::EstablishGpuChannel(

scoped_refptr<gpu::GpuChannelHost> Gpu::EstablishGpuChannelSync(
bool* connection_error) {
TRACE_EVENT0("mus", "Gpu::EstablishGpuChannelSync");
DCHECK(main_task_runner_->BelongsToCurrentThread());
if (connection_error)
*connection_error = false;
Expand Down

0 comments on commit b5dec6f

Please sign in to comment.