| 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 |