| 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> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <algorithm> | 10 #include <algorithm> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 | 43 |
| 44 void CommonDecoder::Bucket::SetSize(size_t size) { | 44 void CommonDecoder::Bucket::SetSize(size_t size) { |
| 45 if (size != size_) { | 45 if (size != size_) { |
| 46 data_.reset(size ? new int8_t[size] : NULL); | 46 data_.reset(size ? new int8_t[size] : NULL); |
| 47 size_ = size; | 47 size_ = size; |
| 48 memset(data_.get(), 0, size); | 48 memset(data_.get(), 0, size); |
| 49 } | 49 } |
| 50 } | 50 } |
| 51 | 51 |
| 52 bool CommonDecoder::Bucket::SetData( | 52 bool CommonDecoder::Bucket::SetData( |
| 53 const void* src, size_t offset, size_t size) { | 53 const volatile void* src, size_t offset, size_t size) { |
| 54 if (OffsetSizeValid(offset, size)) { | 54 if (OffsetSizeValid(offset, size)) { |
| 55 memcpy(data_.get() + offset, src, size); | 55 memcpy(data_.get() + offset, const_cast<const void*>(src), size); |
| 56 return true; | 56 return true; |
| 57 } | 57 } |
| 58 return false; | 58 return false; |
| 59 } | 59 } |
| 60 | 60 |
| 61 void CommonDecoder::Bucket::SetFromString(const char* str) { | 61 void CommonDecoder::Bucket::SetFromString(const char* str) { |
| 62 // Strings are passed NULL terminated to distinguish between empty string | 62 // Strings are passed NULL terminated to distinguish between empty string |
| 63 // and no string. | 63 // and no string. |
| 64 if (!str) { | 64 if (!str) { |
| 65 SetSize(0); | 65 SetSize(0); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 bucket = new Bucket(); | 181 bucket = new Bucket(); |
| 182 buckets_[bucket_id] = std::unique_ptr<Bucket>(bucket); | 182 buckets_[bucket_id] = std::unique_ptr<Bucket>(bucket); |
| 183 } | 183 } |
| 184 return bucket; | 184 return bucket; |
| 185 } | 185 } |
| 186 | 186 |
| 187 namespace { | 187 namespace { |
| 188 | 188 |
| 189 // Returns the address of the first byte after a struct. | 189 // Returns the address of the first byte after a struct. |
| 190 template <typename T> | 190 template <typename T> |
| 191 const void* AddressAfterStruct(const T& pod) { | 191 const volatile void* AddressAfterStruct(const volatile T& pod) { |
| 192 return reinterpret_cast<const uint8_t*>(&pod) + sizeof(pod); | 192 return reinterpret_cast<const volatile uint8_t*>(&pod) + sizeof(pod); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // Returns the address of the frst byte after the struct. | 195 // Returns the address of the frst byte after the struct. |
| 196 template <typename RETURN_TYPE, typename COMMAND_TYPE> | 196 template <typename RETURN_TYPE, typename COMMAND_TYPE> |
| 197 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { | 197 RETURN_TYPE GetImmediateDataAs(const volatile COMMAND_TYPE& pod) { |
| 198 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); | 198 return static_cast<RETURN_TYPE>( |
| 199 const_cast<volatile void*>(AddressAfterStruct(pod))); |
| 199 } | 200 } |
| 200 | 201 |
| 201 } // anonymous namespace. | 202 } // anonymous namespace. |
| 202 | 203 |
| 203 // Decode command with its arguments, and call the corresponding method. | 204 // Decode command with its arguments, and call the corresponding method. |
| 204 // Note: args is a pointer to the command buffer. As such, it could be changed | 205 // Note: args is a pointer to the command buffer. As such, it could be changed |
| 205 // by a (malicious) client at any time, so if validation has to happen, it | 206 // by a (malicious) client at any time, so if validation has to happen, it |
| 206 // should operate on a copy of them. | 207 // should operate on a copy of them. |
| 207 error::Error CommonDecoder::DoCommonCommand( | 208 error::Error CommonDecoder::DoCommonCommand(unsigned int command, |
| 208 unsigned int command, | 209 unsigned int arg_count, |
| 209 unsigned int arg_count, | 210 const volatile void* cmd_data) { |
| 210 const void* cmd_data) { | |
| 211 if (command < arraysize(command_info)) { | 211 if (command < arraysize(command_info)) { |
| 212 const CommandInfo& info = command_info[command]; | 212 const CommandInfo& info = command_info[command]; |
| 213 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); | 213 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); |
| 214 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || | 214 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || |
| 215 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { | 215 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { |
| 216 uint32_t immediate_data_size = | 216 uint32_t immediate_data_size = |
| 217 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT | 217 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT |
| 218 return (this->*info.cmd_handler)(immediate_data_size, cmd_data); | 218 return (this->*info.cmd_handler)(immediate_data_size, cmd_data); |
| 219 } else { | 219 } else { |
| 220 return error::kInvalidArguments; | 220 return error::kInvalidArguments; |
| 221 } | 221 } |
| 222 } | 222 } |
| 223 return error::kUnknownCommand; | 223 return error::kUnknownCommand; |
| 224 } | 224 } |
| 225 | 225 |
| 226 error::Error CommonDecoder::HandleNoop(uint32_t immediate_data_size, | 226 error::Error CommonDecoder::HandleNoop(uint32_t immediate_data_size, |
| 227 const void* cmd_data) { | 227 const volatile void* cmd_data) { |
| 228 return error::kNoError; | 228 return error::kNoError; |
| 229 } | 229 } |
| 230 | 230 |
| 231 error::Error CommonDecoder::HandleSetToken(uint32_t immediate_data_size, | 231 error::Error CommonDecoder::HandleSetToken(uint32_t immediate_data_size, |
| 232 const void* cmd_data) { | 232 const volatile void* cmd_data) { |
| 233 const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data); | 233 const volatile cmd::SetToken& args = |
| 234 *static_cast<const volatile cmd::SetToken*>(cmd_data); |
| 234 engine_->set_token(args.token); | 235 engine_->set_token(args.token); |
| 235 return error::kNoError; | 236 return error::kNoError; |
| 236 } | 237 } |
| 237 | 238 |
| 238 error::Error CommonDecoder::HandleSetBucketSize(uint32_t immediate_data_size, | 239 error::Error CommonDecoder::HandleSetBucketSize(uint32_t immediate_data_size, |
| 239 const void* cmd_data) { | 240 const volatile void* cmd_data) { |
| 240 const cmd::SetBucketSize& args = | 241 const volatile cmd::SetBucketSize& args = |
| 241 *static_cast<const cmd::SetBucketSize*>(cmd_data); | 242 *static_cast<const volatile cmd::SetBucketSize*>(cmd_data); |
| 242 uint32_t bucket_id = args.bucket_id; | 243 uint32_t bucket_id = args.bucket_id; |
| 243 uint32_t size = args.size; | 244 uint32_t size = args.size; |
| 244 if (size > max_bucket_size_) | 245 if (size > max_bucket_size_) |
| 245 return error::kOutOfBounds; | 246 return error::kOutOfBounds; |
| 246 | 247 |
| 247 Bucket* bucket = CreateBucket(bucket_id); | 248 Bucket* bucket = CreateBucket(bucket_id); |
| 248 bucket->SetSize(size); | 249 bucket->SetSize(size); |
| 249 return error::kNoError; | 250 return error::kNoError; |
| 250 } | 251 } |
| 251 | 252 |
| 252 error::Error CommonDecoder::HandleSetBucketData(uint32_t immediate_data_size, | 253 error::Error CommonDecoder::HandleSetBucketData(uint32_t immediate_data_size, |
| 253 const void* cmd_data) { | 254 const volatile void* cmd_data) { |
| 254 const cmd::SetBucketData& args = | 255 const volatile cmd::SetBucketData& args = |
| 255 *static_cast<const cmd::SetBucketData*>(cmd_data); | 256 *static_cast<const volatile cmd::SetBucketData*>(cmd_data); |
| 256 uint32_t bucket_id = args.bucket_id; | 257 uint32_t bucket_id = args.bucket_id; |
| 257 uint32_t offset = args.offset; | 258 uint32_t offset = args.offset; |
| 258 uint32_t size = args.size; | 259 uint32_t size = args.size; |
| 259 const void* data = GetSharedMemoryAs<const void*>( | 260 const void* data = GetSharedMemoryAs<const void*>( |
| 260 args.shared_memory_id, args.shared_memory_offset, size); | 261 args.shared_memory_id, args.shared_memory_offset, size); |
| 261 if (!data) { | 262 if (!data) { |
| 262 return error::kInvalidArguments; | 263 return error::kInvalidArguments; |
| 263 } | 264 } |
| 264 Bucket* bucket = GetBucket(bucket_id); | 265 Bucket* bucket = GetBucket(bucket_id); |
| 265 if (!bucket) { | 266 if (!bucket) { |
| 266 return error::kInvalidArguments; | 267 return error::kInvalidArguments; |
| 267 } | 268 } |
| 268 if (!bucket->SetData(data, offset, size)) { | 269 if (!bucket->SetData(data, offset, size)) { |
| 269 return error::kInvalidArguments; | 270 return error::kInvalidArguments; |
| 270 } | 271 } |
| 271 | 272 |
| 272 return error::kNoError; | 273 return error::kNoError; |
| 273 } | 274 } |
| 274 | 275 |
| 275 error::Error CommonDecoder::HandleSetBucketDataImmediate( | 276 error::Error CommonDecoder::HandleSetBucketDataImmediate( |
| 276 uint32_t immediate_data_size, | 277 uint32_t immediate_data_size, |
| 277 const void* cmd_data) { | 278 const volatile void* cmd_data) { |
| 278 const cmd::SetBucketDataImmediate& args = | 279 const volatile cmd::SetBucketDataImmediate& args = |
| 279 *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data); | 280 *static_cast<const volatile cmd::SetBucketDataImmediate*>(cmd_data); |
| 280 const void* data = GetImmediateDataAs<const void*>(args); | 281 const volatile void* data = GetImmediateDataAs<const volatile void*>(args); |
| 281 uint32_t bucket_id = args.bucket_id; | 282 uint32_t bucket_id = args.bucket_id; |
| 282 uint32_t offset = args.offset; | 283 uint32_t offset = args.offset; |
| 283 uint32_t size = args.size; | 284 uint32_t size = args.size; |
| 284 if (size > immediate_data_size) { | 285 if (size > immediate_data_size) { |
| 285 return error::kInvalidArguments; | 286 return error::kInvalidArguments; |
| 286 } | 287 } |
| 287 Bucket* bucket = GetBucket(bucket_id); | 288 Bucket* bucket = GetBucket(bucket_id); |
| 288 if (!bucket) { | 289 if (!bucket) { |
| 289 return error::kInvalidArguments; | 290 return error::kInvalidArguments; |
| 290 } | 291 } |
| 291 if (!bucket->SetData(data, offset, size)) { | 292 if (!bucket->SetData(data, offset, size)) { |
| 292 return error::kInvalidArguments; | 293 return error::kInvalidArguments; |
| 293 } | 294 } |
| 294 return error::kNoError; | 295 return error::kNoError; |
| 295 } | 296 } |
| 296 | 297 |
| 297 error::Error CommonDecoder::HandleGetBucketStart(uint32_t immediate_data_size, | 298 error::Error CommonDecoder::HandleGetBucketStart( |
| 298 const void* cmd_data) { | 299 uint32_t immediate_data_size, |
| 299 const cmd::GetBucketStart& args = | 300 const volatile void* cmd_data) { |
| 300 *static_cast<const cmd::GetBucketStart*>(cmd_data); | 301 const volatile cmd::GetBucketStart& args = |
| 302 *static_cast<const volatile cmd::GetBucketStart*>(cmd_data); |
| 301 uint32_t bucket_id = args.bucket_id; | 303 uint32_t bucket_id = args.bucket_id; |
| 302 uint32_t* result = GetSharedMemoryAs<uint32_t*>( | 304 uint32_t* result = GetSharedMemoryAs<uint32_t*>( |
| 303 args.result_memory_id, args.result_memory_offset, sizeof(*result)); | 305 args.result_memory_id, args.result_memory_offset, sizeof(*result)); |
| 304 int32_t data_memory_id = args.data_memory_id; | 306 int32_t data_memory_id = args.data_memory_id; |
| 305 uint32_t data_memory_offset = args.data_memory_offset; | 307 uint32_t data_memory_offset = args.data_memory_offset; |
| 306 uint32_t data_memory_size = args.data_memory_size; | 308 uint32_t data_memory_size = args.data_memory_size; |
| 307 uint8_t* data = NULL; | 309 uint8_t* data = NULL; |
| 308 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { | 310 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { |
| 309 data = GetSharedMemoryAs<uint8_t*>(data_memory_id, data_memory_offset, | 311 data = GetSharedMemoryAs<uint8_t*>(data_memory_id, data_memory_offset, |
| 310 data_memory_size); | 312 data_memory_size); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 326 uint32_t bucket_size = bucket->size(); | 328 uint32_t bucket_size = bucket->size(); |
| 327 *result = bucket_size; | 329 *result = bucket_size; |
| 328 if (data) { | 330 if (data) { |
| 329 uint32_t size = std::min(data_memory_size, bucket_size); | 331 uint32_t size = std::min(data_memory_size, bucket_size); |
| 330 memcpy(data, bucket->GetData(0, size), size); | 332 memcpy(data, bucket->GetData(0, size), size); |
| 331 } | 333 } |
| 332 return error::kNoError; | 334 return error::kNoError; |
| 333 } | 335 } |
| 334 | 336 |
| 335 error::Error CommonDecoder::HandleGetBucketData(uint32_t immediate_data_size, | 337 error::Error CommonDecoder::HandleGetBucketData(uint32_t immediate_data_size, |
| 336 const void* cmd_data) { | 338 const volatile void* cmd_data) { |
| 337 const cmd::GetBucketData& args = | 339 const volatile cmd::GetBucketData& args = |
| 338 *static_cast<const cmd::GetBucketData*>(cmd_data); | 340 *static_cast<const volatile cmd::GetBucketData*>(cmd_data); |
| 339 uint32_t bucket_id = args.bucket_id; | 341 uint32_t bucket_id = args.bucket_id; |
| 340 uint32_t offset = args.offset; | 342 uint32_t offset = args.offset; |
| 341 uint32_t size = args.size; | 343 uint32_t size = args.size; |
| 342 void* data = GetSharedMemoryAs<void*>( | 344 void* data = GetSharedMemoryAs<void*>( |
| 343 args.shared_memory_id, args.shared_memory_offset, size); | 345 args.shared_memory_id, args.shared_memory_offset, size); |
| 344 if (!data) { | 346 if (!data) { |
| 345 return error::kInvalidArguments; | 347 return error::kInvalidArguments; |
| 346 } | 348 } |
| 347 Bucket* bucket = GetBucket(bucket_id); | 349 Bucket* bucket = GetBucket(bucket_id); |
| 348 if (!bucket) { | 350 if (!bucket) { |
| 349 return error::kInvalidArguments; | 351 return error::kInvalidArguments; |
| 350 } | 352 } |
| 351 const void* src = bucket->GetData(offset, size); | 353 const void* src = bucket->GetData(offset, size); |
| 352 if (!src) { | 354 if (!src) { |
| 353 return error::kInvalidArguments; | 355 return error::kInvalidArguments; |
| 354 } | 356 } |
| 355 memcpy(data, src, size); | 357 memcpy(data, src, size); |
| 356 return error::kNoError; | 358 return error::kNoError; |
| 357 } | 359 } |
| 358 | 360 |
| 359 } // namespace gpu | 361 } // namespace gpu |
| OLD | NEW |