OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/common_decoder.h" | 5 #include "gpu/command_buffer/service/common_decoder.h" |
6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
7 #include <algorithm> | 10 #include <algorithm> |
8 | 11 |
9 #include "base/numerics/safe_math.h" | 12 #include "base/numerics/safe_math.h" |
10 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 13 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
11 | 14 |
12 namespace gpu { | 15 namespace gpu { |
13 | 16 |
14 const CommonDecoder::CommandInfo CommonDecoder::command_info[] = { | 17 const CommonDecoder::CommandInfo CommonDecoder::command_info[] = { |
15 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ | 18 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ |
16 { \ | 19 { \ |
(...skipping 13 matching lines...) Expand all Loading... |
30 | 33 |
31 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const { | 34 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const { |
32 if (OffsetSizeValid(offset, size)) { | 35 if (OffsetSizeValid(offset, size)) { |
33 return data_.get() + offset; | 36 return data_.get() + offset; |
34 } | 37 } |
35 return NULL; | 38 return NULL; |
36 } | 39 } |
37 | 40 |
38 void CommonDecoder::Bucket::SetSize(size_t size) { | 41 void CommonDecoder::Bucket::SetSize(size_t size) { |
39 if (size != size_) { | 42 if (size != size_) { |
40 data_.reset(size ? new int8[size] : NULL); | 43 data_.reset(size ? new int8_t[size] : NULL); |
41 size_ = size; | 44 size_ = size; |
42 memset(data_.get(), 0, size); | 45 memset(data_.get(), 0, size); |
43 } | 46 } |
44 } | 47 } |
45 | 48 |
46 bool CommonDecoder::Bucket::SetData( | 49 bool CommonDecoder::Bucket::SetData( |
47 const void* src, size_t offset, size_t size) { | 50 const void* src, size_t offset, size_t size) { |
48 if (OffsetSizeValid(offset, size)) { | 51 if (OffsetSizeValid(offset, size)) { |
49 memcpy(data_.get() + offset, src, size); | 52 memcpy(data_.get() + offset, src, size); |
50 return true; | 53 return true; |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 scoped_refptr<gpu::Buffer> CommonDecoder::GetSharedMemoryBuffer( | 140 scoped_refptr<gpu::Buffer> CommonDecoder::GetSharedMemoryBuffer( |
138 unsigned int shm_id) { | 141 unsigned int shm_id) { |
139 return engine_->GetSharedMemoryBuffer(shm_id); | 142 return engine_->GetSharedMemoryBuffer(shm_id); |
140 } | 143 } |
141 | 144 |
142 const char* CommonDecoder::GetCommonCommandName( | 145 const char* CommonDecoder::GetCommonCommandName( |
143 cmd::CommandId command_id) const { | 146 cmd::CommandId command_id) const { |
144 return cmd::GetCommandName(command_id); | 147 return cmd::GetCommandName(command_id); |
145 } | 148 } |
146 | 149 |
147 CommonDecoder::Bucket* CommonDecoder::GetBucket(uint32 bucket_id) const { | 150 CommonDecoder::Bucket* CommonDecoder::GetBucket(uint32_t bucket_id) const { |
148 BucketMap::const_iterator iter(buckets_.find(bucket_id)); | 151 BucketMap::const_iterator iter(buckets_.find(bucket_id)); |
149 return iter != buckets_.end() ? &(*iter->second) : NULL; | 152 return iter != buckets_.end() ? &(*iter->second) : NULL; |
150 } | 153 } |
151 | 154 |
152 CommonDecoder::Bucket* CommonDecoder::CreateBucket(uint32 bucket_id) { | 155 CommonDecoder::Bucket* CommonDecoder::CreateBucket(uint32_t bucket_id) { |
153 Bucket* bucket = GetBucket(bucket_id); | 156 Bucket* bucket = GetBucket(bucket_id); |
154 if (!bucket) { | 157 if (!bucket) { |
155 bucket = new Bucket(); | 158 bucket = new Bucket(); |
156 buckets_[bucket_id] = linked_ptr<Bucket>(bucket); | 159 buckets_[bucket_id] = linked_ptr<Bucket>(bucket); |
157 } | 160 } |
158 return bucket; | 161 return bucket; |
159 } | 162 } |
160 | 163 |
161 namespace { | 164 namespace { |
162 | 165 |
163 // Returns the address of the first byte after a struct. | 166 // Returns the address of the first byte after a struct. |
164 template <typename T> | 167 template <typename T> |
165 const void* AddressAfterStruct(const T& pod) { | 168 const void* AddressAfterStruct(const T& pod) { |
166 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); | 169 return reinterpret_cast<const uint8_t*>(&pod) + sizeof(pod); |
167 } | 170 } |
168 | 171 |
169 // Returns the address of the frst byte after the struct. | 172 // Returns the address of the frst byte after the struct. |
170 template <typename RETURN_TYPE, typename COMMAND_TYPE> | 173 template <typename RETURN_TYPE, typename COMMAND_TYPE> |
171 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { | 174 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { |
172 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); | 175 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); |
173 } | 176 } |
174 | 177 |
175 } // anonymous namespace. | 178 } // anonymous namespace. |
176 | 179 |
177 // Decode command with its arguments, and call the corresponding method. | 180 // Decode command with its arguments, and call the corresponding method. |
178 // Note: args is a pointer to the command buffer. As such, it could be changed | 181 // Note: args is a pointer to the command buffer. As such, it could be changed |
179 // by a (malicious) client at any time, so if validation has to happen, it | 182 // by a (malicious) client at any time, so if validation has to happen, it |
180 // should operate on a copy of them. | 183 // should operate on a copy of them. |
181 error::Error CommonDecoder::DoCommonCommand( | 184 error::Error CommonDecoder::DoCommonCommand( |
182 unsigned int command, | 185 unsigned int command, |
183 unsigned int arg_count, | 186 unsigned int arg_count, |
184 const void* cmd_data) { | 187 const void* cmd_data) { |
185 if (command < arraysize(command_info)) { | 188 if (command < arraysize(command_info)) { |
186 const CommandInfo& info = command_info[command]; | 189 const CommandInfo& info = command_info[command]; |
187 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); | 190 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); |
188 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || | 191 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || |
189 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { | 192 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { |
190 uint32 immediate_data_size = | 193 uint32_t immediate_data_size = |
191 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT | 194 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT |
192 return (this->*info.cmd_handler)(immediate_data_size, cmd_data); | 195 return (this->*info.cmd_handler)(immediate_data_size, cmd_data); |
193 } else { | 196 } else { |
194 return error::kInvalidArguments; | 197 return error::kInvalidArguments; |
195 } | 198 } |
196 } | 199 } |
197 return error::kUnknownCommand; | 200 return error::kUnknownCommand; |
198 } | 201 } |
199 | 202 |
200 error::Error CommonDecoder::HandleNoop( | 203 error::Error CommonDecoder::HandleNoop(uint32_t immediate_data_size, |
201 uint32 immediate_data_size, | 204 const void* cmd_data) { |
202 const void* cmd_data) { | |
203 return error::kNoError; | 205 return error::kNoError; |
204 } | 206 } |
205 | 207 |
206 error::Error CommonDecoder::HandleSetToken( | 208 error::Error CommonDecoder::HandleSetToken(uint32_t immediate_data_size, |
207 uint32 immediate_data_size, | 209 const void* cmd_data) { |
208 const void* cmd_data) { | |
209 const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data); | 210 const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data); |
210 engine_->set_token(args.token); | 211 engine_->set_token(args.token); |
211 return error::kNoError; | 212 return error::kNoError; |
212 } | 213 } |
213 | 214 |
214 error::Error CommonDecoder::HandleSetBucketSize( | 215 error::Error CommonDecoder::HandleSetBucketSize(uint32_t immediate_data_size, |
215 uint32 immediate_data_size, | 216 const void* cmd_data) { |
216 const void* cmd_data) { | |
217 const cmd::SetBucketSize& args = | 217 const cmd::SetBucketSize& args = |
218 *static_cast<const cmd::SetBucketSize*>(cmd_data); | 218 *static_cast<const cmd::SetBucketSize*>(cmd_data); |
219 uint32 bucket_id = args.bucket_id; | 219 uint32_t bucket_id = args.bucket_id; |
220 uint32 size = args.size; | 220 uint32_t size = args.size; |
221 | 221 |
222 Bucket* bucket = CreateBucket(bucket_id); | 222 Bucket* bucket = CreateBucket(bucket_id); |
223 bucket->SetSize(size); | 223 bucket->SetSize(size); |
224 return error::kNoError; | 224 return error::kNoError; |
225 } | 225 } |
226 | 226 |
227 error::Error CommonDecoder::HandleSetBucketData( | 227 error::Error CommonDecoder::HandleSetBucketData(uint32_t immediate_data_size, |
228 uint32 immediate_data_size, | 228 const void* cmd_data) { |
229 const void* cmd_data) { | |
230 const cmd::SetBucketData& args = | 229 const cmd::SetBucketData& args = |
231 *static_cast<const cmd::SetBucketData*>(cmd_data); | 230 *static_cast<const cmd::SetBucketData*>(cmd_data); |
232 uint32 bucket_id = args.bucket_id; | 231 uint32_t bucket_id = args.bucket_id; |
233 uint32 offset = args.offset; | 232 uint32_t offset = args.offset; |
234 uint32 size = args.size; | 233 uint32_t size = args.size; |
235 const void* data = GetSharedMemoryAs<const void*>( | 234 const void* data = GetSharedMemoryAs<const void*>( |
236 args.shared_memory_id, args.shared_memory_offset, size); | 235 args.shared_memory_id, args.shared_memory_offset, size); |
237 if (!data) { | 236 if (!data) { |
238 return error::kInvalidArguments; | 237 return error::kInvalidArguments; |
239 } | 238 } |
240 Bucket* bucket = GetBucket(bucket_id); | 239 Bucket* bucket = GetBucket(bucket_id); |
241 if (!bucket) { | 240 if (!bucket) { |
242 return error::kInvalidArguments; | 241 return error::kInvalidArguments; |
243 } | 242 } |
244 if (!bucket->SetData(data, offset, size)) { | 243 if (!bucket->SetData(data, offset, size)) { |
245 return error::kInvalidArguments; | 244 return error::kInvalidArguments; |
246 } | 245 } |
247 | 246 |
248 return error::kNoError; | 247 return error::kNoError; |
249 } | 248 } |
250 | 249 |
251 error::Error CommonDecoder::HandleSetBucketDataImmediate( | 250 error::Error CommonDecoder::HandleSetBucketDataImmediate( |
252 uint32 immediate_data_size, | 251 uint32_t immediate_data_size, |
253 const void* cmd_data) { | 252 const void* cmd_data) { |
254 const cmd::SetBucketDataImmediate& args = | 253 const cmd::SetBucketDataImmediate& args = |
255 *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data); | 254 *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data); |
256 const void* data = GetImmediateDataAs<const void*>(args); | 255 const void* data = GetImmediateDataAs<const void*>(args); |
257 uint32 bucket_id = args.bucket_id; | 256 uint32_t bucket_id = args.bucket_id; |
258 uint32 offset = args.offset; | 257 uint32_t offset = args.offset; |
259 uint32 size = args.size; | 258 uint32_t size = args.size; |
260 if (size > immediate_data_size) { | 259 if (size > immediate_data_size) { |
261 return error::kInvalidArguments; | 260 return error::kInvalidArguments; |
262 } | 261 } |
263 Bucket* bucket = GetBucket(bucket_id); | 262 Bucket* bucket = GetBucket(bucket_id); |
264 if (!bucket) { | 263 if (!bucket) { |
265 return error::kInvalidArguments; | 264 return error::kInvalidArguments; |
266 } | 265 } |
267 if (!bucket->SetData(data, offset, size)) { | 266 if (!bucket->SetData(data, offset, size)) { |
268 return error::kInvalidArguments; | 267 return error::kInvalidArguments; |
269 } | 268 } |
270 return error::kNoError; | 269 return error::kNoError; |
271 } | 270 } |
272 | 271 |
273 error::Error CommonDecoder::HandleGetBucketStart( | 272 error::Error CommonDecoder::HandleGetBucketStart(uint32_t immediate_data_size, |
274 uint32 immediate_data_size, | 273 const void* cmd_data) { |
275 const void* cmd_data) { | |
276 const cmd::GetBucketStart& args = | 274 const cmd::GetBucketStart& args = |
277 *static_cast<const cmd::GetBucketStart*>(cmd_data); | 275 *static_cast<const cmd::GetBucketStart*>(cmd_data); |
278 uint32 bucket_id = args.bucket_id; | 276 uint32_t bucket_id = args.bucket_id; |
279 uint32* result = GetSharedMemoryAs<uint32*>( | 277 uint32_t* result = GetSharedMemoryAs<uint32_t*>( |
280 args.result_memory_id, args.result_memory_offset, sizeof(*result)); | 278 args.result_memory_id, args.result_memory_offset, sizeof(*result)); |
281 int32 data_memory_id = args.data_memory_id; | 279 int32_t data_memory_id = args.data_memory_id; |
282 uint32 data_memory_offset = args.data_memory_offset; | 280 uint32_t data_memory_offset = args.data_memory_offset; |
283 uint32 data_memory_size = args.data_memory_size; | 281 uint32_t data_memory_size = args.data_memory_size; |
284 uint8* data = NULL; | 282 uint8_t* data = NULL; |
285 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { | 283 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { |
286 data = GetSharedMemoryAs<uint8*>( | 284 data = GetSharedMemoryAs<uint8_t*>( |
287 args.data_memory_id, args.data_memory_offset, args.data_memory_size); | 285 args.data_memory_id, args.data_memory_offset, args.data_memory_size); |
288 if (!data) { | 286 if (!data) { |
289 return error::kInvalidArguments; | 287 return error::kInvalidArguments; |
290 } | 288 } |
291 } | 289 } |
292 if (!result) { | 290 if (!result) { |
293 return error::kInvalidArguments; | 291 return error::kInvalidArguments; |
294 } | 292 } |
295 // Check that the client initialized the result. | 293 // Check that the client initialized the result. |
296 if (*result != 0) { | 294 if (*result != 0) { |
297 return error::kInvalidArguments; | 295 return error::kInvalidArguments; |
298 } | 296 } |
299 Bucket* bucket = GetBucket(bucket_id); | 297 Bucket* bucket = GetBucket(bucket_id); |
300 if (!bucket) { | 298 if (!bucket) { |
301 return error::kInvalidArguments; | 299 return error::kInvalidArguments; |
302 } | 300 } |
303 uint32 bucket_size = bucket->size(); | 301 uint32_t bucket_size = bucket->size(); |
304 *result = bucket_size; | 302 *result = bucket_size; |
305 if (data) { | 303 if (data) { |
306 uint32 size = std::min(data_memory_size, bucket_size); | 304 uint32_t size = std::min(data_memory_size, bucket_size); |
307 memcpy(data, bucket->GetData(0, size), size); | 305 memcpy(data, bucket->GetData(0, size), size); |
308 } | 306 } |
309 return error::kNoError; | 307 return error::kNoError; |
310 } | 308 } |
311 | 309 |
312 error::Error CommonDecoder::HandleGetBucketData( | 310 error::Error CommonDecoder::HandleGetBucketData(uint32_t immediate_data_size, |
313 uint32 immediate_data_size, | 311 const void* cmd_data) { |
314 const void* cmd_data) { | |
315 const cmd::GetBucketData& args = | 312 const cmd::GetBucketData& args = |
316 *static_cast<const cmd::GetBucketData*>(cmd_data); | 313 *static_cast<const cmd::GetBucketData*>(cmd_data); |
317 uint32 bucket_id = args.bucket_id; | 314 uint32_t bucket_id = args.bucket_id; |
318 uint32 offset = args.offset; | 315 uint32_t offset = args.offset; |
319 uint32 size = args.size; | 316 uint32_t size = args.size; |
320 void* data = GetSharedMemoryAs<void*>( | 317 void* data = GetSharedMemoryAs<void*>( |
321 args.shared_memory_id, args.shared_memory_offset, size); | 318 args.shared_memory_id, args.shared_memory_offset, size); |
322 if (!data) { | 319 if (!data) { |
323 return error::kInvalidArguments; | 320 return error::kInvalidArguments; |
324 } | 321 } |
325 Bucket* bucket = GetBucket(bucket_id); | 322 Bucket* bucket = GetBucket(bucket_id); |
326 if (!bucket) { | 323 if (!bucket) { |
327 return error::kInvalidArguments; | 324 return error::kInvalidArguments; |
328 } | 325 } |
329 const void* src = bucket->GetData(offset, size); | 326 const void* src = bucket->GetData(offset, size); |
330 if (!src) { | 327 if (!src) { |
331 return error::kInvalidArguments; | 328 return error::kInvalidArguments; |
332 } | 329 } |
333 memcpy(data, src, size); | 330 memcpy(data, src, size); |
334 return error::kNoError; | 331 return error::kNoError; |
335 } | 332 } |
336 | 333 |
337 } // namespace gpu | 334 } // namespace gpu |
OLD | NEW |