Index: content/common/gpu/client/ipc/chrome/chrome_command_buffer_ipc_transport.cc |
diff --git a/content/common/gpu/client/ipc/chrome/chrome_command_buffer_ipc_transport.cc b/content/common/gpu/client/ipc/chrome/chrome_command_buffer_ipc_transport.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..38311dc2fb4c6b88cde584e2b8ff400416d93b62 |
--- /dev/null |
+++ b/content/common/gpu/client/ipc/chrome/chrome_command_buffer_ipc_transport.cc |
@@ -0,0 +1,295 @@ |
+// Copyright 2016 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/ipc/chrome/chrome_command_buffer_ipc_transport.h" |
+ |
+#include "content/common/gpu/client/gpu_channel_host.h" |
+#include "content/common/gpu/client/gpu_channel_host_factory.h" |
+#include "content/common/gpu/client/ipc/chrome/chrome_gpu_channel_host_ipc_transport.h" |
+#include "content/common/gpu/client/ipc/chrome/chrome_gpu_video_decode_accelerator_host_ipc_transport.h" |
+#include "content/common/gpu/client/ipc/chrome/chrome_gpu_video_encode_accelerator_host_ipc_transport.h" |
+#include "content/common/gpu/gpu_messages.h" |
+#include "ipc/ipc_message.h" |
+ |
+namespace content { |
+ |
+namespace { |
+ |
+uint64_t CommandBufferProxyID(int channel_id, int32_t route_id) { |
+ return (static_cast<uint64_t>(channel_id) << 32) | route_id; |
+} |
+ |
+} // namespace |
+ |
+// static |
+scoped_ptr<CommandBufferIPCTransport> |
+ChromeCommandBufferIPCTransport::Create() { |
+ return make_scoped_ptr<CommandBufferIPCTransport>( |
+ new ChromeCommandBufferIPCTransport()); |
+} |
+ |
+ChromeCommandBufferIPCTransport::~ChromeCommandBufferIPCTransport() {} |
+ |
+base::WeakPtr<ChromeCommandBufferIPCTransport> |
+ChromeCommandBufferIPCTransport::AsWeakPtr() { |
+ return weak_factory_.GetWeakPtr(); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::BindToService( |
+ ChromeGpuChannelHostIPCTransport* channel_transport) { |
+ channel_transport_ = channel_transport; |
+ if (channel_transport_) { |
+ route_id_ = channel_transport_->GenerateRouteID(); |
+ command_buffer_id_ = |
+ CommandBufferProxyID(channel_transport_->channel_id(), route_id_); |
+ } else { |
+ route_id_ = MSG_ROUTING_NONE; |
+ } |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::OnMessageReceived( |
+ const IPC::Message& message) { |
+ if (!client_) |
+ return false; |
+ client_->OnWillHandleMessage(); |
+ bool handled = true; |
+ IPC_BEGIN_MESSAGE_MAP(ChromeCommandBufferIPCTransport, message) |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Destroyed, OnDestroyed); |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ConsoleMsg, OnConsoleMessage); |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SignalAck, OnSignalAck); |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SwapBuffersCompleted, |
+ OnSwapBuffersCompleted); |
+ IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_UpdateVSyncParameters, |
+ OnUpdateVSyncParameters); |
+ IPC_MESSAGE_UNHANDLED(handled = false) |
+ IPC_END_MESSAGE_MAP() |
+ |
+ if (!handled) { |
+ DLOG(ERROR) << "Gpu process sent invalid message."; |
+ InvalidGpuMessage(); |
+ } |
+ client_->OnDidHandleMessage(); |
+ return handled; |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnChannelError() { |
+ if (client_) |
+ client_->OnChannelError(); |
+} |
+ |
+scoped_ptr<base::SharedMemory> |
+ChromeCommandBufferIPCTransport::AllocateSharedMemory(size_t size) { |
+ return channel_transport_->factory()->AllocateSharedMemory(size); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::CreateImage( |
+ const CreateImageParams& params) { |
+ return Send(new GpuCommandBufferMsg_CreateImage(route_id_, params)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::CreateStreamTexture( |
+ uint32_t client_texture_id, |
+ int32_t* stream_id, |
+ bool* succeeded) { |
+ *stream_id = channel_transport_->GenerateRouteID(); |
+ return Send(new GpuCommandBufferMsg_CreateStreamTexture( |
+ route_id_, client_texture_id, *stream_id, succeeded)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::CreateVideoDecoder( |
+ GpuVideoDecodeAcceleratorHostIPCTransport* transport, |
+ const media::VideoDecodeAccelerator::Config& config, |
+ bool* succeeded) { |
+ if (!channel_transport_) { |
+ *succeeded = false; |
+ return false; |
+ } |
+ |
+ ChromeGpuVideoDecodeAcceleratorHostIPCTransport* chrome_ipc_transport = |
+ static_cast<ChromeGpuVideoDecodeAcceleratorHostIPCTransport*>(transport); |
+ chrome_ipc_transport->BindToService(channel_transport_); |
+ int route_id = chrome_ipc_transport->route_id(); |
+ bool sent = Send(new GpuCommandBufferMsg_CreateVideoDecoder( |
+ route_id_, config, route_id, succeeded)); |
+ if (sent && *succeeded) |
+ channel_transport_->AddRoute(route_id, chrome_ipc_transport->AsWeakPtr()); |
+ |
+ return sent; |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::CreateVideoEncoder( |
+ GpuVideoEncodeAcceleratorHostIPCTransport* transport, |
+ media::VideoPixelFormat input_format, |
+ const gfx::Size& input_visible_size, |
+ media::VideoCodecProfile output_profile, |
+ uint32_t initial_bitrate, |
+ bool* succeeded) { |
+ if (!channel_transport_) { |
+ *succeeded = false; |
+ return false; |
+ } |
+ |
+ ChromeGpuVideoEncodeAcceleratorHostIPCTransport* chrome_ipc_transport = |
+ static_cast<ChromeGpuVideoEncodeAcceleratorHostIPCTransport*>(transport); |
+ chrome_ipc_transport->BindToService(channel_transport_); |
+ int route_id = chrome_ipc_transport->route_id(); |
+ bool sent = Send(new GpuCommandBufferMsg_CreateVideoEncoder( |
+ route_id_, input_format, input_visible_size, output_profile, |
+ initial_bitrate, route_id, succeeded)); |
+ if (sent && *succeeded) |
+ channel_transport_->AddRoute(route_id, chrome_ipc_transport->AsWeakPtr()); |
+ |
+ return sent; |
+} |
+bool ChromeCommandBufferIPCTransport::DestroyImage(int32_t id) { |
+ return Send(new GpuCommandBufferMsg_DestroyImage(route_id_, id)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::DestroyTransferBuffer(int32_t id) { |
+ return Send(new GpuCommandBufferMsg_DestroyTransferBuffer(route_id_, id)); |
+} |
+ |
+uint64_t ChromeCommandBufferIPCTransport::GetCommandBufferID() const { |
+ return command_buffer_id_; |
+} |
+ |
+int32_t ChromeCommandBufferIPCTransport::GetShareGroupID() const { |
+ return route_id_; |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::Initialize( |
+ base::SharedMemoryHandle shared_state_handle, |
+ bool* result, |
+ gpu::Capabilities* capabilities) { |
+ return Send(new GpuCommandBufferMsg_Initialize(route_id_, shared_state_handle, |
+ result, capabilities)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::ProduceFrontBuffer( |
+ const gpu::Mailbox& mailbox) { |
+ return Send(new GpuCommandBufferMsg_ProduceFrontBuffer(route_id_, mailbox)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::RegisterTransferBuffer( |
+ int32_t id, |
+ base::SharedMemoryHandle transfer_buffer, |
+ uint32_t size) { |
+ return Send(new GpuCommandBufferMsg_RegisterTransferBuffer( |
+ route_id_, id, transfer_buffer, size)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::SetGetBuffer(int32_t shm_id) { |
+ return Send(new GpuCommandBufferMsg_SetGetBuffer(route_id_, shm_id)); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::SetClient( |
+ CommandBufferIPCTransport::Client* client) { |
+ client_ = client; |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::SignalQuery(uint32_t query, |
+ uint32_t signal_id) { |
+ return Send(new GpuCommandBufferMsg_SignalQuery(route_id_, query, signal_id)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::SignalSyncToken( |
+ const gpu::SyncToken& sync_token, |
+ uint32_t signal_id) { |
+ return Send(new GpuCommandBufferMsg_SignalSyncToken(route_id_, sync_token, |
+ signal_id)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::WaitForGetOffsetInRange( |
+ int32_t start, |
+ int32_t end, |
+ gpu::CommandBuffer::State* state) { |
+ return Send(new GpuCommandBufferMsg_WaitForGetOffsetInRange(route_id_, start, |
+ end, state)); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::WaitForTokenInRange( |
+ int32_t start, |
+ int32_t end, |
+ gpu::CommandBuffer::State* state) { |
+ return Send(new GpuCommandBufferMsg_WaitForTokenInRange(route_id_, start, end, |
+ state)); |
+} |
+ |
+ChromeCommandBufferIPCTransport::ChromeCommandBufferIPCTransport() |
+ : channel_transport_(nullptr), |
+ route_id_(MSG_ROUTING_NONE), |
+ client_(nullptr), |
+ weak_factory_(this) {} |
+ |
+void ChromeCommandBufferIPCTransport::InvalidGpuMessage() { |
+ LOG(ERROR) << "Received invalid message from the GPU process."; |
+ if (!client_) |
+ return; |
+ client_->OnDestroyed(gpu::error::kInvalidGpuMessage, |
+ gpu::error::kLostContext); |
+} |
+ |
+bool ChromeCommandBufferIPCTransport::Send(IPC::Message* msg) { |
+ DCHECK_NE(MSG_ROUTING_NONE, route_id_); |
+ // A transport object should always have a channel. |
+ DCHECK(channel_transport_); |
+ if (channel_transport_) { |
+ if (channel_transport_->Send(msg)) { |
+ return true; |
+ } else { |
+ // Flag the command buffer as lost. Defer deleting the channel until |
+ // OnChannelError is called after returning to the message loop in case |
+ // it is referenced elsewhere. |
+ DVLOG(1) << "CommandBufferProxyImpl::Send failed. Losing context."; |
+ // TODO(fsamuel): We need to tell the listener that something happened. |
+ // last_state_.error = gpu::error::kLostContext; |
+ return false; |
+ } |
+ } |
+ |
+ // Callee takes ownership of message, regardless of whether Send is |
+ // successful. See IPC::Sender. |
+ delete msg; |
+ return false; |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnConsoleMessage( |
+ const CommandBufferConsoleMessage& message) { |
+ if (client_) |
+ client_->OnConsoleMessage(message); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnDestroyed( |
+ gpu::error::ContextLostReason reason, |
+ gpu::error::Error error) { |
+ if (client_) |
+ client_->OnDestroyed(reason, error); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnSignalAck(uint32_t id) { |
+ if (client_) |
+ client_->OnSignalAck(id); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnSwapBuffersCompleted( |
+ const std::vector<ui::LatencyInfo>& latency_info, |
+ gfx::SwapResult result) { |
+ if (client_) |
+ client_->OnSwapBuffersCompleted(latency_info, result); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnUpdateState( |
+ const gpu::CommandBuffer::State& state) { |
+ if (client_) |
+ client_->OnUpdateState(state); |
+} |
+ |
+void ChromeCommandBufferIPCTransport::OnUpdateVSyncParameters( |
+ base::TimeTicks timebase, |
+ base::TimeDelta interval) { |
+ if (client_) |
+ client_->OnUpdateVSyncParameters(timebase, interval); |
+} |
+ |
+} // namespace content |