// Copyright (c) 2010 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. #if defined(ENABLE_GPU) #include "base/process_util.h" #include "base/shared_memory.h" #include "build/build_config.h" #include "chrome/common/gpu_messages.h" #include "chrome/gpu/gpu_channel.h" #include "chrome/gpu/gpu_command_buffer_stub.h" using gpu::Buffer; GpuCommandBufferStub::GpuCommandBufferStub(GpuChannel* channel, gfx::NativeView view, GpuCommandBufferStub* parent, const gfx::Size& size, uint32 parent_texture_id, int32 route_id) : channel_(channel), view_(view), parent_(parent), initial_size_(size), parent_texture_id_(parent_texture_id), route_id_(route_id) { } GpuCommandBufferStub::~GpuCommandBufferStub() { if (processor_.get()) { processor_->Destroy(); } } void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer, OnCreateTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer, OnDestroyTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer, OnGetTransferBuffer); IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer, OnResizeOffscreenFrameBuffer); IPC_MESSAGE_UNHANDLED_ERROR() IPC_END_MESSAGE_MAP() } bool GpuCommandBufferStub::Send(IPC::Message* message) { return channel_->Send(message); } void GpuCommandBufferStub::OnInitialize( int32 size, base::SharedMemoryHandle* ring_buffer) { DCHECK(!command_buffer_.get()); *ring_buffer = base::SharedMemory::NULLHandle(); command_buffer_.reset(new gpu::CommandBufferService); // Initialize the CommandBufferService and GPUProcessor. if (command_buffer_->Initialize(size)) { Buffer buffer = command_buffer_->GetRingBuffer(); if (buffer.shared_memory) { gpu::GPUProcessor* parent_processor = parent_ ? parent_->processor_.get() : NULL; processor_.reset(new gpu::GPUProcessor(command_buffer_.get())); // TODO(apatrick): The reinterpret_cast below is only valid on windows. #if !defined(OS_WIN) DCHECK_EQ(view_, static_cast(0)); #endif if (processor_->Initialize( reinterpret_cast(view_), parent_processor, initial_size_, parent_texture_id_)) { command_buffer_->SetPutOffsetChangeCallback( NewCallback(processor_.get(), &gpu::GPUProcessor::ProcessCommands)); // Assume service is responsible for duplicating the handle from the // calling process. buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), ring_buffer); } else { processor_.reset(); command_buffer_.reset(); } } } } void GpuCommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) { *state = command_buffer_->GetState(); } void GpuCommandBufferStub::OnAsyncGetState() { gpu::CommandBuffer::State state = command_buffer_->GetState(); Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); } void GpuCommandBufferStub::OnFlush(int32 put_offset, gpu::CommandBuffer::State* state) { *state = command_buffer_->Flush(put_offset); } void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) { gpu::CommandBuffer::State state = command_buffer_->Flush(put_offset); Send(new GpuCommandBufferMsg_UpdateState(route_id_, state)); } void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, int32* id) { *id = command_buffer_->CreateTransferBuffer(size); } void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) { command_buffer_->DestroyTransferBuffer(id); } void GpuCommandBufferStub::OnGetTransferBuffer( int32 id, base::SharedMemoryHandle* transfer_buffer, uint32* size) { *transfer_buffer = base::SharedMemoryHandle(); *size = 0; Buffer buffer = command_buffer_->GetTransferBuffer(id); if (buffer.shared_memory) { // Assume service is responsible for duplicating the handle to the calling // process. buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), transfer_buffer); *size = buffer.shared_memory->max_size(); } } void GpuCommandBufferStub::OnResizeOffscreenFrameBuffer(const gfx::Size& size) { processor_->ResizeOffscreenFrameBuffer(size); } #endif // ENABLE_GPU