Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(21)

Side by Side Diff: gpu/command_buffer/service/common_decoder.cc

Issue 2275203002: Make command buffer commands and immediate data volatile (Closed)
Patch Set: std::copy->const_cast+memcpy Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/common_decoder.h ('k') | gpu/command_buffer/service/common_decoder_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698