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

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

Issue 501097: Add Immediate command data size validation.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 11 years 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 <vector> 5 #include <vector>
6 #include <string> 6 #include <string>
7 #include <map> 7 #include <map>
8 #include <build/build_config.h> 8 #include <build/build_config.h>
9 #include "base/scoped_ptr.h" 9 #include "base/scoped_ptr.h"
10 #define GLES2_GPU_SERVICE 1 10 #define GLES2_GPU_SERVICE 1
11 #include "gpu/command_buffer/common/gles2_cmd_format.h" 11 #include "gpu/command_buffer/common/gles2_cmd_format.h"
12 #include "gpu/command_buffer/common/gles2_cmd_utils.h" 12 #include "gpu/command_buffer/common/gles2_cmd_utils.h"
13 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 13 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
14 #include "gpu/command_buffer/service/gl_utils.h" 14 #include "gpu/command_buffer/service/gl_utils.h"
15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h" 15 #include "gpu/command_buffer/service/gles2_cmd_decoder.h"
16 #include "gpu/command_buffer/service/gles2_cmd_validation.h" 16 #include "gpu/command_buffer/service/gles2_cmd_validation.h"
17 17
18 namespace gpu { 18 namespace gpu {
19 namespace gles2 { 19 namespace gles2 {
20 20
21 // Check that certain assumptions the code makes are true. There are places in
22 // the code where shared memory is passed direclty to GL. Example, glUniformiv,
23 // glShaderSource. The command buffer code assumes GLint and GLsizei (and maybe
24 // a few others) are 32bits. If they are not 32bits the code will have to change
25 // to call those GL functions with service side memory and then copy the results
26 // to shared memory, converting the sizes.
27 COMPILE_ASSERT(sizeof(GLint) == sizeof(uint32), // NOLINT
28 GLint_not_same_size_as_uint32);
29 COMPILE_ASSERT(sizeof(GLsizei) == sizeof(uint32), // NOLINT
30 GLint_not_same_size_as_uint32);
31
21 namespace { 32 namespace {
22 33
34 size_t GetGLTypeSize(GLenum type) {
35 switch (type) {
36 case GL_BYTE:
37 return sizeof(GLbyte); // NOLINT
38 case GL_UNSIGNED_BYTE:
39 return sizeof(GLubyte); // NOLINT
40 case GL_SHORT:
41 return sizeof(GLshort); // NOLINT
42 case GL_UNSIGNED_SHORT:
43 return sizeof(GLushort); // NOLINT
44 case GL_FLOAT:
45 return sizeof(GLfloat); // NOLINT
46 default:
47 return 0;
48 }
49 }
50
23 // Returns the address of the first byte after a struct. 51 // Returns the address of the first byte after a struct.
24 template <typename T> 52 template <typename T>
25 const void* AddressAfterStruct(const T& pod) { 53 const void* AddressAfterStruct(const T& pod) {
26 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 54 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
27 } 55 }
28 56
29 // Returns the address of the frst byte after the struct. 57 // Returns the address of the frst byte after the struct or NULL if size >
58 // immediate_data_size.
30 template <typename RETURN_TYPE, typename COMMAND_TYPE> 59 template <typename RETURN_TYPE, typename COMMAND_TYPE>
31 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { 60 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod,
32 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); 61 uint32 size,
62 uint32 immediate_data_size) {
63 return (size <= immediate_data_size) ?
64 static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))) :
65 NULL;
33 } 66 }
34 67
35 // Checks if there is enough immediate data. 68 // Computes the data size for certain gl commands like glUniform.
36 template<typename T> 69 uint32 ComputeImmediateDataSize(
37 bool CheckImmediateDataSize(
38 uint32 immediate_data_size, 70 uint32 immediate_data_size,
39 GLuint count, 71 GLuint count,
40 size_t size, 72 size_t size,
41 unsigned int elements_per_unit) { 73 unsigned int elements_per_unit) {
42 return immediate_data_size == count * size * elements_per_unit; 74 return count * size * elements_per_unit;
43 } 75 }
44 76
45 // A struct to hold info about each command. 77 // A struct to hold info about each command.
46 struct CommandInfo { 78 struct CommandInfo {
47 int arg_flags; // How to handle the arguments for this command 79 int arg_flags; // How to handle the arguments for this command
48 int arg_count; // How many arguments are expected for this command. 80 int arg_count; // How many arguments are expected for this command.
49 }; 81 };
50 82
51 // A table of CommandInfo for all the commands. 83 // A table of CommandInfo for all the commands.
52 const CommandInfo g_command_info[] = { 84 const CommandInfo g_command_info[] = {
53 #define GLES2_CMD_OP(name) { \ 85 #define GLES2_CMD_OP(name) { \
54 name::kArgFlags, \ 86 name::kArgFlags, \
55 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \ 87 sizeof(name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */ \
56 88
57 GLES2_COMMAND_LIST(GLES2_CMD_OP) 89 GLES2_COMMAND_LIST(GLES2_CMD_OP)
58 90
59 #undef GLES2_CMD_OP 91 #undef GLES2_CMD_OP
60 }; 92 };
61 93
62 // These commands convert from c calls to local os calls.
63 void GLGenBuffersHelper(GLsizei n, GLuint* ids) {
64 glGenBuffersARB(n, ids);
65 }
66
67 void GLGenFramebuffersHelper(GLsizei n, GLuint* ids) {
68 glGenFramebuffersEXT(n, ids);
69 }
70
71 void GLGenRenderbuffersHelper(GLsizei n, GLuint* ids) {
72 glGenRenderbuffersEXT(n, ids);
73 }
74
75 void GLGenTexturesHelper(GLsizei n, GLuint* ids) {
76 glGenTextures(n, ids);
77 }
78
79 void GLDeleteBuffersHelper(GLsizei n, GLuint* ids) {
80 glDeleteBuffersARB(n, ids);
81 }
82
83 void GLDeleteFramebuffersHelper(GLsizei n, GLuint* ids) {
84 glDeleteFramebuffersEXT(n, ids);
85 }
86
87 void GLDeleteRenderbuffersHelper(GLsizei n, GLuint* ids) {
88 glDeleteRenderbuffersEXT(n, ids);
89 }
90
91 void GLDeleteTexturesHelper(GLsizei n, GLuint* ids) {
92 glDeleteTextures(n, ids);
93 }
94
95 namespace GLErrorBit { 94 namespace GLErrorBit {
96 enum GLErrorBit { 95 enum GLErrorBit {
97 kNoError = 0, 96 kNoError = 0,
98 kInvalidEnum, 97 kInvalidEnum,
99 kInvalidValue, 98 kInvalidValue,
100 kInvalidOperation, 99 kInvalidOperation,
101 kOutOfMemory, 100 kOutOfMemory,
102 kInvalidFrameBufferOperation, 101 kInvalidFrameBufferOperation,
103 }; 102 };
104 } 103 }
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
214 return true; 213 return true;
215 } 214 }
216 } 215 }
217 return false; 216 return false;
218 } 217 }
219 218
220 // This class implements GLES2Decoder so we don't have to expose all the GLES2 219 // This class implements GLES2Decoder so we don't have to expose all the GLES2
221 // cmd stuff to outside this class. 220 // cmd stuff to outside this class.
222 class GLES2DecoderImpl : public GLES2Decoder { 221 class GLES2DecoderImpl : public GLES2Decoder {
223 public: 222 public:
223 // Info about Vertex Attributes. This is used to track what the user currently
224 // has bound on each Vertex Attribute so that checking can be done at
225 // glDrawXXX time.
226 class VertexAttribInfo {
227 public:
228 VertexAttribInfo()
229 : enabled_(false),
230 size_(0),
231 type_(0),
232 offset_(0),
233 real_stride_(0),
234 buffer_(0),
235 buffer_size_(0),
236 num_elements_(0) {
237 }
238 // Returns true if this VertexAttrib can access index.
239 bool CanAccess(GLuint index);
240
241 void set_enabled(bool enabled) {
242 enabled_ = enabled;
243 }
244
245 GLuint buffer() const {
246 return buffer_;
247 }
248
249 void Clear() {
250 buffer_ = 0;
251 SetBufferSize(0);
252 }
253
254 void SetBufferSize(GLsizeiptr buffer_size) {
255 buffer_size_ = buffer_size;
256 if (offset_ > buffer_size || real_stride_ == 0) {
257 num_elements_ = 0;
258 } else {
259 uint32 size = buffer_size - offset_;
260 num_elements_ = size / real_stride_ +
261 (size % real_stride_ >= GetGLTypeSize(type_) ? 1 : 0);
262 }
263 }
264
265 void SetInfo(
266 GLuint buffer,
267 GLsizeiptr buffer_size,
268 GLint size,
269 GLenum type,
270 GLsizei real_stride,
271 GLsizei offset) {
272 DCHECK(real_stride > 0);
273 buffer_ = buffer;
274 size_ = size;
275 type_ = type;
276 real_stride_ = real_stride;
277 offset_ = offset;
278 SetBufferSize(buffer_size);
279 }
280
281 private:
282 // Whether or not this attribute is enabled.
283 bool enabled_;
284
285 // number of components (1, 2, 3, 4)
286 GLint size_;
287
288 // GL_BYTE, GL_FLOAT, etc. See glVertexAttribPointer.
289 GLenum type_;
290
291 // The offset into the buffer.
292 GLsizei offset_;
293
294 // The stride that will be used to access the buffer. This is the actual
295 // stide, NOT the GL bogus stride. In other words there is never a stride
296 // of 0.
297 GLsizei real_stride_;
298
299 // The service side name of the buffer bound to this attribute. 0 = invalid
300 GLuint buffer_;
301
302 // The size of the buffer.
303 GLsizeiptr buffer_size_;
304
305 // The number of elements that can be accessed.
306 GLuint num_elements_;
307 };
308
309 // Info about Buffers currently in the system.
310 struct BufferInfo {
311 BufferInfo()
312 : size(0) {
313 }
314
315 explicit BufferInfo(GLsizeiptr _size)
316 : size(_size) {
317 }
318
319 GLsizeiptr size;
320 };
321
322 // This is used to track which attributes a particular program needs
323 // so we can verify at glDrawXXX time that every attribute is either disabled
324 // or if enabled that it points to a valid source.
325 class ProgramInfo {
326 public:
327 typedef std::vector<GLuint> AttribLocationVector;
328
329 ProgramInfo() {
330 }
331
332 void SetNumAttributes(int num_attribs) {
333 attrib_locations_.resize(num_attribs);
334 }
335
336 void SetAttributeLocation(GLuint index, int location) {
337 DCHECK(index < attrib_locations_.size());
338 attrib_locations_[index] = location;
339 }
340
341 const AttribLocationVector& GetAttribLocations() const {
342 return attrib_locations_;
343 }
344 private:
345 AttribLocationVector attrib_locations_;
346 };
347
224 GLES2DecoderImpl(); 348 GLES2DecoderImpl();
225 349
226 // Overridden from AsyncAPIInterface. 350 // Overridden from AsyncAPIInterface.
227 virtual ParseError DoCommand(unsigned int command, 351 virtual ParseError DoCommand(unsigned int command,
228 unsigned int arg_count, 352 unsigned int arg_count,
229 const void* args); 353 const void* args);
230 354
231 // Overridden from AsyncAPIInterface. 355 // Overridden from AsyncAPIInterface.
232 virtual const char* GetCommandName(unsigned int command_id) const; 356 virtual const char* GetCommandName(unsigned int command_id) const;
233 357
234 // Overridden from GLES2Decoder. 358 // Overridden from GLES2Decoder.
235 virtual bool Initialize(); 359 virtual bool Initialize();
236 360
237 // Overridden from GLES2Decoder. 361 // Overridden from GLES2Decoder.
238 virtual void Destroy(); 362 virtual void Destroy();
239 363
364 // Removes any buffers in the VertexAtrribInfos and BufferInfos. This is used
365 // on glDeleteBuffers so we can make sure the user does not try to render
366 // with deleted buffers.
367 void RemoveBufferInfo(GLuint buffer_id);
368
240 private: 369 private:
241 bool InitPlatformSpecific(); 370 bool InitPlatformSpecific();
242 bool InitGlew(); 371 bool InitGlew();
243 372
244 // Template to help call glGenXXX functions. 373 // Template to help call glGenXXX functions.
245 template <void gl_gen_function(GLsizei, GLuint*)> 374 template <void gl_gen_function(GLES2DecoderImpl*, GLsizei, GLuint*)>
246 bool GenGLObjects(GLsizei n, const GLuint* client_ids) { 375 bool GenGLObjects(GLsizei n, const GLuint* client_ids) {
247 // TODO(gman): Verify client ids are unused. 376 // TODO(gman): Verify client ids are unused.
248 scoped_array<GLuint>temp(new GLuint[n]); 377 scoped_array<GLuint>temp(new GLuint[n]);
249 gl_gen_function(n, temp.get()); 378 gl_gen_function(this, n, temp.get());
250 // TODO(gman): check for success before copying results. 379 // TODO(gman): check for success before copying results.
251 for (GLsizei ii = 0; ii < n; ++ii) { 380 return RegisterObjects(n, client_ids, temp.get());
252 if (!id_map_.AddMapping(client_ids[ii], temp[ii])) { 381 }
253 // TODO(gman): fail. 382
254 } 383 // Template to help call glDeleteXXX functions.
255 } 384 template <void gl_delete_function(GLES2DecoderImpl*, GLsizei, GLuint*)>
385 bool DeleteGLObjects(GLsizei n, const GLuint* client_ids) {
386 scoped_array<GLuint>temp(new GLuint[n]);
387 UnregisterObjects(n, client_ids, temp.get());
388 gl_delete_function(this, n, temp.get());
256 return true; 389 return true;
257 } 390 }
258 391
259 // Template to help call glDeleteXXX functions. 392 // Register client ids with generated service ids.
260 template <void gl_delete_function(GLsizei, GLuint*)> 393 bool RegisterObjects(
261 bool DeleteGLObjects(GLsizei n, const GLuint* client_ids) { 394 GLsizei n, const GLuint* client_ids, const GLuint* service_ids);
262 scoped_array<GLuint>temp(new GLuint[n]); 395
263 // TODO(gman): check for success before copying results. 396 // Unregisters client ids with service ids.
264 for (GLsizei ii = 0; ii < n; ++ii) { 397 void UnregisterObjects(
265 if (id_map_.GetServiceId(client_ids[ii], &temp[ii])) { 398 GLsizei n, const GLuint* client_ids, GLuint* service_ids);
266 id_map_.RemoveMapping(client_ids[ii], temp[ii]); 399
267 } else { 400 // Gets the program info for the given program. Returns NULL if none exists.
268 temp[ii] = 0; 401 // Programs that have no had glLinkProgram succesfully called on them will
269 } 402 // not exist.
270 } 403 ProgramInfo* GetProgramInfo(GLuint program);
271 gl_delete_function(n, temp.get()); 404
272 return true; 405 // Updates the program info for the given program.
273 } 406 void UpdateProgramInfo(GLuint program);
407
408 // Deletes the program info for the given program.
409 void RemoveProgramInfo(GLuint program);
410
411 // Gets the buffer info for the given buffer.
412 const BufferInfo* GetBufferInfo(GLuint buffer);
413
414 // Sets the info for a buffer.
415 void SetBufferInfo(GLuint buffer, GLsizeiptr size);
274 416
275 // Wrapper for glCreateProgram 417 // Wrapper for glCreateProgram
276 void CreateProgramHelper(GLuint client_id); 418 void CreateProgramHelper(GLuint client_id);
277 419
278 // Wrapper for glCreateShader 420 // Wrapper for glCreateShader
279 void CreateShaderHelper(GLenum type, GLuint client_id); 421 void CreateShaderHelper(GLenum type, GLuint client_id);
280 422
281 // Wrapper for glBindBuffer since we need to track the current targets. 423 // Wrapper for glBindBuffer since we need to track the current targets.
282 void DoBindBuffer(GLenum target, GLuint buffer); 424 void DoBindBuffer(GLenum target, GLuint buffer);
283 425
426 // Wrapper for glBindBuffer since we need to track the current targets.
apatrick 2009/12/22 02:37:21 BindBuffer -> DrawArrays
427 void DoDrawArrays(GLenum mode, GLint first, GLsizei count);
428
429 // Wrapper for glDisableVertexAttribArray.
430 void DoDisableVertexAttribArray(GLuint index);
431
432 // Wrapper for glEnableVertexAttribArray.
433 void DoEnableVertexAttribArray(GLuint index);
434
435 // Wrapper for glLinkProgram
436 void DoLinkProgram(GLuint program);
437
284 // Swaps the buffers (copies/renders to the current window). 438 // Swaps the buffers (copies/renders to the current window).
285 void DoSwapBuffers(); 439 void DoSwapBuffers();
286 440
441 // Wrapper for glUseProgram
442 void DoUseProgram(GLuint program);
443
287 // Gets the GLError through our wrapper. 444 // Gets the GLError through our wrapper.
288 GLenum GetGLError(); 445 GLenum GetGLError();
289 446
290 // Sets our wrapper for the GLError. 447 // Sets our wrapper for the GLError.
291 void SetGLError(GLenum error); 448 void SetGLError(GLenum error);
292 449
450 // Copies the real GL errors to the wrapper. This is so we can
451 // make sure there are no native GL errors before calling some GL function
452 // so that on return we know any error generated was for that specific
453 // command.
454 void CopyRealGLErrorsToWrapper();
455
456 // Checks if the current program and vertex attributes are valid for drawing.
457 bool IsDrawValid(GLuint max_vertex_accessed);
458
459 // Gets the buffer id for a given target.
460 GLuint GetBufferForTarget(GLenum target) {
461 DCHECK(target == GL_ARRAY_BUFFER || target == GL_ELEMENT_ARRAY_BUFFER);
462 return target == GL_ARRAY_BUFFER ? bound_array_buffer_ :
463 bound_element_array_buffer_;
464 }
465
293 // Generate a member function prototype for each command in an automated and 466 // Generate a member function prototype for each command in an automated and
294 // typesafe way. 467 // typesafe way.
295 #define GLES2_CMD_OP(name) \ 468 #define GLES2_CMD_OP(name) \
296 ParseError Handle ## name( \ 469 ParseError Handle ## name( \
297 uint32 immediate_data_size, \ 470 uint32 immediate_data_size, \
298 const gles2::name& args); \ 471 const gles2::name& args); \
299 472
300 GLES2_COMMAND_LIST(GLES2_CMD_OP) 473 GLES2_COMMAND_LIST(GLES2_CMD_OP)
301 474
302 #undef GLES2_CMD_OP 475 #undef GLES2_CMD_OP
(...skipping 14 matching lines...) Expand all
317 GLint unpack_alignment_; 490 GLint unpack_alignment_;
318 491
319 // The currently bound array buffer. If this is 0 it is illegal to call 492 // The currently bound array buffer. If this is 0 it is illegal to call
320 // glVertexAttribPointer. 493 // glVertexAttribPointer.
321 GLuint bound_array_buffer_; 494 GLuint bound_array_buffer_;
322 495
323 // The currently bound element array buffer. If this is 0 it is illegal 496 // The currently bound element array buffer. If this is 0 it is illegal
324 // to call glDrawElements. 497 // to call glDrawElements.
325 GLuint bound_element_array_buffer_; 498 GLuint bound_element_array_buffer_;
326 499
500 // The maximum vertex attributes.
501 GLuint max_vertex_attribs_;
502
503 // Info for each vertex attribute saved so we can check at glDrawXXX time
504 // if it is safe to draw.
505 scoped_array<VertexAttribInfo> vertex_attrib_infos_;
506
507 // Infor for each buffer in the system.
apatrick 2009/12/22 02:37:21 Infor -> Info
508 // TODO(gman): Choose a faster container.
509 typedef std::map<GLuint, BufferInfo> BufferInfoMap;
510 BufferInfoMap buffer_infos_;
511
512 // Info for each "successfully linked" program by service side program Id.
513 // TODO(gman): Choose a faster container.
514 typedef std::map<GLuint, ProgramInfo> ProgramInfoMap;
515 ProgramInfoMap program_infos_;
516
517 // The program in current use through glUseProgram.
518 ProgramInfo* current_program_info_;
519
327 #if defined(OS_WIN) 520 #if defined(OS_WIN)
328 HDC device_context_; 521 HDC device_context_;
329 HGLRC gl_context_; 522 HGLRC gl_context_;
330 #endif 523 #endif
331 524
332 bool anti_aliased_; 525 bool anti_aliased_;
333 526
334 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); 527 DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl);
335 }; 528 };
336 529
337 GLES2Decoder* GLES2Decoder::Create() { 530 GLES2Decoder* GLES2Decoder::Create() {
338 return new GLES2DecoderImpl(); 531 return new GLES2DecoderImpl();
339 } 532 }
340 533
341 GLES2DecoderImpl::GLES2DecoderImpl() 534 GLES2DecoderImpl::GLES2DecoderImpl()
342 : GLES2Decoder(), 535 : GLES2Decoder(),
343 error_bits_(0), 536 error_bits_(0),
344 util_(0), // TODO(gman): Set to actual num compress texture formats. 537 util_(0), // TODO(gman): Set to actual num compress texture formats.
345 pack_alignment_(4), 538 pack_alignment_(4),
346 unpack_alignment_(4), 539 unpack_alignment_(4),
347 bound_array_buffer_(0), 540 bound_array_buffer_(0),
348 bound_element_array_buffer_(0), 541 bound_element_array_buffer_(0),
542 max_vertex_attribs_(0),
543 current_program_info_(NULL),
349 #ifdef OS_WIN 544 #ifdef OS_WIN
350 device_context_(NULL), 545 device_context_(NULL),
351 gl_context_(NULL), 546 gl_context_(NULL),
352 #endif 547 #endif
353 anti_aliased_(false) { 548 anti_aliased_(false) {
354 } 549 }
355 550
356 bool GLES2DecoderImpl::Initialize() { 551 bool GLES2DecoderImpl::Initialize() {
357 if (!InitPlatformSpecific()) 552 if (!InitPlatformSpecific())
358 return false; 553 return false;
359 if (!InitGlew()) 554 if (!InitGlew())
360 return false; 555 return false;
361 CHECK_GL_ERROR(); 556 CHECK_GL_ERROR();
362 557
558 // Lookup GL things we need to know.
559 GLint value;
560 glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &value);
561 max_vertex_attribs_ = value;
562
563 DCHECK_GE(max_vertex_attribs_, 8u);
564
565 vertex_attrib_infos_.reset(new VertexAttribInfo[max_vertex_attribs_]);
566 memset(vertex_attrib_infos_.get(), 0,
567 sizeof(vertex_attrib_infos_[0]) * max_vertex_attribs_);
568
363 //glBindFramebuffer(0, 0); 569 //glBindFramebuffer(0, 0);
364 return true; 570 return true;
365 } 571 }
366 572
367 #if defined(OS_WIN) 573 #if defined(OS_WIN)
368 namespace { 574 namespace {
369 575
370 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = { 576 const PIXELFORMATDESCRIPTOR kPixelFormatDescriptor = {
371 sizeof(kPixelFormatDescriptor), // Size of structure. 577 sizeof(kPixelFormatDescriptor), // Size of structure.
372 1, // Default version. 578 1, // Default version.
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
526 732
527 ::wglMakeCurrent(intermediate_dc, NULL); 733 ::wglMakeCurrent(intermediate_dc, NULL);
528 ::wglDeleteContext(gl_context); 734 ::wglDeleteContext(gl_context);
529 ::ReleaseDC(intermediate_window, intermediate_dc); 735 ::ReleaseDC(intermediate_window, intermediate_dc);
530 ::DestroyWindow(intermediate_window); 736 ::DestroyWindow(intermediate_window);
531 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration), 737 ::UnregisterClass(reinterpret_cast<wchar_t*>(class_registration),
532 module_handle); 738 module_handle);
533 return true; 739 return true;
534 } 740 }
535 741
742 // These commands convert from c calls to local os calls.
743 void GLGenBuffersHelper(
744 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
745 glGenBuffersARB(n, ids);
746 }
747
748 void GLGenFramebuffersHelper(
749 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
750 glGenFramebuffersEXT(n, ids);
751 }
752
753 void GLGenRenderbuffersHelper(
754 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
755 glGenRenderbuffersEXT(n, ids);
756 }
757
758 void GLGenTexturesHelper(
759 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
760 glGenTextures(n, ids);
761 }
762
763 void GLDeleteBuffersHelper(
764 GLES2DecoderImpl* decoder, GLsizei n, GLuint* ids) {
765 glDeleteBuffersARB(n, ids);
766 for (GLsizei ii = 0; ii < n; ++ii) {
767 decoder->RemoveBufferInfo(ids[ii]);
768 }
769 }
770
771 void GLDeleteFramebuffersHelper(
772 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
773 glDeleteFramebuffersEXT(n, ids);
774 }
775
776 void GLDeleteRenderbuffersHelper(
777 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
778 glDeleteRenderbuffersEXT(n, ids);
779 }
780
781 void GLDeleteTexturesHelper(
782 GLES2DecoderImpl*, GLsizei n, GLuint* ids) {
783 glDeleteTextures(n, ids);
784 }
785
536 } // anonymous namespace 786 } // anonymous namespace
537 #endif 787 #endif
538 788
789 bool GLES2DecoderImpl::RegisterObjects(
790 GLsizei n, const GLuint* client_ids, const GLuint* service_ids) {
791 for (GLsizei ii = 0; ii < n; ++ii) {
792 if (!id_map_.AddMapping(client_ids[ii], service_ids[ii])) {
793 // TODO(gman): fail.
794 }
795 }
796 return true;
797 }
798
799 void GLES2DecoderImpl::UnregisterObjects(
800 GLsizei n, const GLuint* client_ids, GLuint* service_ids) {
801 // TODO(gman): check for success before copying results.
802 for (GLsizei ii = 0; ii < n; ++ii) {
803 if (id_map_.GetServiceId(client_ids[ii], &service_ids[ii])) {
804 id_map_.RemoveMapping(client_ids[ii], service_ids[ii]);
805 } else {
806 service_ids[ii] = 0;
807 }
808 }
809 }
810
811 void GLES2DecoderImpl::RemoveBufferInfo(GLuint buffer_id) {
812 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
813 if (vertex_attrib_infos_[ii].buffer() == buffer_id) {
814 vertex_attrib_infos_[ii].Clear();
815 }
816 }
817 buffer_infos_.erase(buffer_id);
818 }
819
539 bool GLES2DecoderImpl::InitPlatformSpecific() { 820 bool GLES2DecoderImpl::InitPlatformSpecific() {
540 #if defined(OS_WIN) 821 #if defined(OS_WIN)
541 device_context_ = ::GetDC(hwnd()); 822 device_context_ = ::GetDC(hwnd());
542 823
543 int pixel_format; 824 int pixel_format;
544 825
545 if (!GetWindowsPixelFormat(hwnd(), 826 if (!GetWindowsPixelFormat(hwnd(),
546 anti_aliased_, 827 anti_aliased_,
547 &pixel_format)) { 828 &pixel_format)) {
548 DLOG(ERROR) << "Unable to determine optimal pixel format for GL context."; 829 DLOG(ERROR) << "Unable to determine optimal pixel format for GL context.";
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 case name::kCmdId: \ 952 case name::kCmdId: \
672 result = Handle ## name( \ 953 result = Handle ## name( \
673 immediate_data_size, \ 954 immediate_data_size, \
674 *static_cast<const name*>(cmd_data)); \ 955 *static_cast<const name*>(cmd_data)); \
675 break; \ 956 break; \
676 957
677 GLES2_COMMAND_LIST(GLES2_CMD_OP) 958 GLES2_COMMAND_LIST(GLES2_CMD_OP)
678 #undef GLES2_CMD_OP 959 #undef GLES2_CMD_OP
679 } 960 }
680 if (debug()) { 961 if (debug()) {
681 if (glGetError() != 0) { 962 GLenum error;
963 while ((error = glGetError()) != GL_NO_ERROR) {
682 // TODO(gman): Change output to something useful for NaCl. 964 // TODO(gman): Change output to something useful for NaCl.
965 SetGLError(error);
683 printf("GL ERROR b4: %s\n", GetCommandName(command)); 966 printf("GL ERROR b4: %s\n", GetCommandName(command));
684 } 967 }
685 } 968 }
686 } else { 969 } else {
687 result = parse_error::kParseInvalidArguments; 970 result = parse_error::kParseInvalidArguments;
688 } 971 }
689 } else { 972 } else {
690 result = DoCommonCommand(command, arg_count, cmd_data); 973 result = DoCommonCommand(command, arg_count, cmd_data);
691 } 974 }
692 return result; 975 return result;
(...skipping 23 matching lines...) Expand all
716 case GL_ELEMENT_ARRAY_BUFFER: 999 case GL_ELEMENT_ARRAY_BUFFER:
717 bound_element_array_buffer_ = buffer; 1000 bound_element_array_buffer_ = buffer;
718 break; 1001 break;
719 default: 1002 default:
720 DCHECK(false); // Validation should prevent us getting here. 1003 DCHECK(false); // Validation should prevent us getting here.
721 break; 1004 break;
722 } 1005 }
723 glBindBuffer(target, buffer); 1006 glBindBuffer(target, buffer);
724 } 1007 }
725 1008
1009 void GLES2DecoderImpl::DoDisableVertexAttribArray(GLuint index) {
1010 if (index < max_vertex_attribs_) {
1011 vertex_attrib_infos_[index].set_enabled(false);
1012 glEnableVertexAttribArray(index);
1013 } else {
1014 SetGLError(GL_INVALID_VALUE);
1015 }
1016 }
1017
1018 void GLES2DecoderImpl::DoEnableVertexAttribArray(GLuint index) {
1019 if (index < max_vertex_attribs_) {
1020 vertex_attrib_infos_[index].set_enabled(true);
1021 glEnableVertexAttribArray(index);
1022 } else {
1023 SetGLError(GL_INVALID_VALUE);
1024 }
1025 }
1026
726 parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader( 1027 parse_error::ParseError GLES2DecoderImpl::HandleDeleteShader(
727 uint32 immediate_data_size, const gles2::DeleteShader& c) { 1028 uint32 immediate_data_size, const gles2::DeleteShader& c) {
728 GLuint shader = c.shader; 1029 GLuint shader = c.shader;
729 GLuint service_id; 1030 GLuint service_id;
730 if (!id_map_.GetServiceId(shader, &service_id)) { 1031 if (!id_map_.GetServiceId(shader, &service_id)) {
731 SetGLError(GL_INVALID_VALUE); 1032 SetGLError(GL_INVALID_VALUE);
732 return parse_error::kParseNoError; 1033 return parse_error::kParseNoError;
733 } 1034 }
734 glDeleteProgram(service_id); 1035 glDeleteShader(service_id);
735 id_map_.RemoveMapping(shader, service_id); 1036 id_map_.RemoveMapping(shader, service_id);
736 return parse_error::kParseNoError; 1037 return parse_error::kParseNoError;
737 } 1038 }
738 1039
739 parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram( 1040 parse_error::ParseError GLES2DecoderImpl::HandleDeleteProgram(
740 uint32 immediate_data_size, const gles2::DeleteProgram& c) { 1041 uint32 immediate_data_size, const gles2::DeleteProgram& c) {
741 GLuint program = c.program; 1042 GLuint program = c.program;
742 GLuint service_id; 1043 GLuint service_id;
743 if (!id_map_.GetServiceId(program, &service_id)) { 1044 if (!id_map_.GetServiceId(program, &service_id)) {
744 SetGLError(GL_INVALID_VALUE); 1045 SetGLError(GL_INVALID_VALUE);
745 return parse_error::kParseNoError; 1046 return parse_error::kParseNoError;
746 } 1047 }
1048 RemoveProgramInfo(program);
747 glDeleteProgram(service_id); 1049 glDeleteProgram(service_id);
748 id_map_.RemoveMapping(program, service_id); 1050 id_map_.RemoveMapping(program, service_id);
749 return parse_error::kParseNoError; 1051 return parse_error::kParseNoError;
750 } 1052 }
751 1053
1054 void GLES2DecoderImpl::DoDrawArrays(
1055 GLenum mode, GLint first, GLsizei count) {
1056 if (IsDrawValid(first + count - 1)) {
1057 glDrawArrays(mode, first, count);
1058 }
1059 }
1060
1061 void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
1062 CopyRealGLErrorsToWrapper();
1063 glLinkProgram(program);
1064 GLenum error = glGetError();
1065 if (error != GL_NO_ERROR) {
1066 RemoveProgramInfo(program);
1067 SetGLError(error);
1068 } else {
1069 UpdateProgramInfo(program);
1070 }
1071 };
1072
752 // NOTE: If you need to know the results of SwapBuffers (like losing 1073 // NOTE: If you need to know the results of SwapBuffers (like losing
753 // the context) then add a new command. Do NOT make SwapBuffers synchronous. 1074 // the context) then add a new command. Do NOT make SwapBuffers synchronous.
754 void GLES2DecoderImpl::DoSwapBuffers() { 1075 void GLES2DecoderImpl::DoSwapBuffers() {
755 #ifdef OS_WIN 1076 #ifdef OS_WIN
756 ::SwapBuffers(device_context_); 1077 ::SwapBuffers(device_context_);
757 #endif 1078 #endif
758 1079
759 #ifdef OS_LINUX 1080 #ifdef OS_LINUX
760 DCHECK(window()); 1081 DCHECK(window());
761 window()->SwapBuffers(); 1082 window()->SwapBuffers();
762 #endif 1083 #endif
763 } 1084 }
764 1085
1086 void GLES2DecoderImpl::DoUseProgram(GLuint program) {
1087 ProgramInfo* info = GetProgramInfo(program);
1088 if (!info) {
1089 // Program was not linked successfully. (ie, glLinkProgram)
1090 SetGLError(GL_INVALID_OPERATION);
1091 } else {
1092 current_program_info_ = info;
1093 glUseProgram(program);
1094 }
1095 }
1096
765 GLenum GLES2DecoderImpl::GetGLError() { 1097 GLenum GLES2DecoderImpl::GetGLError() {
766 // Check the GL error first, then our wrapped error. 1098 // Check the GL error first, then our wrapped error.
767 GLenum error = glGetError(); 1099 GLenum error = glGetError();
768 if (error == GL_NO_ERROR && error_bits_ != 0) { 1100 if (error == GL_NO_ERROR && error_bits_ != 0) {
769 uint32 mask = 1; 1101 uint32 mask = 1;
770 while (mask) { 1102 while (mask) {
771 if ((error_bits_ & mask) != 0) { 1103 if ((error_bits_ & mask) != 0) {
772 error = GLErrorBitToGLError(mask); 1104 error = GLErrorBitToGLError(mask);
773 break; 1105 break;
774 } 1106 }
775 } 1107 }
776 } 1108 }
777 1109
778 if (error != GL_NO_ERROR) { 1110 if (error != GL_NO_ERROR) {
779 // There was an error, clear the corresponding wrapped error. 1111 // There was an error, clear the corresponding wrapped error.
780 error_bits_ &= ~GLErrorToErrorBit(error); 1112 error_bits_ &= ~GLErrorToErrorBit(error);
781 } 1113 }
782 return error; 1114 return error;
783 } 1115 }
784 1116
785 void GLES2DecoderImpl::SetGLError(GLenum error) { 1117 void GLES2DecoderImpl::SetGLError(GLenum error) {
786 error_bits_ |= GLErrorToErrorBit(error); 1118 error_bits_ |= GLErrorToErrorBit(error);
787 } 1119 }
788 1120
1121 void GLES2DecoderImpl::CopyRealGLErrorsToWrapper() {
1122 GLenum error;
1123 while ((error = glGetError()) != GL_NO_ERROR) {
1124 SetGLError(error);
1125 }
1126 }
1127
1128 const GLES2DecoderImpl::BufferInfo* GLES2DecoderImpl::GetBufferInfo(
1129 GLuint buffer) {
1130 BufferInfoMap::iterator it = buffer_infos_.find(buffer);
1131 return it != buffer_infos_.end() ? &it->second : NULL;
1132 }
1133
1134 void GLES2DecoderImpl::SetBufferInfo(GLuint buffer, GLsizeiptr size) {
1135 buffer_infos_[buffer] = BufferInfo(size);
1136
1137 // Also go through VertexAttribInfo and update any info that references
1138 // the same buffer.
1139 for (GLuint ii = 0; ii < max_vertex_attribs_; ++ii) {
1140 if (vertex_attrib_infos_[ii].buffer() == buffer) {
1141 vertex_attrib_infos_[ii].SetBufferSize(size);
1142 }
1143 }
1144 }
1145
1146 GLES2DecoderImpl::ProgramInfo* GLES2DecoderImpl::GetProgramInfo(
1147 GLuint program) {
1148 ProgramInfoMap::iterator it = program_infos_.find(program);
1149 return it != program_infos_.end() ? &it->second : NULL;
1150 }
1151
1152 void GLES2DecoderImpl::UpdateProgramInfo(GLuint program) {
1153 ProgramInfo* info = GetProgramInfo(program);
1154 if (!info) {
1155 std::pair<ProgramInfoMap::iterator, bool> result =
1156 program_infos_.insert(std::make_pair(program, ProgramInfo()));
1157 DCHECK(result.second);
1158 info = &result.first->second;
1159 }
1160 GLint num_attribs = 0;
1161 GLint max_len = 0;
1162 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &num_attribs);
1163 info->SetNumAttributes(num_attribs);
1164 glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max_len);
1165 // TODO(gman): Should we check for error?
1166 scoped_array<char> name_buffer(new char[max_len + 1]);
1167 for (GLint ii = 0; ii < num_attribs; ++ii) {
1168 GLsizei length;
1169 GLsizei size;
1170 GLenum type;
1171 glGetActiveAttrib(
1172 program, ii, max_len + 1, &length, &size, &type, name_buffer.get());
1173 // TODO(gman): Should we check for error?
1174 GLint location = glGetAttribLocation(program, name_buffer.get());
1175 info->SetAttributeLocation(ii, num_attribs);
1176 }
1177 }
1178
1179 void GLES2DecoderImpl::RemoveProgramInfo(GLuint program) {
1180 ProgramInfoMap::iterator it = program_infos_.find(program);
1181 if (it != program_infos_.end()) {
1182 if (current_program_info_ == &it->second) {
1183 current_program_info_ = NULL;
1184 }
1185 program_infos_.erase(it);
1186 }
1187 }
1188
1189 bool GLES2DecoderImpl::VertexAttribInfo::CanAccess(GLuint index) {
1190 return !enabled_ || (buffer_ != 0 && index < num_elements_);
1191 }
1192
1193 bool GLES2DecoderImpl::IsDrawValid(GLuint max_vertex_accessed) {
1194 if (current_program_info_) {
1195 // Validate that all attribs current program needs are setup correctly.
1196 const ProgramInfo::AttribLocationVector& locations =
1197 current_program_info_->GetAttribLocations();
1198 for (size_t ii = 0; ii < locations.size(); ++ii) {
1199 GLuint location = locations[ii];
1200 DCHECK_LT(location, max_vertex_attribs_);
1201 if (!vertex_attrib_infos_[location].CanAccess(max_vertex_accessed)) {
1202 SetGLError(GL_INVALID_OPERATION);
1203 }
1204 }
1205 return true;
1206 }
1207 // We do not set a GL error here because the GL spec says no error if the
1208 // program is invalid.
1209 return false;
1210 };
1211
789 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements( 1212 parse_error::ParseError GLES2DecoderImpl::HandleDrawElements(
790 uint32 immediate_data_size, const gles2::DrawElements& c) { 1213 uint32 immediate_data_size, const gles2::DrawElements& c) {
791 if (bound_element_array_buffer_ != 0) { 1214 if (bound_element_array_buffer_ != 0) {
792 GLenum mode = c.mode; 1215 GLenum mode = c.mode;
793 GLsizei count = c.count; 1216 GLsizei count = c.count;
794 GLenum type = c.type; 1217 GLenum type = c.type;
795 if (!ValidateGLenumDrawMode(mode) || 1218 if (!ValidateGLenumDrawMode(mode) ||
796 !ValidateGLenumIndexType(type)) { 1219 !ValidateGLenumIndexType(type)) {
797 SetGLError(GL_INVALID_VALUE); 1220 SetGLError(GL_INVALID_VALUE);
798 } else { 1221 } else {
799 const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset); 1222 const GLvoid* indices = reinterpret_cast<const GLvoid*>(c.index_offset);
800 // TODO(gman): Validate indices 1223 // TODO(gman): Validate indices. Get maximum index.
801 // TOOD(gman): Validate all attribs current program needs are setup. 1224 //
802 glDrawElements(mode, count, type, indices); 1225 // This value should be computed by walking the index buffer from 0 to
1226 // count and finding the maximum vertex accessed.
1227 // For now we'll special case 0 to not check.
1228 GLuint max_vertex_accessed = 0;
1229 if (IsDrawValid(max_vertex_accessed)) {
1230 glDrawElements(mode, count, type, indices);
1231 }
803 } 1232 }
804 } else { 1233 } else {
805 SetGLError(GL_INVALID_VALUE); 1234 SetGLError(GL_INVALID_VALUE);
806 } 1235 }
807 return parse_error::kParseNoError; 1236 return parse_error::kParseNoError;
808 } 1237 }
809 1238
810 namespace { 1239 namespace {
811 1240
812 // Calls glShaderSource for the various versions of the ShaderSource command. 1241 // Calls glShaderSource for the various versions of the ShaderSource command.
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
858 1287
859 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate( 1288 parse_error::ParseError GLES2DecoderImpl::HandleShaderSourceImmediate(
860 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) { 1289 uint32 immediate_data_size, const gles2::ShaderSourceImmediate& c) {
861 GLuint shader; 1290 GLuint shader;
862 if (!id_map_.GetServiceId(c.shader, &shader)) { 1291 if (!id_map_.GetServiceId(c.shader, &shader)) {
863 SetGLError(GL_INVALID_VALUE); 1292 SetGLError(GL_INVALID_VALUE);
864 return parse_error::kParseNoError; 1293 return parse_error::kParseNoError;
865 } 1294 }
866 GLsizei count = c.count; 1295 GLsizei count = c.count;
867 uint32 data_size = c.data_size; 1296 uint32 data_size = c.data_size;
868 // TODO(gman): need to check that data_size is in range for arg_count. 1297 const char** data = GetImmediateDataAs<const char**>(
869 const char** data = GetImmediateDataAs<const char**>(c); 1298 c, data_size, immediate_data_size);
870 if (!data) { 1299 if (!data) {
871 return parse_error::kParseOutOfBounds; 1300 return parse_error::kParseOutOfBounds;
872 } 1301 }
873 return ShaderSourceHelper( 1302 return ShaderSourceHelper(
874 shader, count, reinterpret_cast<const char*>(data), data_size); 1303 shader, count, reinterpret_cast<const char*>(data), data_size);
875 } 1304 }
876 1305
877 parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer( 1306 parse_error::ParseError GLES2DecoderImpl::HandleVertexAttribPointer(
878 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) { 1307 uint32 immediate_data_size, const gles2::VertexAttribPointer& c) {
879 // TODO(gman): Is this a valid check or does this check have to come
880 // at glDrawElements time.
881 if (bound_array_buffer_ != 0) { 1308 if (bound_array_buffer_ != 0) {
882 GLuint indx = c.indx; 1309 GLuint indx = c.indx;
883 GLint size = c.size; 1310 GLint size = c.size;
884 GLenum type = c.type; 1311 GLenum type = c.type;
885 GLboolean normalized = c.normalized; 1312 GLboolean normalized = c.normalized;
886 GLsizei stride = c.stride; 1313 GLsizei stride = c.stride;
887 GLuint offset = c.offset; 1314 GLsizei offset = c.offset;
888 const void* ptr = reinterpret_cast<const void*>(c.offset); 1315 const void* ptr = reinterpret_cast<const void*>(offset);
889 if (!ValidateGLenumVertexAttribType(type) || 1316 if (!ValidateGLenumVertexAttribType(type) ||
890 !ValidateGLenumVertexAttribSize(size)) { 1317 !ValidateGLenumVertexAttribSize(size) ||
1318 indx >= max_vertex_attribs_ ||
1319 stride < 0) {
891 SetGLError(GL_INVALID_VALUE); 1320 SetGLError(GL_INVALID_VALUE);
892 return parse_error::kParseNoError; 1321 return parse_error::kParseNoError;
893 } 1322 }
1323 const BufferInfo* buffer_info = GetBufferInfo(bound_array_buffer_);
1324 GLsizei component_size = GetGLTypeSize(type);
1325 GLsizei real_stride = stride != 0 ? stride : component_size * size;
1326 if (offset % component_size > 0) {
1327 SetGLError(GL_INVALID_VALUE);
1328 return parse_error::kParseNoError;
1329 }
1330 vertex_attrib_infos_[indx].SetInfo(
1331 bound_array_buffer_,
1332 buffer_info ? buffer_info->size : 0,
1333 size,
1334 type,
1335 real_stride,
1336 offset);
894 glVertexAttribPointer(indx, size, type, normalized, stride, ptr); 1337 glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
895 } else { 1338 } else {
896 SetGLError(GL_INVALID_VALUE); 1339 SetGLError(GL_INVALID_VALUE);
897 } 1340 }
898 return parse_error::kParseNoError; 1341 return parse_error::kParseNoError;
899 } 1342 }
900 1343
901 parse_error::ParseError GLES2DecoderImpl::HandleReadPixels( 1344 parse_error::ParseError GLES2DecoderImpl::HandleReadPixels(
902 uint32 immediate_data_size, const gles2::ReadPixels& c) { 1345 uint32 immediate_data_size, const gles2::ReadPixels& c) {
903 GLint x = c.x; 1346 GLint x = c.x;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 } 1411 }
969 1412
970 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate( 1413 parse_error::ParseError GLES2DecoderImpl::HandleGetAttribLocationImmediate(
971 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) { 1414 uint32 immediate_data_size, const gles2::GetAttribLocationImmediate& c) {
972 GLuint program; 1415 GLuint program;
973 if (!id_map_.GetServiceId(c.program, &program)) { 1416 if (!id_map_.GetServiceId(c.program, &program)) {
974 SetGLError(GL_INVALID_VALUE); 1417 SetGLError(GL_INVALID_VALUE);
975 return parse_error::kParseNoError; 1418 return parse_error::kParseNoError;
976 } 1419 }
977 uint32 name_size = c.data_size; 1420 uint32 name_size = c.data_size;
978 const char* name = GetImmediateDataAs<const char*>(c); 1421 const char* name = GetImmediateDataAs<const char*>(
979 // TODO(gman): Make sure validate checks arg_count 1422 c, name_size, immediate_data_size);
980 // covers data_size.
981 GLint* location = GetSharedMemoryAs<GLint*>( 1423 GLint* location = GetSharedMemoryAs<GLint*>(
982 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); 1424 c.location_shm_id, c.location_shm_offset, sizeof(GLint));
983 if (!location || !name) { 1425 if (!location || !name) {
984 return parse_error::kParseOutOfBounds; 1426 return parse_error::kParseOutOfBounds;
985 } 1427 }
986 String name_str(name, name_size); 1428 String name_str(name, name_size);
987 *location = glGetAttribLocation(program, name_str.c_str()); 1429 *location = glGetAttribLocation(program, name_str.c_str());
988 return parse_error::kParseNoError; 1430 return parse_error::kParseNoError;
989 } 1431 }
990 1432
(...skipping 18 matching lines...) Expand all
1009 } 1451 }
1010 1452
1011 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate( 1453 parse_error::ParseError GLES2DecoderImpl::HandleGetUniformLocationImmediate(
1012 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) { 1454 uint32 immediate_data_size, const gles2::GetUniformLocationImmediate& c) {
1013 GLuint program; 1455 GLuint program;
1014 if (!id_map_.GetServiceId(c.program, &program)) { 1456 if (!id_map_.GetServiceId(c.program, &program)) {
1015 SetGLError(GL_INVALID_VALUE); 1457 SetGLError(GL_INVALID_VALUE);
1016 return parse_error::kParseNoError; 1458 return parse_error::kParseNoError;
1017 } 1459 }
1018 uint32 name_size = c.data_size; 1460 uint32 name_size = c.data_size;
1019 const char* name = GetImmediateDataAs<const char*>(c); 1461 const char* name = GetImmediateDataAs<const char*>(
1020 // TODO(gman): Make sure validate checks arg_count 1462 c, name_size, immediate_data_size);
1021 // covers data_size.
1022 GLint* location = GetSharedMemoryAs<GLint*>( 1463 GLint* location = GetSharedMemoryAs<GLint*>(
1023 c.location_shm_id, c.location_shm_offset, sizeof(GLint)); 1464 c.location_shm_id, c.location_shm_offset, sizeof(GLint));
1024 if (!location || !name) { 1465 if (!location || !name) {
1025 return parse_error::kParseOutOfBounds; 1466 return parse_error::kParseOutOfBounds;
1026 } 1467 }
1027 String name_str(name, name_size); 1468 String name_str(name, name_size);
1028 *location = glGetUniformLocation(program, name_str.c_str()); 1469 *location = glGetUniformLocation(program, name_str.c_str());
1029 return parse_error::kParseNoError; 1470 return parse_error::kParseNoError;
1030 } 1471 }
1031 1472
1032 parse_error::ParseError GLES2DecoderImpl::HandleBufferData( 1473 parse_error::ParseError GLES2DecoderImpl::HandleBufferData(
1033 uint32 immediate_data_size, const gles2::BufferData& c) { 1474 uint32 immediate_data_size, const gles2::BufferData& c) {
1034 GLenum target = static_cast<GLenum>(c.target); 1475 GLenum target = static_cast<GLenum>(c.target);
1035 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 1476 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
1036 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 1477 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
1037 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 1478 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
1038 GLenum usage = static_cast<GLenum>(c.usage); 1479 GLenum usage = static_cast<GLenum>(c.usage);
1039 const void* data = NULL; 1480 const void* data = NULL;
1040 if (data_shm_id != 0 || data_shm_offset != 0) { 1481 if (data_shm_id != 0 || data_shm_offset != 0) {
1041 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size); 1482 data = GetSharedMemoryAs<const void*>(data_shm_id, data_shm_offset, size);
1042 if (!data) { 1483 if (!data) {
1043 return parse_error::kParseOutOfBounds; 1484 return parse_error::kParseOutOfBounds;
1044 } 1485 }
1045 } 1486 }
1046 // TODO(gman): Validate case where data is NULL.
1047 if (!ValidateGLenumBufferTarget(target) || 1487 if (!ValidateGLenumBufferTarget(target) ||
1048 !ValidateGLenumBufferUsage(usage)) { 1488 !ValidateGLenumBufferUsage(usage)) {
1049 SetGLError(GL_INVALID_VALUE); 1489 SetGLError(GL_INVALID_VALUE);
1050 return parse_error::kParseNoError; 1490 return parse_error::kParseNoError;
1051 } 1491 }
1492 // Clear the buffer to 0 if no initial data was passed in.
1493 scoped_array<int8> zero;
1494 if (!data) {
1495 zero.reset(new int8[size]);
1496 memset(zero.get(), 0, size);
1497 data = zero.get();
1498 }
1499 CopyRealGLErrorsToWrapper();
1052 glBufferData(target, size, data, usage); 1500 glBufferData(target, size, data, usage);
1501 GLenum error = glGetError();
1502 if (error != GL_NO_ERROR) {
1503 SetGLError(error);
1504 } else {
1505 SetBufferInfo(GetBufferForTarget(target), size);
1506 }
1053 return parse_error::kParseNoError; 1507 return parse_error::kParseNoError;
1054 } 1508 }
1055 1509
1056 parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate( 1510 parse_error::ParseError GLES2DecoderImpl::HandleBufferDataImmediate(
1057 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) { 1511 uint32 immediate_data_size, const gles2::BufferDataImmediate& c) {
1058 GLenum target = static_cast<GLenum>(c.target); 1512 GLenum target = static_cast<GLenum>(c.target);
1059 GLsizeiptr size = static_cast<GLsizeiptr>(c.size); 1513 GLsizeiptr size = static_cast<GLsizeiptr>(c.size);
1060 const void* data = GetImmediateDataAs<const void*>(c); 1514 const void* data = GetImmediateDataAs<const void*>(
1515 c, size, immediate_data_size);
1516 if (!data) {
1517 return parse_error::kParseOutOfBounds;
1518 }
1061 GLenum usage = static_cast<GLenum>(c.usage); 1519 GLenum usage = static_cast<GLenum>(c.usage);
1062 if (!ValidateGLenumBufferTarget(target) || 1520 if (!ValidateGLenumBufferTarget(target) ||
1063 !ValidateGLenumBufferUsage(usage)) { 1521 !ValidateGLenumBufferUsage(usage)) {
1064 SetGLError(GL_INVALID_VALUE); 1522 SetGLError(GL_INVALID_VALUE);
1065 return parse_error::kParseNoError; 1523 return parse_error::kParseNoError;
1066 } 1524 }
1067 // TODO(gman): Handle case where data is NULL. 1525 CopyRealGLErrorsToWrapper();
1068 glBufferData(target, size, data, usage); 1526 glBufferData(target, size, data, usage);
1527 GLenum error = glGetError();
1528 if (error != GL_NO_ERROR) {
1529 SetGLError(error);
1530 } else {
1531 SetBufferInfo(GetBufferForTarget(target), size);
1532 }
1069 return parse_error::kParseNoError; 1533 return parse_error::kParseNoError;
1070 } 1534 }
1071 1535
1072 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D( 1536 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2D(
1073 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) { 1537 uint32 immediate_data_size, const gles2::CompressedTexImage2D& c) {
1074 GLenum target = static_cast<GLenum>(c.target); 1538 GLenum target = static_cast<GLenum>(c.target);
1075 GLint level = static_cast<GLint>(c.level); 1539 GLint level = static_cast<GLint>(c.level);
1076 GLenum internal_format = static_cast<GLenum>(c.internalformat); 1540 GLenum internal_format = static_cast<GLenum>(c.internalformat);
1077 GLsizei width = static_cast<GLsizei>(c.width); 1541 GLsizei width = static_cast<GLsizei>(c.width);
1078 GLsizei height = static_cast<GLsizei>(c.height); 1542 GLsizei height = static_cast<GLsizei>(c.height);
1079 GLint border = static_cast<GLint>(c.border); 1543 GLint border = static_cast<GLint>(c.border);
1080 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 1544 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
1081 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id); 1545 uint32 data_shm_id = static_cast<uint32>(c.data_shm_id);
1082 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset); 1546 uint32 data_shm_offset = static_cast<uint32>(c.data_shm_offset);
1083 const void* data = NULL; 1547 const void* data = NULL;
1084 if (data_shm_id != 0 || data_shm_offset != 0) { 1548 if (data_shm_id != 0 || data_shm_offset != 0) {
1085 data = GetSharedMemoryAs<const void*>( 1549 data = GetSharedMemoryAs<const void*>(
1086 data_shm_id, data_shm_offset, image_size); 1550 data_shm_id, data_shm_offset, image_size);
1087 if (!data) { 1551 if (!data) {
1088 return parse_error::kParseOutOfBounds; 1552 return parse_error::kParseOutOfBounds;
1089 } 1553 }
1090 } 1554 }
1091 // TODO(gman): Validate internal_format 1555 // TODO(gman): Validate internal_format
1092 if (!ValidateGLenumTextureTarget(target)) { 1556 if (!ValidateGLenumTextureTarget(target)) {
1093 SetGLError(GL_INVALID_VALUE); 1557 SetGLError(GL_INVALID_VALUE);
1094 return parse_error::kParseNoError; 1558 return parse_error::kParseNoError;
1095 } 1559 }
1096 // TODO(gman): Validate case where data is NULL. 1560 scoped_array<int8> zero;
1561 if (!data) {
1562 zero.reset(new int8[image_size]);
1563 memset(zero.get(), 0, image_size);
1564 data = zero.get();
1565 }
1097 glCompressedTexImage2D( 1566 glCompressedTexImage2D(
1098 target, level, internal_format, width, height, border, image_size, data); 1567 target, level, internal_format, width, height, border, image_size, data);
1099 return parse_error::kParseNoError; 1568 return parse_error::kParseNoError;
1100 } 1569 }
1101 1570
1102 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate( 1571 parse_error::ParseError GLES2DecoderImpl::HandleCompressedTexImage2DImmediate(
1103 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) { 1572 uint32 immediate_data_size, const gles2::CompressedTexImage2DImmediate& c) {
1104 GLenum target = static_cast<GLenum>(c.target); 1573 GLenum target = static_cast<GLenum>(c.target);
1105 GLint level = static_cast<GLint>(c.level); 1574 GLint level = static_cast<GLint>(c.level);
1106 GLenum internal_format = static_cast<GLenum>(c.internalformat); 1575 GLenum internal_format = static_cast<GLenum>(c.internalformat);
1107 GLsizei width = static_cast<GLsizei>(c.width); 1576 GLsizei width = static_cast<GLsizei>(c.width);
1108 GLsizei height = static_cast<GLsizei>(c.height); 1577 GLsizei height = static_cast<GLsizei>(c.height);
1109 GLint border = static_cast<GLint>(c.border); 1578 GLint border = static_cast<GLint>(c.border);
1110 GLsizei image_size = static_cast<GLsizei>(c.imageSize); 1579 GLsizei image_size = static_cast<GLsizei>(c.imageSize);
1111 const void* data = GetImmediateDataAs<const void*>(c); 1580 const void* data = GetImmediateDataAs<const void*>(
1112 // Immediate version. 1581 c, image_size, immediate_data_size);
1113 // TODO(gman): Handle case where data is NULL.
1114 if (!data) { 1582 if (!data) {
1115 return parse_error::kParseOutOfBounds; 1583 return parse_error::kParseOutOfBounds;
1116 } 1584 }
1117 // TODO(gman): Validate internal_format 1585 // TODO(gman): Validate internal_format
1118 if (!ValidateGLenumTextureTarget(target)) { 1586 if (!ValidateGLenumTextureTarget(target)) {
1119 SetGLError(GL_INVALID_VALUE); 1587 SetGLError(GL_INVALID_VALUE);
1120 return parse_error::kParseNoError; 1588 return parse_error::kParseNoError;
1121 } 1589 }
1122 glCompressedTexImage2D( 1590 glCompressedTexImage2D(
1123 target, level, internal_format, width, height, border, image_size, data); 1591 target, level, internal_format, width, height, border, image_size, data);
(...skipping 22 matching lines...) Expand all
1146 return parse_error::kParseOutOfBounds; 1614 return parse_error::kParseOutOfBounds;
1147 } 1615 }
1148 } 1616 }
1149 if (!ValidateGLenumTextureTarget(target) || 1617 if (!ValidateGLenumTextureTarget(target) ||
1150 !ValidateGLenumTextureFormat(internal_format) || 1618 !ValidateGLenumTextureFormat(internal_format) ||
1151 !ValidateGLenumTextureFormat(format) || 1619 !ValidateGLenumTextureFormat(format) ||
1152 !ValidateGLenumPixelType(type)) { 1620 !ValidateGLenumPixelType(type)) {
1153 SetGLError(GL_INVALID_VALUE); 1621 SetGLError(GL_INVALID_VALUE);
1154 return parse_error::kParseNoError; 1622 return parse_error::kParseNoError;
1155 } 1623 }
1156 // TODO(gman): Validate case where data is NULL. 1624 scoped_array<int8> zero;
1625 if (!pixels) {
1626 zero.reset(new int8[pixels_size]);
1627 memset(zero.get(), 0, pixels_size);
1628 pixels = zero.get();
1629 }
1157 glTexImage2D( 1630 glTexImage2D(
1158 target, level, internal_format, width, height, border, format, type, 1631 target, level, internal_format, width, height, border, format, type,
1159 pixels); 1632 pixels);
1160 return parse_error::kParseNoError; 1633 return parse_error::kParseNoError;
1161 } 1634 }
1162 1635
1163 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate( 1636 parse_error::ParseError GLES2DecoderImpl::HandleTexImage2DImmediate(
1164 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) { 1637 uint32 immediate_data_size, const gles2::TexImage2DImmediate& c) {
1165 GLenum target = static_cast<GLenum>(c.target); 1638 GLenum target = static_cast<GLenum>(c.target);
1166 GLint level = static_cast<GLint>(c.level); 1639 GLint level = static_cast<GLint>(c.level);
1167 GLint internal_format = static_cast<GLint>(c.internalformat); 1640 GLint internal_format = static_cast<GLint>(c.internalformat);
1168 GLsizei width = static_cast<GLsizei>(c.width); 1641 GLsizei width = static_cast<GLsizei>(c.width);
1169 GLsizei height = static_cast<GLsizei>(c.height); 1642 GLsizei height = static_cast<GLsizei>(c.height);
1170 GLint border = static_cast<GLint>(c.border); 1643 GLint border = static_cast<GLint>(c.border);
1171 GLenum format = static_cast<GLenum>(c.format); 1644 GLenum format = static_cast<GLenum>(c.format);
1172 GLenum type = static_cast<GLenum>(c.type); 1645 GLenum type = static_cast<GLenum>(c.type);
1173 const void* pixels = GetImmediateDataAs<const void*>(c); 1646 uint32 size = GLES2Util::ComputeImageDataSize(
1174 // Immediate version. 1647 width, height, format, type, unpack_alignment_);
1175 // TODO(gman): Handle case where data is NULL. 1648 const void* pixels = GetImmediateDataAs<const void*>(
1649 c, size, immediate_data_size);
1176 if (!pixels) { 1650 if (!pixels) {
1177 return parse_error::kParseOutOfBounds; 1651 return parse_error::kParseOutOfBounds;
1178 } 1652 }
1179 if (!ValidateGLenumTextureTarget(target) || 1653 if (!ValidateGLenumTextureTarget(target) ||
1180 !ValidateGLenumTextureFormat(internal_format) || 1654 !ValidateGLenumTextureFormat(internal_format) ||
1181 !ValidateGLenumTextureFormat(format) || 1655 !ValidateGLenumTextureFormat(format) ||
1182 !ValidateGLenumPixelType(type)) { 1656 !ValidateGLenumPixelType(type)) {
1183 SetGLError(GL_INVALID_VALUE); 1657 SetGLError(GL_INVALID_VALUE);
1184 return parse_error::kParseNoError; 1658 return parse_error::kParseNoError;
1185 } 1659 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 } 1706 }
1233 1707
1234 // Include the auto-generated part of this file. We split this because it means 1708 // Include the auto-generated part of this file. We split this because it means
1235 // we can easily edit the non-auto generated parts right here in this file 1709 // we can easily edit the non-auto generated parts right here in this file
1236 // instead of having to edit some template or the code generator. 1710 // instead of having to edit some template or the code generator.
1237 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h" 1711 #include "gpu/command_buffer/service/gles2_cmd_decoder_autogen.h"
1238 1712
1239 } // namespace gles2 1713 } // namespace gles2
1240 } // namespace gpu 1714 } // namespace gpu
1241 1715
OLDNEW
« no previous file with comments | « gpu/command_buffer/build_gles2_cmd_buffer.py ('k') | gpu/command_buffer/service/gles2_cmd_decoder_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698