mapped_memory.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2011 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/client/mapped_memory.h" 6 7#include <algorithm> 8#include <functional> 9 10#include "gpu/command_buffer/client/cmd_buffer_helper.h" 11 12namespace gpu { 13 14MemoryChunk::MemoryChunk( 15 int32 shm_id, gpu::Buffer shm, CommandBufferHelper* helper) 16 : shm_id_(shm_id), 17 shm_(shm), 18 allocator_(shm.size, helper, shm.ptr) { 19} 20 21MappedMemoryManager::MappedMemoryManager(CommandBufferHelper* helper) 22 : chunk_size_multiple_(1), 23 helper_(helper) { 24} 25 26MappedMemoryManager::~MappedMemoryManager() { 27 CommandBuffer* cmd_buf = helper_->command_buffer(); 28 for (MemoryChunkVector::iterator iter = chunks_.begin(); 29 iter != chunks_.end(); ++iter) { 30 MemoryChunk* chunk = *iter; 31 cmd_buf->DestroyTransferBuffer(chunk->shm_id()); 32 delete chunk; 33 } 34} 35 36void* MappedMemoryManager::Alloc( 37 unsigned int size, int32* shm_id, unsigned int* shm_offset) { 38 GPU_DCHECK(shm_id); 39 GPU_DCHECK(shm_offset); 40 // See if any of the chucks can satisfy this request. 41 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 42 MemoryChunk* chunk = chunks_[ii]; 43 chunk->FreeUnused(); 44 if (chunk->GetLargestFreeSizeWithoutWaiting() >= size) { 45 void* mem = chunk->Alloc(size); 46 GPU_DCHECK(mem); 47 *shm_id = chunk->shm_id(); 48 *shm_offset = chunk->GetOffset(mem); 49 return mem; 50 } 51 } 52 53 // Make a new chunk to satisfy the request. 54 CommandBuffer* cmd_buf = helper_->command_buffer(); 55 unsigned int chunk_size = 56 ((size + chunk_size_multiple_ - 1) / chunk_size_multiple_) * 57 chunk_size_multiple_; 58 int32 id = -1; 59 gpu::Buffer shm = cmd_buf->CreateTransferBuffer(chunk_size, &id); 60 if (id < 0) 61 return NULL; 62 MemoryChunk* mc = new MemoryChunk(id, shm, helper_); 63 chunks_.push_back(mc); 64 void* mem = mc->Alloc(size); 65 GPU_DCHECK(mem); 66 *shm_id = mc->shm_id(); 67 *shm_offset = mc->GetOffset(mem); 68 return mem; 69} 70 71void MappedMemoryManager::Free(void* pointer) { 72 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 73 MemoryChunk* chunk = chunks_[ii]; 74 if (chunk->IsInChunk(pointer)) { 75 chunk->Free(pointer); 76 return; 77 } 78 } 79 GPU_NOTREACHED(); 80} 81 82void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) { 83 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 84 MemoryChunk* chunk = chunks_[ii]; 85 if (chunk->IsInChunk(pointer)) { 86 chunk->FreePendingToken(pointer, token); 87 return; 88 } 89 } 90 GPU_NOTREACHED(); 91} 92 93void MappedMemoryManager::FreeUnused() { 94 CommandBuffer* cmd_buf = helper_->command_buffer(); 95 MemoryChunkVector::iterator iter = chunks_.begin(); 96 while (iter != chunks_.end()) { 97 MemoryChunk* chunk = *iter; 98 chunk->FreeUnused(); 99 if (!chunk->InUse()) { 100 cmd_buf->DestroyTransferBuffer(chunk->shm_id()); 101 iter = chunks_.erase(iter); 102 } else { 103 ++iter; 104 } 105 } 106} 107 108} // namespace gpu 109 110 111 112