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