1 //
2 // Copyright(c) 2014 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 // entry_points_gles_2_0.cpp : Implements the GLES 2.0 entry points.
8
9 #include "libGLESv2/entry_points_gles_2_0.h"
10
11 #include "libGLESv2/global_state.h"
12
13 #include "libANGLE/formatutils.h"
14 #include "libANGLE/Buffer.h"
15 #include "libANGLE/Compiler.h"
16 #include "libANGLE/Context.h"
17 #include "libANGLE/Error.h"
18 #include "libANGLE/Framebuffer.h"
19 #include "libANGLE/Renderbuffer.h"
20 #include "libANGLE/Shader.h"
21 #include "libANGLE/Program.h"
22 #include "libANGLE/Texture.h"
23 #include "libANGLE/VertexArray.h"
24 #include "libANGLE/VertexAttribute.h"
25 #include "libANGLE/FramebufferAttachment.h"
26
27 #include "libANGLE/validationES.h"
28 #include "libANGLE/validationES2.h"
29 #include "libANGLE/validationES3.h"
30 #include "libANGLE/queryconversions.h"
31 #include "libANGLE/queryutils.h"
32
33 #include "common/debug.h"
34 #include "common/utilities.h"
35 #include "common/version.h"
36
37 namespace gl
38 {
39
ActiveTexture(GLenum texture)40 void GL_APIENTRY ActiveTexture(GLenum texture)
41 {
42 EVENT("(GLenum texture = 0x%X)", texture);
43
44 Context *context = GetValidGlobalContext();
45 if (context)
46 {
47 if (!context->skipValidation() && !ValidateActiveTexture(context, texture))
48 {
49 return;
50 }
51
52 context->activeTexture(texture);
53 }
54 }
55
AttachShader(GLuint program,GLuint shader)56 void GL_APIENTRY AttachShader(GLuint program, GLuint shader)
57 {
58 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
59
60 Context *context = GetValidGlobalContext();
61 if (context)
62 {
63 if (!context->skipValidation() && !ValidateAttachShader(context, program, shader))
64 {
65 return;
66 }
67
68 context->attachShader(program, shader);
69 }
70 }
71
BindAttribLocation(GLuint program,GLuint index,const GLchar * name)72 void GL_APIENTRY BindAttribLocation(GLuint program, GLuint index, const GLchar* name)
73 {
74 EVENT("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
75
76 Context *context = GetValidGlobalContext();
77 if (context)
78 {
79 if (!context->skipValidation() &&
80 !ValidateBindAttribLocation(context, program, index, name))
81 {
82 return;
83 }
84
85 context->bindAttribLocation(program, index, name);
86 }
87 }
88
BindBuffer(GLenum target,GLuint buffer)89 void GL_APIENTRY BindBuffer(GLenum target, GLuint buffer)
90 {
91 EVENT("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
92
93 Context *context = GetValidGlobalContext();
94 if (context)
95 {
96 if (!context->skipValidation() && !ValidateBindBuffer(context, target, buffer))
97 {
98 return;
99 }
100
101 context->bindBuffer(target, buffer);
102 }
103 }
104
BindFramebuffer(GLenum target,GLuint framebuffer)105 void GL_APIENTRY BindFramebuffer(GLenum target, GLuint framebuffer)
106 {
107 EVENT("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
108
109 Context *context = GetValidGlobalContext();
110 if (context)
111 {
112 if (!context->skipValidation() && !ValidateBindFramebuffer(context, target, framebuffer))
113 {
114 return;
115 }
116
117 context->bindFramebuffer(target, framebuffer);
118 }
119 }
120
BindRenderbuffer(GLenum target,GLuint renderbuffer)121 void GL_APIENTRY BindRenderbuffer(GLenum target, GLuint renderbuffer)
122 {
123 EVENT("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
124
125 Context *context = GetValidGlobalContext();
126 if (context)
127 {
128 if (!context->skipValidation() && !ValidateBindRenderbuffer(context, target, renderbuffer))
129 {
130 return;
131 }
132
133 context->bindRenderbuffer(target, renderbuffer);
134 }
135 }
136
BindTexture(GLenum target,GLuint texture)137 void GL_APIENTRY BindTexture(GLenum target, GLuint texture)
138 {
139 EVENT("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
140
141 Context *context = GetValidGlobalContext();
142 if (context)
143 {
144 if (!context->skipValidation() && !ValidateBindTexture(context, target, texture))
145 {
146 return;
147 }
148
149 context->bindTexture(target, texture);
150 }
151 }
152
BlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)153 void GL_APIENTRY BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
154 {
155 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
156 red, green, blue, alpha);
157
158 Context *context = GetValidGlobalContext();
159 if (context)
160 {
161 context->blendColor(red, green, blue, alpha);
162 }
163 }
164
BlendEquation(GLenum mode)165 void GL_APIENTRY BlendEquation(GLenum mode)
166 {
167 EVENT("(GLenum mode = 0x%X)", mode);
168
169 Context *context = GetValidGlobalContext();
170 if (context)
171 {
172 if (!context->skipValidation() && !ValidateBlendEquation(context, mode))
173 {
174 return;
175 }
176
177 context->blendEquation(mode);
178 }
179 }
180
BlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)181 void GL_APIENTRY BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
182 {
183 EVENT("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
184
185 Context *context = GetValidGlobalContext();
186 if (context)
187 {
188 if (!context->skipValidation() &&
189 !ValidateBlendEquationSeparate(context, modeRGB, modeAlpha))
190 {
191 return;
192 }
193
194 context->blendEquationSeparate(modeRGB, modeAlpha);
195 }
196 }
197
BlendFunc(GLenum sfactor,GLenum dfactor)198 void GL_APIENTRY BlendFunc(GLenum sfactor, GLenum dfactor)
199 {
200 EVENT("(GLenum sfactor = 0x%X, GLenum dfactor = 0x%X)", sfactor, dfactor);
201
202 Context *context = GetValidGlobalContext();
203 if (context)
204 {
205 if (!context->skipValidation() && !ValidateBlendFunc(context, sfactor, dfactor))
206 {
207 return;
208 }
209
210 context->blendFunc(sfactor, dfactor);
211 }
212 }
213
BlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)214 void GL_APIENTRY BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
215 {
216 EVENT("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
217 srcRGB, dstRGB, srcAlpha, dstAlpha);
218
219 Context *context = GetValidGlobalContext();
220 if (context)
221 {
222 if (!context->skipValidation() &&
223 !ValidateBlendFuncSeparate(context, srcRGB, dstRGB, srcAlpha, dstAlpha))
224 {
225 return;
226 }
227
228 context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
229 }
230 }
231
BufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)232 void GL_APIENTRY BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
233 {
234 EVENT("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
235 target, size, data, usage);
236
237 Context *context = GetValidGlobalContext();
238 if (context)
239 {
240 if (!context->skipValidation() && !ValidateBufferData(context, target, size, data, usage))
241 {
242 return;
243 }
244
245 context->bufferData(target, size, data, usage);
246 }
247 }
248
BufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)249 void GL_APIENTRY BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
250 {
251 EVENT("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
252 target, offset, size, data);
253
254 Context *context = GetValidGlobalContext();
255 if (context)
256 {
257 if (!context->skipValidation() &&
258 !ValidateBufferSubData(context, target, offset, size, data))
259 {
260 return;
261 }
262
263 context->bufferSubData(target, offset, size, data);
264 }
265 }
266
CheckFramebufferStatus(GLenum target)267 GLenum GL_APIENTRY CheckFramebufferStatus(GLenum target)
268 {
269 EVENT("(GLenum target = 0x%X)", target);
270
271 Context *context = GetValidGlobalContext();
272 if (context)
273 {
274 if (!ValidFramebufferTarget(target))
275 {
276 context->handleError(Error(GL_INVALID_ENUM));
277 return 0;
278 }
279
280 Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
281 ASSERT(framebuffer);
282
283 return framebuffer->checkStatus(context->getContextState());
284 }
285
286 return 0;
287 }
288
Clear(GLbitfield mask)289 void GL_APIENTRY Clear(GLbitfield mask)
290 {
291 EVENT("(GLbitfield mask = 0x%X)", mask);
292
293 Context *context = GetValidGlobalContext();
294 if (context)
295 {
296 if (!context->skipValidation() && !ValidateClear(context, mask))
297 {
298 return;
299 }
300
301 context->clear(mask);
302 }
303 }
304
ClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)305 void GL_APIENTRY ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
306 {
307 EVENT("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
308 red, green, blue, alpha);
309
310 Context *context = GetValidGlobalContext();
311 if (context)
312 {
313 context->clearColor(red, green, blue, alpha);
314 }
315 }
316
ClearDepthf(GLclampf depth)317 void GL_APIENTRY ClearDepthf(GLclampf depth)
318 {
319 EVENT("(GLclampf depth = %f)", depth);
320
321 Context *context = GetValidGlobalContext();
322 if (context)
323 {
324 context->clearDepthf(depth);
325 }
326 }
327
ClearStencil(GLint s)328 void GL_APIENTRY ClearStencil(GLint s)
329 {
330 EVENT("(GLint s = %d)", s);
331
332 Context *context = GetValidGlobalContext();
333 if (context)
334 {
335 context->clearStencil(s);
336 }
337 }
338
ColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)339 void GL_APIENTRY ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
340 {
341 EVENT("(GLboolean red = %d, GLboolean green = %u, GLboolean blue = %u, GLboolean alpha = %u)",
342 red, green, blue, alpha);
343
344 Context *context = GetValidGlobalContext();
345 if (context)
346 {
347 context->colorMask(red, green, blue, alpha);
348 }
349 }
350
CompileShader(GLuint shader)351 void GL_APIENTRY CompileShader(GLuint shader)
352 {
353 EVENT("(GLuint shader = %d)", shader);
354
355 Context *context = GetValidGlobalContext();
356 if (context)
357 {
358 Shader *shaderObject = GetValidShader(context, shader);
359 if (!shaderObject)
360 {
361 return;
362 }
363 shaderObject->compile(context);
364 }
365 }
366
CompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)367 void GL_APIENTRY CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
368 GLint border, GLsizei imageSize, const GLvoid* data)
369 {
370 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
371 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
372 target, level, internalformat, width, height, border, imageSize, data);
373
374 Context *context = GetValidGlobalContext();
375 if (context)
376 {
377 if (!context->skipValidation() &&
378 !ValidateCompressedTexImage2D(context, target, level, internalformat, width, height,
379 border, imageSize, data))
380 {
381 return;
382 }
383
384 context->compressedTexImage2D(target, level, internalformat, width, height, border,
385 imageSize, data);
386 }
387 }
388
CompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)389 void GL_APIENTRY CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
390 GLenum format, GLsizei imageSize, const GLvoid* data)
391 {
392 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
393 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
394 "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
395 target, level, xoffset, yoffset, width, height, format, imageSize, data);
396
397 Context *context = GetValidGlobalContext();
398 if (context)
399 {
400 if (!context->skipValidation() &&
401 !ValidateCompressedTexSubImage2D(context, target, level, xoffset, yoffset, width,
402 height, format, imageSize, data))
403 {
404 return;
405 }
406
407 context->compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format,
408 imageSize, data);
409 }
410 }
411
CopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)412 void GL_APIENTRY CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
413 {
414 EVENT("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
415 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
416 target, level, internalformat, x, y, width, height, border);
417
418 Context *context = GetValidGlobalContext();
419 if (context)
420 {
421 if (!context->skipValidation() &&
422 !ValidateCopyTexImage2D(context, target, level, internalformat, x, y, width, height,
423 border))
424 {
425 return;
426 }
427 context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
428 }
429 }
430
CopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)431 void GL_APIENTRY CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
432 {
433 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
434 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
435 target, level, xoffset, yoffset, x, y, width, height);
436
437 Context *context = GetValidGlobalContext();
438 if (context)
439 {
440 if (!context->skipValidation() &&
441 !ValidateCopyTexSubImage2D(context, target, level, xoffset, yoffset, x, y, width,
442 height))
443 {
444 return;
445 }
446
447 context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
448 }
449 }
450
CreateProgram(void)451 GLuint GL_APIENTRY CreateProgram(void)
452 {
453 EVENT("()");
454
455 Context *context = GetValidGlobalContext();
456 if (context)
457 {
458 return context->createProgram();
459 }
460
461 return 0;
462 }
463
CreateShader(GLenum type)464 GLuint GL_APIENTRY CreateShader(GLenum type)
465 {
466 EVENT("(GLenum type = 0x%X)", type);
467
468 Context *context = GetValidGlobalContext();
469 if (context)
470 {
471
472 if (!context->skipValidation() && !ValidateCreateShader(context, type))
473 {
474 return 0;
475 }
476 return context->createShader(type);
477 }
478 return 0;
479 }
480
CullFace(GLenum mode)481 void GL_APIENTRY CullFace(GLenum mode)
482 {
483 EVENT("(GLenum mode = 0x%X)", mode);
484
485 Context *context = GetValidGlobalContext();
486 if (context)
487 {
488 switch (mode)
489 {
490 case GL_FRONT:
491 case GL_BACK:
492 case GL_FRONT_AND_BACK:
493 break;
494
495 default:
496 context->handleError(Error(GL_INVALID_ENUM));
497 return;
498 }
499
500 context->cullFace(mode);
501 }
502 }
503
DeleteBuffers(GLsizei n,const GLuint * buffers)504 void GL_APIENTRY DeleteBuffers(GLsizei n, const GLuint* buffers)
505 {
506 EVENT("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
507
508 Context *context = GetValidGlobalContext();
509 if (context)
510 {
511 if (!context->skipValidation() && !ValidateDeleteBuffers(context, n, buffers))
512 {
513 return;
514 }
515
516 for (int i = 0; i < n; i++)
517 {
518 context->deleteBuffer(buffers[i]);
519 }
520 }
521 }
522
DeleteFramebuffers(GLsizei n,const GLuint * framebuffers)523 void GL_APIENTRY DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
524 {
525 EVENT("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
526
527 Context *context = GetValidGlobalContext();
528 if (context)
529 {
530 if (!context->skipValidation() && !ValidateDeleteFramebuffers(context, n, framebuffers))
531 {
532 return;
533 }
534
535 for (int i = 0; i < n; i++)
536 {
537 if (framebuffers[i] != 0)
538 {
539 context->deleteFramebuffer(framebuffers[i]);
540 }
541 }
542 }
543 }
544
DeleteProgram(GLuint program)545 void GL_APIENTRY DeleteProgram(GLuint program)
546 {
547 EVENT("(GLuint program = %d)", program);
548
549 Context *context = GetValidGlobalContext();
550 if (context)
551 {
552 if (program == 0)
553 {
554 return;
555 }
556
557 if (!context->getProgram(program))
558 {
559 if(context->getShader(program))
560 {
561 context->handleError(Error(GL_INVALID_OPERATION));
562 return;
563 }
564 else
565 {
566 context->handleError(Error(GL_INVALID_VALUE));
567 return;
568 }
569 }
570
571 context->deleteProgram(program);
572 }
573 }
574
DeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)575 void GL_APIENTRY DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
576 {
577 EVENT("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
578
579 Context *context = GetValidGlobalContext();
580 if (context)
581 {
582 if (!context->skipValidation() && !ValidateDeleteRenderbuffers(context, n, renderbuffers))
583 {
584 return;
585 }
586
587 for (int i = 0; i < n; i++)
588 {
589 context->deleteRenderbuffer(renderbuffers[i]);
590 }
591 }
592 }
593
DeleteShader(GLuint shader)594 void GL_APIENTRY DeleteShader(GLuint shader)
595 {
596 EVENT("(GLuint shader = %d)", shader);
597
598 Context *context = GetValidGlobalContext();
599 if (context)
600 {
601 if (shader == 0)
602 {
603 return;
604 }
605
606 if (!context->getShader(shader))
607 {
608 if(context->getProgram(shader))
609 {
610 context->handleError(Error(GL_INVALID_OPERATION));
611 return;
612 }
613 else
614 {
615 context->handleError(Error(GL_INVALID_VALUE));
616 return;
617 }
618 }
619
620 context->deleteShader(shader);
621 }
622 }
623
DeleteTextures(GLsizei n,const GLuint * textures)624 void GL_APIENTRY DeleteTextures(GLsizei n, const GLuint* textures)
625 {
626 EVENT("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
627
628 Context *context = GetValidGlobalContext();
629 if (context)
630 {
631 if (!context->skipValidation() && !ValidateDeleteTextures(context, n, textures))
632 {
633 return;
634 }
635
636 for (int i = 0; i < n; i++)
637 {
638 if (textures[i] != 0)
639 {
640 context->deleteTexture(textures[i]);
641 }
642 }
643 }
644 }
645
DepthFunc(GLenum func)646 void GL_APIENTRY DepthFunc(GLenum func)
647 {
648 EVENT("(GLenum func = 0x%X)", func);
649
650 Context *context = GetValidGlobalContext();
651 if (context)
652 {
653 switch (func)
654 {
655 case GL_NEVER:
656 case GL_ALWAYS:
657 case GL_LESS:
658 case GL_LEQUAL:
659 case GL_EQUAL:
660 case GL_GREATER:
661 case GL_GEQUAL:
662 case GL_NOTEQUAL:
663 break;
664
665 default:
666 context->handleError(Error(GL_INVALID_ENUM));
667 return;
668 }
669
670 context->depthFunc(func);
671 }
672 }
673
DepthMask(GLboolean flag)674 void GL_APIENTRY DepthMask(GLboolean flag)
675 {
676 EVENT("(GLboolean flag = %u)", flag);
677
678 Context *context = GetValidGlobalContext();
679 if (context)
680 {
681 context->depthMask(flag);
682 }
683 }
684
DepthRangef(GLclampf zNear,GLclampf zFar)685 void GL_APIENTRY DepthRangef(GLclampf zNear, GLclampf zFar)
686 {
687 EVENT("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
688
689 Context *context = GetValidGlobalContext();
690 if (context)
691 {
692 context->depthRangef(zNear, zFar);
693 }
694 }
695
DetachShader(GLuint program,GLuint shader)696 void GL_APIENTRY DetachShader(GLuint program, GLuint shader)
697 {
698 EVENT("(GLuint program = %d, GLuint shader = %d)", program, shader);
699
700 Context *context = GetValidGlobalContext();
701 if (context)
702 {
703 Program *programObject = GetValidProgram(context, program);
704 if (!programObject)
705 {
706 return;
707 }
708
709 Shader *shaderObject = GetValidShader(context, shader);
710 if (!shaderObject)
711 {
712 return;
713 }
714
715 if (!programObject->detachShader(shaderObject))
716 {
717 context->handleError(Error(GL_INVALID_OPERATION));
718 return;
719 }
720 }
721 }
722
Disable(GLenum cap)723 void GL_APIENTRY Disable(GLenum cap)
724 {
725 EVENT("(GLenum cap = 0x%X)", cap);
726
727 Context *context = GetValidGlobalContext();
728 if (context)
729 {
730 if (!context->skipValidation() && !ValidateDisable(context, cap))
731 {
732 return;
733 }
734
735 context->disable(cap);
736 }
737 }
738
DisableVertexAttribArray(GLuint index)739 void GL_APIENTRY DisableVertexAttribArray(GLuint index)
740 {
741 EVENT("(GLuint index = %d)", index);
742
743 Context *context = GetValidGlobalContext();
744 if (context)
745 {
746 if (index >= MAX_VERTEX_ATTRIBS)
747 {
748 context->handleError(Error(GL_INVALID_VALUE));
749 return;
750 }
751
752 context->disableVertexAttribArray(index);
753 }
754 }
755
DrawArrays(GLenum mode,GLint first,GLsizei count)756 void GL_APIENTRY DrawArrays(GLenum mode, GLint first, GLsizei count)
757 {
758 EVENT("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
759
760 Context *context = GetValidGlobalContext();
761 if (context)
762 {
763 if (!ValidateDrawArrays(context, mode, first, count, 1))
764 {
765 return;
766 }
767
768 Error error = context->drawArrays(mode, first, count);
769 if (error.isError())
770 {
771 context->handleError(error);
772 return;
773 }
774 }
775 }
776
DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)777 void GL_APIENTRY DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
778 {
779 EVENT("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
780 mode, count, type, indices);
781
782 Context *context = GetValidGlobalContext();
783 if (context)
784 {
785 IndexRange indexRange;
786 if (!ValidateDrawElements(context, mode, count, type, indices, 1, &indexRange))
787 {
788 return;
789 }
790
791 Error error = context->drawElements(mode, count, type, indices, indexRange);
792 if (error.isError())
793 {
794 context->handleError(error);
795 return;
796 }
797 }
798 }
799
Enable(GLenum cap)800 void GL_APIENTRY Enable(GLenum cap)
801 {
802 EVENT("(GLenum cap = 0x%X)", cap);
803
804 Context *context = GetValidGlobalContext();
805 if (context)
806 {
807 if (!context->skipValidation() && !ValidateEnable(context, cap))
808 {
809 return;
810 }
811
812 context->enable(cap);
813 }
814 }
815
EnableVertexAttribArray(GLuint index)816 void GL_APIENTRY EnableVertexAttribArray(GLuint index)
817 {
818 EVENT("(GLuint index = %d)", index);
819
820 Context *context = GetValidGlobalContext();
821 if (context)
822 {
823 if (index >= MAX_VERTEX_ATTRIBS)
824 {
825 context->handleError(Error(GL_INVALID_VALUE));
826 return;
827 }
828
829 context->enableVertexAttribArray(index);
830 }
831 }
832
Finish(void)833 void GL_APIENTRY Finish(void)
834 {
835 EVENT("()");
836
837 Context *context = GetValidGlobalContext();
838 if (context)
839 {
840 Error error = context->finish();
841 if (error.isError())
842 {
843 context->handleError(error);
844 return;
845 }
846 }
847 }
848
Flush(void)849 void GL_APIENTRY Flush(void)
850 {
851 EVENT("()");
852
853 Context *context = GetValidGlobalContext();
854 if (context)
855 {
856 Error error = context->flush();
857 if (error.isError())
858 {
859 context->handleError(error);
860 return;
861 }
862 }
863 }
864
FramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)865 void GL_APIENTRY FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
866 {
867 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
868 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
869
870 Context *context = GetValidGlobalContext();
871 if (context)
872 {
873 if (!context->skipValidation() &&
874 !ValidateFramebufferRenderbuffer(context, target, attachment, renderbuffertarget,
875 renderbuffer))
876 {
877 return;
878 }
879
880 context->framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
881 }
882 }
883
FramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)884 void GL_APIENTRY FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
885 {
886 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
887 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
888
889 Context *context = GetValidGlobalContext();
890 if (context)
891 {
892 if (!context->skipValidation() &&
893 !ValidateFramebufferTexture2D(context, target, attachment, textarget, texture, level))
894 {
895 return;
896 }
897
898 context->framebufferTexture2D(target, attachment, textarget, texture, level);
899 }
900 }
901
FrontFace(GLenum mode)902 void GL_APIENTRY FrontFace(GLenum mode)
903 {
904 EVENT("(GLenum mode = 0x%X)", mode);
905
906 Context *context = GetValidGlobalContext();
907 if (context)
908 {
909 switch (mode)
910 {
911 case GL_CW:
912 case GL_CCW:
913 break;
914 default:
915 context->handleError(Error(GL_INVALID_ENUM));
916 return;
917 }
918
919 context->frontFace(mode);
920 }
921 }
922
GenBuffers(GLsizei n,GLuint * buffers)923 void GL_APIENTRY GenBuffers(GLsizei n, GLuint* buffers)
924 {
925 EVENT("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
926
927 Context *context = GetValidGlobalContext();
928 if (context)
929 {
930 if (!context->skipValidation() && !ValidateGenBuffers(context, n, buffers))
931 {
932 return;
933 }
934
935 for (int i = 0; i < n; i++)
936 {
937 buffers[i] = context->createBuffer();
938 }
939 }
940 }
941
GenerateMipmap(GLenum target)942 void GL_APIENTRY GenerateMipmap(GLenum target)
943 {
944 EVENT("(GLenum target = 0x%X)", target);
945
946 Context *context = GetValidGlobalContext();
947 if (context)
948 {
949 if (!context->skipValidation() && !ValidateGenerateMipmap(context, target))
950 {
951 return;
952 }
953
954 context->generateMipmap(target);
955 }
956 }
957
GenFramebuffers(GLsizei n,GLuint * framebuffers)958 void GL_APIENTRY GenFramebuffers(GLsizei n, GLuint* framebuffers)
959 {
960 EVENT("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
961
962 Context *context = GetValidGlobalContext();
963 if (context)
964 {
965 if (!context->skipValidation() && !ValidateGenFramebuffers(context, n, framebuffers))
966 {
967 return;
968 }
969
970 for (int i = 0; i < n; i++)
971 {
972 framebuffers[i] = context->createFramebuffer();
973 }
974 }
975 }
976
GenRenderbuffers(GLsizei n,GLuint * renderbuffers)977 void GL_APIENTRY GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
978 {
979 EVENT("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
980
981 Context *context = GetValidGlobalContext();
982 if (context)
983 {
984 if (!context->skipValidation() && !ValidateGenRenderbuffers(context, n, renderbuffers))
985 {
986 return;
987 }
988
989 for (int i = 0; i < n; i++)
990 {
991 renderbuffers[i] = context->createRenderbuffer();
992 }
993 }
994 }
995
GenTextures(GLsizei n,GLuint * textures)996 void GL_APIENTRY GenTextures(GLsizei n, GLuint* textures)
997 {
998 EVENT("(GLsizei n = %d, GLuint* textures = 0x%0.8p)", n, textures);
999
1000 Context *context = GetValidGlobalContext();
1001 if (context)
1002 {
1003 if (!context->skipValidation() && !ValidateGenTextures(context, n, textures))
1004 {
1005 return;
1006 }
1007
1008 for (int i = 0; i < n; i++)
1009 {
1010 textures[i] = context->createTexture();
1011 }
1012 }
1013 }
1014
GetActiveAttrib(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)1015 void GL_APIENTRY GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
1016 {
1017 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
1018 "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
1019 program, index, bufsize, length, size, type, name);
1020
1021 Context *context = GetValidGlobalContext();
1022 if (context)
1023 {
1024 if (bufsize < 0)
1025 {
1026 context->handleError(Error(GL_INVALID_VALUE));
1027 return;
1028 }
1029
1030 Program *programObject = GetValidProgram(context, program);
1031
1032 if (!programObject)
1033 {
1034 return;
1035 }
1036
1037 if (index >= (GLuint)programObject->getActiveAttributeCount())
1038 {
1039 context->handleError(Error(GL_INVALID_VALUE));
1040 return;
1041 }
1042
1043 programObject->getActiveAttribute(index, bufsize, length, size, type, name);
1044 }
1045 }
1046
GetActiveUniform(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)1047 void GL_APIENTRY GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
1048 {
1049 EVENT("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
1050 "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
1051 program, index, bufsize, length, size, type, name);
1052
1053
1054 Context *context = GetValidGlobalContext();
1055 if (context)
1056 {
1057 if (bufsize < 0)
1058 {
1059 context->handleError(Error(GL_INVALID_VALUE));
1060 return;
1061 }
1062
1063 Program *programObject = GetValidProgram(context, program);
1064
1065 if (!programObject)
1066 {
1067 return;
1068 }
1069
1070 if (index >= (GLuint)programObject->getActiveUniformCount())
1071 {
1072 context->handleError(Error(GL_INVALID_VALUE));
1073 return;
1074 }
1075
1076 programObject->getActiveUniform(index, bufsize, length, size, type, name);
1077 }
1078 }
1079
GetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)1080 void GL_APIENTRY GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
1081 {
1082 EVENT("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
1083 program, maxcount, count, shaders);
1084
1085 Context *context = GetValidGlobalContext();
1086 if (context)
1087 {
1088 if (maxcount < 0)
1089 {
1090 context->handleError(Error(GL_INVALID_VALUE));
1091 return;
1092 }
1093
1094 Program *programObject = GetValidProgram(context, program);
1095
1096 if (!programObject)
1097 {
1098 return;
1099 }
1100
1101 return programObject->getAttachedShaders(maxcount, count, shaders);
1102 }
1103 }
1104
GetAttribLocation(GLuint program,const GLchar * name)1105 GLint GL_APIENTRY GetAttribLocation(GLuint program, const GLchar* name)
1106 {
1107 EVENT("(GLuint program = %d, const GLchar* name = %s)", program, name);
1108
1109 Context *context = GetValidGlobalContext();
1110 if (context)
1111 {
1112 Program *programObject = GetValidProgram(context, program);
1113
1114 if (!programObject)
1115 {
1116 return -1;
1117 }
1118
1119 if (!programObject->isLinked())
1120 {
1121 context->handleError(Error(GL_INVALID_OPERATION));
1122 return -1;
1123 }
1124
1125 return programObject->getAttributeLocation(name);
1126 }
1127
1128 return -1;
1129 }
1130
GetBooleanv(GLenum pname,GLboolean * params)1131 void GL_APIENTRY GetBooleanv(GLenum pname, GLboolean* params)
1132 {
1133 EVENT("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)", pname, params);
1134
1135 Context *context = GetValidGlobalContext();
1136 if (context)
1137 {
1138 GLenum nativeType;
1139 unsigned int numParams = 0;
1140 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
1141 {
1142 return;
1143 }
1144
1145 if (nativeType == GL_BOOL)
1146 {
1147 context->getBooleanv(pname, params);
1148 }
1149 else
1150 {
1151 CastStateValues(context, nativeType, pname, numParams, params);
1152 }
1153 }
1154 }
1155
GetBufferParameteriv(GLenum target,GLenum pname,GLint * params)1156 void GL_APIENTRY GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1157 {
1158 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
1159
1160 Context *context = GetValidGlobalContext();
1161 if (context)
1162 {
1163 if (!context->skipValidation() &&
1164 !ValidateGetBufferParameteriv(context, target, pname, params))
1165 {
1166 return;
1167 }
1168
1169 Buffer *buffer = context->getGLState().getTargetBuffer(target);
1170 QueryBufferParameteriv(buffer, pname, params);
1171 }
1172 }
1173
GetError(void)1174 GLenum GL_APIENTRY GetError(void)
1175 {
1176 EVENT("()");
1177
1178 Context *context = GetGlobalContext();
1179
1180 if (context)
1181 {
1182 return context->getError();
1183 }
1184
1185 return GL_NO_ERROR;
1186 }
1187
GetFloatv(GLenum pname,GLfloat * params)1188 void GL_APIENTRY GetFloatv(GLenum pname, GLfloat* params)
1189 {
1190 EVENT("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
1191
1192 Context *context = GetValidGlobalContext();
1193 if (context)
1194 {
1195 GLenum nativeType;
1196 unsigned int numParams = 0;
1197 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
1198 {
1199 return;
1200 }
1201
1202 if (nativeType == GL_FLOAT)
1203 {
1204 context->getFloatv(pname, params);
1205 }
1206 else
1207 {
1208 CastStateValues(context, nativeType, pname, numParams, params);
1209 }
1210 }
1211 }
1212
GetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)1213 void GL_APIENTRY GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
1214 {
1215 EVENT("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
1216 target, attachment, pname, params);
1217
1218 Context *context = GetValidGlobalContext();
1219 if (context)
1220 {
1221 GLsizei numParams = 0;
1222 if (!context->skipValidation() &&
1223 !ValidateGetFramebufferAttachmentParameteriv(context, target, attachment, pname,
1224 &numParams))
1225 {
1226 return;
1227 }
1228
1229 const Framebuffer *framebuffer = context->getGLState().getTargetFramebuffer(target);
1230 QueryFramebufferAttachmentParameteriv(framebuffer, attachment, pname, params);
1231 }
1232 }
1233
GetIntegerv(GLenum pname,GLint * params)1234 void GL_APIENTRY GetIntegerv(GLenum pname, GLint* params)
1235 {
1236 EVENT("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
1237
1238 Context *context = GetValidGlobalContext();
1239 if (context)
1240 {
1241 GLenum nativeType;
1242 unsigned int numParams = 0;
1243
1244 if (!ValidateStateQuery(context, pname, &nativeType, &numParams))
1245 {
1246 return;
1247 }
1248
1249 if (nativeType == GL_INT)
1250 {
1251 context->getIntegerv(pname, params);
1252 }
1253 else
1254 {
1255 CastStateValues(context, nativeType, pname, numParams, params);
1256 }
1257 }
1258 }
1259
GetProgramiv(GLuint program,GLenum pname,GLint * params)1260 void GL_APIENTRY GetProgramiv(GLuint program, GLenum pname, GLint* params)
1261 {
1262 EVENT("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
1263
1264 Context *context = GetValidGlobalContext();
1265 if (context)
1266 {
1267 GLsizei numParams = 0;
1268 if (!context->skipValidation() &&
1269 !ValidateGetProgramiv(context, program, pname, &numParams))
1270 {
1271 return;
1272 }
1273
1274 Program *programObject = context->getProgram(program);
1275 QueryProgramiv(programObject, pname, params);
1276 }
1277 }
1278
GetProgramInfoLog(GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)1279 void GL_APIENTRY GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
1280 {
1281 EVENT("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
1282 program, bufsize, length, infolog);
1283
1284 Context *context = GetValidGlobalContext();
1285 if (context)
1286 {
1287 if (bufsize < 0)
1288 {
1289 context->handleError(Error(GL_INVALID_VALUE));
1290 return;
1291 }
1292
1293 Program *programObject = GetValidProgram(context, program);
1294 if (!programObject)
1295 {
1296 return;
1297 }
1298
1299 programObject->getInfoLog(bufsize, length, infolog);
1300 }
1301 }
1302
GetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)1303 void GL_APIENTRY GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
1304 {
1305 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
1306
1307 Context *context = GetValidGlobalContext();
1308 if (context)
1309 {
1310 if (!context->skipValidation() &&
1311 !ValidateGetRenderbufferParameteriv(context, target, pname, params))
1312 {
1313 return;
1314 }
1315
1316 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
1317 QueryRenderbufferiv(renderbuffer, pname, params);
1318 }
1319 }
1320
GetShaderiv(GLuint shader,GLenum pname,GLint * params)1321 void GL_APIENTRY GetShaderiv(GLuint shader, GLenum pname, GLint* params)
1322 {
1323 EVENT("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
1324
1325 Context *context = GetValidGlobalContext();
1326 if (context)
1327 {
1328 if (!context->skipValidation() && !ValidateGetShaderiv(context, shader, pname, params))
1329 {
1330 return;
1331 }
1332
1333 Shader *shaderObject = context->getShader(shader);
1334 QueryShaderiv(shaderObject, pname, params);
1335 }
1336 }
1337
GetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)1338 void GL_APIENTRY GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
1339 {
1340 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
1341 shader, bufsize, length, infolog);
1342
1343 Context *context = GetValidGlobalContext();
1344 if (context)
1345 {
1346 if (bufsize < 0)
1347 {
1348 context->handleError(Error(GL_INVALID_VALUE));
1349 return;
1350 }
1351
1352 Shader *shaderObject = GetValidShader(context, shader);
1353 if (!shaderObject)
1354 {
1355 return;
1356 }
1357
1358 shaderObject->getInfoLog(bufsize, length, infolog);
1359 }
1360 }
1361
GetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)1362 void GL_APIENTRY GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
1363 {
1364 EVENT("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
1365 shadertype, precisiontype, range, precision);
1366
1367 Context *context = GetValidGlobalContext();
1368 if (context)
1369 {
1370 switch (shadertype)
1371 {
1372 case GL_VERTEX_SHADER:
1373 switch (precisiontype)
1374 {
1375 case GL_LOW_FLOAT:
1376 context->getCaps().vertexLowpFloat.get(range, precision);
1377 break;
1378 case GL_MEDIUM_FLOAT:
1379 context->getCaps().vertexMediumpFloat.get(range, precision);
1380 break;
1381 case GL_HIGH_FLOAT:
1382 context->getCaps().vertexHighpFloat.get(range, precision);
1383 break;
1384
1385 case GL_LOW_INT:
1386 context->getCaps().vertexLowpInt.get(range, precision);
1387 break;
1388 case GL_MEDIUM_INT:
1389 context->getCaps().vertexMediumpInt.get(range, precision);
1390 break;
1391 case GL_HIGH_INT:
1392 context->getCaps().vertexHighpInt.get(range, precision);
1393 break;
1394
1395 default:
1396 context->handleError(Error(GL_INVALID_ENUM));
1397 return;
1398 }
1399 break;
1400 case GL_FRAGMENT_SHADER:
1401 switch (precisiontype)
1402 {
1403 case GL_LOW_FLOAT:
1404 context->getCaps().fragmentLowpFloat.get(range, precision);
1405 break;
1406 case GL_MEDIUM_FLOAT:
1407 context->getCaps().fragmentMediumpFloat.get(range, precision);
1408 break;
1409 case GL_HIGH_FLOAT:
1410 context->getCaps().fragmentHighpFloat.get(range, precision);
1411 break;
1412
1413 case GL_LOW_INT:
1414 context->getCaps().fragmentLowpInt.get(range, precision);
1415 break;
1416 case GL_MEDIUM_INT:
1417 context->getCaps().fragmentMediumpInt.get(range, precision);
1418 break;
1419 case GL_HIGH_INT:
1420 context->getCaps().fragmentHighpInt.get(range, precision);
1421 break;
1422
1423 default:
1424 context->handleError(Error(GL_INVALID_ENUM));
1425 return;
1426 }
1427 break;
1428 default:
1429 context->handleError(Error(GL_INVALID_ENUM));
1430 return;
1431 }
1432
1433 }
1434 }
1435
GetShaderSource(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)1436 void GL_APIENTRY GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
1437 {
1438 EVENT("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
1439 shader, bufsize, length, source);
1440
1441 Context *context = GetValidGlobalContext();
1442 if (context)
1443 {
1444 if (bufsize < 0)
1445 {
1446 context->handleError(Error(GL_INVALID_VALUE));
1447 return;
1448 }
1449
1450 Shader *shaderObject = GetValidShader(context, shader);
1451 if (!shaderObject)
1452 {
1453 return;
1454 }
1455
1456 shaderObject->getSource(bufsize, length, source);
1457 }
1458 }
1459
GetString(GLenum name)1460 const GLubyte *GL_APIENTRY GetString(GLenum name)
1461 {
1462 EVENT("(GLenum name = 0x%X)", name);
1463
1464 Context *context = GetValidGlobalContext();
1465
1466 if (context)
1467 {
1468 switch (name)
1469 {
1470 case GL_VENDOR:
1471 return reinterpret_cast<const GLubyte *>("Google Inc.");
1472
1473 case GL_RENDERER:
1474 return reinterpret_cast<const GLubyte *>(context->getRendererString());
1475
1476 case GL_VERSION:
1477 if (context->getClientMajorVersion() == 2)
1478 {
1479 return reinterpret_cast<const GLubyte *>(
1480 "OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")");
1481 }
1482 else
1483 {
1484 return reinterpret_cast<const GLubyte *>(
1485 "OpenGL ES 3.0 (ANGLE " ANGLE_VERSION_STRING ")");
1486 }
1487
1488 case GL_SHADING_LANGUAGE_VERSION:
1489 if (context->getClientMajorVersion() == 2)
1490 {
1491 return reinterpret_cast<const GLubyte *>(
1492 "OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")");
1493 }
1494 else
1495 {
1496 return reinterpret_cast<const GLubyte *>(
1497 "OpenGL ES GLSL ES 3.00 (ANGLE " ANGLE_VERSION_STRING ")");
1498 }
1499
1500 case GL_EXTENSIONS:
1501 return reinterpret_cast<const GLubyte *>(context->getExtensionString());
1502
1503 default:
1504 context->handleError(Error(GL_INVALID_ENUM));
1505 return nullptr;
1506 }
1507 }
1508
1509 return nullptr;
1510 }
1511
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)1512 void GL_APIENTRY GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
1513 {
1514 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
1515
1516 Context *context = GetValidGlobalContext();
1517 if (context)
1518 {
1519 if (!context->skipValidation() &&
1520 !ValidateGetTexParameterfv(context, target, pname, params))
1521 {
1522 return;
1523 }
1524
1525 Texture *texture = context->getTargetTexture(target);
1526 QueryTexParameterfv(texture, pname, params);
1527 }
1528 }
1529
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)1530 void GL_APIENTRY GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
1531 {
1532 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
1533
1534 Context *context = GetValidGlobalContext();
1535 if (context)
1536 {
1537 if (!context->skipValidation() &&
1538 !ValidateGetTexParameteriv(context, target, pname, params))
1539 {
1540 return;
1541 }
1542
1543 Texture *texture = context->getTargetTexture(target);
1544 QueryTexParameteriv(texture, pname, params);
1545 }
1546 }
1547
GetUniformfv(GLuint program,GLint location,GLfloat * params)1548 void GL_APIENTRY GetUniformfv(GLuint program, GLint location, GLfloat* params)
1549 {
1550 EVENT("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
1551
1552 Context *context = GetValidGlobalContext();
1553 if (context)
1554 {
1555 if (!ValidateGetUniformfv(context, program, location, params))
1556 {
1557 return;
1558 }
1559
1560 Program *programObject = context->getProgram(program);
1561 ASSERT(programObject);
1562
1563 programObject->getUniformfv(location, params);
1564 }
1565 }
1566
GetUniformiv(GLuint program,GLint location,GLint * params)1567 void GL_APIENTRY GetUniformiv(GLuint program, GLint location, GLint* params)
1568 {
1569 EVENT("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
1570
1571 Context *context = GetValidGlobalContext();
1572 if (context)
1573 {
1574 if (!ValidateGetUniformiv(context, program, location, params))
1575 {
1576 return;
1577 }
1578
1579 Program *programObject = context->getProgram(program);
1580 ASSERT(programObject);
1581
1582 programObject->getUniformiv(location, params);
1583 }
1584 }
1585
GetUniformLocation(GLuint program,const GLchar * name)1586 GLint GL_APIENTRY GetUniformLocation(GLuint program, const GLchar* name)
1587 {
1588 EVENT("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
1589
1590 Context *context = GetValidGlobalContext();
1591 if (context)
1592 {
1593 if (strstr(name, "gl_") == name)
1594 {
1595 return -1;
1596 }
1597
1598 Program *programObject = GetValidProgram(context, program);
1599
1600 if (!programObject)
1601 {
1602 return -1;
1603 }
1604
1605 if (!programObject->isLinked())
1606 {
1607 context->handleError(Error(GL_INVALID_OPERATION));
1608 return -1;
1609 }
1610
1611 return programObject->getUniformLocation(name);
1612 }
1613
1614 return -1;
1615 }
1616
GetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)1617 void GL_APIENTRY GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
1618 {
1619 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
1620
1621 Context *context = GetValidGlobalContext();
1622 if (context)
1623 {
1624 if (!context->skipValidation() && !ValidateGetVertexAttribfv(context, index, pname, params))
1625 {
1626 return;
1627 }
1628
1629 const VertexAttribCurrentValueData ¤tValues =
1630 context->getGLState().getVertexAttribCurrentValue(index);
1631 const VertexAttribute &attrib =
1632 context->getGLState().getVertexArray()->getVertexAttribute(index);
1633 QueryVertexAttribfv(attrib, currentValues, pname, params);
1634 }
1635 }
1636
GetVertexAttribiv(GLuint index,GLenum pname,GLint * params)1637 void GL_APIENTRY GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
1638 {
1639 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
1640
1641 Context *context = GetValidGlobalContext();
1642 if (context)
1643 {
1644 if (!context->skipValidation() && !ValidateGetVertexAttribiv(context, index, pname, params))
1645 {
1646 return;
1647 }
1648
1649 const VertexAttribCurrentValueData ¤tValues =
1650 context->getGLState().getVertexAttribCurrentValue(index);
1651 const VertexAttribute &attrib =
1652 context->getGLState().getVertexArray()->getVertexAttribute(index);
1653 QueryVertexAttribiv(attrib, currentValues, pname, params);
1654 }
1655 }
1656
GetVertexAttribPointerv(GLuint index,GLenum pname,GLvoid ** pointer)1657 void GL_APIENTRY GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
1658 {
1659 EVENT("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
1660
1661 Context *context = GetValidGlobalContext();
1662 if (context)
1663 {
1664 if (!context->skipValidation() &&
1665 !ValidateGetVertexAttribPointerv(context, index, pname, pointer))
1666 {
1667 return;
1668 }
1669
1670 const VertexAttribute &attrib =
1671 context->getGLState().getVertexArray()->getVertexAttribute(index);
1672 QueryVertexAttribPointerv(attrib, pname, pointer);
1673 }
1674 }
1675
Hint(GLenum target,GLenum mode)1676 void GL_APIENTRY Hint(GLenum target, GLenum mode)
1677 {
1678 EVENT("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
1679
1680 Context *context = GetValidGlobalContext();
1681 if (context)
1682 {
1683 switch (mode)
1684 {
1685 case GL_FASTEST:
1686 case GL_NICEST:
1687 case GL_DONT_CARE:
1688 break;
1689
1690 default:
1691 context->handleError(Error(GL_INVALID_ENUM));
1692 return;
1693 }
1694
1695 switch (target)
1696 {
1697 case GL_GENERATE_MIPMAP_HINT:
1698 case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
1699 break;
1700
1701 default:
1702 context->handleError(Error(GL_INVALID_ENUM));
1703 return;
1704 }
1705
1706 context->hint(target, mode);
1707 }
1708 }
1709
IsBuffer(GLuint buffer)1710 GLboolean GL_APIENTRY IsBuffer(GLuint buffer)
1711 {
1712 EVENT("(GLuint buffer = %d)", buffer);
1713
1714 Context *context = GetValidGlobalContext();
1715 if (context && buffer)
1716 {
1717 Buffer *bufferObject = context->getBuffer(buffer);
1718
1719 if (bufferObject)
1720 {
1721 return GL_TRUE;
1722 }
1723 }
1724
1725 return GL_FALSE;
1726 }
1727
IsEnabled(GLenum cap)1728 GLboolean GL_APIENTRY IsEnabled(GLenum cap)
1729 {
1730 EVENT("(GLenum cap = 0x%X)", cap);
1731
1732 Context *context = GetValidGlobalContext();
1733 if (context)
1734 {
1735 if (!context->skipValidation() && !ValidateIsEnabled(context, cap))
1736 {
1737 return GL_FALSE;
1738 }
1739
1740 return context->getGLState().getEnableFeature(cap);
1741 }
1742
1743 return false;
1744 }
1745
IsFramebuffer(GLuint framebuffer)1746 GLboolean GL_APIENTRY IsFramebuffer(GLuint framebuffer)
1747 {
1748 EVENT("(GLuint framebuffer = %d)", framebuffer);
1749
1750 Context *context = GetValidGlobalContext();
1751 if (context && framebuffer)
1752 {
1753 Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
1754
1755 if (framebufferObject)
1756 {
1757 return GL_TRUE;
1758 }
1759 }
1760
1761 return GL_FALSE;
1762 }
1763
IsProgram(GLuint program)1764 GLboolean GL_APIENTRY IsProgram(GLuint program)
1765 {
1766 EVENT("(GLuint program = %d)", program);
1767
1768 Context *context = GetValidGlobalContext();
1769 if (context && program)
1770 {
1771 Program *programObject = context->getProgram(program);
1772
1773 if (programObject)
1774 {
1775 return GL_TRUE;
1776 }
1777 }
1778
1779 return GL_FALSE;
1780 }
1781
IsRenderbuffer(GLuint renderbuffer)1782 GLboolean GL_APIENTRY IsRenderbuffer(GLuint renderbuffer)
1783 {
1784 EVENT("(GLuint renderbuffer = %d)", renderbuffer);
1785
1786 Context *context = GetValidGlobalContext();
1787 if (context && renderbuffer)
1788 {
1789 Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
1790
1791 if (renderbufferObject)
1792 {
1793 return GL_TRUE;
1794 }
1795 }
1796
1797 return GL_FALSE;
1798 }
1799
IsShader(GLuint shader)1800 GLboolean GL_APIENTRY IsShader(GLuint shader)
1801 {
1802 EVENT("(GLuint shader = %d)", shader);
1803
1804 Context *context = GetValidGlobalContext();
1805 if (context && shader)
1806 {
1807 Shader *shaderObject = context->getShader(shader);
1808
1809 if (shaderObject)
1810 {
1811 return GL_TRUE;
1812 }
1813 }
1814
1815 return GL_FALSE;
1816 }
1817
IsTexture(GLuint texture)1818 GLboolean GL_APIENTRY IsTexture(GLuint texture)
1819 {
1820 EVENT("(GLuint texture = %d)", texture);
1821
1822 Context *context = GetValidGlobalContext();
1823 if (context && texture)
1824 {
1825 Texture *textureObject = context->getTexture(texture);
1826
1827 if (textureObject)
1828 {
1829 return GL_TRUE;
1830 }
1831 }
1832
1833 return GL_FALSE;
1834 }
1835
LineWidth(GLfloat width)1836 void GL_APIENTRY LineWidth(GLfloat width)
1837 {
1838 EVENT("(GLfloat width = %f)", width);
1839
1840 Context *context = GetValidGlobalContext();
1841 if (context)
1842 {
1843 if (width <= 0.0f)
1844 {
1845 context->handleError(Error(GL_INVALID_VALUE));
1846 return;
1847 }
1848
1849 context->lineWidth(width);
1850 }
1851 }
1852
LinkProgram(GLuint program)1853 void GL_APIENTRY LinkProgram(GLuint program)
1854 {
1855 EVENT("(GLuint program = %d)", program);
1856
1857 Context *context = GetValidGlobalContext();
1858 if (context)
1859 {
1860 if (!context->skipValidation() && !ValidateLinkProgram(context, program))
1861 {
1862 return;
1863 }
1864
1865 Program *programObject = GetValidProgram(context, program);
1866 if (!programObject)
1867 {
1868 return;
1869 }
1870
1871 Error error = programObject->link(context->getContextState());
1872 if (error.isError())
1873 {
1874 context->handleError(error);
1875 return;
1876 }
1877 }
1878 }
1879
PixelStorei(GLenum pname,GLint param)1880 void GL_APIENTRY PixelStorei(GLenum pname, GLint param)
1881 {
1882 EVENT("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
1883
1884 Context *context = GetValidGlobalContext();
1885 if (context)
1886 {
1887 if (context->getClientMajorVersion() < 3)
1888 {
1889 switch (pname)
1890 {
1891 case GL_UNPACK_IMAGE_HEIGHT:
1892 case GL_UNPACK_SKIP_IMAGES:
1893 context->handleError(Error(GL_INVALID_ENUM));
1894 return;
1895
1896 case GL_UNPACK_ROW_LENGTH:
1897 case GL_UNPACK_SKIP_ROWS:
1898 case GL_UNPACK_SKIP_PIXELS:
1899 if (!context->getExtensions().unpackSubimage)
1900 {
1901 context->handleError(Error(GL_INVALID_ENUM));
1902 return;
1903 }
1904 break;
1905
1906 case GL_PACK_ROW_LENGTH:
1907 case GL_PACK_SKIP_ROWS:
1908 case GL_PACK_SKIP_PIXELS:
1909 if (!context->getExtensions().packSubimage)
1910 {
1911 context->handleError(Error(GL_INVALID_ENUM));
1912 return;
1913 }
1914 break;
1915 }
1916 }
1917
1918 if (param < 0)
1919 {
1920 context->handleError(
1921 Error(GL_INVALID_VALUE, "Cannot use negative values in PixelStorei"));
1922 return;
1923 }
1924
1925 switch (pname)
1926 {
1927 case GL_UNPACK_ALIGNMENT:
1928 if (param != 1 && param != 2 && param != 4 && param != 8)
1929 {
1930 context->handleError(Error(GL_INVALID_VALUE));
1931 return;
1932 }
1933 break;
1934
1935 case GL_PACK_ALIGNMENT:
1936 if (param != 1 && param != 2 && param != 4 && param != 8)
1937 {
1938 context->handleError(Error(GL_INVALID_VALUE));
1939 return;
1940 }
1941 break;
1942
1943 case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
1944 case GL_UNPACK_ROW_LENGTH:
1945 case GL_UNPACK_IMAGE_HEIGHT:
1946 case GL_UNPACK_SKIP_IMAGES:
1947 case GL_UNPACK_SKIP_ROWS:
1948 case GL_UNPACK_SKIP_PIXELS:
1949 case GL_PACK_ROW_LENGTH:
1950 case GL_PACK_SKIP_ROWS:
1951 case GL_PACK_SKIP_PIXELS:
1952 break;
1953
1954 default:
1955 context->handleError(Error(GL_INVALID_ENUM));
1956 return;
1957 }
1958
1959 context->pixelStorei(pname, param);
1960 }
1961 }
1962
PolygonOffset(GLfloat factor,GLfloat units)1963 void GL_APIENTRY PolygonOffset(GLfloat factor, GLfloat units)
1964 {
1965 EVENT("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
1966
1967 Context *context = GetValidGlobalContext();
1968 if (context)
1969 {
1970 context->polygonOffset(factor, units);
1971 }
1972 }
1973
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)1974 void GL_APIENTRY ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
1975 GLenum format, GLenum type, GLvoid* pixels)
1976 {
1977 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
1978 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
1979 x, y, width, height, format, type, pixels);
1980
1981 Context *context = GetValidGlobalContext();
1982 if (context)
1983 {
1984 if (!context->skipValidation() &&
1985 !ValidateReadPixels(context, x, y, width, height, format, type, pixels))
1986 {
1987 return;
1988 }
1989
1990 context->readPixels(x, y, width, height, format, type, pixels);
1991 }
1992 }
1993
ReleaseShaderCompiler(void)1994 void GL_APIENTRY ReleaseShaderCompiler(void)
1995 {
1996 EVENT("()");
1997
1998 Context *context = GetValidGlobalContext();
1999
2000 if (context)
2001 {
2002 Compiler *compiler = context->getCompiler();
2003 Error error = compiler->release();
2004 if (error.isError())
2005 {
2006 context->handleError(error);
2007 return;
2008 }
2009 }
2010 }
2011
RenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)2012 void GL_APIENTRY RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
2013 {
2014 EVENT("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
2015 target, internalformat, width, height);
2016
2017 Context *context = GetValidGlobalContext();
2018 if (context)
2019 {
2020 if (!ValidateRenderbufferStorageParametersANGLE(context, target, 0, internalformat,
2021 width, height))
2022 {
2023 return;
2024 }
2025
2026 Renderbuffer *renderbuffer = context->getGLState().getCurrentRenderbuffer();
2027 Error error = renderbuffer->setStorage(internalformat, width, height);
2028 if (error.isError())
2029 {
2030 context->handleError(error);
2031 return;
2032 }
2033 }
2034 }
2035
SampleCoverage(GLclampf value,GLboolean invert)2036 void GL_APIENTRY SampleCoverage(GLclampf value, GLboolean invert)
2037 {
2038 EVENT("(GLclampf value = %f, GLboolean invert = %u)", value, invert);
2039
2040 Context* context = GetValidGlobalContext();
2041
2042 if (context)
2043 {
2044 context->sampleCoverage(value, invert);
2045 }
2046 }
2047
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)2048 void GL_APIENTRY Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
2049 {
2050 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
2051
2052 Context* context = GetValidGlobalContext();
2053 if (context)
2054 {
2055 if (width < 0 || height < 0)
2056 {
2057 context->handleError(Error(GL_INVALID_VALUE));
2058 return;
2059 }
2060
2061 context->scissor(x, y, width, height);
2062 }
2063 }
2064
ShaderBinary(GLsizei n,const GLuint * shaders,GLenum binaryformat,const GLvoid * binary,GLsizei length)2065 void GL_APIENTRY ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
2066 {
2067 EVENT("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
2068 "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
2069 n, shaders, binaryformat, binary, length);
2070
2071 Context* context = GetValidGlobalContext();
2072 if (context)
2073 {
2074 const std::vector<GLenum> &shaderBinaryFormats = context->getCaps().shaderBinaryFormats;
2075 if (std::find(shaderBinaryFormats.begin(), shaderBinaryFormats.end(), binaryformat) == shaderBinaryFormats.end())
2076 {
2077 context->handleError(Error(GL_INVALID_ENUM));
2078 return;
2079 }
2080
2081 // No binary shader formats are supported.
2082 UNIMPLEMENTED();
2083 }
2084 }
2085
ShaderSource(GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)2086 void GL_APIENTRY ShaderSource(GLuint shader, GLsizei count, const GLchar* const* string, const GLint* length)
2087 {
2088 EVENT("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
2089 shader, count, string, length);
2090
2091 Context *context = GetValidGlobalContext();
2092 if (context)
2093 {
2094 if (count < 0)
2095 {
2096 context->handleError(Error(GL_INVALID_VALUE));
2097 return;
2098 }
2099
2100 Shader *shaderObject = GetValidShader(context, shader);
2101 if (!shaderObject)
2102 {
2103 return;
2104 }
2105 shaderObject->setSource(count, string, length);
2106 }
2107 }
2108
StencilFunc(GLenum func,GLint ref,GLuint mask)2109 void GL_APIENTRY StencilFunc(GLenum func, GLint ref, GLuint mask)
2110 {
2111 StencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
2112 }
2113
StencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)2114 void GL_APIENTRY StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
2115 {
2116 EVENT("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
2117
2118 Context *context = GetValidGlobalContext();
2119 if (context)
2120 {
2121 switch (face)
2122 {
2123 case GL_FRONT:
2124 case GL_BACK:
2125 case GL_FRONT_AND_BACK:
2126 break;
2127
2128 default:
2129 context->handleError(Error(GL_INVALID_ENUM));
2130 return;
2131 }
2132
2133 switch (func)
2134 {
2135 case GL_NEVER:
2136 case GL_ALWAYS:
2137 case GL_LESS:
2138 case GL_LEQUAL:
2139 case GL_EQUAL:
2140 case GL_GEQUAL:
2141 case GL_GREATER:
2142 case GL_NOTEQUAL:
2143 break;
2144
2145 default:
2146 context->handleError(Error(GL_INVALID_ENUM));
2147 return;
2148 }
2149
2150 context->stencilFuncSeparate(face, func, ref, mask);
2151 }
2152 }
2153
StencilMask(GLuint mask)2154 void GL_APIENTRY StencilMask(GLuint mask)
2155 {
2156 StencilMaskSeparate(GL_FRONT_AND_BACK, mask);
2157 }
2158
StencilMaskSeparate(GLenum face,GLuint mask)2159 void GL_APIENTRY StencilMaskSeparate(GLenum face, GLuint mask)
2160 {
2161 EVENT("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
2162
2163 Context *context = GetValidGlobalContext();
2164 if (context)
2165 {
2166 switch (face)
2167 {
2168 case GL_FRONT:
2169 case GL_BACK:
2170 case GL_FRONT_AND_BACK:
2171 break;
2172
2173 default:
2174 context->handleError(Error(GL_INVALID_ENUM));
2175 return;
2176 }
2177
2178 context->stencilMaskSeparate(face, mask);
2179 }
2180 }
2181
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)2182 void GL_APIENTRY StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
2183 {
2184 StencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
2185 }
2186
StencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)2187 void GL_APIENTRY StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
2188 {
2189 EVENT("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
2190 face, fail, zfail, zpass);
2191
2192 Context *context = GetValidGlobalContext();
2193 if (context)
2194 {
2195 switch (face)
2196 {
2197 case GL_FRONT:
2198 case GL_BACK:
2199 case GL_FRONT_AND_BACK:
2200 break;
2201
2202 default:
2203 context->handleError(Error(GL_INVALID_ENUM));
2204 return;
2205 }
2206
2207 switch (fail)
2208 {
2209 case GL_ZERO:
2210 case GL_KEEP:
2211 case GL_REPLACE:
2212 case GL_INCR:
2213 case GL_DECR:
2214 case GL_INVERT:
2215 case GL_INCR_WRAP:
2216 case GL_DECR_WRAP:
2217 break;
2218
2219 default:
2220 context->handleError(Error(GL_INVALID_ENUM));
2221 return;
2222 }
2223
2224 switch (zfail)
2225 {
2226 case GL_ZERO:
2227 case GL_KEEP:
2228 case GL_REPLACE:
2229 case GL_INCR:
2230 case GL_DECR:
2231 case GL_INVERT:
2232 case GL_INCR_WRAP:
2233 case GL_DECR_WRAP:
2234 break;
2235
2236 default:
2237 context->handleError(Error(GL_INVALID_ENUM));
2238 return;
2239 }
2240
2241 switch (zpass)
2242 {
2243 case GL_ZERO:
2244 case GL_KEEP:
2245 case GL_REPLACE:
2246 case GL_INCR:
2247 case GL_DECR:
2248 case GL_INVERT:
2249 case GL_INCR_WRAP:
2250 case GL_DECR_WRAP:
2251 break;
2252
2253 default:
2254 context->handleError(Error(GL_INVALID_ENUM));
2255 return;
2256 }
2257
2258 context->stencilOpSeparate(face, fail, zfail, zpass);
2259 }
2260 }
2261
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)2262 void GL_APIENTRY TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
2263 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
2264 {
2265 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
2266 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = 0x%0.8p)",
2267 target, level, internalformat, width, height, border, format, type, pixels);
2268
2269 Context *context = GetValidGlobalContext();
2270 if (context)
2271 {
2272 if (!context->skipValidation() &&
2273 !ValidateTexImage2D(context, target, level, internalformat, width, height, border,
2274 format, type, pixels))
2275 {
2276 return;
2277 }
2278
2279 context->texImage2D(target, level, internalformat, width, height, border, format, type,
2280 pixels);
2281 }
2282 }
2283
TexParameterf(GLenum target,GLenum pname,GLfloat param)2284 void GL_APIENTRY TexParameterf(GLenum target, GLenum pname, GLfloat param)
2285 {
2286 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %f)", target, pname, param);
2287
2288 Context *context = GetValidGlobalContext();
2289 if (context)
2290 {
2291 if (!context->skipValidation() && !ValidateTexParameterf(context, target, pname, param))
2292 {
2293 return;
2294 }
2295
2296 Texture *texture = context->getTargetTexture(target);
2297 SetTexParameterf(texture, pname, param);
2298 }
2299 }
2300
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)2301 void GL_APIENTRY TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
2302 {
2303 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat* params = 0x%0.8p)", target,
2304 pname, params);
2305
2306 Context *context = GetValidGlobalContext();
2307 if (context)
2308 {
2309 if (!context->skipValidation() && !ValidateTexParameterfv(context, target, pname, params))
2310 {
2311 return;
2312 }
2313
2314 Texture *texture = context->getTargetTexture(target);
2315 SetTexParameterfv(texture, pname, params);
2316 }
2317 }
2318
TexParameteri(GLenum target,GLenum pname,GLint param)2319 void GL_APIENTRY TexParameteri(GLenum target, GLenum pname, GLint param)
2320 {
2321 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
2322
2323 Context *context = GetValidGlobalContext();
2324 if (context)
2325 {
2326 if (!context->skipValidation() && !ValidateTexParameteri(context, target, pname, param))
2327 {
2328 return;
2329 }
2330
2331 Texture *texture = context->getTargetTexture(target);
2332 SetTexParameteri(texture, pname, param);
2333 }
2334 }
2335
TexParameteriv(GLenum target,GLenum pname,const GLint * params)2336 void GL_APIENTRY TexParameteriv(GLenum target, GLenum pname, const GLint *params)
2337 {
2338 EVENT("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLint* params = 0x%0.8p)", target,
2339 pname, params);
2340
2341 Context *context = GetValidGlobalContext();
2342 if (context)
2343 {
2344 if (!context->skipValidation() && !ValidateTexParameteriv(context, target, pname, params))
2345 {
2346 return;
2347 }
2348
2349 Texture *texture = context->getTargetTexture(target);
2350 SetTexParameteriv(texture, pname, params);
2351 }
2352 }
2353
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)2354 void GL_APIENTRY TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
2355 GLenum format, GLenum type, const GLvoid* pixels)
2356 {
2357 EVENT("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
2358 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
2359 "const GLvoid* pixels = 0x%0.8p)",
2360 target, level, xoffset, yoffset, width, height, format, type, pixels);
2361
2362 Context *context = GetValidGlobalContext();
2363 if (context)
2364 {
2365 if (!context->skipValidation() &&
2366 !ValidateTexSubImage2D(context, target, level, xoffset, yoffset, width, height, format,
2367 type, pixels))
2368 {
2369 return;
2370 }
2371
2372 context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type,
2373 pixels);
2374 }
2375 }
2376
Uniform1f(GLint location,GLfloat x)2377 void GL_APIENTRY Uniform1f(GLint location, GLfloat x)
2378 {
2379 Uniform1fv(location, 1, &x);
2380 }
2381
Uniform1fv(GLint location,GLsizei count,const GLfloat * v)2382 void GL_APIENTRY Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
2383 {
2384 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
2385
2386 Context *context = GetValidGlobalContext();
2387 if (context)
2388 {
2389 if (!ValidateUniform(context, GL_FLOAT, location, count))
2390 {
2391 return;
2392 }
2393
2394 Program *program = context->getGLState().getProgram();
2395 program->setUniform1fv(location, count, v);
2396 }
2397 }
2398
Uniform1i(GLint location,GLint x)2399 void GL_APIENTRY Uniform1i(GLint location, GLint x)
2400 {
2401 Uniform1iv(location, 1, &x);
2402 }
2403
Uniform1iv(GLint location,GLsizei count,const GLint * v)2404 void GL_APIENTRY Uniform1iv(GLint location, GLsizei count, const GLint* v)
2405 {
2406 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
2407
2408 Context *context = GetValidGlobalContext();
2409 if (context)
2410 {
2411 if (!ValidateUniform(context, GL_INT, location, count))
2412 {
2413 return;
2414 }
2415
2416 Program *program = context->getGLState().getProgram();
2417 program->setUniform1iv(location, count, v);
2418 }
2419 }
2420
Uniform2f(GLint location,GLfloat x,GLfloat y)2421 void GL_APIENTRY Uniform2f(GLint location, GLfloat x, GLfloat y)
2422 {
2423 GLfloat xy[2] = {x, y};
2424
2425 Uniform2fv(location, 1, xy);
2426 }
2427
Uniform2fv(GLint location,GLsizei count,const GLfloat * v)2428 void GL_APIENTRY Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
2429 {
2430 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
2431
2432 Context *context = GetValidGlobalContext();
2433 if (context)
2434 {
2435 if (!ValidateUniform(context, GL_FLOAT_VEC2, location, count))
2436 {
2437 return;
2438 }
2439
2440 Program *program = context->getGLState().getProgram();
2441 program->setUniform2fv(location, count, v);
2442 }
2443 }
2444
Uniform2i(GLint location,GLint x,GLint y)2445 void GL_APIENTRY Uniform2i(GLint location, GLint x, GLint y)
2446 {
2447 GLint xy[2] = {x, y};
2448
2449 Uniform2iv(location, 1, xy);
2450 }
2451
Uniform2iv(GLint location,GLsizei count,const GLint * v)2452 void GL_APIENTRY Uniform2iv(GLint location, GLsizei count, const GLint* v)
2453 {
2454 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
2455
2456 Context *context = GetValidGlobalContext();
2457 if (context)
2458 {
2459 if (!ValidateUniform(context, GL_INT_VEC2, location, count))
2460 {
2461 return;
2462 }
2463
2464 Program *program = context->getGLState().getProgram();
2465 program->setUniform2iv(location, count, v);
2466 }
2467 }
2468
Uniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)2469 void GL_APIENTRY Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
2470 {
2471 GLfloat xyz[3] = {x, y, z};
2472
2473 Uniform3fv(location, 1, xyz);
2474 }
2475
Uniform3fv(GLint location,GLsizei count,const GLfloat * v)2476 void GL_APIENTRY Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
2477 {
2478 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
2479
2480 Context *context = GetValidGlobalContext();
2481 if (context)
2482 {
2483 if (!ValidateUniform(context, GL_FLOAT_VEC3, location, count))
2484 {
2485 return;
2486 }
2487
2488 Program *program = context->getGLState().getProgram();
2489 program->setUniform3fv(location, count, v);
2490 }
2491 }
2492
Uniform3i(GLint location,GLint x,GLint y,GLint z)2493 void GL_APIENTRY Uniform3i(GLint location, GLint x, GLint y, GLint z)
2494 {
2495 GLint xyz[3] = {x, y, z};
2496
2497 Uniform3iv(location, 1, xyz);
2498 }
2499
Uniform3iv(GLint location,GLsizei count,const GLint * v)2500 void GL_APIENTRY Uniform3iv(GLint location, GLsizei count, const GLint* v)
2501 {
2502 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
2503
2504 Context *context = GetValidGlobalContext();
2505 if (context)
2506 {
2507 if (!ValidateUniform(context, GL_INT_VEC3, location, count))
2508 {
2509 return;
2510 }
2511
2512 Program *program = context->getGLState().getProgram();
2513 program->setUniform3iv(location, count, v);
2514 }
2515 }
2516
Uniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)2517 void GL_APIENTRY Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2518 {
2519 GLfloat xyzw[4] = {x, y, z, w};
2520
2521 Uniform4fv(location, 1, xyzw);
2522 }
2523
Uniform4fv(GLint location,GLsizei count,const GLfloat * v)2524 void GL_APIENTRY Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
2525 {
2526 EVENT("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
2527
2528 Context *context = GetValidGlobalContext();
2529 if (context)
2530 {
2531 if (!ValidateUniform(context, GL_FLOAT_VEC4, location, count))
2532 {
2533 return;
2534 }
2535
2536 Program *program = context->getGLState().getProgram();
2537 program->setUniform4fv(location, count, v);
2538 }
2539 }
2540
Uniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)2541 void GL_APIENTRY Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
2542 {
2543 GLint xyzw[4] = {x, y, z, w};
2544
2545 Uniform4iv(location, 1, xyzw);
2546 }
2547
Uniform4iv(GLint location,GLsizei count,const GLint * v)2548 void GL_APIENTRY Uniform4iv(GLint location, GLsizei count, const GLint* v)
2549 {
2550 EVENT("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
2551
2552 Context *context = GetValidGlobalContext();
2553 if (context)
2554 {
2555 if (!ValidateUniform(context, GL_INT_VEC4, location, count))
2556 {
2557 return;
2558 }
2559
2560 Program *program = context->getGLState().getProgram();
2561 program->setUniform4iv(location, count, v);
2562 }
2563 }
2564
UniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2565 void GL_APIENTRY UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2566 {
2567 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
2568 location, count, transpose, value);
2569
2570 Context *context = GetValidGlobalContext();
2571 if (context)
2572 {
2573 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT2, location, count, transpose))
2574 {
2575 return;
2576 }
2577
2578 Program *program = context->getGLState().getProgram();
2579 program->setUniformMatrix2fv(location, count, transpose, value);
2580 }
2581 }
2582
UniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2583 void GL_APIENTRY UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2584 {
2585 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
2586 location, count, transpose, value);
2587
2588 Context *context = GetValidGlobalContext();
2589 if (context)
2590 {
2591 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT3, location, count, transpose))
2592 {
2593 return;
2594 }
2595
2596 Program *program = context->getGLState().getProgram();
2597 program->setUniformMatrix3fv(location, count, transpose, value);
2598 }
2599 }
2600
UniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)2601 void GL_APIENTRY UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
2602 {
2603 EVENT("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %u, const GLfloat* value = 0x%0.8p)",
2604 location, count, transpose, value);
2605
2606 Context *context = GetValidGlobalContext();
2607 if (context)
2608 {
2609 if (!ValidateUniformMatrix(context, GL_FLOAT_MAT4, location, count, transpose))
2610 {
2611 return;
2612 }
2613
2614 Program *program = context->getGLState().getProgram();
2615 program->setUniformMatrix4fv(location, count, transpose, value);
2616 }
2617 }
2618
UseProgram(GLuint program)2619 void GL_APIENTRY UseProgram(GLuint program)
2620 {
2621 EVENT("(GLuint program = %d)", program);
2622
2623 Context *context = GetValidGlobalContext();
2624 if (context)
2625 {
2626 if (!context->skipValidation() && !ValidateUseProgram(context, program))
2627 {
2628 return;
2629 }
2630
2631 context->useProgram(program);
2632 }
2633 }
2634
ValidateProgram(GLuint program)2635 void GL_APIENTRY ValidateProgram(GLuint program)
2636 {
2637 EVENT("(GLuint program = %d)", program);
2638
2639 Context *context = GetValidGlobalContext();
2640 if (context)
2641 {
2642 Program *programObject = GetValidProgram(context, program);
2643
2644 if (!programObject)
2645 {
2646 return;
2647 }
2648
2649 programObject->validate(context->getCaps());
2650 }
2651 }
2652
VertexAttrib1f(GLuint index,GLfloat x)2653 void GL_APIENTRY VertexAttrib1f(GLuint index, GLfloat x)
2654 {
2655 EVENT("(GLuint index = %d, GLfloat x = %f)", index, x);
2656
2657 Context *context = GetValidGlobalContext();
2658 if (context)
2659 {
2660 if (index >= MAX_VERTEX_ATTRIBS)
2661 {
2662 context->handleError(Error(GL_INVALID_VALUE));
2663 return;
2664 }
2665
2666 context->vertexAttrib1f(index, x);
2667 }
2668 }
2669
VertexAttrib1fv(GLuint index,const GLfloat * values)2670 void GL_APIENTRY VertexAttrib1fv(GLuint index, const GLfloat* values)
2671 {
2672 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
2673
2674 Context *context = GetValidGlobalContext();
2675 if (context)
2676 {
2677 if (index >= MAX_VERTEX_ATTRIBS)
2678 {
2679 context->handleError(Error(GL_INVALID_VALUE));
2680 return;
2681 }
2682
2683 context->vertexAttrib1fv(index, values);
2684 }
2685 }
2686
VertexAttrib2f(GLuint index,GLfloat x,GLfloat y)2687 void GL_APIENTRY VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
2688 {
2689 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
2690
2691 Context *context = GetValidGlobalContext();
2692 if (context)
2693 {
2694 if (index >= MAX_VERTEX_ATTRIBS)
2695 {
2696 context->handleError(Error(GL_INVALID_VALUE));
2697 return;
2698 }
2699
2700 context->vertexAttrib2f(index, x, y);
2701 }
2702 }
2703
VertexAttrib2fv(GLuint index,const GLfloat * values)2704 void GL_APIENTRY VertexAttrib2fv(GLuint index, const GLfloat* values)
2705 {
2706 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
2707
2708 Context *context = GetValidGlobalContext();
2709 if (context)
2710 {
2711 if (index >= MAX_VERTEX_ATTRIBS)
2712 {
2713 context->handleError(Error(GL_INVALID_VALUE));
2714 return;
2715 }
2716
2717 context->vertexAttrib2fv(index, values);
2718 }
2719 }
2720
VertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)2721 void GL_APIENTRY VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
2722 {
2723 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
2724
2725 Context *context = GetValidGlobalContext();
2726 if (context)
2727 {
2728 if (index >= MAX_VERTEX_ATTRIBS)
2729 {
2730 context->handleError(Error(GL_INVALID_VALUE));
2731 return;
2732 }
2733
2734 context->vertexAttrib3f(index, x, y, z);
2735 }
2736 }
2737
VertexAttrib3fv(GLuint index,const GLfloat * values)2738 void GL_APIENTRY VertexAttrib3fv(GLuint index, const GLfloat* values)
2739 {
2740 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
2741
2742 Context *context = GetValidGlobalContext();
2743 if (context)
2744 {
2745 if (index >= MAX_VERTEX_ATTRIBS)
2746 {
2747 context->handleError(Error(GL_INVALID_VALUE));
2748 return;
2749 }
2750
2751 context->vertexAttrib3fv(index, values);
2752 }
2753 }
2754
VertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)2755 void GL_APIENTRY VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
2756 {
2757 EVENT("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
2758
2759 Context *context = GetValidGlobalContext();
2760 if (context)
2761 {
2762 if (index >= MAX_VERTEX_ATTRIBS)
2763 {
2764 context->handleError(Error(GL_INVALID_VALUE));
2765 return;
2766 }
2767
2768 context->vertexAttrib4f(index, x, y, z, w);
2769 }
2770 }
2771
VertexAttrib4fv(GLuint index,const GLfloat * values)2772 void GL_APIENTRY VertexAttrib4fv(GLuint index, const GLfloat* values)
2773 {
2774 EVENT("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
2775
2776 Context *context = GetValidGlobalContext();
2777 if (context)
2778 {
2779 if (index >= MAX_VERTEX_ATTRIBS)
2780 {
2781 context->handleError(Error(GL_INVALID_VALUE));
2782 return;
2783 }
2784
2785 context->vertexAttrib4fv(index, values);
2786 }
2787 }
2788
VertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)2789 void GL_APIENTRY VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
2790 {
2791 EVENT("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
2792 "GLboolean normalized = %u, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
2793 index, size, type, normalized, stride, ptr);
2794
2795 Context *context = GetValidGlobalContext();
2796 if (context)
2797 {
2798 if (index >= MAX_VERTEX_ATTRIBS)
2799 {
2800 context->handleError(Error(GL_INVALID_VALUE));
2801 return;
2802 }
2803
2804 if (size < 1 || size > 4)
2805 {
2806 context->handleError(Error(GL_INVALID_VALUE));
2807 return;
2808 }
2809
2810 switch (type)
2811 {
2812 case GL_BYTE:
2813 case GL_UNSIGNED_BYTE:
2814 case GL_SHORT:
2815 case GL_UNSIGNED_SHORT:
2816 case GL_FIXED:
2817 case GL_FLOAT:
2818 break;
2819
2820 case GL_HALF_FLOAT:
2821 case GL_INT:
2822 case GL_UNSIGNED_INT:
2823 case GL_INT_2_10_10_10_REV:
2824 case GL_UNSIGNED_INT_2_10_10_10_REV:
2825 if (context->getClientMajorVersion() < 3)
2826 {
2827 context->handleError(Error(GL_INVALID_ENUM));
2828 return;
2829 }
2830 break;
2831
2832 default:
2833 context->handleError(Error(GL_INVALID_ENUM));
2834 return;
2835 }
2836
2837 if (stride < 0)
2838 {
2839 context->handleError(Error(GL_INVALID_VALUE));
2840 return;
2841 }
2842
2843 if ((type == GL_INT_2_10_10_10_REV || type == GL_UNSIGNED_INT_2_10_10_10_REV) && size != 4)
2844 {
2845 context->handleError(Error(GL_INVALID_OPERATION));
2846 return;
2847 }
2848
2849 // [OpenGL ES 3.0.2] Section 2.8 page 24:
2850 // An INVALID_OPERATION error is generated when a non-zero vertex array object
2851 // is bound, zero is bound to the ARRAY_BUFFER buffer object binding point,
2852 // and the pointer argument is not NULL.
2853 if (context->getGLState().getVertexArray()->id() != 0 &&
2854 context->getGLState().getArrayBufferId() == 0 && ptr != NULL)
2855 {
2856 context->handleError(Error(GL_INVALID_OPERATION));
2857 return;
2858 }
2859
2860 context->vertexAttribPointer(index, size, type, normalized, stride, ptr);
2861 }
2862 }
2863
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)2864 void GL_APIENTRY Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
2865 {
2866 EVENT("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
2867
2868 Context *context = GetValidGlobalContext();
2869 if (context)
2870 {
2871 if (width < 0 || height < 0)
2872 {
2873 context->handleError(Error(GL_INVALID_VALUE));
2874 return;
2875 }
2876
2877 context->viewport(x, y, width, height);
2878 }
2879 }
2880
2881 } // namespace gl
2882