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 |