OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 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/process_util.h" | 9 #include "base/process_util.h" |
10 #include "gpu/command_buffer/common/cmd_buffer_common.h" | 10 #include "gpu/command_buffer/common/cmd_buffer_common.h" |
11 | 11 |
12 using ::base::SharedMemory; | 12 using ::base::SharedMemory; |
13 | 13 |
14 namespace gpu { | 14 namespace gpu { |
15 | 15 |
16 CommandBufferService::CommandBufferService() | 16 CommandBufferService::CommandBufferService() |
17 : ring_buffer_id_(-1), | 17 : num_entries_(0), |
18 num_entries_(0), | |
19 get_offset_(0), | 18 get_offset_(0), |
20 put_offset_(0), | 19 put_offset_(0), |
21 token_(0), | 20 token_(0), |
22 generation_(0), | 21 generation_(0), |
23 error_(error::kNoError) { | 22 error_(error::kNoError) { |
24 // Element zero is always NULL. | 23 // Element zero is always NULL. |
25 registered_objects_.push_back(Buffer()); | 24 registered_objects_.push_back(Buffer()); |
26 } | 25 } |
27 | 26 |
28 CommandBufferService::~CommandBufferService() { | 27 CommandBufferService::~CommandBufferService() { |
| 28 delete ring_buffer_.shared_memory; |
| 29 |
29 for (size_t i = 0; i < registered_objects_.size(); ++i) { | 30 for (size_t i = 0; i < registered_objects_.size(); ++i) { |
30 if (registered_objects_[i].shared_memory) | 31 if (registered_objects_[i].shared_memory) |
31 delete registered_objects_[i].shared_memory; | 32 delete registered_objects_[i].shared_memory; |
32 } | 33 } |
33 } | 34 } |
34 | 35 |
35 bool CommandBufferService::Initialize() { | 36 bool CommandBufferService::Initialize(int32 size) { |
| 37 // Fail if already initialized. |
| 38 if (ring_buffer_.shared_memory) { |
| 39 LOG(ERROR) << "Failed because already initialized."; |
| 40 return false; |
| 41 } |
| 42 |
| 43 if (size <= 0 || size > kMaxCommandBufferSize) { |
| 44 LOG(ERROR) << "Failed because command buffer size was invalid."; |
| 45 return false; |
| 46 } |
| 47 |
| 48 num_entries_ = size / sizeof(CommandBufferEntry); |
| 49 |
| 50 SharedMemory shared_memory; |
| 51 if (!shared_memory.CreateAnonymous(size)) { |
| 52 LOG(ERROR) << "Failed to create shared memory for command buffer."; |
| 53 return true; |
| 54 } |
| 55 |
| 56 return Initialize(&shared_memory, size); |
| 57 } |
| 58 |
| 59 bool CommandBufferService::Initialize(base::SharedMemory* buffer, int32 size) { |
| 60 // Fail if already initialized. |
| 61 if (ring_buffer_.shared_memory) { |
| 62 LOG(ERROR) << "Failed because already initialized."; |
| 63 return false; |
| 64 } |
| 65 |
| 66 base::SharedMemoryHandle shared_memory_handle; |
| 67 if (!buffer->ShareToProcess(base::GetCurrentProcessHandle(), |
| 68 &shared_memory_handle)) { |
| 69 LOG(ERROR) << "Failed to duplicate command buffer shared memory handle."; |
| 70 return false; |
| 71 } |
| 72 |
| 73 ring_buffer_.shared_memory = new base::SharedMemory(shared_memory_handle, |
| 74 false); |
| 75 if (!ring_buffer_.shared_memory->Map(size)) { |
| 76 LOG(ERROR) << "Failed because ring buffer could not be created or mapped "; |
| 77 delete ring_buffer_.shared_memory; |
| 78 ring_buffer_.shared_memory = NULL; |
| 79 return false; |
| 80 } |
| 81 |
| 82 ring_buffer_.ptr = ring_buffer_.shared_memory->memory(); |
| 83 ring_buffer_.size = size; |
| 84 num_entries_ = size / sizeof(CommandBufferEntry); |
| 85 |
36 return true; | 86 return true; |
37 } | 87 } |
38 | 88 |
| 89 Buffer CommandBufferService::GetRingBuffer() { |
| 90 return ring_buffer_; |
| 91 } |
| 92 |
39 CommandBufferService::State CommandBufferService::GetState() { | 93 CommandBufferService::State CommandBufferService::GetState() { |
40 State state; | 94 State state; |
41 state.num_entries = num_entries_; | 95 state.num_entries = num_entries_; |
42 state.get_offset = get_offset_; | 96 state.get_offset = get_offset_; |
43 state.put_offset = put_offset_; | 97 state.put_offset = put_offset_; |
44 state.token = token_; | 98 state.token = token_; |
45 state.error = error_; | 99 state.error = error_; |
46 state.context_lost_reason = context_lost_reason_; | 100 state.context_lost_reason = context_lost_reason_; |
47 state.generation = ++generation_; | 101 state.generation = ++generation_; |
48 | 102 |
(...skipping 24 matching lines...) Expand all Loading... |
73 error_ = gpu::error::kOutOfBounds; | 127 error_ = gpu::error::kOutOfBounds; |
74 return; | 128 return; |
75 } | 129 } |
76 | 130 |
77 put_offset_ = put_offset; | 131 put_offset_ = put_offset; |
78 | 132 |
79 if (!put_offset_change_callback_.is_null()) | 133 if (!put_offset_change_callback_.is_null()) |
80 put_offset_change_callback_.Run(); | 134 put_offset_change_callback_.Run(); |
81 } | 135 } |
82 | 136 |
83 void CommandBufferService::SetGetBuffer(int32 transfer_buffer_id) { | |
84 DCHECK_EQ(-1, ring_buffer_id_); | |
85 DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. | |
86 ring_buffer_ = GetTransferBuffer(transfer_buffer_id); | |
87 DCHECK(ring_buffer_.ptr); | |
88 ring_buffer_id_ = transfer_buffer_id; | |
89 num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry); | |
90 put_offset_ = 0; | |
91 SetGetOffset(0); | |
92 if (!get_buffer_change_callback_.is_null()) { | |
93 get_buffer_change_callback_.Run(ring_buffer_id_); | |
94 } | |
95 } | |
96 | |
97 void CommandBufferService::SetGetOffset(int32 get_offset) { | 137 void CommandBufferService::SetGetOffset(int32 get_offset) { |
98 DCHECK(get_offset >= 0 && get_offset < num_entries_); | 138 DCHECK(get_offset >= 0 && get_offset < num_entries_); |
99 get_offset_ = get_offset; | 139 get_offset_ = get_offset; |
100 } | 140 } |
101 | 141 |
102 int32 CommandBufferService::CreateTransferBuffer(size_t size, | 142 int32 CommandBufferService::CreateTransferBuffer(size_t size, |
103 int32 id_request) { | 143 int32 id_request) { |
104 SharedMemory buffer; | 144 SharedMemory buffer; |
105 if (!buffer.CreateAnonymous(size)) | 145 if (!buffer.CreateAnonymous(size)) |
106 return -1; | 146 return -1; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 if (handle <= 0) | 216 if (handle <= 0) |
177 return; | 217 return; |
178 | 218 |
179 if (static_cast<size_t>(handle) >= registered_objects_.size()) | 219 if (static_cast<size_t>(handle) >= registered_objects_.size()) |
180 return; | 220 return; |
181 | 221 |
182 delete registered_objects_[handle].shared_memory; | 222 delete registered_objects_[handle].shared_memory; |
183 registered_objects_[handle] = Buffer(); | 223 registered_objects_[handle] = Buffer(); |
184 unused_registered_object_elements_.insert(handle); | 224 unused_registered_object_elements_.insert(handle); |
185 | 225 |
186 if (handle == ring_buffer_id_) { | |
187 ring_buffer_id_ = -1; | |
188 ring_buffer_ = Buffer(); | |
189 num_entries_ = 0; | |
190 get_offset_ = 0; | |
191 put_offset_ = 0; | |
192 } | |
193 | |
194 // Remove all null objects from the end of the vector. This allows the vector | 226 // Remove all null objects from the end of the vector. This allows the vector |
195 // to shrink when, for example, all objects are unregistered. Note that this | 227 // to shrink when, for example, all objects are unregistered. Note that this |
196 // loop never removes element zero, which is always NULL. | 228 // loop never removes element zero, which is always NULL. |
197 while (registered_objects_.size() > 1 && | 229 while (registered_objects_.size() > 1 && |
198 !registered_objects_.back().shared_memory) { | 230 !registered_objects_.back().shared_memory) { |
199 registered_objects_.pop_back(); | 231 registered_objects_.pop_back(); |
200 unused_registered_object_elements_.erase( | 232 unused_registered_object_elements_.erase( |
201 static_cast<int32>(registered_objects_.size())); | 233 static_cast<int32>(registered_objects_.size())); |
202 } | 234 } |
203 } | 235 } |
(...skipping 23 matching lines...) Expand all Loading... |
227 void CommandBufferService::SetContextLostReason( | 259 void CommandBufferService::SetContextLostReason( |
228 error::ContextLostReason reason) { | 260 error::ContextLostReason reason) { |
229 context_lost_reason_ = reason; | 261 context_lost_reason_ = reason; |
230 } | 262 } |
231 | 263 |
232 void CommandBufferService::SetPutOffsetChangeCallback( | 264 void CommandBufferService::SetPutOffsetChangeCallback( |
233 const base::Closure& callback) { | 265 const base::Closure& callback) { |
234 put_offset_change_callback_ = callback; | 266 put_offset_change_callback_ = callback; |
235 } | 267 } |
236 | 268 |
237 void CommandBufferService::SetGetBufferChangeCallback( | |
238 const GetBufferChangedCallback& callback) { | |
239 get_buffer_change_callback_ = callback; | |
240 } | |
241 | |
242 void CommandBufferService::SetParseErrorCallback( | 269 void CommandBufferService::SetParseErrorCallback( |
243 const base::Closure& callback) { | 270 const base::Closure& callback) { |
244 parse_error_callback_ = callback; | 271 parse_error_callback_ = callback; |
245 } | 272 } |
246 | 273 |
247 } // namespace gpu | 274 } // namespace gpu |
OLD | NEW |