blob: 76443a1f2500022dd797f8847b4997b1a36fdbe9 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/command_buffer/service/transfer_buffer_manager.h"
#include <limits>
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/debug/trace_event.h"
#include "base/process/process_handle.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
using ::base::SharedMemory;
namespace gpu {
TransferBufferManagerInterface::~TransferBufferManagerInterface() {
}
TransferBufferManager::TransferBufferManager()
: shared_memory_bytes_allocated_(0) {
}
TransferBufferManager::~TransferBufferManager() {
while (!registered_buffers_.empty()) {
BufferMap::iterator it = registered_buffers_.begin();
DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
shared_memory_bytes_allocated_ -= it->second.size;
delete it->second.shared_memory;
registered_buffers_.erase(it);
}
DCHECK(!shared_memory_bytes_allocated_);
}
bool TransferBufferManager::Initialize() {
return true;
}
bool TransferBufferManager::RegisterTransferBuffer(
int32 id,
base::SharedMemory* shared_memory,
size_t size) {
if (id <= 0) {
DVLOG(0) << "Cannot register transfer buffer with non-positive ID.";
return false;
}
// Fail if the ID is in use.
if (registered_buffers_.find(id) != registered_buffers_.end()) {
DVLOG(0) << "Buffer ID already in use.";
return false;
}
// Duplicate the handle.
base::SharedMemoryHandle duped_shared_memory_handle;
if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
&duped_shared_memory_handle)) {
DVLOG(0) << "Failed to duplicate shared memory handle.";
return false;
}
scoped_ptr<SharedMemory> duped_shared_memory(
new SharedMemory(duped_shared_memory_handle, false));
// Map the shared memory into this process. This validates the size.
if (!duped_shared_memory->Map(size)) {
DVLOG(0) << "Failed to map shared memory.";
return false;
}
// If it could be mapped register the shared memory with the ID.
Buffer buffer;
buffer.ptr = duped_shared_memory->memory();
buffer.size = size;
buffer.shared_memory = duped_shared_memory.release();
shared_memory_bytes_allocated_ += size;
TRACE_COUNTER_ID1(
"gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
registered_buffers_[id] = buffer;
return true;
}
void TransferBufferManager::DestroyTransferBuffer(int32 id) {
BufferMap::iterator it = registered_buffers_.find(id);
if (it == registered_buffers_.end()) {
DVLOG(0) << "Transfer buffer ID was not registered.";
return;
}
DCHECK(shared_memory_bytes_allocated_ >= it->second.size);
shared_memory_bytes_allocated_ -= it->second.size;
TRACE_COUNTER_ID1(
"gpu", "GpuTransferBufferMemory", this, shared_memory_bytes_allocated_);
delete it->second.shared_memory;
registered_buffers_.erase(it);
}
Buffer TransferBufferManager::GetTransferBuffer(int32 id) {
if (id == 0)
return Buffer();
BufferMap::iterator it = registered_buffers_.find(id);
if (it == registered_buffers_.end())
return Buffer();
return it->second;
}
} // namespace gpu