mapped_memory.cc revision 3551c9c881056c480085172ff9840cab31610854
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 "base/debug/trace_event.h" 11#include "gpu/command_buffer/client/cmd_buffer_helper.h" 12 13namespace gpu { 14 15MemoryChunk::MemoryChunk( 16 int32 shm_id, gpu::Buffer shm, CommandBufferHelper* helper) 17 : shm_id_(shm_id), 18 shm_(shm), 19 allocator_(shm.size, helper, shm.ptr) { 20} 21 22MappedMemoryManager::MappedMemoryManager(CommandBufferHelper* helper, 23 size_t unused_memory_reclaim_limit) 24 : chunk_size_multiple_(1), 25 helper_(helper), 26 allocated_memory_(0), 27 max_free_bytes_(unused_memory_reclaim_limit) { 28} 29 30MappedMemoryManager::~MappedMemoryManager() { 31 CommandBuffer* cmd_buf = helper_->command_buffer(); 32 for (MemoryChunkVector::iterator iter = chunks_.begin(); 33 iter != chunks_.end(); ++iter) { 34 MemoryChunk* chunk = *iter; 35 cmd_buf->DestroyTransferBuffer(chunk->shm_id()); 36 } 37} 38 39void* MappedMemoryManager::Alloc( 40 unsigned int size, int32* shm_id, unsigned int* shm_offset) { 41 GPU_DCHECK(shm_id); 42 GPU_DCHECK(shm_offset); 43 if (size <= allocated_memory_) { 44 size_t total_bytes_in_use = 0; 45 // See if any of the chunks can satisfy this request. 46 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 47 MemoryChunk* chunk = chunks_[ii]; 48 chunk->FreeUnused(); 49 total_bytes_in_use += chunk->bytes_in_use(); 50 if (chunk->GetLargestFreeSizeWithoutWaiting() >= size) { 51 void* mem = chunk->Alloc(size); 52 GPU_DCHECK(mem); 53 *shm_id = chunk->shm_id(); 54 *shm_offset = chunk->GetOffset(mem); 55 return mem; 56 } 57 } 58 59 // If there is a memory limit being enforced and total free 60 // memory (allocated_memory_ - total_bytes_in_use) is larger than 61 // the limit try waiting. 62 if (max_free_bytes_ != kNoLimit && 63 (allocated_memory_ - total_bytes_in_use) >= max_free_bytes_) { 64 TRACE_EVENT0("gpu", "MappedMemoryManager::Alloc::wait"); 65 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 66 MemoryChunk* chunk = chunks_[ii]; 67 if (chunk->GetLargestFreeSizeWithWaiting() >= size) { 68 void* mem = chunk->Alloc(size); 69 GPU_DCHECK(mem); 70 *shm_id = chunk->shm_id(); 71 *shm_offset = chunk->GetOffset(mem); 72 return mem; 73 } 74 } 75 } 76 } 77 78 // Make a new chunk to satisfy the request. 79 CommandBuffer* cmd_buf = helper_->command_buffer(); 80 unsigned int chunk_size = 81 ((size + chunk_size_multiple_ - 1) / chunk_size_multiple_) * 82 chunk_size_multiple_; 83 int32 id = -1; 84 gpu::Buffer shm = cmd_buf->CreateTransferBuffer(chunk_size, &id); 85 if (id < 0) 86 return NULL; 87 MemoryChunk* mc = new MemoryChunk(id, shm, helper_); 88 allocated_memory_ += mc->GetSize(); 89 chunks_.push_back(mc); 90 void* mem = mc->Alloc(size); 91 GPU_DCHECK(mem); 92 *shm_id = mc->shm_id(); 93 *shm_offset = mc->GetOffset(mem); 94 return mem; 95} 96 97void MappedMemoryManager::Free(void* pointer) { 98 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 99 MemoryChunk* chunk = chunks_[ii]; 100 if (chunk->IsInChunk(pointer)) { 101 chunk->Free(pointer); 102 return; 103 } 104 } 105 GPU_NOTREACHED(); 106} 107 108void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) { 109 for (size_t ii = 0; ii < chunks_.size(); ++ii) { 110 MemoryChunk* chunk = chunks_[ii]; 111 if (chunk->IsInChunk(pointer)) { 112 chunk->FreePendingToken(pointer, token); 113 return; 114 } 115 } 116 GPU_NOTREACHED(); 117} 118 119void MappedMemoryManager::FreeUnused() { 120 CommandBuffer* cmd_buf = helper_->command_buffer(); 121 MemoryChunkVector::iterator iter = chunks_.begin(); 122 while (iter != chunks_.end()) { 123 MemoryChunk* chunk = *iter; 124 chunk->FreeUnused(); 125 if (!chunk->InUse()) { 126 cmd_buf->DestroyTransferBuffer(chunk->shm_id()); 127 allocated_memory_ -= chunk->GetSize(); 128 iter = chunks_.erase(iter); 129 } else { 130 ++iter; 131 } 132 } 133} 134 135} // namespace gpu 136