command_buffer_service.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/command_buffer_service.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/cmd_buffer_common.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/common/command_buffer_shared.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "gpu/command_buffer/service/transfer_buffer_manager.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using ::base::SharedMemory; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace gpu { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferService::CommandBufferService( 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransferBufferManagerInterface* transfer_buffer_manager) 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : ring_buffer_id_(-1), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_state_(NULL), 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_entries_(0), 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_offset_(0), 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_(0), 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer_manager_(transfer_buffer_manager), 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_(0), 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) generation_(0), 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_(error::kNoError), 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_lost_reason_(error::kUnknown) { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferService::~CommandBufferService() { 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CommandBufferService::Initialize() { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferService::State CommandBufferService::GetState() { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.num_entries = num_entries_; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.get_offset = get_offset_; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.put_offset = put_offset_; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.token = token_; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.error = error_; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.context_lost_reason = context_lost_reason_; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state.generation = ++generation_; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferService::State CommandBufferService::GetLastState() { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetState(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::UpdateState() { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (shared_state_) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CommandBufferService::State state = GetState(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_state_->Write(state); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CommandBufferService::State CommandBufferService::FlushSync( 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 put_offset, int32 last_known_get) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (put_offset < 0 || put_offset > num_entries_) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = gpu::error::kOutOfBounds; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetState(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_ = put_offset; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!put_offset_change_callback_.is_null()) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_change_callback_.Run(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return GetState(); 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::Flush(int32 put_offset) { 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (put_offset < 0 || put_offset > num_entries_) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = gpu::error::kOutOfBounds; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_ = put_offset; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!put_offset_change_callback_.is_null()) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_change_callback_.Run(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(-1, ring_buffer_id_); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ring_buffer_ = GetTransferBuffer(transfer_buffer_id); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(ring_buffer_.ptr); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ring_buffer_id_ = transfer_buffer_id; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_ = 0; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetGetOffset(0); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!get_buffer_change_callback_.is_null()) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_buffer_change_callback_.Run(ring_buffer_id_); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateState(); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetSharedStateBuffer(int32 transfer_buffer_id) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gpu::Buffer buffer = GetTransferBuffer(transfer_buffer_id); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_state_ = reinterpret_cast<CommandBufferSharedState*>(buffer.ptr); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateState(); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetGetOffset(int32 get_offset) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(get_offset >= 0 && get_offset < num_entries_); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_offset_ = get_offset; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 CommandBufferService::CreateTransferBuffer(size_t size, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 id_request) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transfer_buffer_manager_->CreateTransferBuffer(size, id_request); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 CommandBufferService::RegisterTransferBuffer( 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::SharedMemory* shared_memory, size_t size, int32 id_request) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transfer_buffer_manager_->RegisterTransferBuffer( 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shared_memory, size, id_request); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::DestroyTransferBuffer(int32 handle) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transfer_buffer_manager_->DestroyTransferBuffer(handle); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (handle == ring_buffer_id_) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ring_buffer_id_ = -1; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ring_buffer_ = Buffer(); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_entries_ = 0; 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_offset_ = 0; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_ = 0; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Buffer CommandBufferService::GetTransferBuffer(int32 handle) { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transfer_buffer_manager_->GetTransferBuffer(handle); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetToken(int32 token) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token_ = token; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetParseError(error::Error error) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (error_ == error::kNoError) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_ = error; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!parse_error_callback_.is_null()) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parse_error_callback_.Run(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetContextLostReason( 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error::ContextLostReason reason) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context_lost_reason_ = reason; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetPutOffsetChangeCallback( 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) put_offset_change_callback_ = callback; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetGetBufferChangeCallback( 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GetBufferChangedCallback& callback) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) get_buffer_change_callback_ = callback; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CommandBufferService::SetParseErrorCallback( 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parse_error_callback_ = callback; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace gpu 178