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 : num_entries_(0), | 17 : ring_buffer_id_(-1), |
| 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 generation_(0), | 22 generation_(0), |
22 error_(error::kNoError) { | 23 error_(error::kNoError) { |
23 // Element zero is always NULL. | 24 // Element zero is always NULL. |
24 registered_objects_.push_back(Buffer()); | 25 registered_objects_.push_back(Buffer()); |
25 } | 26 } |
26 | 27 |
27 CommandBufferService::~CommandBufferService() { | 28 CommandBufferService::~CommandBufferService() { |
28 delete ring_buffer_.shared_memory; | |
29 | |
30 for (size_t i = 0; i < registered_objects_.size(); ++i) { | 29 for (size_t i = 0; i < registered_objects_.size(); ++i) { |
31 if (registered_objects_[i].shared_memory) | 30 if (registered_objects_[i].shared_memory) |
32 delete registered_objects_[i].shared_memory; | 31 delete registered_objects_[i].shared_memory; |
33 } | 32 } |
34 } | 33 } |
35 | 34 |
36 bool CommandBufferService::Initialize(int32 size) { | 35 bool CommandBufferService::Initialize() { |
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 | |
86 return true; | 36 return true; |
87 } | 37 } |
88 | 38 |
89 Buffer CommandBufferService::GetRingBuffer() { | |
90 return ring_buffer_; | |
91 } | |
92 | |
93 CommandBufferService::State CommandBufferService::GetState() { | 39 CommandBufferService::State CommandBufferService::GetState() { |
94 State state; | 40 State state; |
95 state.num_entries = num_entries_; | 41 state.num_entries = num_entries_; |
96 state.get_offset = get_offset_; | 42 state.get_offset = get_offset_; |
97 state.put_offset = put_offset_; | 43 state.put_offset = put_offset_; |
98 state.token = token_; | 44 state.token = token_; |
99 state.error = error_; | 45 state.error = error_; |
100 state.context_lost_reason = context_lost_reason_; | 46 state.context_lost_reason = context_lost_reason_; |
101 state.generation = ++generation_; | 47 state.generation = ++generation_; |
102 | 48 |
(...skipping 24 matching lines...) Expand all Loading... |
127 error_ = gpu::error::kOutOfBounds; | 73 error_ = gpu::error::kOutOfBounds; |
128 return; | 74 return; |
129 } | 75 } |
130 | 76 |
131 put_offset_ = put_offset; | 77 put_offset_ = put_offset; |
132 | 78 |
133 if (!put_offset_change_callback_.is_null()) | 79 if (!put_offset_change_callback_.is_null()) |
134 put_offset_change_callback_.Run(); | 80 put_offset_change_callback_.Run(); |
135 } | 81 } |
136 | 82 |
| 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 |
137 void CommandBufferService::SetGetOffset(int32 get_offset) { | 97 void CommandBufferService::SetGetOffset(int32 get_offset) { |
138 DCHECK(get_offset >= 0 && get_offset < num_entries_); | 98 DCHECK(get_offset >= 0 && get_offset < num_entries_); |
139 get_offset_ = get_offset; | 99 get_offset_ = get_offset; |
140 } | 100 } |
141 | 101 |
142 int32 CommandBufferService::CreateTransferBuffer(size_t size, | 102 int32 CommandBufferService::CreateTransferBuffer(size_t size, |
143 int32 id_request) { | 103 int32 id_request) { |
144 SharedMemory buffer; | 104 SharedMemory buffer; |
145 if (!buffer.CreateAnonymous(size)) | 105 if (!buffer.CreateAnonymous(size)) |
146 return -1; | 106 return -1; |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
216 if (handle <= 0) | 176 if (handle <= 0) |
217 return; | 177 return; |
218 | 178 |
219 if (static_cast<size_t>(handle) >= registered_objects_.size()) | 179 if (static_cast<size_t>(handle) >= registered_objects_.size()) |
220 return; | 180 return; |
221 | 181 |
222 delete registered_objects_[handle].shared_memory; | 182 delete registered_objects_[handle].shared_memory; |
223 registered_objects_[handle] = Buffer(); | 183 registered_objects_[handle] = Buffer(); |
224 unused_registered_object_elements_.insert(handle); | 184 unused_registered_object_elements_.insert(handle); |
225 | 185 |
| 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 |
226 // Remove all null objects from the end of the vector. This allows the vector | 194 // Remove all null objects from the end of the vector. This allows the vector |
227 // to shrink when, for example, all objects are unregistered. Note that this | 195 // to shrink when, for example, all objects are unregistered. Note that this |
228 // loop never removes element zero, which is always NULL. | 196 // loop never removes element zero, which is always NULL. |
229 while (registered_objects_.size() > 1 && | 197 while (registered_objects_.size() > 1 && |
230 !registered_objects_.back().shared_memory) { | 198 !registered_objects_.back().shared_memory) { |
231 registered_objects_.pop_back(); | 199 registered_objects_.pop_back(); |
232 unused_registered_object_elements_.erase( | 200 unused_registered_object_elements_.erase( |
233 static_cast<int32>(registered_objects_.size())); | 201 static_cast<int32>(registered_objects_.size())); |
234 } | 202 } |
235 } | 203 } |
(...skipping 23 matching lines...) Expand all Loading... |
259 void CommandBufferService::SetContextLostReason( | 227 void CommandBufferService::SetContextLostReason( |
260 error::ContextLostReason reason) { | 228 error::ContextLostReason reason) { |
261 context_lost_reason_ = reason; | 229 context_lost_reason_ = reason; |
262 } | 230 } |
263 | 231 |
264 void CommandBufferService::SetPutOffsetChangeCallback( | 232 void CommandBufferService::SetPutOffsetChangeCallback( |
265 const base::Closure& callback) { | 233 const base::Closure& callback) { |
266 put_offset_change_callback_ = callback; | 234 put_offset_change_callback_ = callback; |
267 } | 235 } |
268 | 236 |
| 237 void CommandBufferService::SetGetBufferChangeCallback( |
| 238 const GetBufferChangedCallback& callback) { |
| 239 get_buffer_change_callback_ = callback; |
| 240 } |
| 241 |
269 void CommandBufferService::SetParseErrorCallback( | 242 void CommandBufferService::SetParseErrorCallback( |
270 const base::Closure& callback) { | 243 const base::Closure& callback) { |
271 parse_error_callback_ = callback; | 244 parse_error_callback_ = callback; |
272 } | 245 } |
273 | 246 |
274 } // namespace gpu | 247 } // namespace gpu |
OLD | NEW |