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