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..a0992b3de404a4304e692ba7dd6d8d2291d8e6b0 |
--- /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()) { |
+ pending_requests_.front().Run(IPC::ChannelHandle(), 0); |
Owen Lin
2015/11/26 03:54:40
I thought result "0" means success, but it is actu
kcwu
2015/11/26 10:34:42
Acknowledged.
|
+ 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(figure out before commit) Does this guarantee? |
+ pending_requests_.front().Run(handle, result); |
+ pending_requests_.pop(); |
+} |
+ |
+} // namespace content |