| 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 #include "gpu/command_buffer/service/cmd_buffer_engine.h" | 6 #include "gpu/command_buffer/service/cmd_buffer_engine.h" |
| 7 | 7 |
| 8 namespace gpu { | 8 namespace gpu { |
| 9 | 9 |
| 10 const CommonDecoder::CommandInfo CommonDecoder::command_info[] = { |
| 11 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ |
| 12 { \ |
| 13 &CommonDecoder::Handle##name, cmd::name::kArgFlags, \ |
| 14 cmd::name::cmd_flags, \ |
| 15 sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, \ |
| 16 } \ |
| 17 , /* NOLINT */ |
| 18 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) |
| 19 #undef COMMON_COMMAND_BUFFER_CMD_OP |
| 20 }; |
| 21 |
| 22 |
| 10 CommonDecoder::Bucket::Bucket() : size_(0) {} | 23 CommonDecoder::Bucket::Bucket() : size_(0) {} |
| 11 | 24 |
| 12 CommonDecoder::Bucket::~Bucket() {} | 25 CommonDecoder::Bucket::~Bucket() {} |
| 13 | 26 |
| 14 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const { | 27 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const { |
| 15 if (OffsetSizeValid(offset, size)) { | 28 if (OffsetSizeValid(offset, size)) { |
| 16 return data_.get() + offset; | 29 return data_.get() + offset; |
| 17 } | 30 } |
| 18 return NULL; | 31 return NULL; |
| 19 } | 32 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 const void* AddressAfterStruct(const T& pod) { | 114 const void* AddressAfterStruct(const T& pod) { |
| 102 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); | 115 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); |
| 103 } | 116 } |
| 104 | 117 |
| 105 // Returns the address of the frst byte after the struct. | 118 // Returns the address of the frst byte after the struct. |
| 106 template <typename RETURN_TYPE, typename COMMAND_TYPE> | 119 template <typename RETURN_TYPE, typename COMMAND_TYPE> |
| 107 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { | 120 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { |
| 108 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); | 121 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); |
| 109 } | 122 } |
| 110 | 123 |
| 111 // TODO(vmiura): Looks like this g_command_info is duplicated in | |
| 112 // common_decoder.cc | |
| 113 // and gles2_cmd_decoder.cc. Fix it! | |
| 114 | |
| 115 // A struct to hold info about each command. | |
| 116 struct CommandInfo { | |
| 117 uint8 arg_flags; // How to handle the arguments for this command | |
| 118 uint8 cmd_flags; // How to handle this command | |
| 119 uint16 arg_count; // How many arguments are expected for this command. | |
| 120 }; | |
| 121 | |
| 122 // A table of CommandInfo for all the commands. | |
| 123 const CommandInfo g_command_info[] = { | |
| 124 #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \ | |
| 125 cmd::name::kArgFlags, \ | |
| 126 cmd::name::cmd_flags, \ | |
| 127 sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ | |
| 128 | |
| 129 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) | |
| 130 | |
| 131 #undef COMMON_COMMAND_BUFFER_CMD_OP | |
| 132 }; | |
| 133 | |
| 134 } // anonymous namespace. | 124 } // anonymous namespace. |
| 135 | 125 |
| 136 // Decode command with its arguments, and call the corresponding method. | 126 // Decode command with its arguments, and call the corresponding method. |
| 137 // Note: args is a pointer to the command buffer. As such, it could be changed | 127 // Note: args is a pointer to the command buffer. As such, it could be changed |
| 138 // by a (malicious) client at any time, so if validation has to happen, it | 128 // by a (malicious) client at any time, so if validation has to happen, it |
| 139 // should operate on a copy of them. | 129 // should operate on a copy of them. |
| 140 error::Error CommonDecoder::DoCommonCommand( | 130 error::Error CommonDecoder::DoCommonCommand( |
| 141 unsigned int command, | 131 unsigned int command, |
| 142 unsigned int arg_count, | 132 unsigned int arg_count, |
| 143 const void* cmd_data) { | 133 const void* cmd_data) { |
| 144 if (command < arraysize(g_command_info)) { | 134 if (command < arraysize(command_info)) { |
| 145 const CommandInfo& info = g_command_info[command]; | 135 const CommandInfo& info = command_info[command]; |
| 146 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); | 136 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); |
| 147 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || | 137 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || |
| 148 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { | 138 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { |
| 149 uint32 immediate_data_size = | 139 uint32 immediate_data_size = |
| 150 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT | 140 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT |
| 151 switch (command) { | 141 return (this->*info.cmd_handler)(immediate_data_size, cmd_data); |
| 152 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \ | |
| 153 case cmd::name::kCmdId: \ | |
| 154 return Handle ## name( \ | |
| 155 immediate_data_size, \ | |
| 156 *static_cast<const cmd::name*>(cmd_data)); \ | |
| 157 | |
| 158 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP) | |
| 159 | |
| 160 #undef COMMON_COMMAND_BUFFER_CMD_OP | |
| 161 } | |
| 162 } else { | 142 } else { |
| 163 return error::kInvalidArguments; | 143 return error::kInvalidArguments; |
| 164 } | 144 } |
| 165 } | 145 } |
| 166 return error::kUnknownCommand; | 146 return error::kUnknownCommand; |
| 167 } | 147 } |
| 168 | 148 |
| 169 error::Error CommonDecoder::HandleNoop( | 149 error::Error CommonDecoder::HandleNoop( |
| 170 uint32 immediate_data_size, | 150 uint32 immediate_data_size, |
| 171 const cmd::Noop& args) { | 151 const void* cmd_data) { |
| 172 return error::kNoError; | 152 return error::kNoError; |
| 173 } | 153 } |
| 174 | 154 |
| 175 error::Error CommonDecoder::HandleSetToken( | 155 error::Error CommonDecoder::HandleSetToken( |
| 176 uint32 immediate_data_size, | 156 uint32 immediate_data_size, |
| 177 const cmd::SetToken& args) { | 157 const void* cmd_data) { |
| 158 const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data); |
| 178 engine_->set_token(args.token); | 159 engine_->set_token(args.token); |
| 179 return error::kNoError; | 160 return error::kNoError; |
| 180 } | 161 } |
| 181 | 162 |
| 182 error::Error CommonDecoder::HandleSetBucketSize( | 163 error::Error CommonDecoder::HandleSetBucketSize( |
| 183 uint32 immediate_data_size, | 164 uint32 immediate_data_size, |
| 184 const cmd::SetBucketSize& args) { | 165 const void* cmd_data) { |
| 166 const cmd::SetBucketSize& args = |
| 167 *static_cast<const cmd::SetBucketSize*>(cmd_data); |
| 185 uint32 bucket_id = args.bucket_id; | 168 uint32 bucket_id = args.bucket_id; |
| 186 uint32 size = args.size; | 169 uint32 size = args.size; |
| 187 | 170 |
| 188 Bucket* bucket = CreateBucket(bucket_id); | 171 Bucket* bucket = CreateBucket(bucket_id); |
| 189 bucket->SetSize(size); | 172 bucket->SetSize(size); |
| 190 return error::kNoError; | 173 return error::kNoError; |
| 191 } | 174 } |
| 192 | 175 |
| 193 error::Error CommonDecoder::HandleSetBucketData( | 176 error::Error CommonDecoder::HandleSetBucketData( |
| 194 uint32 immediate_data_size, | 177 uint32 immediate_data_size, |
| 195 const cmd::SetBucketData& args) { | 178 const void* cmd_data) { |
| 179 const cmd::SetBucketData& args = |
| 180 *static_cast<const cmd::SetBucketData*>(cmd_data); |
| 196 uint32 bucket_id = args.bucket_id; | 181 uint32 bucket_id = args.bucket_id; |
| 197 uint32 offset = args.offset; | 182 uint32 offset = args.offset; |
| 198 uint32 size = args.size; | 183 uint32 size = args.size; |
| 199 const void* data = GetSharedMemoryAs<const void*>( | 184 const void* data = GetSharedMemoryAs<const void*>( |
| 200 args.shared_memory_id, args.shared_memory_offset, size); | 185 args.shared_memory_id, args.shared_memory_offset, size); |
| 201 if (!data) { | 186 if (!data) { |
| 202 return error::kInvalidArguments; | 187 return error::kInvalidArguments; |
| 203 } | 188 } |
| 204 Bucket* bucket = GetBucket(bucket_id); | 189 Bucket* bucket = GetBucket(bucket_id); |
| 205 if (!bucket) { | 190 if (!bucket) { |
| 206 return error::kInvalidArguments; | 191 return error::kInvalidArguments; |
| 207 } | 192 } |
| 208 if (!bucket->SetData(data, offset, size)) { | 193 if (!bucket->SetData(data, offset, size)) { |
| 209 return error::kInvalidArguments; | 194 return error::kInvalidArguments; |
| 210 } | 195 } |
| 211 | 196 |
| 212 return error::kNoError; | 197 return error::kNoError; |
| 213 } | 198 } |
| 214 | 199 |
| 215 error::Error CommonDecoder::HandleSetBucketDataImmediate( | 200 error::Error CommonDecoder::HandleSetBucketDataImmediate( |
| 216 uint32 immediate_data_size, | 201 uint32 immediate_data_size, |
| 217 const cmd::SetBucketDataImmediate& args) { | 202 const void* cmd_data) { |
| 203 const cmd::SetBucketDataImmediate& args = |
| 204 *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data); |
| 218 const void* data = GetImmediateDataAs<const void*>(args); | 205 const void* data = GetImmediateDataAs<const void*>(args); |
| 219 uint32 bucket_id = args.bucket_id; | 206 uint32 bucket_id = args.bucket_id; |
| 220 uint32 offset = args.offset; | 207 uint32 offset = args.offset; |
| 221 uint32 size = args.size; | 208 uint32 size = args.size; |
| 222 if (size > immediate_data_size) { | 209 if (size > immediate_data_size) { |
| 223 return error::kInvalidArguments; | 210 return error::kInvalidArguments; |
| 224 } | 211 } |
| 225 Bucket* bucket = GetBucket(bucket_id); | 212 Bucket* bucket = GetBucket(bucket_id); |
| 226 if (!bucket) { | 213 if (!bucket) { |
| 227 return error::kInvalidArguments; | 214 return error::kInvalidArguments; |
| 228 } | 215 } |
| 229 if (!bucket->SetData(data, offset, size)) { | 216 if (!bucket->SetData(data, offset, size)) { |
| 230 return error::kInvalidArguments; | 217 return error::kInvalidArguments; |
| 231 } | 218 } |
| 232 return error::kNoError; | 219 return error::kNoError; |
| 233 } | 220 } |
| 234 | 221 |
| 235 error::Error CommonDecoder::HandleGetBucketStart( | 222 error::Error CommonDecoder::HandleGetBucketStart( |
| 236 uint32 immediate_data_size, | 223 uint32 immediate_data_size, |
| 237 const cmd::GetBucketStart& args) { | 224 const void* cmd_data) { |
| 225 const cmd::GetBucketStart& args = |
| 226 *static_cast<const cmd::GetBucketStart*>(cmd_data); |
| 238 uint32 bucket_id = args.bucket_id; | 227 uint32 bucket_id = args.bucket_id; |
| 239 uint32* result = GetSharedMemoryAs<uint32*>( | 228 uint32* result = GetSharedMemoryAs<uint32*>( |
| 240 args.result_memory_id, args.result_memory_offset, sizeof(*result)); | 229 args.result_memory_id, args.result_memory_offset, sizeof(*result)); |
| 241 int32 data_memory_id = args.data_memory_id; | 230 int32 data_memory_id = args.data_memory_id; |
| 242 uint32 data_memory_offset = args.data_memory_offset; | 231 uint32 data_memory_offset = args.data_memory_offset; |
| 243 uint32 data_memory_size = args.data_memory_size; | 232 uint32 data_memory_size = args.data_memory_size; |
| 244 uint8* data = NULL; | 233 uint8* data = NULL; |
| 245 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { | 234 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { |
| 246 data = GetSharedMemoryAs<uint8*>( | 235 data = GetSharedMemoryAs<uint8*>( |
| 247 args.data_memory_id, args.data_memory_offset, args.data_memory_size); | 236 args.data_memory_id, args.data_memory_offset, args.data_memory_size); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 264 *result = bucket_size; | 253 *result = bucket_size; |
| 265 if (data) { | 254 if (data) { |
| 266 uint32 size = std::min(data_memory_size, bucket_size); | 255 uint32 size = std::min(data_memory_size, bucket_size); |
| 267 memcpy(data, bucket->GetData(0, size), size); | 256 memcpy(data, bucket->GetData(0, size), size); |
| 268 } | 257 } |
| 269 return error::kNoError; | 258 return error::kNoError; |
| 270 } | 259 } |
| 271 | 260 |
| 272 error::Error CommonDecoder::HandleGetBucketData( | 261 error::Error CommonDecoder::HandleGetBucketData( |
| 273 uint32 immediate_data_size, | 262 uint32 immediate_data_size, |
| 274 const cmd::GetBucketData& args) { | 263 const void* cmd_data) { |
| 264 const cmd::GetBucketData& args = |
| 265 *static_cast<const cmd::GetBucketData*>(cmd_data); |
| 275 uint32 bucket_id = args.bucket_id; | 266 uint32 bucket_id = args.bucket_id; |
| 276 uint32 offset = args.offset; | 267 uint32 offset = args.offset; |
| 277 uint32 size = args.size; | 268 uint32 size = args.size; |
| 278 void* data = GetSharedMemoryAs<void*>( | 269 void* data = GetSharedMemoryAs<void*>( |
| 279 args.shared_memory_id, args.shared_memory_offset, size); | 270 args.shared_memory_id, args.shared_memory_offset, size); |
| 280 if (!data) { | 271 if (!data) { |
| 281 return error::kInvalidArguments; | 272 return error::kInvalidArguments; |
| 282 } | 273 } |
| 283 Bucket* bucket = GetBucket(bucket_id); | 274 Bucket* bucket = GetBucket(bucket_id); |
| 284 if (!bucket) { | 275 if (!bucket) { |
| 285 return error::kInvalidArguments; | 276 return error::kInvalidArguments; |
| 286 } | 277 } |
| 287 const void* src = bucket->GetData(offset, size); | 278 const void* src = bucket->GetData(offset, size); |
| 288 if (!src) { | 279 if (!src) { |
| 289 return error::kInvalidArguments; | 280 return error::kInvalidArguments; |
| 290 } | 281 } |
| 291 memcpy(data, src, size); | 282 memcpy(data, src, size); |
| 292 return error::kNoError; | 283 return error::kNoError; |
| 293 } | 284 } |
| 294 | 285 |
| 295 } // namespace gpu | 286 } // namespace gpu |
| OLD | NEW |