Chromium Code Reviews| Index: content/common/gpu/client/gpu_arc_accelerator_host.cc |
| diff --git a/content/common/gpu/client/gpu_arc_accelerator_host.cc b/content/common/gpu/client/gpu_arc_accelerator_host.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..4021b9942aed3e27677c654a33e0f129c03c63ae |
| --- /dev/null |
| +++ b/content/common/gpu/client/gpu_arc_accelerator_host.cc |
| @@ -0,0 +1,118 @@ |
| +// Copyright 2015 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "content/common/gpu/client/gpu_arc_accelerator_host.h" |
| + |
| +#include "base/logging.h" |
| +#include "base/message_loop/message_loop.h" |
| +#include "content/browser/gpu/browser_gpu_channel_host_factory.h" |
| +#include "content/common/gpu/client/gpu_channel_host.h" |
| +#include "content/common/gpu/gpu_messages.h" |
| +#include "content/public/browser/browser_thread.h" |
| +#include "ipc/ipc_message_macros.h" |
| +#include "ipc/ipc_message_utils.h" |
| + |
| +namespace content { |
| + |
| +GpuArcAcceleratorHost::GpuArcAcceleratorHost() : route_id_(MSG_ROUTING_NONE) { |
| + DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| +} |
| + |
| +GpuArcAcceleratorHost::~GpuArcAcceleratorHost() { |
| + DCHECK(CalledOnValidThread()); |
| +} |
| + |
| +bool GpuArcAcceleratorHost::OnMessageReceived(const IPC::Message& msg) { |
| + DCHECK(CalledOnValidThread()); |
| + bool handled = true; |
| + IPC_BEGIN_MESSAGE_MAP(GpuArcAcceleratorHost, msg) |
| + IPC_MESSAGE_HANDLER(GpuHostMsg_ArcAcceleratorCreated, |
| + OnArcAcceleratorCreated) |
| + IPC_MESSAGE_UNHANDLED(handled = false) |
| + IPC_END_MESSAGE_MAP() |
| + DCHECK(handled); |
| + return handled; |
| +} |
| + |
| +void GpuArcAcceleratorHost::OnChannelError() { |
| + AbortPendingRequests(); |
| +} |
| + |
| +void GpuArcAcceleratorHost::CreateArcAccelerator(uint32_t device_type, |
| + const CreatedCallback& cb) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(BrowserGpuChannelHostFactory::instance()); |
| + |
| + if (gpu_channel_host_ && !gpu_channel_host_->IsLost()) { |
| + CreateArcAcceleratorWithGpuChannel(device_type, cb); |
| + return; |
| + } |
| + |
| + BrowserGpuChannelHostFactory::instance()->EstablishGpuChannel( |
| + CAUSE_FOR_GPU_LAUNCH_ARCACCELERATOR, |
| + base::Bind(&GpuArcAcceleratorHost::GpuChannelEstablished, AsWeakPtr(), |
| + device_type, cb)); |
| +} |
| + |
| +void GpuArcAcceleratorHost::GpuChannelEstablished(uint32_t device_type, |
| + const CreatedCallback& cb) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK_EQ(MSG_ROUTING_NONE, route_id_); |
| + |
| + gpu_channel_host_ = BrowserGpuChannelHostFactory::instance()->GetGpuChannel(); |
| + route_id_ = gpu_channel_host_->GenerateRouteID(); |
| + gpu_channel_host_->AddRoute(route_id_, AsWeakPtr()); |
| + |
| + CreateArcAcceleratorWithGpuChannel(device_type, cb); |
| +} |
| + |
| +void GpuArcAcceleratorHost::CreateArcAcceleratorWithGpuChannel( |
| + uint32_t device_type, |
| + const CreatedCallback& cb) { |
| + DCHECK(CalledOnValidThread()); |
| + DCHECK(gpu_channel_host_); |
| + DCHECK(!gpu_channel_host_->IsLost()); |
| + |
| + pending_requests_.push(cb); |
| + if (!gpu_channel_host_->Send(new GpuMsg_CreateArcAccelerator(device_type))) |
| + AbortPendingRequests(); |
| +} |
| + |
| +void GpuArcAcceleratorHost::AbortPendingRequests() { |
| + DCHECK(CalledOnValidThread()); |
| + if (gpu_channel_host_) { |
| + DCHECK_NE(MSG_ROUTING_NONE, route_id_); |
| + gpu_channel_host_->RemoveRoute(route_id_); |
| + gpu_channel_host_ = nullptr; |
| + route_id_ = MSG_ROUTING_NONE; |
| + } |
| + while (pending_requests_.empty()) { |
|
Owen Lin
2015/11/23 05:31:06
while (!empty)?
kcwu
2015/11/23 08:11:48
Done.
|
| + pending_requests_.front().Run(IPC::ChannelHandle(), 0); |
| + pending_requests_.pop(); |
| + } |
| +} |
| + |
| +void GpuArcAcceleratorHost::Shutdown() { |
| + if (gpu_channel_host_ && !gpu_channel_host_->IsLost()) |
| + gpu_channel_host_->Send(new GpuMsg_ShutdownArcAccelerators()); |
| + AbortPendingRequests(); |
| +} |
| + |
| +void GpuArcAcceleratorHost::OnArcAcceleratorCreated(IPC::ChannelHandle handle, |
| + uint32_t result) { |
| + DCHECK(CalledOnValidThread()); |
| + |
| + if (pending_requests_.empty()) { |
| + // Maybe got reply after error or Shutdown(). |
| + LOG(WARNING) << "Arc accelerator created but no pending requests."; |
| + return; |
| + } |
| + |
| + // The order of response messages must match the order of request messages. |
| + // XXX Does this guarantee? |
| + pending_requests_.front().Run(handle, result); |
| + pending_requests_.pop(); |
| +} |
| + |
| +} // namespace content |