transfer_buffer_manager.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "gpu/command_buffer/service/transfer_buffer_manager.h" 6 7#include <limits> 8 9#include "base/logging.h" 10#include "base/memory/scoped_ptr.h" 11#include "base/debug/trace_event.h" 12#include "base/process/process_handle.h" 13#include "gpu/command_buffer/common/cmd_buffer_common.h" 14#include "gpu/command_buffer/common/gles2_cmd_utils.h" 15 16using ::base::SharedMemory; 17 18namespace gpu { 19 20TransferBufferManagerInterface::~TransferBufferManagerInterface() { 21} 22 23TransferBufferManager::TransferBufferManager() 24 : shared_memory_bytes_allocated_(0) { 25} 26 27TransferBufferManager::~TransferBufferManager() { 28 while (!registered_buffers_.empty()) { 29 BufferMap::iterator it = registered_buffers_.begin(); 30 DCHECK(shared_memory_bytes_allocated_ >= it->second.size); 31 shared_memory_bytes_allocated_ -= it->second.size; 32 delete it->second.shared_memory; 33 registered_buffers_.erase(it); 34 } 35 DCHECK(!shared_memory_bytes_allocated_); 36} 37 38bool TransferBufferManager::Initialize() { 39 return true; 40} 41 42bool TransferBufferManager::RegisterTransferBuffer( 43 int32 id, 44 base::SharedMemory* shared_memory, 45 size_t size) { 46 if (id <= 0) { 47 DVLOG(0) << "Cannot register transfer buffer with non-positive ID."; 48 return false; 49 } 50 51 // Fail if the ID is in use. 52 if (registered_buffers_.find(id) != registered_buffers_.end()) { 53 DVLOG(0) << "Buffer ID already in use."; 54 return false; 55 } 56 57 // Duplicate the handle. 58 base::SharedMemoryHandle duped_shared_memory_handle; 59 if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), 60 &duped_shared_memory_handle)) { 61 DVLOG(0) << "Failed to duplicate shared memory handle."; 62 return false; 63 } 64 scoped_ptr<SharedMemory> duped_shared_memory( 65 new SharedMemory(duped_shared_memory_handle, false)); 66 67 // Map the shared memory into this process. This validates the size. 68 if (!duped_shared_memory->Map(size)) { 69 DVLOG(0) << "Failed to map shared memory."; 70 return false; 71 } 72 73 // If it could be mapped register the shared memory with the ID. 74 Buffer buffer; 75 buffer.ptr = duped_shared_memory->memory(); 76 buffer.size = size; 77 buffer.shared_memory = duped_shared_memory.release(); 78 79 // Check buffer alignment is sane. 80 DCHECK(!(reinterpret_cast<uintptr_t>(buffer.ptr) & 81 (kCommandBufferEntrySize - 1))); 82 83 shared_memory_bytes_allocated_ += size; 84 TRACE_COUNTER_ID1( 85 "gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_); 86 87 registered_buffers_[id] = buffer; 88 89 return true; 90} 91 92void TransferBufferManager::DestroyTransferBuffer(int32 id) { 93 BufferMap::iterator it = registered_buffers_.find(id); 94 if (it == registered_buffers_.end()) { 95 DVLOG(0) << "Transfer buffer ID was not registered."; 96 return; 97 } 98 99 DCHECK(shared_memory_bytes_allocated_ >= it->second.size); 100 shared_memory_bytes_allocated_ -= it->second.size; 101 TRACE_COUNTER_ID1( 102 "gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_); 103 104 delete it->second.shared_memory; 105 registered_buffers_.erase(it); 106} 107 108Buffer TransferBufferManager::GetTransferBuffer(int32 id) { 109 if (id == 0) 110 return Buffer(); 111 112 BufferMap::iterator it = registered_buffers_.find(id); 113 if (it == registered_buffers_.end()) 114 return Buffer(); 115 116 return it->second; 117} 118 119} // namespace gpu 120 121