| 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
|
|
|