| 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/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/process_util.h" | 10 #include "base/process_util.h" |
| 11 #include "gpu/command_buffer/common/cmd_buffer_common.h" | 11 #include "gpu/command_buffer/common/cmd_buffer_common.h" |
| 12 | 12 |
| 13 using ::base::SharedMemory; | 13 using ::base::SharedMemory; |
| 14 | 14 |
| 15 namespace gpu { | 15 namespace gpu { |
| 16 | 16 |
| 17 CommandBufferService::CommandBufferService() | 17 CommandBufferService::CommandBufferService() |
| 18 : num_entries_(0), | 18 : ring_buffer_id_(-1), |
| 19 num_entries_(0), |
| 19 get_offset_(0), | 20 get_offset_(0), |
| 20 put_offset_(0), | 21 put_offset_(0), |
| 21 token_(0), | 22 token_(0), |
| 22 generation_(0), | 23 generation_(0), |
| 23 error_(error::kNoError) { | 24 error_(error::kNoError) { |
| 24 // Element zero is always NULL. | 25 // Element zero is always NULL. |
| 25 registered_objects_.push_back(Buffer()); | 26 registered_objects_.push_back(Buffer()); |
| 26 } | 27 } |
| 27 | 28 |
| 28 CommandBufferService::~CommandBufferService() { | 29 CommandBufferService::~CommandBufferService() { |
| 29 delete ring_buffer_.shared_memory; | |
| 30 | |
| 31 for (size_t i = 0; i < registered_objects_.size(); ++i) { | 30 for (size_t i = 0; i < registered_objects_.size(); ++i) { |
| 32 if (registered_objects_[i].shared_memory) | 31 if (registered_objects_[i].shared_memory) |
| 33 delete registered_objects_[i].shared_memory; | 32 delete registered_objects_[i].shared_memory; |
| 34 } | 33 } |
| 35 } | 34 } |
| 36 | 35 |
| 37 bool CommandBufferService::Initialize(int32 size) { | 36 bool CommandBufferService::Initialize() { |
| 38 // Fail if already initialized. | |
| 39 if (ring_buffer_.shared_memory) { | |
| 40 LOG(ERROR) << "Failed because already initialized."; | |
| 41 return false; | |
| 42 } | |
| 43 | |
| 44 if (size <= 0 || size > kMaxCommandBufferSize) { | |
| 45 LOG(ERROR) << "Failed because command buffer size was invalid."; | |
| 46 return false; | |
| 47 } | |
| 48 | |
| 49 num_entries_ = size / sizeof(CommandBufferEntry); | |
| 50 | |
| 51 SharedMemory shared_memory; | |
| 52 if (!shared_memory.CreateAnonymous(size)) { | |
| 53 LOG(ERROR) << "Failed to create shared memory for command buffer."; | |
| 54 return true; | |
| 55 } | |
| 56 | |
| 57 return Initialize(&shared_memory, size); | |
| 58 } | |
| 59 | |
| 60 bool CommandBufferService::Initialize(base::SharedMemory* buffer, int32 size) { | |
| 61 // Fail if already initialized. | |
| 62 if (ring_buffer_.shared_memory) { | |
| 63 LOG(ERROR) << "Failed because already initialized."; | |
| 64 return false; | |
| 65 } | |
| 66 | |
| 67 base::SharedMemoryHandle shared_memory_handle; | |
| 68 if (!buffer->ShareToProcess(base::GetCurrentProcessHandle(), | |
| 69 &shared_memory_handle)) { | |
| 70 LOG(ERROR) << "Failed to duplicate command buffer shared memory handle."; | |
| 71 return false; | |
| 72 } | |
| 73 | |
| 74 ring_buffer_.shared_memory = new base::SharedMemory(shared_memory_handle, | |
| 75 false); | |
| 76 if (!ring_buffer_.shared_memory->Map(size)) { | |
| 77 LOG(ERROR) << "Failed because ring buffer could not be created or mapped "; | |
| 78 delete ring_buffer_.shared_memory; | |
| 79 ring_buffer_.shared_memory = NULL; | |
| 80 return false; | |
| 81 } | |
| 82 | |
| 83 ring_buffer_.ptr = ring_buffer_.shared_memory->memory(); | |
| 84 ring_buffer_.size = size; | |
| 85 num_entries_ = size / sizeof(CommandBufferEntry); | |
| 86 | |
| 87 return true; | 37 return true; |
| 88 } | 38 } |
| 89 | 39 |
| 90 Buffer CommandBufferService::GetRingBuffer() { | |
| 91 return ring_buffer_; | |
| 92 } | |
| 93 | |
| 94 CommandBufferService::State CommandBufferService::GetState() { | 40 CommandBufferService::State CommandBufferService::GetState() { |
| 95 State state; | 41 State state; |
| 96 state.num_entries = num_entries_; | 42 state.num_entries = num_entries_; |
| 97 state.get_offset = get_offset_; | 43 state.get_offset = get_offset_; |
| 98 state.put_offset = put_offset_; | 44 state.put_offset = put_offset_; |
| 99 state.token = token_; | 45 state.token = token_; |
| 100 state.error = error_; | 46 state.error = error_; |
| 101 state.context_lost_reason = context_lost_reason_; | 47 state.context_lost_reason = context_lost_reason_; |
| 102 state.generation = ++generation_; | 48 state.generation = ++generation_; |
| 103 | 49 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 130 return; | 76 return; |
| 131 } | 77 } |
| 132 | 78 |
| 133 put_offset_ = put_offset; | 79 put_offset_ = put_offset; |
| 134 | 80 |
| 135 if (put_offset_change_callback_.get()) { | 81 if (put_offset_change_callback_.get()) { |
| 136 put_offset_change_callback_->Run(); | 82 put_offset_change_callback_->Run(); |
| 137 } | 83 } |
| 138 } | 84 } |
| 139 | 85 |
| 86 void CommandBufferService::SetGetBuffer(int32 shm_id) { |
| 87 DCHECK_EQ(-1, ring_buffer_id_); |
| 88 DCHECK_EQ(put_offset_, get_offset_); // Only if it's empty. |
| 89 ring_buffer_ = GetTransferBuffer(shm_id); |
| 90 DCHECK(ring_buffer_.ptr); |
| 91 ring_buffer_id_ = shm_id; |
| 92 num_entries_ = ring_buffer_.size / sizeof(CommandBufferEntry); |
| 93 put_offset_ = 0; |
| 94 SetGetOffset(0); |
| 95 } |
| 96 |
| 140 void CommandBufferService::SetGetOffset(int32 get_offset) { | 97 void CommandBufferService::SetGetOffset(int32 get_offset) { |
| 141 DCHECK(get_offset >= 0 && get_offset < num_entries_); | 98 DCHECK(get_offset >= 0 && get_offset < num_entries_); |
| 142 get_offset_ = get_offset; | 99 get_offset_ = get_offset; |
| 143 } | 100 } |
| 144 | 101 |
| 145 int32 CommandBufferService::CreateTransferBuffer(size_t size, | 102 int32 CommandBufferService::CreateTransferBuffer(size_t size, |
| 146 int32 id_request) { | 103 int32 id_request) { |
| 147 SharedMemory buffer; | 104 SharedMemory buffer; |
| 148 if (!buffer.CreateAnonymous(size)) | 105 if (!buffer.CreateAnonymous(size)) |
| 149 return -1; | 106 return -1; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 if (handle <= 0) | 176 if (handle <= 0) |
| 220 return; | 177 return; |
| 221 | 178 |
| 222 if (static_cast<size_t>(handle) >= registered_objects_.size()) | 179 if (static_cast<size_t>(handle) >= registered_objects_.size()) |
| 223 return; | 180 return; |
| 224 | 181 |
| 225 delete registered_objects_[handle].shared_memory; | 182 delete registered_objects_[handle].shared_memory; |
| 226 registered_objects_[handle] = Buffer(); | 183 registered_objects_[handle] = Buffer(); |
| 227 unused_registered_object_elements_.insert(handle); | 184 unused_registered_object_elements_.insert(handle); |
| 228 | 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 |
| 229 // 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 |
| 230 // 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 |
| 231 // loop never removes element zero, which is always NULL. | 196 // loop never removes element zero, which is always NULL. |
| 232 while (registered_objects_.size() > 1 && | 197 while (registered_objects_.size() > 1 && |
| 233 !registered_objects_.back().shared_memory) { | 198 !registered_objects_.back().shared_memory) { |
| 234 registered_objects_.pop_back(); | 199 registered_objects_.pop_back(); |
| 235 unused_registered_object_elements_.erase( | 200 unused_registered_object_elements_.erase( |
| 236 static_cast<int32>(registered_objects_.size())); | 201 static_cast<int32>(registered_objects_.size())); |
| 237 } | 202 } |
| 238 } | 203 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 268 Callback0::Type* callback) { | 233 Callback0::Type* callback) { |
| 269 put_offset_change_callback_.reset(callback); | 234 put_offset_change_callback_.reset(callback); |
| 270 } | 235 } |
| 271 | 236 |
| 272 void CommandBufferService::SetParseErrorCallback( | 237 void CommandBufferService::SetParseErrorCallback( |
| 273 Callback0::Type* callback) { | 238 Callback0::Type* callback) { |
| 274 parse_error_callback_.reset(callback); | 239 parse_error_callback_.reset(callback); |
| 275 } | 240 } |
| 276 | 241 |
| 277 } // namespace gpu | 242 } // namespace gpu |
| OLD | NEW |