OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "gpu/command_buffer/service/command_buffer_service.h" | 5 #include "gpu/command_buffer/service/command_buffer_service.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/process_util.h" |
10 #include "gpu/command_buffer/common/cmd_buffer_common.h" | 11 #include "gpu/command_buffer/common/cmd_buffer_common.h" |
11 | 12 |
12 using ::base::SharedMemory; | 13 using ::base::SharedMemory; |
13 | 14 |
14 namespace gpu { | 15 namespace gpu { |
15 | 16 |
16 CommandBufferService::CommandBufferService() | 17 CommandBufferService::CommandBufferService() |
17 : num_entries_(0), | 18 : num_entries_(0), |
18 get_offset_(0), | 19 get_offset_(0), |
19 put_offset_(0), | 20 put_offset_(0), |
20 token_(0), | 21 token_(0), |
21 error_(error::kNoError) { | 22 error_(error::kNoError) { |
22 // Element zero is always NULL. | 23 // Element zero is always NULL. |
23 registered_objects_.push_back(linked_ptr<SharedMemory>()); | 24 registered_objects_.push_back(Buffer()); |
24 } | 25 } |
25 | 26 |
26 CommandBufferService::~CommandBufferService() { | 27 CommandBufferService::~CommandBufferService() { |
| 28 for (size_t i = 0; i < registered_objects_.size(); ++i) { |
| 29 if (registered_objects_[i].shared_memory) |
| 30 delete registered_objects_[i].shared_memory; |
| 31 } |
27 } | 32 } |
28 | 33 |
29 bool CommandBufferService::Initialize(int32 size) { | 34 bool CommandBufferService::Initialize(int32 size) { |
30 // Fail if already initialized. | 35 // Fail if already initialized. |
31 if (ring_buffer_.get()) { | 36 if (ring_buffer_.get()) { |
32 LOG(ERROR) << "CommandBufferService::Initialize " | 37 LOG(ERROR) << "CommandBufferService::Initialize " |
33 << "failed because already initialized."; | 38 << "failed because already initialized."; |
34 return false; | 39 return false; |
35 } | 40 } |
36 | 41 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 void CommandBufferService::Flush(int32 put_offset) { | 100 void CommandBufferService::Flush(int32 put_offset) { |
96 FlushSync(put_offset); | 101 FlushSync(put_offset); |
97 } | 102 } |
98 | 103 |
99 void CommandBufferService::SetGetOffset(int32 get_offset) { | 104 void CommandBufferService::SetGetOffset(int32 get_offset) { |
100 DCHECK(get_offset >= 0 && get_offset < num_entries_); | 105 DCHECK(get_offset >= 0 && get_offset < num_entries_); |
101 get_offset_ = get_offset; | 106 get_offset_ = get_offset; |
102 } | 107 } |
103 | 108 |
104 int32 CommandBufferService::CreateTransferBuffer(size_t size) { | 109 int32 CommandBufferService::CreateTransferBuffer(size_t size) { |
105 linked_ptr<SharedMemory> buffer(new SharedMemory); | 110 SharedMemory buffer; |
106 if (!buffer->CreateAnonymous(size)) | 111 if (!buffer.CreateAnonymous(size)) |
107 return -1; | 112 return -1; |
108 | 113 |
| 114 return RegisterTransferBuffer(&buffer, size); |
| 115 } |
| 116 |
| 117 int32 CommandBufferService::RegisterTransferBuffer( |
| 118 base::SharedMemory* shared_memory, size_t size) { |
| 119 // Duplicate the handle. |
| 120 base::SharedMemoryHandle shared_memory_handle; |
| 121 if (!shared_memory->ShareToProcess(base::GetCurrentProcessHandle(), |
| 122 &shared_memory_handle)) { |
| 123 return -1; |
| 124 } |
| 125 |
| 126 Buffer buffer; |
| 127 buffer.ptr = NULL; |
| 128 buffer.size = size; |
| 129 buffer.shared_memory = new SharedMemory(shared_memory_handle, false); |
| 130 |
109 if (unused_registered_object_elements_.empty()) { | 131 if (unused_registered_object_elements_.empty()) { |
110 // Check we haven't exceeded the range that fits in a 32-bit integer. | 132 // Check we haven't exceeded the range that fits in a 32-bit integer. |
111 if (registered_objects_.size() > std::numeric_limits<uint32>::max()) | 133 if (registered_objects_.size() > std::numeric_limits<uint32>::max()) |
112 return -1; | 134 return -1; |
113 | 135 |
114 int32 handle = static_cast<int32>(registered_objects_.size()); | 136 int32 handle = static_cast<int32>(registered_objects_.size()); |
115 registered_objects_.push_back(buffer); | 137 registered_objects_.push_back(buffer); |
116 return handle; | 138 return handle; |
117 } | 139 } |
118 | 140 |
119 int32 handle = *unused_registered_object_elements_.begin(); | 141 int32 handle = *unused_registered_object_elements_.begin(); |
120 unused_registered_object_elements_.erase( | 142 unused_registered_object_elements_.erase( |
121 unused_registered_object_elements_.begin()); | 143 unused_registered_object_elements_.begin()); |
122 DCHECK(!registered_objects_[handle].get()); | 144 DCHECK(!registered_objects_[handle].shared_memory); |
123 registered_objects_[handle] = buffer; | 145 registered_objects_[handle] = buffer; |
124 return handle; | 146 return handle; |
125 } | 147 } |
126 | 148 |
127 void CommandBufferService::DestroyTransferBuffer(int32 handle) { | 149 void CommandBufferService::DestroyTransferBuffer(int32 handle) { |
128 if (handle <= 0) | 150 if (handle <= 0) |
129 return; | 151 return; |
130 | 152 |
131 if (static_cast<size_t>(handle) >= registered_objects_.size()) | 153 if (static_cast<size_t>(handle) >= registered_objects_.size()) |
132 return; | 154 return; |
133 | 155 |
134 registered_objects_[handle].reset(); | 156 delete registered_objects_[handle].shared_memory; |
| 157 registered_objects_[handle] = Buffer(); |
135 unused_registered_object_elements_.insert(handle); | 158 unused_registered_object_elements_.insert(handle); |
136 | 159 |
137 // Remove all null objects from the end of the vector. This allows the vector | 160 // Remove all null objects from the end of the vector. This allows the vector |
138 // to shrink when, for example, all objects are unregistered. Note that this | 161 // to shrink when, for example, all objects are unregistered. Note that this |
139 // loop never removes element zero, which is always NULL. | 162 // loop never removes element zero, which is always NULL. |
140 while (registered_objects_.size() > 1 && !registered_objects_.back().get()) { | 163 while (registered_objects_.size() > 1 && |
| 164 !registered_objects_.back().shared_memory) { |
141 registered_objects_.pop_back(); | 165 registered_objects_.pop_back(); |
142 unused_registered_object_elements_.erase( | 166 unused_registered_object_elements_.erase( |
143 static_cast<int32>(registered_objects_.size())); | 167 static_cast<int32>(registered_objects_.size())); |
144 } | 168 } |
145 } | 169 } |
146 | 170 |
147 Buffer CommandBufferService::GetTransferBuffer(int32 handle) { | 171 Buffer CommandBufferService::GetTransferBuffer(int32 handle) { |
148 if (handle < 0) | 172 if (handle < 0) |
149 return Buffer(); | 173 return Buffer(); |
150 | 174 |
151 if (static_cast<size_t>(handle) >= registered_objects_.size()) | 175 if (static_cast<size_t>(handle) >= registered_objects_.size()) |
152 return Buffer(); | 176 return Buffer(); |
153 | 177 |
154 base::SharedMemory* shared_memory = registered_objects_[handle].get(); | 178 Buffer buffer = registered_objects_[handle]; |
155 if (!shared_memory) | 179 if (!buffer.shared_memory) |
156 return Buffer(); | 180 return Buffer(); |
157 | 181 |
158 if (!shared_memory->memory()) { | 182 if (!buffer.shared_memory->memory()) { |
159 if (!shared_memory->Map(shared_memory->created_size())) | 183 if (!buffer.shared_memory->Map(buffer.size)) |
160 return Buffer(); | 184 return Buffer(); |
161 } | 185 } |
162 | 186 |
163 Buffer buffer; | 187 buffer.ptr = buffer.shared_memory->memory(); |
164 buffer.ptr = shared_memory->memory(); | |
165 buffer.size = shared_memory->created_size(); | |
166 buffer.shared_memory = shared_memory; | |
167 return buffer; | 188 return buffer; |
168 } | 189 } |
169 | 190 |
170 void CommandBufferService::SetToken(int32 token) { | 191 void CommandBufferService::SetToken(int32 token) { |
171 token_ = token; | 192 token_ = token; |
172 } | 193 } |
173 | 194 |
174 void CommandBufferService::SetParseError(error::Error error) { | 195 void CommandBufferService::SetParseError(error::Error error) { |
175 if (error_ == error::kNoError) { | 196 if (error_ == error::kNoError) { |
176 error_ = error; | 197 error_ = error; |
177 } | 198 } |
178 } | 199 } |
179 | 200 |
180 void CommandBufferService::SetPutOffsetChangeCallback( | 201 void CommandBufferService::SetPutOffsetChangeCallback( |
181 Callback0::Type* callback) { | 202 Callback0::Type* callback) { |
182 put_offset_change_callback_.reset(callback); | 203 put_offset_change_callback_.reset(callback); |
183 } | 204 } |
184 | 205 |
185 } // namespace gpu | 206 } // namespace gpu |
OLD | NEW |