• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (c) 2002-2010 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 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.
8 
9 #define GL_APICALL
10 #include <GLES2/gl2.h>
11 #include <GLES2/gl2ext.h>
12 
13 #include <exception>
14 #include <limits>
15 
16 #include "common/debug.h"
17 
18 #include "libGLESv2/main.h"
19 #include "libGLESv2/mathutil.h"
20 #include "libGLESv2/utilities.h"
21 #include "libGLESv2/Buffer.h"
22 #include "libGLESv2/Context.h"
23 #include "libGLESv2/Fence.h"
24 #include "libGLESv2/Framebuffer.h"
25 #include "libGLESv2/Program.h"
26 #include "libGLESv2/Renderbuffer.h"
27 #include "libGLESv2/Shader.h"
28 #include "libGLESv2/Texture.h"
29 
30 extern "C"
31 {
32 
glActiveTexture(GLenum texture)33 void __stdcall glActiveTexture(GLenum texture)
34 {
35     TRACE("(GLenum texture = 0x%X)", texture);
36 
37     try
38     {
39         if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + gl::MAX_TEXTURE_IMAGE_UNITS - 1)
40         {
41             return error(GL_INVALID_ENUM);
42         }
43 
44         gl::Context *context = gl::getContext();
45 
46         if (context)
47         {
48             context->setActiveSampler(texture - GL_TEXTURE0);
49         }
50     }
51     catch(std::bad_alloc&)
52     {
53         return error(GL_OUT_OF_MEMORY);
54     }
55 }
56 
glAttachShader(GLuint program,GLuint shader)57 void __stdcall glAttachShader(GLuint program, GLuint shader)
58 {
59     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
60 
61     try
62     {
63         gl::Context *context = gl::getContext();
64 
65         if (context)
66         {
67             gl::Program *programObject = context->getProgram(program);
68             gl::Shader *shaderObject = context->getShader(shader);
69 
70             if (!programObject)
71             {
72                 if (context->getShader(program))
73                 {
74                     return error(GL_INVALID_OPERATION);
75                 }
76                 else
77                 {
78                     return error(GL_INVALID_VALUE);
79                 }
80             }
81 
82             if (!shaderObject)
83             {
84                 if (context->getProgram(shader))
85                 {
86                     return error(GL_INVALID_OPERATION);
87                 }
88                 else
89                 {
90                     return error(GL_INVALID_VALUE);
91                 }
92             }
93 
94             if (!programObject->attachShader(shaderObject))
95             {
96                 return error(GL_INVALID_OPERATION);
97             }
98         }
99     }
100     catch(std::bad_alloc&)
101     {
102         return error(GL_OUT_OF_MEMORY);
103     }
104 }
105 
glBindAttribLocation(GLuint program,GLuint index,const GLchar * name)106 void __stdcall glBindAttribLocation(GLuint program, GLuint index, const GLchar* name)
107 {
108     TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = 0x%0.8p)", program, index, name);
109 
110     try
111     {
112         if (index >= gl::MAX_VERTEX_ATTRIBS)
113         {
114             return error(GL_INVALID_VALUE);
115         }
116 
117         gl::Context *context = gl::getContext();
118 
119         if (context)
120         {
121             gl::Program *programObject = context->getProgram(program);
122 
123             if (!programObject)
124             {
125                 if (context->getShader(program))
126                 {
127                     return error(GL_INVALID_OPERATION);
128                 }
129                 else
130                 {
131                     return error(GL_INVALID_VALUE);
132                 }
133             }
134 
135             if (strncmp(name, "gl_", 3) == 0)
136             {
137                 return error(GL_INVALID_OPERATION);
138             }
139 
140             programObject->bindAttributeLocation(index, name);
141         }
142     }
143     catch(std::bad_alloc&)
144     {
145         return error(GL_OUT_OF_MEMORY);
146     }
147 }
148 
glBindBuffer(GLenum target,GLuint buffer)149 void __stdcall glBindBuffer(GLenum target, GLuint buffer)
150 {
151     TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
152 
153     try
154     {
155         gl::Context *context = gl::getContext();
156 
157         if (context)
158         {
159             switch (target)
160             {
161               case GL_ARRAY_BUFFER:
162                 context->bindArrayBuffer(buffer);
163                 return;
164               case GL_ELEMENT_ARRAY_BUFFER:
165                 context->bindElementArrayBuffer(buffer);
166                 return;
167               default:
168                 return error(GL_INVALID_ENUM);
169             }
170         }
171     }
172     catch(std::bad_alloc&)
173     {
174         return error(GL_OUT_OF_MEMORY);
175     }
176 }
177 
glBindFramebuffer(GLenum target,GLuint framebuffer)178 void __stdcall glBindFramebuffer(GLenum target, GLuint framebuffer)
179 {
180     TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
181 
182     try
183     {
184         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
185         {
186             return error(GL_INVALID_ENUM);
187         }
188 
189         gl::Context *context = gl::getContext();
190 
191         if (context)
192         {
193             if (target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
194             {
195                 context->bindReadFramebuffer(framebuffer);
196             }
197 
198             if (target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)
199             {
200                 context->bindDrawFramebuffer(framebuffer);
201             }
202         }
203     }
204     catch(std::bad_alloc&)
205     {
206         return error(GL_OUT_OF_MEMORY);
207     }
208 }
209 
glBindRenderbuffer(GLenum target,GLuint renderbuffer)210 void __stdcall glBindRenderbuffer(GLenum target, GLuint renderbuffer)
211 {
212     TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
213 
214     try
215     {
216         if (target != GL_RENDERBUFFER)
217         {
218             return error(GL_INVALID_ENUM);
219         }
220 
221         gl::Context *context = gl::getContext();
222 
223         if (context)
224         {
225             context->bindRenderbuffer(renderbuffer);
226         }
227     }
228     catch(std::bad_alloc&)
229     {
230         return error(GL_OUT_OF_MEMORY);
231     }
232 }
233 
glBindTexture(GLenum target,GLuint texture)234 void __stdcall glBindTexture(GLenum target, GLuint texture)
235 {
236     TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
237 
238     try
239     {
240         gl::Context *context = gl::getContext();
241 
242         if (context)
243         {
244             gl::Texture *textureObject = context->getTexture(texture);
245 
246             if (textureObject && textureObject->getTarget() != target && texture != 0)
247             {
248                 return error(GL_INVALID_OPERATION);
249             }
250 
251             switch (target)
252             {
253               case GL_TEXTURE_2D:
254                 context->bindTexture2D(texture);
255                 return;
256               case GL_TEXTURE_CUBE_MAP:
257                 context->bindTextureCubeMap(texture);
258                 return;
259               default:
260                 return error(GL_INVALID_ENUM);
261             }
262         }
263     }
264     catch(std::bad_alloc&)
265     {
266         return error(GL_OUT_OF_MEMORY);
267     }
268 }
269 
glBlendColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)270 void __stdcall glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
271 {
272     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
273           red, green, blue, alpha);
274 
275     try
276     {
277         gl::Context* context = gl::getContext();
278 
279         if (context)
280         {
281             context->setBlendColor(gl::clamp01(red), gl::clamp01(green), gl::clamp01(blue), gl::clamp01(alpha));
282         }
283     }
284     catch(std::bad_alloc&)
285     {
286         return error(GL_OUT_OF_MEMORY);
287     }
288 }
289 
glBlendEquation(GLenum mode)290 void __stdcall glBlendEquation(GLenum mode)
291 {
292     glBlendEquationSeparate(mode, mode);
293 }
294 
glBlendEquationSeparate(GLenum modeRGB,GLenum modeAlpha)295 void __stdcall glBlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
296 {
297     TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
298 
299     try
300     {
301         switch (modeRGB)
302         {
303           case GL_FUNC_ADD:
304           case GL_FUNC_SUBTRACT:
305           case GL_FUNC_REVERSE_SUBTRACT:
306             break;
307           default:
308             return error(GL_INVALID_ENUM);
309         }
310 
311         switch (modeAlpha)
312         {
313           case GL_FUNC_ADD:
314           case GL_FUNC_SUBTRACT:
315           case GL_FUNC_REVERSE_SUBTRACT:
316             break;
317           default:
318             return error(GL_INVALID_ENUM);
319         }
320 
321         gl::Context *context = gl::getContext();
322 
323         if (context)
324         {
325             context->setBlendEquation(modeRGB, modeAlpha);
326         }
327     }
328     catch(std::bad_alloc&)
329     {
330         return error(GL_OUT_OF_MEMORY);
331     }
332 }
333 
glBlendFunc(GLenum sfactor,GLenum dfactor)334 void __stdcall glBlendFunc(GLenum sfactor, GLenum dfactor)
335 {
336     glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);
337 }
338 
glBlendFuncSeparate(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)339 void __stdcall glBlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
340 {
341     TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
342           srcRGB, dstRGB, srcAlpha, dstAlpha);
343 
344     try
345     {
346         switch (srcRGB)
347         {
348           case GL_ZERO:
349           case GL_ONE:
350           case GL_SRC_COLOR:
351           case GL_ONE_MINUS_SRC_COLOR:
352           case GL_DST_COLOR:
353           case GL_ONE_MINUS_DST_COLOR:
354           case GL_SRC_ALPHA:
355           case GL_ONE_MINUS_SRC_ALPHA:
356           case GL_DST_ALPHA:
357           case GL_ONE_MINUS_DST_ALPHA:
358           case GL_CONSTANT_COLOR:
359           case GL_ONE_MINUS_CONSTANT_COLOR:
360           case GL_CONSTANT_ALPHA:
361           case GL_ONE_MINUS_CONSTANT_ALPHA:
362           case GL_SRC_ALPHA_SATURATE:
363             break;
364           default:
365             return error(GL_INVALID_ENUM);
366         }
367 
368         switch (dstRGB)
369         {
370           case GL_ZERO:
371           case GL_ONE:
372           case GL_SRC_COLOR:
373           case GL_ONE_MINUS_SRC_COLOR:
374           case GL_DST_COLOR:
375           case GL_ONE_MINUS_DST_COLOR:
376           case GL_SRC_ALPHA:
377           case GL_ONE_MINUS_SRC_ALPHA:
378           case GL_DST_ALPHA:
379           case GL_ONE_MINUS_DST_ALPHA:
380           case GL_CONSTANT_COLOR:
381           case GL_ONE_MINUS_CONSTANT_COLOR:
382           case GL_CONSTANT_ALPHA:
383           case GL_ONE_MINUS_CONSTANT_ALPHA:
384             break;
385           default:
386             return error(GL_INVALID_ENUM);
387         }
388 
389         switch (srcAlpha)
390         {
391           case GL_ZERO:
392           case GL_ONE:
393           case GL_SRC_COLOR:
394           case GL_ONE_MINUS_SRC_COLOR:
395           case GL_DST_COLOR:
396           case GL_ONE_MINUS_DST_COLOR:
397           case GL_SRC_ALPHA:
398           case GL_ONE_MINUS_SRC_ALPHA:
399           case GL_DST_ALPHA:
400           case GL_ONE_MINUS_DST_ALPHA:
401           case GL_CONSTANT_COLOR:
402           case GL_ONE_MINUS_CONSTANT_COLOR:
403           case GL_CONSTANT_ALPHA:
404           case GL_ONE_MINUS_CONSTANT_ALPHA:
405           case GL_SRC_ALPHA_SATURATE:
406             break;
407           default:
408             return error(GL_INVALID_ENUM);
409         }
410 
411         switch (dstAlpha)
412         {
413           case GL_ZERO:
414           case GL_ONE:
415           case GL_SRC_COLOR:
416           case GL_ONE_MINUS_SRC_COLOR:
417           case GL_DST_COLOR:
418           case GL_ONE_MINUS_DST_COLOR:
419           case GL_SRC_ALPHA:
420           case GL_ONE_MINUS_SRC_ALPHA:
421           case GL_DST_ALPHA:
422           case GL_ONE_MINUS_DST_ALPHA:
423           case GL_CONSTANT_COLOR:
424           case GL_ONE_MINUS_CONSTANT_COLOR:
425           case GL_CONSTANT_ALPHA:
426           case GL_ONE_MINUS_CONSTANT_ALPHA:
427             break;
428           default:
429             return error(GL_INVALID_ENUM);
430         }
431 
432         bool constantColorUsed = (srcRGB == GL_CONSTANT_COLOR || srcRGB == GL_ONE_MINUS_CONSTANT_COLOR ||
433                                   dstRGB == GL_CONSTANT_COLOR || dstRGB == GL_ONE_MINUS_CONSTANT_COLOR);
434 
435         bool constantAlphaUsed = (srcRGB == GL_CONSTANT_ALPHA || srcRGB == GL_ONE_MINUS_CONSTANT_ALPHA ||
436                                   dstRGB == GL_CONSTANT_ALPHA || dstRGB == GL_ONE_MINUS_CONSTANT_ALPHA);
437 
438         if (constantColorUsed && constantAlphaUsed)
439         {
440             ERR("Simultaneous use of GL_CONSTANT_ALPHA/GL_ONE_MINUS_CONSTANT_ALPHA and GL_CONSTANT_COLOR/GL_ONE_MINUS_CONSTANT_COLOR invalid under WebGL");
441             return error(GL_INVALID_OPERATION);
442         }
443 
444         gl::Context *context = gl::getContext();
445 
446         if (context)
447         {
448             context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
449         }
450     }
451     catch(std::bad_alloc&)
452     {
453         return error(GL_OUT_OF_MEMORY);
454     }
455 }
456 
glBufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)457 void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
458 {
459     TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p, GLenum usage = %d)",
460           target, size, data, usage);
461 
462     try
463     {
464         if (size < 0)
465         {
466             return error(GL_INVALID_VALUE);
467         }
468 
469         switch (usage)
470         {
471           case GL_STREAM_DRAW:
472           case GL_STATIC_DRAW:
473           case GL_DYNAMIC_DRAW:
474             break;
475           default:
476             return error(GL_INVALID_ENUM);
477         }
478 
479         gl::Context *context = gl::getContext();
480 
481         if (context)
482         {
483             gl::Buffer *buffer;
484 
485             switch (target)
486             {
487               case GL_ARRAY_BUFFER:
488                 buffer = context->getArrayBuffer();
489                 break;
490               case GL_ELEMENT_ARRAY_BUFFER:
491                 buffer = context->getElementArrayBuffer();
492                 break;
493               default:
494                 return error(GL_INVALID_ENUM);
495             }
496 
497             if (!buffer)
498             {
499                 return error(GL_INVALID_OPERATION);
500             }
501 
502             buffer->bufferData(data, size, usage);
503         }
504     }
505     catch(std::bad_alloc&)
506     {
507         return error(GL_OUT_OF_MEMORY);
508     }
509 }
510 
glBufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)511 void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
512 {
513     TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = 0x%0.8p)",
514           target, offset, size, data);
515 
516     try
517     {
518         if (size < 0 || offset < 0)
519         {
520             return error(GL_INVALID_VALUE);
521         }
522 
523         if (data == NULL)
524         {
525             return;
526         }
527 
528         gl::Context *context = gl::getContext();
529 
530         if (context)
531         {
532             gl::Buffer *buffer;
533 
534             switch (target)
535             {
536               case GL_ARRAY_BUFFER:
537                 buffer = context->getArrayBuffer();
538                 break;
539               case GL_ELEMENT_ARRAY_BUFFER:
540                 buffer = context->getElementArrayBuffer();
541                 break;
542               default:
543                 return error(GL_INVALID_ENUM);
544             }
545 
546             if (!buffer)
547             {
548                 return error(GL_INVALID_OPERATION);
549             }
550 
551             if ((size_t)size + offset > buffer->size())
552             {
553                 return error(GL_INVALID_VALUE);
554             }
555 
556             buffer->bufferSubData(data, size, offset);
557         }
558     }
559     catch(std::bad_alloc&)
560     {
561         return error(GL_OUT_OF_MEMORY);
562     }
563 }
564 
glCheckFramebufferStatus(GLenum target)565 GLenum __stdcall glCheckFramebufferStatus(GLenum target)
566 {
567     TRACE("(GLenum target = 0x%X)", target);
568 
569     try
570     {
571         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
572         {
573             return error(GL_INVALID_ENUM, 0);
574         }
575 
576         gl::Context *context = gl::getContext();
577 
578         if (context)
579         {
580             gl::Framebuffer *framebuffer = NULL;
581             if (target == GL_READ_FRAMEBUFFER_ANGLE)
582             {
583                 framebuffer = context->getReadFramebuffer();
584             }
585             else
586             {
587                 framebuffer = context->getDrawFramebuffer();
588             }
589 
590             return framebuffer->completeness();
591         }
592     }
593     catch(std::bad_alloc&)
594     {
595         return error(GL_OUT_OF_MEMORY, 0);
596     }
597 
598     return 0;
599 }
600 
glClear(GLbitfield mask)601 void __stdcall glClear(GLbitfield mask)
602 {
603     TRACE("(GLbitfield mask = %X)", mask);
604 
605     try
606     {
607         gl::Context *context = gl::getContext();
608 
609         if (context)
610         {
611             context->clear(mask);
612         }
613     }
614     catch(std::bad_alloc&)
615     {
616         return error(GL_OUT_OF_MEMORY);
617     }
618 }
619 
glClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)620 void __stdcall glClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
621 {
622     TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
623           red, green, blue, alpha);
624 
625     try
626     {
627         gl::Context *context = gl::getContext();
628 
629         if (context)
630         {
631             context->setClearColor(red, green, blue, alpha);
632         }
633     }
634     catch(std::bad_alloc&)
635     {
636         return error(GL_OUT_OF_MEMORY);
637     }
638 }
639 
glClearDepthf(GLclampf depth)640 void __stdcall glClearDepthf(GLclampf depth)
641 {
642     TRACE("(GLclampf depth = %f)", depth);
643 
644     try
645     {
646         gl::Context *context = gl::getContext();
647 
648         if (context)
649         {
650             context->setClearDepth(depth);
651         }
652     }
653     catch(std::bad_alloc&)
654     {
655         return error(GL_OUT_OF_MEMORY);
656     }
657 }
658 
glClearStencil(GLint s)659 void __stdcall glClearStencil(GLint s)
660 {
661     TRACE("(GLint s = %d)", s);
662 
663     try
664     {
665         gl::Context *context = gl::getContext();
666 
667         if (context)
668         {
669             context->setClearStencil(s);
670         }
671     }
672     catch(std::bad_alloc&)
673     {
674         return error(GL_OUT_OF_MEMORY);
675     }
676 }
677 
glColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)678 void __stdcall glColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
679 {
680     TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
681           red, green, blue, alpha);
682 
683     try
684     {
685         gl::Context *context = gl::getContext();
686 
687         if (context)
688         {
689             context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
690         }
691     }
692     catch(std::bad_alloc&)
693     {
694         return error(GL_OUT_OF_MEMORY);
695     }
696 }
697 
glCompileShader(GLuint shader)698 void __stdcall glCompileShader(GLuint shader)
699 {
700     TRACE("(GLuint shader = %d)", shader);
701 
702     try
703     {
704         gl::Context *context = gl::getContext();
705 
706         if (context)
707         {
708             gl::Shader *shaderObject = context->getShader(shader);
709 
710             if (!shaderObject)
711             {
712                 if (context->getProgram(shader))
713                 {
714                     return error(GL_INVALID_OPERATION);
715                 }
716                 else
717                 {
718                     return error(GL_INVALID_VALUE);
719                 }
720             }
721 
722             shaderObject->compile();
723         }
724     }
725     catch(std::bad_alloc&)
726     {
727         return error(GL_OUT_OF_MEMORY);
728     }
729 }
730 
glCompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)731 void __stdcall glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
732                                       GLint border, GLsizei imageSize, const GLvoid* data)
733 {
734     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
735           "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
736           target, level, internalformat, width, height, border, imageSize, data);
737 
738     try
739     {
740         if (level < 0)
741         {
742             return error(GL_INVALID_VALUE);
743         }
744 
745         if (width < 0 || height < 0 || (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || border != 0 || imageSize < 0)
746         {
747             return error(GL_INVALID_VALUE);
748         }
749 
750         switch (internalformat)
751         {
752           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
753           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
754             break;
755           default:
756             return error(GL_INVALID_ENUM);
757         }
758 
759         if (border != 0)
760         {
761             return error(GL_INVALID_VALUE);
762         }
763 
764         gl::Context *context = gl::getContext();
765 
766         if (context)
767         {
768             if (level > context->getMaximumTextureLevel())
769             {
770                 return error(GL_INVALID_VALUE);
771             }
772 
773             switch (target)
774             {
775               case GL_TEXTURE_2D:
776                 if (width > (context->getMaximumTextureDimension() >> level) ||
777                     height > (context->getMaximumTextureDimension() >> level))
778                 {
779                     return error(GL_INVALID_VALUE);
780                 }
781                 break;
782               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
783               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
784               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
785               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
786               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
787               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
788                 if (width != height)
789                 {
790                     return error(GL_INVALID_VALUE);
791                 }
792 
793                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
794                     height > (context->getMaximumCubeTextureDimension() >> level))
795                 {
796                     return error(GL_INVALID_VALUE);
797                 }
798                 break;
799               default:
800                 return error(GL_INVALID_ENUM);
801             }
802 
803             if (!context->supportsCompressedTextures())
804             {
805                 return error(GL_INVALID_ENUM); // in this case, it's as though the internal format switch failed
806             }
807 
808             if (imageSize != gl::ComputeCompressedSize(width, height, internalformat))
809             {
810                 return error(GL_INVALID_VALUE);
811             }
812 
813             if (target == GL_TEXTURE_2D)
814             {
815                 gl::Texture2D *texture = context->getTexture2D();
816 
817                 if (!texture)
818                 {
819                     return error(GL_INVALID_OPERATION);
820                 }
821 
822                 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
823             }
824             else
825             {
826                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
827 
828                 if (!texture)
829                 {
830                     return error(GL_INVALID_OPERATION);
831                 }
832 
833                 switch (target)
834                 {
835                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
836                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
837                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
838                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
839                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
840                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
841                     texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);
842                     break;
843                   default: UNREACHABLE();
844                 }
845             }
846         }
847 
848     }
849     catch(std::bad_alloc&)
850     {
851         return error(GL_OUT_OF_MEMORY);
852     }
853 }
854 
glCompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)855 void __stdcall glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
856                                          GLenum format, GLsizei imageSize, const GLvoid* data)
857 {
858     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
859           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
860           "GLsizei imageSize = %d, const GLvoid* data = 0x%0.8p)",
861           target, level, xoffset, yoffset, width, height, format, imageSize, data);
862 
863     try
864     {
865         if (!gl::IsTextureTarget(target))
866         {
867             return error(GL_INVALID_ENUM);
868         }
869 
870         if (level < 0)
871         {
872             return error(GL_INVALID_VALUE);
873         }
874 
875         if (xoffset < 0 || yoffset < 0 || width < 0 || height < 0 ||
876             (level > 0 && !gl::isPow2(width)) || (level > 0 && !gl::isPow2(height)) || imageSize < 0)
877         {
878             return error(GL_INVALID_VALUE);
879         }
880 
881         switch (format)
882         {
883           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
884           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
885             break;
886           default:
887             return error(GL_INVALID_ENUM);
888         }
889 
890         if (width == 0 || height == 0 || data == NULL)
891         {
892             return;
893         }
894 
895         gl::Context *context = gl::getContext();
896 
897         if (context)
898         {
899             if (level > context->getMaximumTextureLevel())
900             {
901                 return error(GL_INVALID_VALUE);
902             }
903 
904             if (!context->supportsCompressedTextures())
905             {
906                 return error(GL_INVALID_ENUM); // in this case, it's as though the format switch has failed.
907             }
908 
909             if (imageSize != gl::ComputeCompressedSize(width, height, format))
910             {
911                 return error(GL_INVALID_VALUE);
912             }
913 
914             if (xoffset % 4 != 0 || yoffset % 4 != 0)
915             {
916                 return error(GL_INVALID_OPERATION); // we wait to check the offsets until this point, because the multiple-of-four restriction
917                                                     // does not exist unless DXT1 textures are supported.
918             }
919 
920             if (target == GL_TEXTURE_2D)
921             {
922                 gl::Texture2D *texture = context->getTexture2D();
923 
924                 if (!texture)
925                 {
926                     return error(GL_INVALID_OPERATION);
927                 }
928 
929                 if (!texture->isCompressed())
930                 {
931                     return error(GL_INVALID_OPERATION);
932                 }
933 
934                 if ((width % 4 != 0 && width != texture->getWidth()) ||
935                     (height % 4 != 0 && height != texture->getHeight()))
936                 {
937                     return error(GL_INVALID_OPERATION);
938                 }
939 
940                 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
941             }
942             else if (gl::IsCubemapTextureTarget(target))
943             {
944                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
945 
946                 if (!texture)
947                 {
948                     return error(GL_INVALID_OPERATION);
949                 }
950 
951                 if (!texture->isCompressed())
952                 {
953                     return error(GL_INVALID_OPERATION);
954                 }
955 
956                 if ((width % 4 != 0 && width != texture->getWidth()) ||
957                     (height % 4 != 0 && height != texture->getHeight()))
958                 {
959                     return error(GL_INVALID_OPERATION);
960                 }
961 
962                 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, format, imageSize, data);
963             }
964             else
965             {
966                 UNREACHABLE();
967             }
968         }
969     }
970     catch(std::bad_alloc&)
971     {
972         return error(GL_OUT_OF_MEMORY);
973     }
974 }
975 
glCopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)976 void __stdcall glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
977 {
978     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
979           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
980           target, level, internalformat, x, y, width, height, border);
981 
982     try
983     {
984         if (level < 0 || width < 0 || height < 0)
985         {
986             return error(GL_INVALID_VALUE);
987         }
988 
989         if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
990         {
991             return error(GL_INVALID_VALUE);
992         }
993 
994         if (border != 0)
995         {
996             return error(GL_INVALID_VALUE);
997         }
998 
999         gl::Context *context = gl::getContext();
1000 
1001         if (context)
1002         {
1003             switch (target)
1004             {
1005               case GL_TEXTURE_2D:
1006                 if (width > (context->getMaximumTextureDimension() >> level) ||
1007                     height > (context->getMaximumTextureDimension() >> level))
1008                 {
1009                     return error(GL_INVALID_VALUE);
1010                 }
1011                 break;
1012               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
1013               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
1014               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
1015               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
1016               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
1017               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
1018                 if (width != height)
1019                 {
1020                     return error(GL_INVALID_VALUE);
1021                 }
1022 
1023                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
1024                     height > (context->getMaximumCubeTextureDimension() >> level))
1025                 {
1026                     return error(GL_INVALID_VALUE);
1027                 }
1028                 break;
1029               default:
1030                 return error(GL_INVALID_ENUM);
1031             }
1032 
1033             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
1034 
1035             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1036             {
1037                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1038             }
1039 
1040             if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1041             {
1042                 return error(GL_INVALID_OPERATION);
1043             }
1044 
1045             gl::Colorbuffer *source = framebuffer->getColorbuffer();
1046             GLenum colorbufferFormat = source->getFormat();
1047 
1048             // [OpenGL ES 2.0.24] table 3.9
1049             switch (internalformat)
1050             {
1051               case GL_ALPHA:
1052                 if (colorbufferFormat != GL_ALPHA &&
1053                     colorbufferFormat != GL_RGBA &&
1054                     colorbufferFormat != GL_RGBA4 &&
1055                     colorbufferFormat != GL_RGB5_A1 &&
1056                     colorbufferFormat != GL_RGBA8_OES)
1057                 {
1058                     return error(GL_INVALID_OPERATION);
1059                 }
1060                 break;
1061               case GL_LUMINANCE:
1062               case GL_RGB:
1063                 if (colorbufferFormat != GL_RGB &&
1064                     colorbufferFormat != GL_RGB565 &&
1065                     colorbufferFormat != GL_RGB8_OES &&
1066                     colorbufferFormat != GL_RGBA &&
1067                     colorbufferFormat != GL_RGBA4 &&
1068                     colorbufferFormat != GL_RGB5_A1 &&
1069                     colorbufferFormat != GL_RGBA8_OES)
1070                 {
1071                     return error(GL_INVALID_OPERATION);
1072                 }
1073                 break;
1074               case GL_LUMINANCE_ALPHA:
1075               case GL_RGBA:
1076                 if (colorbufferFormat != GL_RGBA &&
1077                     colorbufferFormat != GL_RGBA4 &&
1078                     colorbufferFormat != GL_RGB5_A1 &&
1079                     colorbufferFormat != GL_RGBA8_OES)
1080                  {
1081                      return error(GL_INVALID_OPERATION);
1082                  }
1083                  break;
1084               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1085               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1086                 if (context->supportsCompressedTextures())
1087                 {
1088                     return error(GL_INVALID_OPERATION);
1089                 }
1090                 else
1091                 {
1092                     return error(GL_INVALID_ENUM);
1093                 }
1094                 break;
1095               default:
1096                 return error(GL_INVALID_ENUM);
1097             }
1098 
1099             if (target == GL_TEXTURE_2D)
1100             {
1101                 gl::Texture2D *texture = context->getTexture2D();
1102 
1103                 if (!texture)
1104                 {
1105                     return error(GL_INVALID_OPERATION);
1106                 }
1107 
1108                 texture->copyImage(level, internalformat, x, y, width, height, source);
1109             }
1110             else if (gl::IsCubemapTextureTarget(target))
1111             {
1112                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
1113 
1114                 if (!texture)
1115                 {
1116                     return error(GL_INVALID_OPERATION);
1117                 }
1118 
1119                 texture->copyImage(target, level, internalformat, x, y, width, height, source);
1120             }
1121             else UNREACHABLE();
1122         }
1123     }
1124     catch(std::bad_alloc&)
1125     {
1126         return error(GL_OUT_OF_MEMORY);
1127     }
1128 }
1129 
glCopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)1130 void __stdcall glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
1131 {
1132     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
1133           "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
1134           target, level, xoffset, yoffset, x, y, width, height);
1135 
1136     try
1137     {
1138         if (!gl::IsTextureTarget(target))
1139         {
1140             return error(GL_INVALID_ENUM);
1141         }
1142 
1143         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
1144         {
1145             return error(GL_INVALID_VALUE);
1146         }
1147 
1148         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
1149         {
1150             return error(GL_INVALID_VALUE);
1151         }
1152 
1153         if (width == 0 || height == 0)
1154         {
1155             return;
1156         }
1157 
1158         gl::Context *context = gl::getContext();
1159 
1160         if (context)
1161         {
1162             if (level > context->getMaximumTextureLevel())
1163             {
1164                 return error(GL_INVALID_VALUE);
1165             }
1166 
1167             gl::Framebuffer *framebuffer = context->getReadFramebuffer();
1168 
1169             if (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
1170             {
1171                 return error(GL_INVALID_FRAMEBUFFER_OPERATION);
1172             }
1173 
1174             if (context->getReadFramebufferHandle() != 0 && framebuffer->getColorbuffer()->getSamples() != 0)
1175             {
1176                 return error(GL_INVALID_OPERATION);
1177             }
1178 
1179             gl::Colorbuffer *source = framebuffer->getColorbuffer();
1180             GLenum colorbufferFormat = source->getFormat();
1181             gl::Texture *texture = NULL;
1182 
1183             if (target == GL_TEXTURE_2D)
1184             {
1185                 texture = context->getTexture2D();
1186             }
1187             else if (gl::IsCubemapTextureTarget(target))
1188             {
1189                 texture = context->getTextureCubeMap();
1190             }
1191             else UNREACHABLE();
1192 
1193             if (!texture)
1194             {
1195                 return error(GL_INVALID_OPERATION);
1196             }
1197 
1198             GLenum textureFormat = texture->getFormat();
1199 
1200             // [OpenGL ES 2.0.24] table 3.9
1201             switch (textureFormat)
1202             {
1203               case GL_ALPHA:
1204                 if (colorbufferFormat != GL_ALPHA &&
1205                     colorbufferFormat != GL_RGBA &&
1206                     colorbufferFormat != GL_RGBA4 &&
1207                     colorbufferFormat != GL_RGB5_A1 &&
1208                     colorbufferFormat != GL_RGBA8_OES)
1209                 {
1210                     return error(GL_INVALID_OPERATION);
1211                 }
1212                 break;
1213               case GL_LUMINANCE:
1214               case GL_RGB:
1215                 if (colorbufferFormat != GL_RGB &&
1216                     colorbufferFormat != GL_RGB565 &&
1217                     colorbufferFormat != GL_RGB8_OES &&
1218                     colorbufferFormat != GL_RGBA &&
1219                     colorbufferFormat != GL_RGBA4 &&
1220                     colorbufferFormat != GL_RGB5_A1 &&
1221                     colorbufferFormat != GL_RGBA8_OES)
1222                 {
1223                     return error(GL_INVALID_OPERATION);
1224                 }
1225                 break;
1226               case GL_LUMINANCE_ALPHA:
1227               case GL_RGBA:
1228                 if (colorbufferFormat != GL_RGBA &&
1229                     colorbufferFormat != GL_RGBA4 &&
1230                     colorbufferFormat != GL_RGB5_A1 &&
1231                     colorbufferFormat != GL_RGBA8_OES)
1232                 {
1233                     return error(GL_INVALID_OPERATION);
1234                 }
1235                 break;
1236               case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
1237               case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
1238                 return error(GL_INVALID_OPERATION);
1239               default:
1240                 return error(GL_INVALID_OPERATION);
1241             }
1242 
1243             texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, source);
1244         }
1245     }
1246 
1247     catch(std::bad_alloc&)
1248     {
1249         return error(GL_OUT_OF_MEMORY);
1250     }
1251 }
1252 
glCreateProgram(void)1253 GLuint __stdcall glCreateProgram(void)
1254 {
1255     TRACE("()");
1256 
1257     try
1258     {
1259         gl::Context *context = gl::getContext();
1260 
1261         if (context)
1262         {
1263             return context->createProgram();
1264         }
1265     }
1266     catch(std::bad_alloc&)
1267     {
1268         return error(GL_OUT_OF_MEMORY, 0);
1269     }
1270 
1271     return 0;
1272 }
1273 
glCreateShader(GLenum type)1274 GLuint __stdcall glCreateShader(GLenum type)
1275 {
1276     TRACE("(GLenum type = 0x%X)", type);
1277 
1278     try
1279     {
1280         gl::Context *context = gl::getContext();
1281 
1282         if (context)
1283         {
1284             switch (type)
1285             {
1286               case GL_FRAGMENT_SHADER:
1287               case GL_VERTEX_SHADER:
1288                 return context->createShader(type);
1289               default:
1290                 return error(GL_INVALID_ENUM, 0);
1291             }
1292         }
1293     }
1294     catch(std::bad_alloc&)
1295     {
1296         return error(GL_OUT_OF_MEMORY, 0);
1297     }
1298 
1299     return 0;
1300 }
1301 
glCullFace(GLenum mode)1302 void __stdcall glCullFace(GLenum mode)
1303 {
1304     TRACE("(GLenum mode = 0x%X)", mode);
1305 
1306     try
1307     {
1308         switch (mode)
1309         {
1310           case GL_FRONT:
1311           case GL_BACK:
1312           case GL_FRONT_AND_BACK:
1313             {
1314                 gl::Context *context = gl::getContext();
1315 
1316                 if (context)
1317                 {
1318                     context->setCullMode(mode);
1319                 }
1320             }
1321             break;
1322           default:
1323             return error(GL_INVALID_ENUM);
1324         }
1325     }
1326     catch(std::bad_alloc&)
1327     {
1328         return error(GL_OUT_OF_MEMORY);
1329     }
1330 }
1331 
glDeleteBuffers(GLsizei n,const GLuint * buffers)1332 void __stdcall glDeleteBuffers(GLsizei n, const GLuint* buffers)
1333 {
1334     TRACE("(GLsizei n = %d, const GLuint* buffers = 0x%0.8p)", n, buffers);
1335 
1336     try
1337     {
1338         if (n < 0)
1339         {
1340             return error(GL_INVALID_VALUE);
1341         }
1342 
1343         gl::Context *context = gl::getContext();
1344 
1345         if (context)
1346         {
1347             for (int i = 0; i < n; i++)
1348             {
1349                 context->deleteBuffer(buffers[i]);
1350             }
1351         }
1352     }
1353     catch(std::bad_alloc&)
1354     {
1355         return error(GL_OUT_OF_MEMORY);
1356     }
1357 }
1358 
glDeleteFencesNV(GLsizei n,const GLuint * fences)1359 void __stdcall glDeleteFencesNV(GLsizei n, const GLuint* fences)
1360 {
1361     TRACE("(GLsizei n = %d, const GLuint* fences = 0x%0.8p)", n, fences);
1362 
1363     try
1364     {
1365         if (n < 0)
1366         {
1367             return error(GL_INVALID_VALUE);
1368         }
1369 
1370         gl::Context *context = gl::getContext();
1371 
1372         if (context)
1373         {
1374             for (int i = 0; i < n; i++)
1375             {
1376                 context->deleteFence(fences[i]);
1377             }
1378         }
1379     }
1380     catch(std::bad_alloc&)
1381     {
1382         return error(GL_OUT_OF_MEMORY);
1383     }
1384 }
1385 
glDeleteFramebuffers(GLsizei n,const GLuint * framebuffers)1386 void __stdcall glDeleteFramebuffers(GLsizei n, const GLuint* framebuffers)
1387 {
1388     TRACE("(GLsizei n = %d, const GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
1389 
1390     try
1391     {
1392         if (n < 0)
1393         {
1394             return error(GL_INVALID_VALUE);
1395         }
1396 
1397         gl::Context *context = gl::getContext();
1398 
1399         if (context)
1400         {
1401             for (int i = 0; i < n; i++)
1402             {
1403                 if (framebuffers[i] != 0)
1404                 {
1405                     context->deleteFramebuffer(framebuffers[i]);
1406                 }
1407             }
1408         }
1409     }
1410     catch(std::bad_alloc&)
1411     {
1412         return error(GL_OUT_OF_MEMORY);
1413     }
1414 }
1415 
glDeleteProgram(GLuint program)1416 void __stdcall glDeleteProgram(GLuint program)
1417 {
1418     TRACE("(GLuint program = %d)", program);
1419 
1420     try
1421     {
1422         if (program == 0)
1423         {
1424             return;
1425         }
1426 
1427         gl::Context *context = gl::getContext();
1428 
1429         if (context)
1430         {
1431             if (!context->getProgram(program))
1432             {
1433                 if(context->getShader(program))
1434                 {
1435                     return error(GL_INVALID_OPERATION);
1436                 }
1437                 else
1438                 {
1439                     return error(GL_INVALID_VALUE);
1440                 }
1441             }
1442 
1443             context->deleteProgram(program);
1444         }
1445     }
1446     catch(std::bad_alloc&)
1447     {
1448         return error(GL_OUT_OF_MEMORY);
1449     }
1450 }
1451 
glDeleteRenderbuffers(GLsizei n,const GLuint * renderbuffers)1452 void __stdcall glDeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)
1453 {
1454     TRACE("(GLsizei n = %d, const GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
1455 
1456     try
1457     {
1458         if (n < 0)
1459         {
1460             return error(GL_INVALID_VALUE);
1461         }
1462 
1463         gl::Context *context = gl::getContext();
1464 
1465         if (context)
1466         {
1467             for (int i = 0; i < n; i++)
1468             {
1469                 context->deleteRenderbuffer(renderbuffers[i]);
1470             }
1471         }
1472     }
1473     catch(std::bad_alloc&)
1474     {
1475         return error(GL_OUT_OF_MEMORY);
1476     }
1477 }
1478 
glDeleteShader(GLuint shader)1479 void __stdcall glDeleteShader(GLuint shader)
1480 {
1481     TRACE("(GLuint shader = %d)", shader);
1482 
1483     try
1484     {
1485         if (shader == 0)
1486         {
1487             return;
1488         }
1489 
1490         gl::Context *context = gl::getContext();
1491 
1492         if (context)
1493         {
1494             if (!context->getShader(shader))
1495             {
1496                 if(context->getProgram(shader))
1497                 {
1498                     return error(GL_INVALID_OPERATION);
1499                 }
1500                 else
1501                 {
1502                     return error(GL_INVALID_VALUE);
1503                 }
1504             }
1505 
1506             context->deleteShader(shader);
1507         }
1508     }
1509     catch(std::bad_alloc&)
1510     {
1511         return error(GL_OUT_OF_MEMORY);
1512     }
1513 }
1514 
glDeleteTextures(GLsizei n,const GLuint * textures)1515 void __stdcall glDeleteTextures(GLsizei n, const GLuint* textures)
1516 {
1517     TRACE("(GLsizei n = %d, const GLuint* textures = 0x%0.8p)", n, textures);
1518 
1519     try
1520     {
1521         if (n < 0)
1522         {
1523             return error(GL_INVALID_VALUE);
1524         }
1525 
1526         gl::Context *context = gl::getContext();
1527 
1528         if (context)
1529         {
1530             for (int i = 0; i < n; i++)
1531             {
1532                 if (textures[i] != 0)
1533                 {
1534                     context->deleteTexture(textures[i]);
1535                 }
1536             }
1537         }
1538     }
1539     catch(std::bad_alloc&)
1540     {
1541         return error(GL_OUT_OF_MEMORY);
1542     }
1543 }
1544 
glDepthFunc(GLenum func)1545 void __stdcall glDepthFunc(GLenum func)
1546 {
1547     TRACE("(GLenum func = 0x%X)", func);
1548 
1549     try
1550     {
1551         switch (func)
1552         {
1553           case GL_NEVER:
1554           case GL_ALWAYS:
1555           case GL_LESS:
1556           case GL_LEQUAL:
1557           case GL_EQUAL:
1558           case GL_GREATER:
1559           case GL_GEQUAL:
1560           case GL_NOTEQUAL:
1561             break;
1562           default:
1563             return error(GL_INVALID_ENUM);
1564         }
1565 
1566         gl::Context *context = gl::getContext();
1567 
1568         if (context)
1569         {
1570             context->setDepthFunc(func);
1571         }
1572     }
1573     catch(std::bad_alloc&)
1574     {
1575         return error(GL_OUT_OF_MEMORY);
1576     }
1577 }
1578 
glDepthMask(GLboolean flag)1579 void __stdcall glDepthMask(GLboolean flag)
1580 {
1581     TRACE("(GLboolean flag = %d)", flag);
1582 
1583     try
1584     {
1585         gl::Context *context = gl::getContext();
1586 
1587         if (context)
1588         {
1589             context->setDepthMask(flag != GL_FALSE);
1590         }
1591     }
1592     catch(std::bad_alloc&)
1593     {
1594         return error(GL_OUT_OF_MEMORY);
1595     }
1596 }
1597 
glDepthRangef(GLclampf zNear,GLclampf zFar)1598 void __stdcall glDepthRangef(GLclampf zNear, GLclampf zFar)
1599 {
1600     TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1601 
1602     try
1603     {
1604         gl::Context *context = gl::getContext();
1605 
1606         if (context)
1607         {
1608             context->setDepthRange(zNear, zFar);
1609         }
1610     }
1611     catch(std::bad_alloc&)
1612     {
1613         return error(GL_OUT_OF_MEMORY);
1614     }
1615 }
1616 
glDetachShader(GLuint program,GLuint shader)1617 void __stdcall glDetachShader(GLuint program, GLuint shader)
1618 {
1619     TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);
1620 
1621     try
1622     {
1623         gl::Context *context = gl::getContext();
1624 
1625         if (context)
1626         {
1627 
1628             gl::Program *programObject = context->getProgram(program);
1629             gl::Shader *shaderObject = context->getShader(shader);
1630 
1631             if (!programObject)
1632             {
1633                 gl::Shader *shaderByProgramHandle;
1634                 shaderByProgramHandle = context->getShader(program);
1635                 if (!shaderByProgramHandle)
1636                 {
1637                     return error(GL_INVALID_VALUE);
1638                 }
1639                 else
1640                 {
1641                     return error(GL_INVALID_OPERATION);
1642                 }
1643             }
1644 
1645             if (!shaderObject)
1646             {
1647                 gl::Program *programByShaderHandle = context->getProgram(shader);
1648                 if (!programByShaderHandle)
1649                 {
1650                     return error(GL_INVALID_VALUE);
1651                 }
1652                 else
1653                 {
1654                     return error(GL_INVALID_OPERATION);
1655                 }
1656             }
1657 
1658             if (!programObject->detachShader(shaderObject))
1659             {
1660                 return error(GL_INVALID_OPERATION);
1661             }
1662         }
1663     }
1664     catch(std::bad_alloc&)
1665     {
1666         return error(GL_OUT_OF_MEMORY);
1667     }
1668 }
1669 
glDisable(GLenum cap)1670 void __stdcall glDisable(GLenum cap)
1671 {
1672     TRACE("(GLenum cap = 0x%X)", cap);
1673 
1674     try
1675     {
1676         gl::Context *context = gl::getContext();
1677 
1678         if (context)
1679         {
1680             switch (cap)
1681             {
1682               case GL_CULL_FACE:                context->setCullFace(false);              break;
1683               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(false);     break;
1684               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(false); break;
1685               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(false);        break;
1686               case GL_SCISSOR_TEST:             context->setScissorTest(false);           break;
1687               case GL_STENCIL_TEST:             context->setStencilTest(false);           break;
1688               case GL_DEPTH_TEST:               context->setDepthTest(false);             break;
1689               case GL_BLEND:                    context->setBlend(false);                 break;
1690               case GL_DITHER:                   context->setDither(false);                break;
1691               default:
1692                 return error(GL_INVALID_ENUM);
1693             }
1694         }
1695     }
1696     catch(std::bad_alloc&)
1697     {
1698         return error(GL_OUT_OF_MEMORY);
1699     }
1700 }
1701 
glDisableVertexAttribArray(GLuint index)1702 void __stdcall glDisableVertexAttribArray(GLuint index)
1703 {
1704     TRACE("(GLuint index = %d)", index);
1705 
1706     try
1707     {
1708         if (index >= gl::MAX_VERTEX_ATTRIBS)
1709         {
1710             return error(GL_INVALID_VALUE);
1711         }
1712 
1713         gl::Context *context = gl::getContext();
1714 
1715         if (context)
1716         {
1717             context->setEnableVertexAttribArray(index, false);
1718         }
1719     }
1720     catch(std::bad_alloc&)
1721     {
1722         return error(GL_OUT_OF_MEMORY);
1723     }
1724 }
1725 
glDrawArrays(GLenum mode,GLint first,GLsizei count)1726 void __stdcall glDrawArrays(GLenum mode, GLint first, GLsizei count)
1727 {
1728     TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1729 
1730     try
1731     {
1732         if (count < 0 || first < 0)
1733         {
1734             return error(GL_INVALID_VALUE);
1735         }
1736 
1737         gl::Context *context = gl::getContext();
1738 
1739         if (context)
1740         {
1741             context->drawArrays(mode, first, count);
1742         }
1743     }
1744     catch(std::bad_alloc&)
1745     {
1746         return error(GL_OUT_OF_MEMORY);
1747     }
1748 }
1749 
glDrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1750 void __stdcall glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1751 {
1752     TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = 0x%0.8p)",
1753           mode, count, type, indices);
1754 
1755     try
1756     {
1757         if (count < 0)
1758         {
1759             return error(GL_INVALID_VALUE);
1760         }
1761 
1762         gl::Context *context = gl::getContext();
1763 
1764         if (context)
1765         {
1766             switch (type)
1767             {
1768               case GL_UNSIGNED_BYTE:
1769               case GL_UNSIGNED_SHORT:
1770                 break;
1771               case GL_UNSIGNED_INT:
1772                 if (!context->supports32bitIndices())
1773                 {
1774                     return error(GL_INVALID_ENUM);
1775                 }
1776                 break;
1777               default:
1778                 return error(GL_INVALID_ENUM);
1779             }
1780 
1781             context->drawElements(mode, count, type, indices);
1782         }
1783     }
1784     catch(std::bad_alloc&)
1785     {
1786         return error(GL_OUT_OF_MEMORY);
1787     }
1788 }
1789 
glEnable(GLenum cap)1790 void __stdcall glEnable(GLenum cap)
1791 {
1792     TRACE("(GLenum cap = 0x%X)", cap);
1793 
1794     try
1795     {
1796         gl::Context *context = gl::getContext();
1797 
1798         if (context)
1799         {
1800             switch (cap)
1801             {
1802               case GL_CULL_FACE:                context->setCullFace(true);              break;
1803               case GL_POLYGON_OFFSET_FILL:      context->setPolygonOffsetFill(true);     break;
1804               case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverage(true); break;
1805               case GL_SAMPLE_COVERAGE:          context->setSampleCoverage(true);        break;
1806               case GL_SCISSOR_TEST:             context->setScissorTest(true);           break;
1807               case GL_STENCIL_TEST:             context->setStencilTest(true);           break;
1808               case GL_DEPTH_TEST:               context->setDepthTest(true);             break;
1809               case GL_BLEND:                    context->setBlend(true);                 break;
1810               case GL_DITHER:                   context->setDither(true);                break;
1811               default:
1812                 return error(GL_INVALID_ENUM);
1813             }
1814         }
1815     }
1816     catch(std::bad_alloc&)
1817     {
1818         return error(GL_OUT_OF_MEMORY);
1819     }
1820 }
1821 
glEnableVertexAttribArray(GLuint index)1822 void __stdcall glEnableVertexAttribArray(GLuint index)
1823 {
1824     TRACE("(GLuint index = %d)", index);
1825 
1826     try
1827     {
1828         if (index >= gl::MAX_VERTEX_ATTRIBS)
1829         {
1830             return error(GL_INVALID_VALUE);
1831         }
1832 
1833         gl::Context *context = gl::getContext();
1834 
1835         if (context)
1836         {
1837             context->setEnableVertexAttribArray(index, true);
1838         }
1839     }
1840     catch(std::bad_alloc&)
1841     {
1842         return error(GL_OUT_OF_MEMORY);
1843     }
1844 }
1845 
glFinishFenceNV(GLuint fence)1846 void __stdcall glFinishFenceNV(GLuint fence)
1847 {
1848     TRACE("(GLuint fence = %d)", fence);
1849 
1850     try
1851     {
1852         gl::Context *context = gl::getContext();
1853 
1854         if (context)
1855         {
1856             gl::Fence* fenceObject = context->getFence(fence);
1857 
1858             if (fenceObject == NULL)
1859             {
1860                 return error(GL_INVALID_OPERATION);
1861             }
1862 
1863             fenceObject->finishFence();
1864         }
1865     }
1866     catch(std::bad_alloc&)
1867     {
1868         return error(GL_OUT_OF_MEMORY);
1869     }
1870 }
1871 
glFinish(void)1872 void __stdcall glFinish(void)
1873 {
1874     TRACE("()");
1875 
1876     try
1877     {
1878         gl::Context *context = gl::getContext();
1879 
1880         if (context)
1881         {
1882             context->finish();
1883         }
1884     }
1885     catch(std::bad_alloc&)
1886     {
1887         return error(GL_OUT_OF_MEMORY);
1888     }
1889 }
1890 
glFlush(void)1891 void __stdcall glFlush(void)
1892 {
1893     TRACE("()");
1894 
1895     try
1896     {
1897         gl::Context *context = gl::getContext();
1898 
1899         if (context)
1900         {
1901             context->flush();
1902         }
1903     }
1904     catch(std::bad_alloc&)
1905     {
1906         return error(GL_OUT_OF_MEMORY);
1907     }
1908 }
1909 
glFramebufferRenderbuffer(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)1910 void __stdcall glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1911 {
1912     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1913           "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1914 
1915     try
1916     {
1917         if ((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1918             || renderbuffertarget != GL_RENDERBUFFER)
1919         {
1920             return error(GL_INVALID_ENUM);
1921         }
1922 
1923         gl::Context *context = gl::getContext();
1924 
1925         if (context)
1926         {
1927             gl::Framebuffer *framebuffer = NULL;
1928             GLuint framebufferHandle = 0;
1929             if (target == GL_READ_FRAMEBUFFER_ANGLE)
1930             {
1931                 framebuffer = context->getReadFramebuffer();
1932                 framebufferHandle = context->getReadFramebufferHandle();
1933             }
1934             else
1935             {
1936                 framebuffer = context->getDrawFramebuffer();
1937                 framebufferHandle = context->getDrawFramebufferHandle();
1938             }
1939 
1940             if (framebufferHandle == 0 || !framebuffer)
1941             {
1942                 return error(GL_INVALID_OPERATION);
1943             }
1944 
1945             switch (attachment)
1946             {
1947               case GL_COLOR_ATTACHMENT0:
1948                 framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer);
1949                 break;
1950               case GL_DEPTH_ATTACHMENT:
1951                 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);
1952                 break;
1953               case GL_STENCIL_ATTACHMENT:
1954                 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);
1955                 break;
1956               default:
1957                 return error(GL_INVALID_ENUM);
1958             }
1959         }
1960     }
1961     catch(std::bad_alloc&)
1962     {
1963         return error(GL_OUT_OF_MEMORY);
1964     }
1965 }
1966 
glFramebufferTexture2D(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)1967 void __stdcall glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1968 {
1969     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1970           "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1971 
1972     try
1973     {
1974         if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
1975         {
1976             return error(GL_INVALID_ENUM);
1977         }
1978 
1979         switch (attachment)
1980         {
1981           case GL_COLOR_ATTACHMENT0:
1982           case GL_DEPTH_ATTACHMENT:
1983           case GL_STENCIL_ATTACHMENT:
1984             break;
1985           default:
1986             return error(GL_INVALID_ENUM);
1987         }
1988 
1989         gl::Context *context = gl::getContext();
1990 
1991         if (context)
1992         {
1993             if (texture == 0)
1994             {
1995                 textarget = GL_NONE;
1996             }
1997             else
1998             {
1999                 gl::Texture *tex = context->getTexture(texture);
2000 
2001                 if (tex == NULL)
2002                 {
2003                     return error(GL_INVALID_OPERATION);
2004                 }
2005 
2006                 if (tex->isCompressed())
2007                 {
2008                     return error(GL_INVALID_OPERATION);
2009                 }
2010 
2011                 switch (textarget)
2012                 {
2013                   case GL_TEXTURE_2D:
2014                     if (tex->getTarget() != GL_TEXTURE_2D)
2015                     {
2016                         return error(GL_INVALID_OPERATION);
2017                     }
2018                     break;
2019 
2020                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2021                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2022                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2023                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2024                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2025                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2026                     if (tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2027                     {
2028                         return error(GL_INVALID_OPERATION);
2029                     }
2030                     break;
2031 
2032                   default:
2033                     return error(GL_INVALID_ENUM);
2034                 }
2035 
2036                 if (level != 0)
2037                 {
2038                     return error(GL_INVALID_VALUE);
2039                 }
2040             }
2041 
2042             gl::Framebuffer *framebuffer = NULL;
2043             GLuint framebufferHandle = 0;
2044             if (target == GL_READ_FRAMEBUFFER_ANGLE)
2045             {
2046                 framebuffer = context->getReadFramebuffer();
2047                 framebufferHandle = context->getReadFramebufferHandle();
2048             }
2049             else
2050             {
2051                 framebuffer = context->getDrawFramebuffer();
2052                 framebufferHandle = context->getDrawFramebufferHandle();
2053             }
2054 
2055             if (framebufferHandle == 0 || !framebuffer)
2056             {
2057                 return error(GL_INVALID_OPERATION);
2058             }
2059 
2060             switch (attachment)
2061             {
2062               case GL_COLOR_ATTACHMENT0:  framebuffer->setColorbuffer(textarget, texture);   break;
2063               case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
2064               case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
2065             }
2066         }
2067     }
2068     catch(std::bad_alloc&)
2069     {
2070         return error(GL_OUT_OF_MEMORY);
2071     }
2072 }
2073 
glFrontFace(GLenum mode)2074 void __stdcall glFrontFace(GLenum mode)
2075 {
2076     TRACE("(GLenum mode = 0x%X)", mode);
2077 
2078     try
2079     {
2080         switch (mode)
2081         {
2082           case GL_CW:
2083           case GL_CCW:
2084             {
2085                 gl::Context *context = gl::getContext();
2086 
2087                 if (context)
2088                 {
2089                     context->setFrontFace(mode);
2090                 }
2091             }
2092             break;
2093           default:
2094             return error(GL_INVALID_ENUM);
2095         }
2096     }
2097     catch(std::bad_alloc&)
2098     {
2099         return error(GL_OUT_OF_MEMORY);
2100     }
2101 }
2102 
glGenBuffers(GLsizei n,GLuint * buffers)2103 void __stdcall glGenBuffers(GLsizei n, GLuint* buffers)
2104 {
2105     TRACE("(GLsizei n = %d, GLuint* buffers = 0x%0.8p)", n, buffers);
2106 
2107     try
2108     {
2109         if (n < 0)
2110         {
2111             return error(GL_INVALID_VALUE);
2112         }
2113 
2114         gl::Context *context = gl::getContext();
2115 
2116         if (context)
2117         {
2118             for (int i = 0; i < n; i++)
2119             {
2120                 buffers[i] = context->createBuffer();
2121             }
2122         }
2123     }
2124     catch(std::bad_alloc&)
2125     {
2126         return error(GL_OUT_OF_MEMORY);
2127     }
2128 }
2129 
glGenerateMipmap(GLenum target)2130 void __stdcall glGenerateMipmap(GLenum target)
2131 {
2132     TRACE("(GLenum target = 0x%X)", target);
2133 
2134     try
2135     {
2136         gl::Context *context = gl::getContext();
2137 
2138         if (context)
2139         {
2140             gl::Texture *texture;
2141 
2142             switch (target)
2143             {
2144               case GL_TEXTURE_2D:
2145                 texture = context->getTexture2D();
2146                 break;
2147 
2148               case GL_TEXTURE_CUBE_MAP:
2149                 texture = context->getTextureCubeMap();
2150                 break;
2151 
2152               default:
2153                 return error(GL_INVALID_ENUM);
2154             }
2155 
2156             if (texture->isCompressed())
2157             {
2158                 return error(GL_INVALID_OPERATION);
2159             }
2160 
2161             texture->generateMipmaps();
2162         }
2163     }
2164     catch(std::bad_alloc&)
2165     {
2166         return error(GL_OUT_OF_MEMORY);
2167     }
2168 }
2169 
glGenFencesNV(GLsizei n,GLuint * fences)2170 void __stdcall glGenFencesNV(GLsizei n, GLuint* fences)
2171 {
2172     TRACE("(GLsizei n = %d, GLuint* fences = 0x%0.8p)", n, fences);
2173 
2174     try
2175     {
2176         if (n < 0)
2177         {
2178             return error(GL_INVALID_VALUE);
2179         }
2180 
2181         gl::Context *context = gl::getContext();
2182 
2183         if (context)
2184         {
2185             for (int i = 0; i < n; i++)
2186             {
2187                 fences[i] = context->createFence();
2188             }
2189         }
2190     }
2191     catch(std::bad_alloc&)
2192     {
2193         return error(GL_OUT_OF_MEMORY);
2194     }
2195 }
2196 
glGenFramebuffers(GLsizei n,GLuint * framebuffers)2197 void __stdcall glGenFramebuffers(GLsizei n, GLuint* framebuffers)
2198 {
2199     TRACE("(GLsizei n = %d, GLuint* framebuffers = 0x%0.8p)", n, framebuffers);
2200 
2201     try
2202     {
2203         if (n < 0)
2204         {
2205             return error(GL_INVALID_VALUE);
2206         }
2207 
2208         gl::Context *context = gl::getContext();
2209 
2210         if (context)
2211         {
2212             for (int i = 0; i < n; i++)
2213             {
2214                 framebuffers[i] = context->createFramebuffer();
2215             }
2216         }
2217     }
2218     catch(std::bad_alloc&)
2219     {
2220         return error(GL_OUT_OF_MEMORY);
2221     }
2222 }
2223 
glGenRenderbuffers(GLsizei n,GLuint * renderbuffers)2224 void __stdcall glGenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2225 {
2226     TRACE("(GLsizei n = %d, GLuint* renderbuffers = 0x%0.8p)", n, renderbuffers);
2227 
2228     try
2229     {
2230         if (n < 0)
2231         {
2232             return error(GL_INVALID_VALUE);
2233         }
2234 
2235         gl::Context *context = gl::getContext();
2236 
2237         if (context)
2238         {
2239             for (int i = 0; i < n; i++)
2240             {
2241                 renderbuffers[i] = context->createRenderbuffer();
2242             }
2243         }
2244     }
2245     catch(std::bad_alloc&)
2246     {
2247         return error(GL_OUT_OF_MEMORY);
2248     }
2249 }
2250 
glGenTextures(GLsizei n,GLuint * textures)2251 void __stdcall glGenTextures(GLsizei n, GLuint* textures)
2252 {
2253     TRACE("(GLsizei n = %d, GLuint* textures =  0x%0.8p)", n, textures);
2254 
2255     try
2256     {
2257         if (n < 0)
2258         {
2259             return error(GL_INVALID_VALUE);
2260         }
2261 
2262         gl::Context *context = gl::getContext();
2263 
2264         if (context)
2265         {
2266             for (int i = 0; i < n; i++)
2267             {
2268                 textures[i] = context->createTexture();
2269             }
2270         }
2271     }
2272     catch(std::bad_alloc&)
2273     {
2274         return error(GL_OUT_OF_MEMORY);
2275     }
2276 }
2277 
glGetActiveAttrib(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)2278 void __stdcall glGetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2279 {
2280     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = 0x%0.8p, "
2281           "GLint *size = 0x%0.8p, GLenum *type = %0.8p, GLchar *name = %0.8p)",
2282           program, index, bufsize, length, size, type, name);
2283 
2284     try
2285     {
2286         if (bufsize < 0)
2287         {
2288             return error(GL_INVALID_VALUE);
2289         }
2290 
2291         gl::Context *context = gl::getContext();
2292 
2293         if (context)
2294         {
2295             gl::Program *programObject = context->getProgram(program);
2296 
2297             if (!programObject)
2298             {
2299                 if (context->getShader(program))
2300                 {
2301                     return error(GL_INVALID_OPERATION);
2302                 }
2303                 else
2304                 {
2305                     return error(GL_INVALID_VALUE);
2306                 }
2307             }
2308 
2309             if (index >= (GLuint)programObject->getActiveAttributeCount())
2310             {
2311                 return error(GL_INVALID_VALUE);
2312             }
2313 
2314             programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2315         }
2316     }
2317     catch(std::bad_alloc&)
2318     {
2319         return error(GL_OUT_OF_MEMORY);
2320     }
2321 }
2322 
glGetActiveUniform(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)2323 void __stdcall glGetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2324 {
2325     TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2326           "GLsizei* length = 0x%0.8p, GLint* size = 0x%0.8p, GLenum* type = 0x%0.8p, GLchar* name = 0x%0.8p)",
2327           program, index, bufsize, length, size, type, name);
2328 
2329     try
2330     {
2331         if (bufsize < 0)
2332         {
2333             return error(GL_INVALID_VALUE);
2334         }
2335 
2336         gl::Context *context = gl::getContext();
2337 
2338         if (context)
2339         {
2340             gl::Program *programObject = context->getProgram(program);
2341 
2342             if (!programObject)
2343             {
2344                 if (context->getShader(program))
2345                 {
2346                     return error(GL_INVALID_OPERATION);
2347                 }
2348                 else
2349                 {
2350                     return error(GL_INVALID_VALUE);
2351                 }
2352             }
2353 
2354             if (index >= (GLuint)programObject->getActiveUniformCount())
2355             {
2356                 return error(GL_INVALID_VALUE);
2357             }
2358 
2359             programObject->getActiveUniform(index, bufsize, length, size, type, name);
2360         }
2361     }
2362     catch(std::bad_alloc&)
2363     {
2364         return error(GL_OUT_OF_MEMORY);
2365     }
2366 }
2367 
glGetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)2368 void __stdcall glGetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2369 {
2370     TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = 0x%0.8p, GLuint* shaders = 0x%0.8p)",
2371           program, maxcount, count, shaders);
2372 
2373     try
2374     {
2375         if (maxcount < 0)
2376         {
2377             return error(GL_INVALID_VALUE);
2378         }
2379 
2380         gl::Context *context = gl::getContext();
2381 
2382         if (context)
2383         {
2384             gl::Program *programObject = context->getProgram(program);
2385 
2386             if (!programObject)
2387             {
2388                 if (context->getShader(program))
2389                 {
2390                     return error(GL_INVALID_OPERATION);
2391                 }
2392                 else
2393                 {
2394                     return error(GL_INVALID_VALUE);
2395                 }
2396             }
2397 
2398             return programObject->getAttachedShaders(maxcount, count, shaders);
2399         }
2400     }
2401     catch(std::bad_alloc&)
2402     {
2403         return error(GL_OUT_OF_MEMORY);
2404     }
2405 }
2406 
glGetAttribLocation(GLuint program,const GLchar * name)2407 int __stdcall glGetAttribLocation(GLuint program, const GLchar* name)
2408 {
2409     TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2410 
2411     try
2412     {
2413         gl::Context *context = gl::getContext();
2414 
2415         if (context)
2416         {
2417 
2418             gl::Program *programObject = context->getProgram(program);
2419 
2420             if (!programObject)
2421             {
2422                 if (context->getShader(program))
2423                 {
2424                     return error(GL_INVALID_OPERATION, -1);
2425                 }
2426                 else
2427                 {
2428                     return error(GL_INVALID_VALUE, -1);
2429                 }
2430             }
2431 
2432             if (!programObject->isLinked())
2433             {
2434                 return error(GL_INVALID_OPERATION, -1);
2435             }
2436 
2437             return programObject->getAttributeLocation(name);
2438         }
2439     }
2440     catch(std::bad_alloc&)
2441     {
2442         return error(GL_OUT_OF_MEMORY, -1);
2443     }
2444 
2445     return -1;
2446 }
2447 
glGetBooleanv(GLenum pname,GLboolean * params)2448 void __stdcall glGetBooleanv(GLenum pname, GLboolean* params)
2449 {
2450     TRACE("(GLenum pname = 0x%X, GLboolean* params = 0x%0.8p)",  pname, params);
2451 
2452     try
2453     {
2454         gl::Context *context = gl::getContext();
2455 
2456         if (context)
2457         {
2458             if (!(context->getBooleanv(pname, params)))
2459             {
2460                 GLenum nativeType;
2461                 unsigned int numParams = 0;
2462                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2463                     return error(GL_INVALID_ENUM);
2464 
2465                 if (numParams == 0)
2466                     return; // it is known that the pname is valid, but there are no parameters to return
2467 
2468                 if (nativeType == GL_FLOAT)
2469                 {
2470                     GLfloat *floatParams = NULL;
2471                     floatParams = new GLfloat[numParams];
2472 
2473                     context->getFloatv(pname, floatParams);
2474 
2475                     for (unsigned int i = 0; i < numParams; ++i)
2476                     {
2477                         if (floatParams[i] == 0.0f)
2478                             params[i] = GL_FALSE;
2479                         else
2480                             params[i] = GL_TRUE;
2481                     }
2482 
2483                     delete [] floatParams;
2484                 }
2485                 else if (nativeType == GL_INT)
2486                 {
2487                     GLint *intParams = NULL;
2488                     intParams = new GLint[numParams];
2489 
2490                     context->getIntegerv(pname, intParams);
2491 
2492                     for (unsigned int i = 0; i < numParams; ++i)
2493                     {
2494                         if (intParams[i] == 0)
2495                             params[i] = GL_FALSE;
2496                         else
2497                             params[i] = GL_TRUE;
2498                     }
2499 
2500                     delete [] intParams;
2501                 }
2502             }
2503         }
2504     }
2505     catch(std::bad_alloc&)
2506     {
2507         return error(GL_OUT_OF_MEMORY);
2508     }
2509 }
2510 
glGetBufferParameteriv(GLenum target,GLenum pname,GLint * params)2511 void __stdcall glGetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2512 {
2513     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2514 
2515     try
2516     {
2517         gl::Context *context = gl::getContext();
2518 
2519         if (context)
2520         {
2521             gl::Buffer *buffer;
2522 
2523             switch (target)
2524             {
2525               case GL_ARRAY_BUFFER:
2526                 buffer = context->getArrayBuffer();
2527                 break;
2528               case GL_ELEMENT_ARRAY_BUFFER:
2529                 buffer = context->getElementArrayBuffer();
2530                 break;
2531               default: return error(GL_INVALID_ENUM);
2532             }
2533 
2534             if (!buffer)
2535             {
2536                 // A null buffer means that "0" is bound to the requested buffer target
2537                 return error(GL_INVALID_OPERATION);
2538             }
2539 
2540             switch (pname)
2541             {
2542               case GL_BUFFER_USAGE:
2543                 *params = buffer->usage();
2544                 break;
2545               case GL_BUFFER_SIZE:
2546                 *params = buffer->size();
2547                 break;
2548               default: return error(GL_INVALID_ENUM);
2549             }
2550         }
2551     }
2552     catch(std::bad_alloc&)
2553     {
2554         return error(GL_OUT_OF_MEMORY);
2555     }
2556 }
2557 
glGetError(void)2558 GLenum __stdcall glGetError(void)
2559 {
2560     TRACE("()");
2561 
2562     gl::Context *context = gl::getContext();
2563 
2564     if (context)
2565     {
2566         return context->getError();
2567     }
2568 
2569     return GL_NO_ERROR;
2570 }
2571 
glGetFenceivNV(GLuint fence,GLenum pname,GLint * params)2572 void __stdcall glGetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2573 {
2574     TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = 0x%0.8p)", fence, pname, params);
2575 
2576     try
2577     {
2578 
2579         gl::Context *context = gl::getContext();
2580 
2581         if (context)
2582         {
2583             gl::Fence *fenceObject = context->getFence(fence);
2584 
2585             if (fenceObject == NULL)
2586             {
2587                 return error(GL_INVALID_OPERATION);
2588             }
2589 
2590             fenceObject->getFenceiv(pname, params);
2591         }
2592     }
2593     catch(std::bad_alloc&)
2594     {
2595         return error(GL_OUT_OF_MEMORY);
2596     }
2597 }
2598 
glGetFloatv(GLenum pname,GLfloat * params)2599 void __stdcall glGetFloatv(GLenum pname, GLfloat* params)
2600 {
2601     TRACE("(GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", pname, params);
2602 
2603     try
2604     {
2605         gl::Context *context = gl::getContext();
2606 
2607         if (context)
2608         {
2609             if (!(context->getFloatv(pname, params)))
2610             {
2611                 GLenum nativeType;
2612                 unsigned int numParams = 0;
2613                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2614                     return error(GL_INVALID_ENUM);
2615 
2616                 if (numParams == 0)
2617                     return; // it is known that the pname is valid, but that there are no parameters to return.
2618 
2619                 if (nativeType == GL_BOOL)
2620                 {
2621                     GLboolean *boolParams = NULL;
2622                     boolParams = new GLboolean[numParams];
2623 
2624                     context->getBooleanv(pname, boolParams);
2625 
2626                     for (unsigned int i = 0; i < numParams; ++i)
2627                     {
2628                         if (boolParams[i] == GL_FALSE)
2629                             params[i] = 0.0f;
2630                         else
2631                             params[i] = 1.0f;
2632                     }
2633 
2634                     delete [] boolParams;
2635                 }
2636                 else if (nativeType == GL_INT)
2637                 {
2638                     GLint *intParams = NULL;
2639                     intParams = new GLint[numParams];
2640 
2641                     context->getIntegerv(pname, intParams);
2642 
2643                     for (unsigned int i = 0; i < numParams; ++i)
2644                     {
2645                         params[i] = (GLfloat)intParams[i];
2646                     }
2647 
2648                     delete [] intParams;
2649                 }
2650             }
2651         }
2652     }
2653     catch(std::bad_alloc&)
2654     {
2655         return error(GL_OUT_OF_MEMORY);
2656     }
2657 }
2658 
glGetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)2659 void __stdcall glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2660 {
2661     TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)",
2662           target, attachment, pname, params);
2663 
2664     try
2665     {
2666         gl::Context *context = gl::getContext();
2667 
2668         if (context)
2669         {
2670             if (target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
2671             {
2672                 return error(GL_INVALID_ENUM);
2673             }
2674 
2675             gl::Framebuffer *framebuffer = NULL;
2676             if (target == GL_READ_FRAMEBUFFER_ANGLE)
2677             {
2678                 if(context->getReadFramebufferHandle() == 0)
2679                 {
2680                     return error(GL_INVALID_OPERATION);
2681                 }
2682 
2683                 framebuffer = context->getReadFramebuffer();
2684             }
2685             else
2686             {
2687                 if (context->getDrawFramebufferHandle() == 0)
2688                 {
2689                     return error(GL_INVALID_OPERATION);
2690                 }
2691 
2692                 framebuffer = context->getDrawFramebuffer();
2693             }
2694 
2695             GLenum attachmentType;
2696             GLuint attachmentHandle;
2697             switch (attachment)
2698             {
2699               case GL_COLOR_ATTACHMENT0:
2700                 attachmentType = framebuffer->getColorbufferType();
2701                 attachmentHandle = framebuffer->getColorbufferHandle();
2702                 break;
2703               case GL_DEPTH_ATTACHMENT:
2704                 attachmentType = framebuffer->getDepthbufferType();
2705                 attachmentHandle = framebuffer->getDepthbufferHandle();
2706                 break;
2707               case GL_STENCIL_ATTACHMENT:
2708                 attachmentType = framebuffer->getStencilbufferType();
2709                 attachmentHandle = framebuffer->getStencilbufferHandle();
2710                 break;
2711               default: return error(GL_INVALID_ENUM);
2712             }
2713 
2714             GLenum attachmentObjectType;   // Type category
2715             if (attachmentType == GL_NONE || attachmentType == GL_RENDERBUFFER)
2716             {
2717                 attachmentObjectType = attachmentType;
2718             }
2719             else if (gl::IsTextureTarget(attachmentType))
2720             {
2721                 attachmentObjectType = GL_TEXTURE;
2722             }
2723             else UNREACHABLE();
2724 
2725             switch (pname)
2726             {
2727               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2728                 *params = attachmentObjectType;
2729                 break;
2730               case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2731                 if (attachmentObjectType == GL_RENDERBUFFER || attachmentObjectType == GL_TEXTURE)
2732                 {
2733                     *params = attachmentHandle;
2734                 }
2735                 else
2736                 {
2737                     return error(GL_INVALID_ENUM);
2738                 }
2739                 break;
2740               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2741                 if (attachmentObjectType == GL_TEXTURE)
2742                 {
2743                     *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2744                 }
2745                 else
2746                 {
2747                     return error(GL_INVALID_ENUM);
2748                 }
2749                 break;
2750               case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2751                 if (attachmentObjectType == GL_TEXTURE)
2752                 {
2753                     if (gl::IsCubemapTextureTarget(attachmentType))
2754                     {
2755                         *params = attachmentType;
2756                     }
2757                     else
2758                     {
2759                         *params = 0;
2760                     }
2761                 }
2762                 else
2763                 {
2764                     return error(GL_INVALID_ENUM);
2765                 }
2766                 break;
2767               default:
2768                 return error(GL_INVALID_ENUM);
2769             }
2770         }
2771     }
2772     catch(std::bad_alloc&)
2773     {
2774         return error(GL_OUT_OF_MEMORY);
2775     }
2776 }
2777 
glGetIntegerv(GLenum pname,GLint * params)2778 void __stdcall glGetIntegerv(GLenum pname, GLint* params)
2779 {
2780     TRACE("(GLenum pname = 0x%X, GLint* params = 0x%0.8p)", pname, params);
2781 
2782     try
2783     {
2784         gl::Context *context = gl::getContext();
2785 
2786         if (context)
2787         {
2788             if (!(context->getIntegerv(pname, params)))
2789             {
2790                 GLenum nativeType;
2791                 unsigned int numParams = 0;
2792                 if (!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2793                     return error(GL_INVALID_ENUM);
2794 
2795                 if (numParams == 0)
2796                     return; // it is known that pname is valid, but there are no parameters to return
2797 
2798                 if (nativeType == GL_BOOL)
2799                 {
2800                     GLboolean *boolParams = NULL;
2801                     boolParams = new GLboolean[numParams];
2802 
2803                     context->getBooleanv(pname, boolParams);
2804 
2805                     for (unsigned int i = 0; i < numParams; ++i)
2806                     {
2807                         if (boolParams[i] == GL_FALSE)
2808                             params[i] = 0;
2809                         else
2810                             params[i] = 1;
2811                     }
2812 
2813                     delete [] boolParams;
2814                 }
2815                 else if (nativeType == GL_FLOAT)
2816                 {
2817                     GLfloat *floatParams = NULL;
2818                     floatParams = new GLfloat[numParams];
2819 
2820                     context->getFloatv(pname, floatParams);
2821 
2822                     for (unsigned int i = 0; i < numParams; ++i)
2823                     {
2824                         if (pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
2825                         {
2826                             params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2827                         }
2828                         else
2829                             params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2830                     }
2831 
2832                     delete [] floatParams;
2833                 }
2834             }
2835         }
2836     }
2837     catch(std::bad_alloc&)
2838     {
2839         return error(GL_OUT_OF_MEMORY);
2840     }
2841 }
2842 
glGetProgramiv(GLuint program,GLenum pname,GLint * params)2843 void __stdcall glGetProgramiv(GLuint program, GLenum pname, GLint* params)
2844 {
2845     TRACE("(GLuint program = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", program, pname, params);
2846 
2847     try
2848     {
2849         gl::Context *context = gl::getContext();
2850 
2851         if (context)
2852         {
2853             gl::Program *programObject = context->getProgram(program);
2854 
2855             if (!programObject)
2856             {
2857                 return error(GL_INVALID_VALUE);
2858             }
2859 
2860             switch (pname)
2861             {
2862               case GL_DELETE_STATUS:
2863                 *params = programObject->isFlaggedForDeletion();
2864                 return;
2865               case GL_LINK_STATUS:
2866                 *params = programObject->isLinked();
2867                 return;
2868               case GL_VALIDATE_STATUS:
2869                 *params = programObject->isValidated();
2870                 return;
2871               case GL_INFO_LOG_LENGTH:
2872                 *params = programObject->getInfoLogLength();
2873                 return;
2874               case GL_ATTACHED_SHADERS:
2875                 *params = programObject->getAttachedShadersCount();
2876                 return;
2877               case GL_ACTIVE_ATTRIBUTES:
2878                 *params = programObject->getActiveAttributeCount();
2879                 return;
2880               case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
2881                 *params = programObject->getActiveAttributeMaxLength();
2882                 return;
2883               case GL_ACTIVE_UNIFORMS:
2884                 *params = programObject->getActiveUniformCount();
2885                 return;
2886               case GL_ACTIVE_UNIFORM_MAX_LENGTH:
2887                 *params = programObject->getActiveUniformMaxLength();
2888                 return;
2889               default:
2890                 return error(GL_INVALID_ENUM);
2891             }
2892         }
2893     }
2894     catch(std::bad_alloc&)
2895     {
2896         return error(GL_OUT_OF_MEMORY);
2897     }
2898 }
2899 
glGetProgramInfoLog(GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)2900 void __stdcall glGetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
2901 {
2902     TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
2903           program, bufsize, length, infolog);
2904 
2905     try
2906     {
2907         if (bufsize < 0)
2908         {
2909             return error(GL_INVALID_VALUE);
2910         }
2911 
2912         gl::Context *context = gl::getContext();
2913 
2914         if (context)
2915         {
2916             gl::Program *programObject = context->getProgram(program);
2917 
2918             if (!programObject)
2919             {
2920                 return error(GL_INVALID_VALUE);
2921             }
2922 
2923             programObject->getInfoLog(bufsize, length, infolog);
2924         }
2925     }
2926     catch(std::bad_alloc&)
2927     {
2928         return error(GL_OUT_OF_MEMORY);
2929     }
2930 }
2931 
glGetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)2932 void __stdcall glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
2933 {
2934     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
2935 
2936     try
2937     {
2938         gl::Context *context = gl::getContext();
2939 
2940         if (context)
2941         {
2942             if (target != GL_RENDERBUFFER)
2943             {
2944                 return error(GL_INVALID_ENUM);
2945             }
2946 
2947             if (context->getRenderbufferHandle() == 0)
2948             {
2949                 return error(GL_INVALID_OPERATION);
2950             }
2951 
2952             gl::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferHandle());
2953 
2954             switch (pname)
2955             {
2956               case GL_RENDERBUFFER_WIDTH:
2957                 *params = renderbuffer->getWidth();
2958                 break;
2959               case GL_RENDERBUFFER_HEIGHT:
2960                 *params = renderbuffer->getHeight();
2961                 break;
2962               case GL_RENDERBUFFER_INTERNAL_FORMAT:
2963                 *params = renderbuffer->getFormat();
2964                 break;
2965               case GL_RENDERBUFFER_RED_SIZE:
2966                 if (renderbuffer->isColorbuffer())
2967                 {
2968                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getRedSize();
2969                 }
2970                 else
2971                 {
2972                     *params = 0;
2973                 }
2974                 break;
2975               case GL_RENDERBUFFER_GREEN_SIZE:
2976                 if (renderbuffer->isColorbuffer())
2977                 {
2978                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getGreenSize();
2979                 }
2980                 else
2981                 {
2982                     *params = 0;
2983                 }
2984                 break;
2985               case GL_RENDERBUFFER_BLUE_SIZE:
2986                 if (renderbuffer->isColorbuffer())
2987                 {
2988                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getBlueSize();
2989                 }
2990                 else
2991                 {
2992                     *params = 0;
2993                 }
2994                 break;
2995               case GL_RENDERBUFFER_ALPHA_SIZE:
2996                 if (renderbuffer->isColorbuffer())
2997                 {
2998                     *params = static_cast<gl::Colorbuffer*>(renderbuffer->getStorage())->getAlphaSize();
2999                 }
3000                 else
3001                 {
3002                     *params = 0;
3003                 }
3004                 break;
3005               case GL_RENDERBUFFER_DEPTH_SIZE:
3006                 if (renderbuffer->isDepthbuffer())
3007                 {
3008                     *params = static_cast<gl::Depthbuffer*>(renderbuffer->getStorage())->getDepthSize();
3009                 }
3010                 else
3011                 {
3012                     *params = 0;
3013                 }
3014                 break;
3015               case GL_RENDERBUFFER_STENCIL_SIZE:
3016                 if (renderbuffer->isStencilbuffer())
3017                 {
3018                     *params = static_cast<gl::Stencilbuffer*>(renderbuffer->getStorage())->getStencilSize();
3019                 }
3020                 else
3021                 {
3022                     *params = 0;
3023                 }
3024                 break;
3025               case GL_RENDERBUFFER_SAMPLES_ANGLE:
3026                 {
3027                     if (context->getMaxSupportedSamples() != 0)
3028                     {
3029                         *params = renderbuffer->getStorage()->getSamples();
3030                     }
3031                     else
3032                     {
3033                         return error(GL_INVALID_ENUM);
3034                     }
3035                 }
3036                 break;
3037               default:
3038                 return error(GL_INVALID_ENUM);
3039             }
3040         }
3041     }
3042     catch(std::bad_alloc&)
3043     {
3044         return error(GL_OUT_OF_MEMORY);
3045     }
3046 }
3047 
glGetShaderiv(GLuint shader,GLenum pname,GLint * params)3048 void __stdcall glGetShaderiv(GLuint shader, GLenum pname, GLint* params)
3049 {
3050     TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = 0x%0.8p)", shader, pname, params);
3051 
3052     try
3053     {
3054         gl::Context *context = gl::getContext();
3055 
3056         if (context)
3057         {
3058             gl::Shader *shaderObject = context->getShader(shader);
3059 
3060             if (!shaderObject)
3061             {
3062                 return error(GL_INVALID_VALUE);
3063             }
3064 
3065             switch (pname)
3066             {
3067               case GL_SHADER_TYPE:
3068                 *params = shaderObject->getType();
3069                 return;
3070               case GL_DELETE_STATUS:
3071                 *params = shaderObject->isFlaggedForDeletion();
3072                 return;
3073               case GL_COMPILE_STATUS:
3074                 *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3075                 return;
3076               case GL_INFO_LOG_LENGTH:
3077                 *params = shaderObject->getInfoLogLength();
3078                 return;
3079               case GL_SHADER_SOURCE_LENGTH:
3080                 *params = shaderObject->getSourceLength();
3081                 return;
3082               default:
3083                 return error(GL_INVALID_ENUM);
3084             }
3085         }
3086     }
3087     catch(std::bad_alloc&)
3088     {
3089         return error(GL_OUT_OF_MEMORY);
3090     }
3091 }
3092 
glGetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)3093 void __stdcall glGetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3094 {
3095     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* infolog = 0x%0.8p)",
3096           shader, bufsize, length, infolog);
3097 
3098     try
3099     {
3100         if (bufsize < 0)
3101         {
3102             return error(GL_INVALID_VALUE);
3103         }
3104 
3105         gl::Context *context = gl::getContext();
3106 
3107         if (context)
3108         {
3109             gl::Shader *shaderObject = context->getShader(shader);
3110 
3111             if (!shaderObject)
3112             {
3113                 return error(GL_INVALID_VALUE);
3114             }
3115 
3116             shaderObject->getInfoLog(bufsize, length, infolog);
3117         }
3118     }
3119     catch(std::bad_alloc&)
3120     {
3121         return error(GL_OUT_OF_MEMORY);
3122     }
3123 }
3124 
glGetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)3125 void __stdcall glGetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3126 {
3127     TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = 0x%0.8p, GLint* precision = 0x%0.8p)",
3128           shadertype, precisiontype, range, precision);
3129 
3130     try
3131     {
3132         switch (shadertype)
3133         {
3134           case GL_VERTEX_SHADER:
3135           case GL_FRAGMENT_SHADER:
3136             break;
3137           default:
3138             return error(GL_INVALID_ENUM);
3139         }
3140 
3141         switch (precisiontype)
3142         {
3143           case GL_LOW_FLOAT:
3144           case GL_MEDIUM_FLOAT:
3145           case GL_HIGH_FLOAT:
3146             // Assume IEEE 754 precision
3147             range[0] = 127;
3148             range[1] = 127;
3149             *precision = 23;
3150             break;
3151           case GL_LOW_INT:
3152           case GL_MEDIUM_INT:
3153           case GL_HIGH_INT:
3154             // Some (most) hardware only supports single-precision floating-point numbers,
3155             // which can accurately represent integers up to +/-16777216
3156             range[0] = 24;
3157             range[1] = 24;
3158             *precision = 0;
3159             break;
3160           default:
3161             return error(GL_INVALID_ENUM);
3162         }
3163     }
3164     catch(std::bad_alloc&)
3165     {
3166         return error(GL_OUT_OF_MEMORY);
3167     }
3168 }
3169 
glGetShaderSource(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)3170 void __stdcall glGetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3171 {
3172     TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = 0x%0.8p, GLchar* source = 0x%0.8p)",
3173           shader, bufsize, length, source);
3174 
3175     try
3176     {
3177         if (bufsize < 0)
3178         {
3179             return error(GL_INVALID_VALUE);
3180         }
3181 
3182         gl::Context *context = gl::getContext();
3183 
3184         if (context)
3185         {
3186             gl::Shader *shaderObject = context->getShader(shader);
3187 
3188             if (!shaderObject)
3189             {
3190                 return error(GL_INVALID_OPERATION);
3191             }
3192 
3193             shaderObject->getSource(bufsize, length, source);
3194         }
3195     }
3196     catch(std::bad_alloc&)
3197     {
3198         return error(GL_OUT_OF_MEMORY);
3199     }
3200 }
3201 
glGetString(GLenum name)3202 const GLubyte* __stdcall glGetString(GLenum name)
3203 {
3204     TRACE("(GLenum name = 0x%X)", name);
3205 
3206     try
3207     {
3208         gl::Context *context = gl::getContext();
3209 
3210         switch (name)
3211         {
3212           case GL_VENDOR:
3213             return (GLubyte*)"TransGaming Inc.";
3214           case GL_RENDERER:
3215             return (GLubyte*)"ANGLE";
3216           case GL_VERSION:
3217             return (GLubyte*)"OpenGL ES 2.0 (git-devel "__DATE__ " " __TIME__")";
3218           case GL_SHADING_LANGUAGE_VERSION:
3219             return (GLubyte*)"OpenGL ES GLSL ES 1.00 (git-devel "__DATE__ " " __TIME__")";
3220           case GL_EXTENSIONS:
3221             return (GLubyte*)((context != NULL) ? context->getExtensionString() : "");
3222           default:
3223             return error(GL_INVALID_ENUM, (GLubyte*)NULL);
3224         }
3225     }
3226     catch(std::bad_alloc&)
3227     {
3228         return error(GL_OUT_OF_MEMORY, (GLubyte*)NULL);
3229     }
3230 
3231     return NULL;
3232 }
3233 
glGetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)3234 void __stdcall glGetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3235 {
3236     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", target, pname, params);
3237 
3238     try
3239     {
3240         gl::Context *context = gl::getContext();
3241 
3242         if (context)
3243         {
3244             gl::Texture *texture;
3245 
3246             switch (target)
3247             {
3248               case GL_TEXTURE_2D:
3249                 texture = context->getTexture2D();
3250                 break;
3251               case GL_TEXTURE_CUBE_MAP:
3252                 texture = context->getTextureCubeMap();
3253                 break;
3254               default:
3255                 return error(GL_INVALID_ENUM);
3256             }
3257 
3258             switch (pname)
3259             {
3260               case GL_TEXTURE_MAG_FILTER:
3261                 *params = (GLfloat)texture->getMagFilter();
3262                 break;
3263               case GL_TEXTURE_MIN_FILTER:
3264                 *params = (GLfloat)texture->getMinFilter();
3265                 break;
3266               case GL_TEXTURE_WRAP_S:
3267                 *params = (GLfloat)texture->getWrapS();
3268                 break;
3269               case GL_TEXTURE_WRAP_T:
3270                 *params = (GLfloat)texture->getWrapT();
3271                 break;
3272               default:
3273                 return error(GL_INVALID_ENUM);
3274             }
3275         }
3276     }
3277     catch(std::bad_alloc&)
3278     {
3279         return error(GL_OUT_OF_MEMORY);
3280     }
3281 }
3282 
glGetTexParameteriv(GLenum target,GLenum pname,GLint * params)3283 void __stdcall glGetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3284 {
3285     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", target, pname, params);
3286 
3287     try
3288     {
3289         gl::Context *context = gl::getContext();
3290 
3291         if (context)
3292         {
3293             gl::Texture *texture;
3294 
3295             switch (target)
3296             {
3297               case GL_TEXTURE_2D:
3298                 texture = context->getTexture2D();
3299                 break;
3300               case GL_TEXTURE_CUBE_MAP:
3301                 texture = context->getTextureCubeMap();
3302                 break;
3303               default:
3304                 return error(GL_INVALID_ENUM);
3305             }
3306 
3307             switch (pname)
3308             {
3309               case GL_TEXTURE_MAG_FILTER:
3310                 *params = texture->getMagFilter();
3311                 break;
3312               case GL_TEXTURE_MIN_FILTER:
3313                 *params = texture->getMinFilter();
3314                 break;
3315               case GL_TEXTURE_WRAP_S:
3316                 *params = texture->getWrapS();
3317                 break;
3318               case GL_TEXTURE_WRAP_T:
3319                 *params = texture->getWrapT();
3320                 break;
3321               default:
3322                 return error(GL_INVALID_ENUM);
3323             }
3324         }
3325     }
3326     catch(std::bad_alloc&)
3327     {
3328         return error(GL_OUT_OF_MEMORY);
3329     }
3330 }
3331 
glGetUniformfv(GLuint program,GLint location,GLfloat * params)3332 void __stdcall glGetUniformfv(GLuint program, GLint location, GLfloat* params)
3333 {
3334     TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = 0x%0.8p)", program, location, params);
3335 
3336     try
3337     {
3338         gl::Context *context = gl::getContext();
3339 
3340         if (context)
3341         {
3342             if (program == 0)
3343             {
3344                 return error(GL_INVALID_VALUE);
3345             }
3346 
3347             gl::Program *programObject = context->getProgram(program);
3348 
3349             if (!programObject || !programObject->isLinked())
3350             {
3351                 return error(GL_INVALID_OPERATION);
3352             }
3353 
3354             if (!programObject->getUniformfv(location, params))
3355             {
3356                 return error(GL_INVALID_OPERATION);
3357             }
3358         }
3359     }
3360     catch(std::bad_alloc&)
3361     {
3362         return error(GL_OUT_OF_MEMORY);
3363     }
3364 }
3365 
glGetUniformiv(GLuint program,GLint location,GLint * params)3366 void __stdcall glGetUniformiv(GLuint program, GLint location, GLint* params)
3367 {
3368     TRACE("(GLuint program = %d, GLint location = %d, GLint* params = 0x%0.8p)", program, location, params);
3369 
3370     try
3371     {
3372         gl::Context *context = gl::getContext();
3373 
3374         if (context)
3375         {
3376             if (program == 0)
3377             {
3378                 return error(GL_INVALID_VALUE);
3379             }
3380 
3381             gl::Program *programObject = context->getProgram(program);
3382 
3383             if (!programObject || !programObject->isLinked())
3384             {
3385                 return error(GL_INVALID_OPERATION);
3386             }
3387 
3388             if (!programObject)
3389             {
3390                 return error(GL_INVALID_OPERATION);
3391             }
3392 
3393             if (!programObject->getUniformiv(location, params))
3394             {
3395                 return error(GL_INVALID_OPERATION);
3396             }
3397         }
3398     }
3399     catch(std::bad_alloc&)
3400     {
3401         return error(GL_OUT_OF_MEMORY);
3402     }
3403 }
3404 
glGetUniformLocation(GLuint program,const GLchar * name)3405 int __stdcall glGetUniformLocation(GLuint program, const GLchar* name)
3406 {
3407     TRACE("(GLuint program = %d, const GLchar* name = 0x%0.8p)", program, name);
3408 
3409     try
3410     {
3411         gl::Context *context = gl::getContext();
3412 
3413         if (strstr(name, "gl_") == name)
3414         {
3415             return -1;
3416         }
3417 
3418         if (context)
3419         {
3420             gl::Program *programObject = context->getProgram(program);
3421 
3422             if (!programObject)
3423             {
3424                 if (context->getShader(program))
3425                 {
3426                     return error(GL_INVALID_OPERATION, -1);
3427                 }
3428                 else
3429                 {
3430                     return error(GL_INVALID_VALUE, -1);
3431                 }
3432             }
3433 
3434             if (!programObject->isLinked())
3435             {
3436                 return error(GL_INVALID_OPERATION, -1);
3437             }
3438 
3439             return programObject->getUniformLocation(name, false);
3440         }
3441     }
3442     catch(std::bad_alloc&)
3443     {
3444         return error(GL_OUT_OF_MEMORY, -1);
3445     }
3446 
3447     return -1;
3448 }
3449 
glGetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)3450 void __stdcall glGetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
3451 {
3452     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = 0x%0.8p)", index, pname, params);
3453 
3454     try
3455     {
3456         gl::Context *context = gl::getContext();
3457 
3458         if (context)
3459         {
3460             if (index >= gl::MAX_VERTEX_ATTRIBS)
3461             {
3462                 return error(GL_INVALID_VALUE);
3463             }
3464 
3465             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
3466 
3467             switch (pname)
3468             {
3469               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3470                 *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3471                 break;
3472               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3473                 *params = (GLfloat)attribState.mSize;
3474                 break;
3475               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3476                 *params = (GLfloat)attribState.mStride;
3477                 break;
3478               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3479                 *params = (GLfloat)attribState.mType;
3480                 break;
3481               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3482                 *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
3483                 break;
3484               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3485                 *params = (GLfloat)attribState.mBoundBuffer.id();
3486                 break;
3487               case GL_CURRENT_VERTEX_ATTRIB:
3488                 for (int i = 0; i < 4; ++i)
3489                 {
3490                     params[i] = attribState.mCurrentValue[i];
3491                 }
3492                 break;
3493               default: return error(GL_INVALID_ENUM);
3494             }
3495         }
3496     }
3497     catch(std::bad_alloc&)
3498     {
3499         return error(GL_OUT_OF_MEMORY);
3500     }
3501 }
3502 
glGetVertexAttribiv(GLuint index,GLenum pname,GLint * params)3503 void __stdcall glGetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
3504 {
3505     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = 0x%0.8p)", index, pname, params);
3506 
3507     try
3508     {
3509         gl::Context *context = gl::getContext();
3510 
3511         if (context)
3512         {
3513             if (index >= gl::MAX_VERTEX_ATTRIBS)
3514             {
3515                 return error(GL_INVALID_VALUE);
3516             }
3517 
3518             const gl::VertexAttribute &attribState = context->getVertexAttribState(index);
3519 
3520             switch (pname)
3521             {
3522               case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
3523                 *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
3524                 break;
3525               case GL_VERTEX_ATTRIB_ARRAY_SIZE:
3526                 *params = attribState.mSize;
3527                 break;
3528               case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
3529                 *params = attribState.mStride;
3530                 break;
3531               case GL_VERTEX_ATTRIB_ARRAY_TYPE:
3532                 *params = attribState.mType;
3533                 break;
3534               case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
3535                 *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
3536                 break;
3537               case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
3538                 *params = attribState.mBoundBuffer.id();
3539                 break;
3540               case GL_CURRENT_VERTEX_ATTRIB:
3541                 for (int i = 0; i < 4; ++i)
3542                 {
3543                     float currentValue = attribState.mCurrentValue[i];
3544                     params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
3545                 }
3546                 break;
3547               default: return error(GL_INVALID_ENUM);
3548             }
3549         }
3550     }
3551     catch(std::bad_alloc&)
3552     {
3553         return error(GL_OUT_OF_MEMORY);
3554     }
3555 }
3556 
glGetVertexAttribPointerv(GLuint index,GLenum pname,GLvoid ** pointer)3557 void __stdcall glGetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
3558 {
3559     TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = 0x%0.8p)", index, pname, pointer);
3560 
3561     try
3562     {
3563         gl::Context *context = gl::getContext();
3564 
3565         if (context)
3566         {
3567             if (index >= gl::MAX_VERTEX_ATTRIBS)
3568             {
3569                 return error(GL_INVALID_VALUE);
3570             }
3571 
3572             if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
3573             {
3574                 return error(GL_INVALID_ENUM);
3575             }
3576 
3577             *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
3578         }
3579     }
3580     catch(std::bad_alloc&)
3581     {
3582         return error(GL_OUT_OF_MEMORY);
3583     }
3584 }
3585 
glHint(GLenum target,GLenum mode)3586 void __stdcall glHint(GLenum target, GLenum mode)
3587 {
3588     TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
3589 
3590     try
3591     {
3592         switch (mode)
3593         {
3594           case GL_FASTEST:
3595           case GL_NICEST:
3596           case GL_DONT_CARE:
3597             break;
3598           default:
3599             return error(GL_INVALID_ENUM);
3600         }
3601 
3602         gl::Context *context = gl::getContext();
3603         switch (target)
3604         {
3605           case GL_GENERATE_MIPMAP_HINT:
3606             if (context) context->setGenerateMipmapHint(mode);
3607             break;
3608           case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
3609             if (context) context->setFragmentShaderDerivativeHint(mode);
3610             break;
3611           default:
3612             return error(GL_INVALID_ENUM);
3613         }
3614     }
3615     catch(std::bad_alloc&)
3616     {
3617         return error(GL_OUT_OF_MEMORY);
3618     }
3619 }
3620 
glIsBuffer(GLuint buffer)3621 GLboolean __stdcall glIsBuffer(GLuint buffer)
3622 {
3623     TRACE("(GLuint buffer = %d)", buffer);
3624 
3625     try
3626     {
3627         gl::Context *context = gl::getContext();
3628 
3629         if (context && buffer)
3630         {
3631             gl::Buffer *bufferObject = context->getBuffer(buffer);
3632 
3633             if (bufferObject)
3634             {
3635                 return GL_TRUE;
3636             }
3637         }
3638     }
3639     catch(std::bad_alloc&)
3640     {
3641         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3642     }
3643 
3644     return GL_FALSE;
3645 }
3646 
glIsEnabled(GLenum cap)3647 GLboolean __stdcall glIsEnabled(GLenum cap)
3648 {
3649     TRACE("(GLenum cap = 0x%X)", cap);
3650 
3651     try
3652     {
3653         gl::Context *context = gl::getContext();
3654 
3655         if (context)
3656         {
3657             switch (cap)
3658             {
3659               case GL_CULL_FACE:                return context->isCullFaceEnabled();
3660               case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
3661               case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
3662               case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
3663               case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
3664               case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
3665               case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
3666               case GL_BLEND:                    return context->isBlendEnabled();
3667               case GL_DITHER:                   return context->isDitherEnabled();
3668               default:
3669                 return error(GL_INVALID_ENUM, false);
3670             }
3671         }
3672     }
3673     catch(std::bad_alloc&)
3674     {
3675         return error(GL_OUT_OF_MEMORY, false);
3676     }
3677 
3678     return false;
3679 }
3680 
glIsFenceNV(GLuint fence)3681 GLboolean __stdcall glIsFenceNV(GLuint fence)
3682 {
3683     TRACE("(GLuint fence = %d)", fence);
3684 
3685     try
3686     {
3687         gl::Context *context = gl::getContext();
3688 
3689         if (context)
3690         {
3691             gl::Fence *fenceObject = context->getFence(fence);
3692 
3693             if (fenceObject == NULL)
3694             {
3695                 return GL_FALSE;
3696             }
3697 
3698             return fenceObject->isFence();
3699         }
3700     }
3701     catch(std::bad_alloc&)
3702     {
3703         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3704     }
3705 
3706     return GL_FALSE;
3707 }
3708 
glIsFramebuffer(GLuint framebuffer)3709 GLboolean __stdcall glIsFramebuffer(GLuint framebuffer)
3710 {
3711     TRACE("(GLuint framebuffer = %d)", framebuffer);
3712 
3713     try
3714     {
3715         gl::Context *context = gl::getContext();
3716 
3717         if (context && framebuffer)
3718         {
3719             gl::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
3720 
3721             if (framebufferObject)
3722             {
3723                 return GL_TRUE;
3724             }
3725         }
3726     }
3727     catch(std::bad_alloc&)
3728     {
3729         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3730     }
3731 
3732     return GL_FALSE;
3733 }
3734 
glIsProgram(GLuint program)3735 GLboolean __stdcall glIsProgram(GLuint program)
3736 {
3737     TRACE("(GLuint program = %d)", program);
3738 
3739     try
3740     {
3741         gl::Context *context = gl::getContext();
3742 
3743         if (context && program)
3744         {
3745             gl::Program *programObject = context->getProgram(program);
3746 
3747             if (programObject)
3748             {
3749                 return GL_TRUE;
3750             }
3751         }
3752     }
3753     catch(std::bad_alloc&)
3754     {
3755         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3756     }
3757 
3758     return GL_FALSE;
3759 }
3760 
glIsRenderbuffer(GLuint renderbuffer)3761 GLboolean __stdcall glIsRenderbuffer(GLuint renderbuffer)
3762 {
3763     TRACE("(GLuint renderbuffer = %d)", renderbuffer);
3764 
3765     try
3766     {
3767         gl::Context *context = gl::getContext();
3768 
3769         if (context && renderbuffer)
3770         {
3771             gl::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
3772 
3773             if (renderbufferObject)
3774             {
3775                 return GL_TRUE;
3776             }
3777         }
3778     }
3779     catch(std::bad_alloc&)
3780     {
3781         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3782     }
3783 
3784     return GL_FALSE;
3785 }
3786 
glIsShader(GLuint shader)3787 GLboolean __stdcall glIsShader(GLuint shader)
3788 {
3789     TRACE("(GLuint shader = %d)", shader);
3790 
3791     try
3792     {
3793         gl::Context *context = gl::getContext();
3794 
3795         if (context && shader)
3796         {
3797             gl::Shader *shaderObject = context->getShader(shader);
3798 
3799             if (shaderObject)
3800             {
3801                 return GL_TRUE;
3802             }
3803         }
3804     }
3805     catch(std::bad_alloc&)
3806     {
3807         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3808     }
3809 
3810     return GL_FALSE;
3811 }
3812 
glIsTexture(GLuint texture)3813 GLboolean __stdcall glIsTexture(GLuint texture)
3814 {
3815     TRACE("(GLuint texture = %d)", texture);
3816 
3817     try
3818     {
3819         gl::Context *context = gl::getContext();
3820 
3821         if (context && texture)
3822         {
3823             gl::Texture *textureObject = context->getTexture(texture);
3824 
3825             if (textureObject)
3826             {
3827                 return GL_TRUE;
3828             }
3829         }
3830     }
3831     catch(std::bad_alloc&)
3832     {
3833         return error(GL_OUT_OF_MEMORY, GL_FALSE);
3834     }
3835 
3836     return GL_FALSE;
3837 }
3838 
glLineWidth(GLfloat width)3839 void __stdcall glLineWidth(GLfloat width)
3840 {
3841     TRACE("(GLfloat width = %f)", width);
3842 
3843     try
3844     {
3845         if (width <= 0.0f)
3846         {
3847             return error(GL_INVALID_VALUE);
3848         }
3849 
3850         gl::Context *context = gl::getContext();
3851 
3852         if (context)
3853         {
3854             context->setLineWidth(width);
3855         }
3856     }
3857     catch(std::bad_alloc&)
3858     {
3859         return error(GL_OUT_OF_MEMORY);
3860     }
3861 }
3862 
glLinkProgram(GLuint program)3863 void __stdcall glLinkProgram(GLuint program)
3864 {
3865     TRACE("(GLuint program = %d)", program);
3866 
3867     try
3868     {
3869         gl::Context *context = gl::getContext();
3870 
3871         if (context)
3872         {
3873             gl::Program *programObject = context->getProgram(program);
3874 
3875             if (!programObject)
3876             {
3877                 if (context->getShader(program))
3878                 {
3879                     return error(GL_INVALID_OPERATION);
3880                 }
3881                 else
3882                 {
3883                     return error(GL_INVALID_VALUE);
3884                 }
3885             }
3886 
3887             programObject->link();
3888         }
3889     }
3890     catch(std::bad_alloc&)
3891     {
3892         return error(GL_OUT_OF_MEMORY);
3893     }
3894 }
3895 
glPixelStorei(GLenum pname,GLint param)3896 void __stdcall glPixelStorei(GLenum pname, GLint param)
3897 {
3898     TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3899 
3900     try
3901     {
3902         gl::Context *context = gl::getContext();
3903 
3904         if (context)
3905         {
3906             switch (pname)
3907             {
3908               case GL_UNPACK_ALIGNMENT:
3909                 if (param != 1 && param != 2 && param != 4 && param != 8)
3910                 {
3911                     return error(GL_INVALID_VALUE);
3912                 }
3913 
3914                 context->setUnpackAlignment(param);
3915                 break;
3916 
3917               case GL_PACK_ALIGNMENT:
3918                 if (param != 1 && param != 2 && param != 4 && param != 8)
3919                 {
3920                     return error(GL_INVALID_VALUE);
3921                 }
3922 
3923                 context->setPackAlignment(param);
3924                 break;
3925 
3926               default:
3927                 return error(GL_INVALID_ENUM);
3928             }
3929         }
3930     }
3931     catch(std::bad_alloc&)
3932     {
3933         return error(GL_OUT_OF_MEMORY);
3934     }
3935 }
3936 
glPolygonOffset(GLfloat factor,GLfloat units)3937 void __stdcall glPolygonOffset(GLfloat factor, GLfloat units)
3938 {
3939     TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3940 
3941     try
3942     {
3943         gl::Context *context = gl::getContext();
3944 
3945         if (context)
3946         {
3947             context->setPolygonOffsetParams(factor, units);
3948         }
3949     }
3950     catch(std::bad_alloc&)
3951     {
3952         return error(GL_OUT_OF_MEMORY);
3953     }
3954 }
3955 
glReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3956 void __stdcall glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
3957 {
3958     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3959           "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = 0x%0.8p)",
3960           x, y, width, height, format, type,  pixels);
3961 
3962     try
3963     {
3964         if (width < 0 || height < 0)
3965         {
3966             return error(GL_INVALID_VALUE);
3967         }
3968 
3969         switch (format)
3970         {
3971           case GL_RGBA:
3972             switch (type)
3973             {
3974               case GL_UNSIGNED_BYTE:
3975                 break;
3976               default:
3977                 return error(GL_INVALID_OPERATION);
3978             }
3979             break;
3980           case GL_BGRA_EXT:
3981             switch (type)
3982             {
3983               case GL_UNSIGNED_BYTE:
3984               case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT:
3985               case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT:
3986                 break;
3987               default:
3988                 return error(GL_INVALID_OPERATION);
3989             }
3990             break;
3991           case gl::IMPLEMENTATION_COLOR_READ_FORMAT:
3992             switch (type)
3993             {
3994               case gl::IMPLEMENTATION_COLOR_READ_TYPE:
3995                 break;
3996               default:
3997                 return error(GL_INVALID_OPERATION);
3998             }
3999             break;
4000           default:
4001             return error(GL_INVALID_OPERATION);
4002         }
4003 
4004         gl::Context *context = gl::getContext();
4005 
4006         if (context)
4007         {
4008             context->readPixels(x, y, width, height, format, type, pixels);
4009         }
4010     }
4011     catch(std::bad_alloc&)
4012     {
4013         return error(GL_OUT_OF_MEMORY);
4014     }
4015 }
4016 
glReleaseShaderCompiler(void)4017 void __stdcall glReleaseShaderCompiler(void)
4018 {
4019     TRACE("()");
4020 
4021     try
4022     {
4023         gl::Shader::releaseCompiler();
4024     }
4025     catch(std::bad_alloc&)
4026     {
4027         return error(GL_OUT_OF_MEMORY);
4028     }
4029 }
4030 
glRenderbufferStorageMultisampleANGLE(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)4031 void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4032 {
4033     TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4034           target, samples, internalformat, width, height);
4035 
4036     try
4037     {
4038         switch (target)
4039         {
4040           case GL_RENDERBUFFER:
4041             break;
4042           default:
4043             return error(GL_INVALID_ENUM);
4044         }
4045 
4046         if (!gl::IsColorRenderable(internalformat) && !gl::IsDepthRenderable(internalformat) && !gl::IsStencilRenderable(internalformat))
4047         {
4048             return error(GL_INVALID_ENUM);
4049         }
4050 
4051         if (width < 0 || height < 0 || samples < 0)
4052         {
4053             return error(GL_INVALID_VALUE);
4054         }
4055 
4056         gl::Context *context = gl::getContext();
4057 
4058         if (context)
4059         {
4060             if (width > context->getMaximumRenderbufferDimension() ||
4061                 height > context->getMaximumRenderbufferDimension() ||
4062                 samples > context->getMaxSupportedSamples())
4063             {
4064                 return error(GL_INVALID_VALUE);
4065             }
4066 
4067             GLuint handle = context->getRenderbufferHandle();
4068             if (handle == 0)
4069             {
4070                 return error(GL_INVALID_OPERATION);
4071             }
4072 
4073             switch (internalformat)
4074             {
4075               case GL_DEPTH_COMPONENT16:
4076                 context->setRenderbufferStorage(new gl::Depthbuffer(width, height, samples));
4077                 break;
4078               case GL_RGBA4:
4079               case GL_RGB5_A1:
4080               case GL_RGB565:
4081               case GL_RGB8_OES:
4082               case GL_RGBA8_OES:
4083                 context->setRenderbufferStorage(new gl::Colorbuffer(width, height, internalformat, samples));
4084                 break;
4085               case GL_STENCIL_INDEX8:
4086                 context->setRenderbufferStorage(new gl::Stencilbuffer(width, height, samples));
4087                 break;
4088               case GL_DEPTH24_STENCIL8_OES:
4089                 context->setRenderbufferStorage(new gl::DepthStencilbuffer(width, height, samples));
4090                 break;
4091               default:
4092                 return error(GL_INVALID_ENUM);
4093             }
4094         }
4095     }
4096     catch(std::bad_alloc&)
4097     {
4098         return error(GL_OUT_OF_MEMORY);
4099     }
4100 }
4101 
glRenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)4102 void __stdcall glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4103 {
4104     glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4105 }
4106 
glSampleCoverage(GLclampf value,GLboolean invert)4107 void __stdcall glSampleCoverage(GLclampf value, GLboolean invert)
4108 {
4109     TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4110 
4111     try
4112     {
4113         gl::Context* context = gl::getContext();
4114 
4115         if (context)
4116         {
4117             context->setSampleCoverageParams(gl::clamp01(value), invert == GL_TRUE);
4118         }
4119     }
4120     catch(std::bad_alloc&)
4121     {
4122         return error(GL_OUT_OF_MEMORY);
4123     }
4124 }
4125 
glSetFenceNV(GLuint fence,GLenum condition)4126 void __stdcall glSetFenceNV(GLuint fence, GLenum condition)
4127 {
4128     TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4129 
4130     try
4131     {
4132         if (condition != GL_ALL_COMPLETED_NV)
4133         {
4134             return error(GL_INVALID_ENUM);
4135         }
4136 
4137         gl::Context *context = gl::getContext();
4138 
4139         if (context)
4140         {
4141             gl::Fence *fenceObject = context->getFence(fence);
4142 
4143             if (fenceObject == NULL)
4144             {
4145                 return error(GL_INVALID_OPERATION);
4146             }
4147 
4148             fenceObject->setFence(condition);
4149         }
4150     }
4151     catch(std::bad_alloc&)
4152     {
4153         return error(GL_OUT_OF_MEMORY);
4154     }
4155 }
4156 
glScissor(GLint x,GLint y,GLsizei width,GLsizei height)4157 void __stdcall glScissor(GLint x, GLint y, GLsizei width, GLsizei height)
4158 {
4159     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4160 
4161     try
4162     {
4163         if (width < 0 || height < 0)
4164         {
4165             return error(GL_INVALID_VALUE);
4166         }
4167 
4168         gl::Context* context = gl::getContext();
4169 
4170         if (context)
4171         {
4172             context->setScissorParams(x, y, width, height);
4173         }
4174     }
4175     catch(std::bad_alloc&)
4176     {
4177         return error(GL_OUT_OF_MEMORY);
4178     }
4179 }
4180 
glShaderBinary(GLsizei n,const GLuint * shaders,GLenum binaryformat,const GLvoid * binary,GLsizei length)4181 void __stdcall glShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4182 {
4183     TRACE("(GLsizei n = %d, const GLuint* shaders = 0x%0.8p, GLenum binaryformat = 0x%X, "
4184           "const GLvoid* binary = 0x%0.8p, GLsizei length = %d)",
4185           n, shaders, binaryformat, binary, length);
4186 
4187     try
4188     {
4189         // No binary shader formats are supported.
4190         return error(GL_INVALID_ENUM);
4191     }
4192     catch(std::bad_alloc&)
4193     {
4194         return error(GL_OUT_OF_MEMORY);
4195     }
4196 }
4197 
glShaderSource(GLuint shader,GLsizei count,const GLchar ** string,const GLint * length)4198 void __stdcall glShaderSource(GLuint shader, GLsizei count, const GLchar** string, const GLint* length)
4199 {
4200     TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = 0x%0.8p, const GLint* length = 0x%0.8p)",
4201           shader, count, string, length);
4202 
4203     try
4204     {
4205         if (count < 0)
4206         {
4207             return error(GL_INVALID_VALUE);
4208         }
4209 
4210         gl::Context *context = gl::getContext();
4211 
4212         if (context)
4213         {
4214             gl::Shader *shaderObject = context->getShader(shader);
4215 
4216             if (!shaderObject)
4217             {
4218                 if (context->getProgram(shader))
4219                 {
4220                     return error(GL_INVALID_OPERATION);
4221                 }
4222                 else
4223                 {
4224                     return error(GL_INVALID_VALUE);
4225                 }
4226             }
4227 
4228             shaderObject->setSource(count, string, length);
4229         }
4230     }
4231     catch(std::bad_alloc&)
4232     {
4233         return error(GL_OUT_OF_MEMORY);
4234     }
4235 }
4236 
glStencilFunc(GLenum func,GLint ref,GLuint mask)4237 void __stdcall glStencilFunc(GLenum func, GLint ref, GLuint mask)
4238 {
4239     glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4240 }
4241 
glStencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)4242 void __stdcall glStencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4243 {
4244     TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4245 
4246     try
4247     {
4248         switch (face)
4249         {
4250           case GL_FRONT:
4251           case GL_BACK:
4252           case GL_FRONT_AND_BACK:
4253             break;
4254           default:
4255             return error(GL_INVALID_ENUM);
4256         }
4257 
4258         switch (func)
4259         {
4260           case GL_NEVER:
4261           case GL_ALWAYS:
4262           case GL_LESS:
4263           case GL_LEQUAL:
4264           case GL_EQUAL:
4265           case GL_GEQUAL:
4266           case GL_GREATER:
4267           case GL_NOTEQUAL:
4268             break;
4269           default:
4270             return error(GL_INVALID_ENUM);
4271         }
4272 
4273         gl::Context *context = gl::getContext();
4274 
4275         if (context)
4276         {
4277             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4278             {
4279                 context->setStencilParams(func, ref, mask);
4280             }
4281 
4282             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4283             {
4284                 context->setStencilBackParams(func, ref, mask);
4285             }
4286         }
4287     }
4288     catch(std::bad_alloc&)
4289     {
4290         return error(GL_OUT_OF_MEMORY);
4291     }
4292 }
4293 
glStencilMask(GLuint mask)4294 void __stdcall glStencilMask(GLuint mask)
4295 {
4296     glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4297 }
4298 
glStencilMaskSeparate(GLenum face,GLuint mask)4299 void __stdcall glStencilMaskSeparate(GLenum face, GLuint mask)
4300 {
4301     TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4302 
4303     try
4304     {
4305         switch (face)
4306         {
4307           case GL_FRONT:
4308           case GL_BACK:
4309           case GL_FRONT_AND_BACK:
4310             break;
4311           default:
4312             return error(GL_INVALID_ENUM);
4313         }
4314 
4315         gl::Context *context = gl::getContext();
4316 
4317         if (context)
4318         {
4319             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4320             {
4321                 context->setStencilWritemask(mask);
4322             }
4323 
4324             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4325             {
4326                 context->setStencilBackWritemask(mask);
4327             }
4328         }
4329     }
4330     catch(std::bad_alloc&)
4331     {
4332         return error(GL_OUT_OF_MEMORY);
4333     }
4334 }
4335 
glStencilOp(GLenum fail,GLenum zfail,GLenum zpass)4336 void __stdcall glStencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4337 {
4338     glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4339 }
4340 
glStencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)4341 void __stdcall glStencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4342 {
4343     TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4344           face, fail, zfail, zpass);
4345 
4346     try
4347     {
4348         switch (face)
4349         {
4350           case GL_FRONT:
4351           case GL_BACK:
4352           case GL_FRONT_AND_BACK:
4353             break;
4354           default:
4355             return error(GL_INVALID_ENUM);
4356         }
4357 
4358         switch (fail)
4359         {
4360           case GL_ZERO:
4361           case GL_KEEP:
4362           case GL_REPLACE:
4363           case GL_INCR:
4364           case GL_DECR:
4365           case GL_INVERT:
4366           case GL_INCR_WRAP:
4367           case GL_DECR_WRAP:
4368             break;
4369           default:
4370             return error(GL_INVALID_ENUM);
4371         }
4372 
4373         switch (zfail)
4374         {
4375           case GL_ZERO:
4376           case GL_KEEP:
4377           case GL_REPLACE:
4378           case GL_INCR:
4379           case GL_DECR:
4380           case GL_INVERT:
4381           case GL_INCR_WRAP:
4382           case GL_DECR_WRAP:
4383             break;
4384           default:
4385             return error(GL_INVALID_ENUM);
4386         }
4387 
4388         switch (zpass)
4389         {
4390           case GL_ZERO:
4391           case GL_KEEP:
4392           case GL_REPLACE:
4393           case GL_INCR:
4394           case GL_DECR:
4395           case GL_INVERT:
4396           case GL_INCR_WRAP:
4397           case GL_DECR_WRAP:
4398             break;
4399           default:
4400             return error(GL_INVALID_ENUM);
4401         }
4402 
4403         gl::Context *context = gl::getContext();
4404 
4405         if (context)
4406         {
4407             if (face == GL_FRONT || face == GL_FRONT_AND_BACK)
4408             {
4409                 context->setStencilOperations(fail, zfail, zpass);
4410             }
4411 
4412             if (face == GL_BACK || face == GL_FRONT_AND_BACK)
4413             {
4414                 context->setStencilBackOperations(fail, zfail, zpass);
4415             }
4416         }
4417     }
4418     catch(std::bad_alloc&)
4419     {
4420         return error(GL_OUT_OF_MEMORY);
4421     }
4422 }
4423 
glTestFenceNV(GLuint fence)4424 GLboolean __stdcall glTestFenceNV(GLuint fence)
4425 {
4426     TRACE("(GLuint fence = %d)", fence);
4427 
4428     try
4429     {
4430         gl::Context *context = gl::getContext();
4431 
4432         if (context)
4433         {
4434             gl::Fence *fenceObject = context->getFence(fence);
4435 
4436             if (fenceObject == NULL)
4437             {
4438                 return error(GL_INVALID_OPERATION, GL_TRUE);
4439             }
4440 
4441             return fenceObject->testFence();
4442         }
4443     }
4444     catch(std::bad_alloc&)
4445     {
4446         error(GL_OUT_OF_MEMORY);
4447     }
4448 
4449     return GL_TRUE;
4450 }
4451 
glTexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4452 void __stdcall glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4453                             GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4454 {
4455     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4456           "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  0x%0.8p)",
4457           target, level, internalformat, width, height, border, format, type, pixels);
4458 
4459     try
4460     {
4461         if (level < 0 || width < 0 || height < 0)
4462         {
4463             return error(GL_INVALID_VALUE);
4464         }
4465 
4466         if (level > 0 && (!gl::isPow2(width) || !gl::isPow2(height)))
4467         {
4468             return error(GL_INVALID_VALUE);
4469         }
4470 
4471         if (internalformat != format)
4472         {
4473             return error(GL_INVALID_OPERATION);
4474         }
4475 
4476         switch (internalformat)
4477         {
4478           case GL_ALPHA:
4479           case GL_LUMINANCE:
4480           case GL_LUMINANCE_ALPHA:
4481             switch (type)
4482             {
4483               case GL_UNSIGNED_BYTE:
4484               case GL_FLOAT:
4485               case GL_HALF_FLOAT_OES:
4486                 break;
4487               default:
4488                 return error(GL_INVALID_ENUM);
4489             }
4490             break;
4491           case GL_RGB:
4492             switch (type)
4493             {
4494               case GL_UNSIGNED_BYTE:
4495               case GL_UNSIGNED_SHORT_5_6_5:
4496               case GL_FLOAT:
4497               case GL_HALF_FLOAT_OES:
4498                 break;
4499               default:
4500                 return error(GL_INVALID_ENUM);
4501             }
4502             break;
4503           case GL_RGBA:
4504             switch (type)
4505             {
4506               case GL_UNSIGNED_BYTE:
4507               case GL_UNSIGNED_SHORT_4_4_4_4:
4508               case GL_UNSIGNED_SHORT_5_5_5_1:
4509               case GL_FLOAT:
4510               case GL_HALF_FLOAT_OES:
4511                 break;
4512               default:
4513                 return error(GL_INVALID_ENUM);
4514             }
4515             break;
4516           case GL_BGRA_EXT:
4517             switch (type)
4518             {
4519               case GL_UNSIGNED_BYTE:
4520                 break;
4521               default:
4522                 return error(GL_INVALID_ENUM);
4523             }
4524             break;
4525           case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:  // error cases for compressed textures are handled below
4526           case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4527             break;
4528           default:
4529             return error(GL_INVALID_VALUE);
4530         }
4531 
4532         if (border != 0)
4533         {
4534             return error(GL_INVALID_VALUE);
4535         }
4536 
4537         gl::Context *context = gl::getContext();
4538 
4539         if (context)
4540         {
4541             switch (target)
4542             {
4543               case GL_TEXTURE_2D:
4544                 if (width > (context->getMaximumTextureDimension() >> level) ||
4545                     height > (context->getMaximumTextureDimension() >> level))
4546                 {
4547                     return error(GL_INVALID_VALUE);
4548                 }
4549                 break;
4550               case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4551               case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4552               case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4553               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4554               case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4555               case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4556                 if (width != height)
4557                 {
4558                     return error(GL_INVALID_VALUE);
4559                 }
4560 
4561                 if (width > (context->getMaximumCubeTextureDimension() >> level) ||
4562                     height > (context->getMaximumCubeTextureDimension() >> level))
4563                 {
4564                     return error(GL_INVALID_VALUE);
4565                 }
4566                 break;
4567               default:
4568                 return error(GL_INVALID_ENUM);
4569             }
4570 
4571             if (internalformat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ||
4572                 internalformat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
4573             {
4574                 if (context->supportsCompressedTextures())
4575                 {
4576                     return error(GL_INVALID_OPERATION);
4577                 }
4578                 else
4579                 {
4580                     return error(GL_INVALID_ENUM);
4581                 }
4582             }
4583 
4584             if (type == GL_FLOAT)
4585             {
4586                 if (!context->supportsFloatTextures())
4587                 {
4588                     return error(GL_INVALID_ENUM);
4589                 }
4590             }
4591             else if (type == GL_HALF_FLOAT_OES)
4592             {
4593                 if (!context->supportsHalfFloatTextures())
4594                 {
4595                     return error(GL_INVALID_ENUM);
4596                 }
4597             }
4598 
4599             if (target == GL_TEXTURE_2D)
4600             {
4601                 gl::Texture2D *texture = context->getTexture2D();
4602 
4603                 if (!texture)
4604                 {
4605                     return error(GL_INVALID_OPERATION);
4606                 }
4607 
4608                 texture->setImage(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4609             }
4610             else
4611             {
4612                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4613 
4614                 if (!texture)
4615                 {
4616                     return error(GL_INVALID_OPERATION);
4617                 }
4618 
4619                 switch (target)
4620                 {
4621                   case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
4622                     texture->setImagePosX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4623                     break;
4624                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
4625                     texture->setImageNegX(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4626                     break;
4627                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
4628                     texture->setImagePosY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4629                     break;
4630                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
4631                     texture->setImageNegY(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4632                     break;
4633                   case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
4634                     texture->setImagePosZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4635                     break;
4636                   case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
4637                     texture->setImageNegZ(level, internalformat, width, height, format, type, context->getUnpackAlignment(), pixels);
4638                     break;
4639                   default: UNREACHABLE();
4640                 }
4641             }
4642         }
4643     }
4644     catch(std::bad_alloc&)
4645     {
4646         return error(GL_OUT_OF_MEMORY);
4647     }
4648 }
4649 
glTexParameterf(GLenum target,GLenum pname,GLfloat param)4650 void __stdcall glTexParameterf(GLenum target, GLenum pname, GLfloat param)
4651 {
4652     glTexParameteri(target, pname, (GLint)param);
4653 }
4654 
glTexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4655 void __stdcall glTexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4656 {
4657     glTexParameteri(target, pname, (GLint)*params);
4658 }
4659 
glTexParameteri(GLenum target,GLenum pname,GLint param)4660 void __stdcall glTexParameteri(GLenum target, GLenum pname, GLint param)
4661 {
4662     TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4663 
4664     try
4665     {
4666         gl::Context *context = gl::getContext();
4667 
4668         if (context)
4669         {
4670             gl::Texture *texture;
4671 
4672             switch (target)
4673             {
4674               case GL_TEXTURE_2D:
4675                 texture = context->getTexture2D();
4676                 break;
4677               case GL_TEXTURE_CUBE_MAP:
4678                 texture = context->getTextureCubeMap();
4679                 break;
4680               default:
4681                 return error(GL_INVALID_ENUM);
4682             }
4683 
4684             switch (pname)
4685             {
4686               case GL_TEXTURE_WRAP_S:
4687                 if (!texture->setWrapS((GLenum)param))
4688                 {
4689                     return error(GL_INVALID_ENUM);
4690                 }
4691                 break;
4692               case GL_TEXTURE_WRAP_T:
4693                 if (!texture->setWrapT((GLenum)param))
4694                 {
4695                     return error(GL_INVALID_ENUM);
4696                 }
4697                 break;
4698               case GL_TEXTURE_MIN_FILTER:
4699                 if (!texture->setMinFilter((GLenum)param))
4700                 {
4701                     return error(GL_INVALID_ENUM);
4702                 }
4703                 break;
4704               case GL_TEXTURE_MAG_FILTER:
4705                 if (!texture->setMagFilter((GLenum)param))
4706                 {
4707                     return error(GL_INVALID_ENUM);
4708                 }
4709                 break;
4710               default:
4711                 return error(GL_INVALID_ENUM);
4712             }
4713         }
4714     }
4715     catch(std::bad_alloc&)
4716     {
4717         return error(GL_OUT_OF_MEMORY);
4718     }
4719 }
4720 
glTexParameteriv(GLenum target,GLenum pname,const GLint * params)4721 void __stdcall glTexParameteriv(GLenum target, GLenum pname, const GLint* params)
4722 {
4723     glTexParameteri(target, pname, *params);
4724 }
4725 
glTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4726 void __stdcall glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4727                                GLenum format, GLenum type, const GLvoid* pixels)
4728 {
4729     TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4730           "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4731           "const GLvoid* pixels = 0x%0.8p)",
4732            target, level, xoffset, yoffset, width, height, format, type, pixels);
4733 
4734     try
4735     {
4736         if (!gl::IsTextureTarget(target))
4737         {
4738             return error(GL_INVALID_ENUM);
4739         }
4740 
4741         if (level < 0 || xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4742         {
4743             return error(GL_INVALID_VALUE);
4744         }
4745 
4746         if (std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4747         {
4748             return error(GL_INVALID_VALUE);
4749         }
4750 
4751         if (!gl::CheckTextureFormatType(format, type))
4752         {
4753             return error(GL_INVALID_ENUM);
4754         }
4755 
4756         if (width == 0 || height == 0 || pixels == NULL)
4757         {
4758             return;
4759         }
4760 
4761         gl::Context *context = gl::getContext();
4762 
4763         if (context)
4764         {
4765             if (level > context->getMaximumTextureLevel())
4766             {
4767                 return error(GL_INVALID_VALUE);
4768             }
4769 
4770             if (format == GL_FLOAT)
4771             {
4772                 if (!context->supportsFloatTextures())
4773                 {
4774                     return error(GL_INVALID_ENUM);
4775                 }
4776             }
4777             else if (format == GL_HALF_FLOAT_OES)
4778             {
4779                 if (!context->supportsHalfFloatTextures())
4780                 {
4781                     return error(GL_INVALID_ENUM);
4782                 }
4783             }
4784 
4785             if (target == GL_TEXTURE_2D)
4786             {
4787                 gl::Texture2D *texture = context->getTexture2D();
4788 
4789                 if (!texture)
4790                 {
4791                     return error(GL_INVALID_OPERATION);
4792                 }
4793 
4794                 if (texture->isCompressed())
4795                 {
4796                     return error(GL_INVALID_OPERATION);
4797                 }
4798 
4799                 if (format != texture->getFormat())
4800                 {
4801                     return error(GL_INVALID_OPERATION);
4802                 }
4803 
4804                 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4805             }
4806             else if (gl::IsCubemapTextureTarget(target))
4807             {
4808                 gl::TextureCubeMap *texture = context->getTextureCubeMap();
4809 
4810                 if (!texture)
4811                 {
4812                     return error(GL_INVALID_OPERATION);
4813                 }
4814 
4815                 if (texture->isCompressed())
4816                 {
4817                     return error(GL_INVALID_OPERATION);
4818                 }
4819 
4820                 if (format != texture->getFormat())
4821                 {
4822                     return error(GL_INVALID_OPERATION);
4823                 }
4824 
4825                 texture->subImage(target, level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4826             }
4827             else
4828             {
4829                 UNREACHABLE();
4830             }
4831         }
4832     }
4833     catch(std::bad_alloc&)
4834     {
4835         return error(GL_OUT_OF_MEMORY);
4836     }
4837 }
4838 
glUniform1f(GLint location,GLfloat x)4839 void __stdcall glUniform1f(GLint location, GLfloat x)
4840 {
4841     glUniform1fv(location, 1, &x);
4842 }
4843 
glUniform1fv(GLint location,GLsizei count,const GLfloat * v)4844 void __stdcall glUniform1fv(GLint location, GLsizei count, const GLfloat* v)
4845 {
4846     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4847 
4848     try
4849     {
4850         if (count < 0)
4851         {
4852             return error(GL_INVALID_VALUE);
4853         }
4854 
4855         if (location == -1)
4856         {
4857             return;
4858         }
4859 
4860         gl::Context *context = gl::getContext();
4861 
4862         if (context)
4863         {
4864             gl::Program *program = context->getCurrentProgram();
4865 
4866             if (!program)
4867             {
4868                 return error(GL_INVALID_OPERATION);
4869             }
4870 
4871             if (!program->setUniform1fv(location, count, v))
4872             {
4873                 return error(GL_INVALID_OPERATION);
4874             }
4875         }
4876     }
4877     catch(std::bad_alloc&)
4878     {
4879         return error(GL_OUT_OF_MEMORY);
4880     }
4881 }
4882 
glUniform1i(GLint location,GLint x)4883 void __stdcall glUniform1i(GLint location, GLint x)
4884 {
4885     glUniform1iv(location, 1, &x);
4886 }
4887 
glUniform1iv(GLint location,GLsizei count,const GLint * v)4888 void __stdcall glUniform1iv(GLint location, GLsizei count, const GLint* v)
4889 {
4890     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4891 
4892     try
4893     {
4894         if (count < 0)
4895         {
4896             return error(GL_INVALID_VALUE);
4897         }
4898 
4899         if (location == -1)
4900         {
4901             return;
4902         }
4903 
4904         gl::Context *context = gl::getContext();
4905 
4906         if (context)
4907         {
4908             gl::Program *program = context->getCurrentProgram();
4909 
4910             if (!program)
4911             {
4912                 return error(GL_INVALID_OPERATION);
4913             }
4914 
4915             if (!program->setUniform1iv(location, count, v))
4916             {
4917                 return error(GL_INVALID_OPERATION);
4918             }
4919         }
4920     }
4921     catch(std::bad_alloc&)
4922     {
4923         return error(GL_OUT_OF_MEMORY);
4924     }
4925 }
4926 
glUniform2f(GLint location,GLfloat x,GLfloat y)4927 void __stdcall glUniform2f(GLint location, GLfloat x, GLfloat y)
4928 {
4929     GLfloat xy[2] = {x, y};
4930 
4931     glUniform2fv(location, 1, (GLfloat*)&xy);
4932 }
4933 
glUniform2fv(GLint location,GLsizei count,const GLfloat * v)4934 void __stdcall glUniform2fv(GLint location, GLsizei count, const GLfloat* v)
4935 {
4936     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
4937 
4938     try
4939     {
4940         if (count < 0)
4941         {
4942             return error(GL_INVALID_VALUE);
4943         }
4944 
4945         if (location == -1)
4946         {
4947             return;
4948         }
4949 
4950         gl::Context *context = gl::getContext();
4951 
4952         if (context)
4953         {
4954             gl::Program *program = context->getCurrentProgram();
4955 
4956             if (!program)
4957             {
4958                 return error(GL_INVALID_OPERATION);
4959             }
4960 
4961             if (!program->setUniform2fv(location, count, v))
4962             {
4963                 return error(GL_INVALID_OPERATION);
4964             }
4965         }
4966     }
4967     catch(std::bad_alloc&)
4968     {
4969         return error(GL_OUT_OF_MEMORY);
4970     }
4971 }
4972 
glUniform2i(GLint location,GLint x,GLint y)4973 void __stdcall glUniform2i(GLint location, GLint x, GLint y)
4974 {
4975     GLint xy[4] = {x, y};
4976 
4977     glUniform2iv(location, 1, (GLint*)&xy);
4978 }
4979 
glUniform2iv(GLint location,GLsizei count,const GLint * v)4980 void __stdcall glUniform2iv(GLint location, GLsizei count, const GLint* v)
4981 {
4982     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
4983 
4984     try
4985     {
4986         if (count < 0)
4987         {
4988             return error(GL_INVALID_VALUE);
4989         }
4990 
4991         if (location == -1)
4992         {
4993             return;
4994         }
4995 
4996         gl::Context *context = gl::getContext();
4997 
4998         if (context)
4999         {
5000             gl::Program *program = context->getCurrentProgram();
5001 
5002             if (!program)
5003             {
5004                 return error(GL_INVALID_OPERATION);
5005             }
5006 
5007             if (!program->setUniform2iv(location, count, v))
5008             {
5009                 return error(GL_INVALID_OPERATION);
5010             }
5011         }
5012     }
5013     catch(std::bad_alloc&)
5014     {
5015         return error(GL_OUT_OF_MEMORY);
5016     }
5017 }
5018 
glUniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)5019 void __stdcall glUniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5020 {
5021     GLfloat xyz[3] = {x, y, z};
5022 
5023     glUniform3fv(location, 1, (GLfloat*)&xyz);
5024 }
5025 
glUniform3fv(GLint location,GLsizei count,const GLfloat * v)5026 void __stdcall glUniform3fv(GLint location, GLsizei count, const GLfloat* v)
5027 {
5028     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
5029 
5030     try
5031     {
5032         if (count < 0)
5033         {
5034             return error(GL_INVALID_VALUE);
5035         }
5036 
5037         if (location == -1)
5038         {
5039             return;
5040         }
5041 
5042         gl::Context *context = gl::getContext();
5043 
5044         if (context)
5045         {
5046             gl::Program *program = context->getCurrentProgram();
5047 
5048             if (!program)
5049             {
5050                 return error(GL_INVALID_OPERATION);
5051             }
5052 
5053             if (!program->setUniform3fv(location, count, v))
5054             {
5055                 return error(GL_INVALID_OPERATION);
5056             }
5057         }
5058     }
5059     catch(std::bad_alloc&)
5060     {
5061         return error(GL_OUT_OF_MEMORY);
5062     }
5063 }
5064 
glUniform3i(GLint location,GLint x,GLint y,GLint z)5065 void __stdcall glUniform3i(GLint location, GLint x, GLint y, GLint z)
5066 {
5067     GLint xyz[3] = {x, y, z};
5068 
5069     glUniform3iv(location, 1, (GLint*)&xyz);
5070 }
5071 
glUniform3iv(GLint location,GLsizei count,const GLint * v)5072 void __stdcall glUniform3iv(GLint location, GLsizei count, const GLint* v)
5073 {
5074     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
5075 
5076     try
5077     {
5078         if (count < 0)
5079         {
5080             return error(GL_INVALID_VALUE);
5081         }
5082 
5083         if (location == -1)
5084         {
5085             return;
5086         }
5087 
5088         gl::Context *context = gl::getContext();
5089 
5090         if (context)
5091         {
5092             gl::Program *program = context->getCurrentProgram();
5093 
5094             if (!program)
5095             {
5096                 return error(GL_INVALID_OPERATION);
5097             }
5098 
5099             if (!program->setUniform3iv(location, count, v))
5100             {
5101                 return error(GL_INVALID_OPERATION);
5102             }
5103         }
5104     }
5105     catch(std::bad_alloc&)
5106     {
5107         return error(GL_OUT_OF_MEMORY);
5108     }
5109 }
5110 
glUniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)5111 void __stdcall glUniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5112 {
5113     GLfloat xyzw[4] = {x, y, z, w};
5114 
5115     glUniform4fv(location, 1, (GLfloat*)&xyzw);
5116 }
5117 
glUniform4fv(GLint location,GLsizei count,const GLfloat * v)5118 void __stdcall glUniform4fv(GLint location, GLsizei count, const GLfloat* v)
5119 {
5120     TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = 0x%0.8p)", location, count, v);
5121 
5122     try
5123     {
5124         if (count < 0)
5125         {
5126             return error(GL_INVALID_VALUE);
5127         }
5128 
5129         if (location == -1)
5130         {
5131             return;
5132         }
5133 
5134         gl::Context *context = gl::getContext();
5135 
5136         if (context)
5137         {
5138             gl::Program *program = context->getCurrentProgram();
5139 
5140             if (!program)
5141             {
5142                 return error(GL_INVALID_OPERATION);
5143             }
5144 
5145             if (!program->setUniform4fv(location, count, v))
5146             {
5147                 return error(GL_INVALID_OPERATION);
5148             }
5149         }
5150     }
5151     catch(std::bad_alloc&)
5152     {
5153         return error(GL_OUT_OF_MEMORY);
5154     }
5155 }
5156 
glUniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)5157 void __stdcall glUniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5158 {
5159     GLint xyzw[4] = {x, y, z, w};
5160 
5161     glUniform4iv(location, 1, (GLint*)&xyzw);
5162 }
5163 
glUniform4iv(GLint location,GLsizei count,const GLint * v)5164 void __stdcall glUniform4iv(GLint location, GLsizei count, const GLint* v)
5165 {
5166     TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = 0x%0.8p)", location, count, v);
5167 
5168     try
5169     {
5170         if (count < 0)
5171         {
5172             return error(GL_INVALID_VALUE);
5173         }
5174 
5175         if (location == -1)
5176         {
5177             return;
5178         }
5179 
5180         gl::Context *context = gl::getContext();
5181 
5182         if (context)
5183         {
5184             gl::Program *program = context->getCurrentProgram();
5185 
5186             if (!program)
5187             {
5188                 return error(GL_INVALID_OPERATION);
5189             }
5190 
5191             if (!program->setUniform4iv(location, count, v))
5192             {
5193                 return error(GL_INVALID_OPERATION);
5194             }
5195         }
5196     }
5197     catch(std::bad_alloc&)
5198     {
5199         return error(GL_OUT_OF_MEMORY);
5200     }
5201 }
5202 
glUniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5203 void __stdcall glUniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5204 {
5205     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5206           location, count, transpose, value);
5207 
5208     try
5209     {
5210         if (count < 0 || transpose != GL_FALSE)
5211         {
5212             return error(GL_INVALID_VALUE);
5213         }
5214 
5215         if (location == -1)
5216         {
5217             return;
5218         }
5219 
5220         gl::Context *context = gl::getContext();
5221 
5222         if (context)
5223         {
5224             gl::Program *program = context->getCurrentProgram();
5225 
5226             if (!program)
5227             {
5228                 return error(GL_INVALID_OPERATION);
5229             }
5230 
5231             if (!program->setUniformMatrix2fv(location, count, value))
5232             {
5233                 return error(GL_INVALID_OPERATION);
5234             }
5235         }
5236     }
5237     catch(std::bad_alloc&)
5238     {
5239         return error(GL_OUT_OF_MEMORY);
5240     }
5241 }
5242 
glUniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5243 void __stdcall glUniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5244 {
5245     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5246           location, count, transpose, value);
5247 
5248     try
5249     {
5250         if (count < 0 || transpose != GL_FALSE)
5251         {
5252             return error(GL_INVALID_VALUE);
5253         }
5254 
5255         if (location == -1)
5256         {
5257             return;
5258         }
5259 
5260         gl::Context *context = gl::getContext();
5261 
5262         if (context)
5263         {
5264             gl::Program *program = context->getCurrentProgram();
5265 
5266             if (!program)
5267             {
5268                 return error(GL_INVALID_OPERATION);
5269             }
5270 
5271             if (!program->setUniformMatrix3fv(location, count, value))
5272             {
5273                 return error(GL_INVALID_OPERATION);
5274             }
5275         }
5276     }
5277     catch(std::bad_alloc&)
5278     {
5279         return error(GL_OUT_OF_MEMORY);
5280     }
5281 }
5282 
glUniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5283 void __stdcall glUniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5284 {
5285     TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = 0x%0.8p)",
5286           location, count, transpose, value);
5287 
5288     try
5289     {
5290         if (count < 0 || transpose != GL_FALSE)
5291         {
5292             return error(GL_INVALID_VALUE);
5293         }
5294 
5295         if (location == -1)
5296         {
5297             return;
5298         }
5299 
5300         gl::Context *context = gl::getContext();
5301 
5302         if (context)
5303         {
5304             gl::Program *program = context->getCurrentProgram();
5305 
5306             if (!program)
5307             {
5308                 return error(GL_INVALID_OPERATION);
5309             }
5310 
5311             if (!program->setUniformMatrix4fv(location, count, value))
5312             {
5313                 return error(GL_INVALID_OPERATION);
5314             }
5315         }
5316     }
5317     catch(std::bad_alloc&)
5318     {
5319         return error(GL_OUT_OF_MEMORY);
5320     }
5321 }
5322 
glUseProgram(GLuint program)5323 void __stdcall glUseProgram(GLuint program)
5324 {
5325     TRACE("(GLuint program = %d)", program);
5326 
5327     try
5328     {
5329         gl::Context *context = gl::getContext();
5330 
5331         if (context)
5332         {
5333             gl::Program *programObject = context->getProgram(program);
5334 
5335             if (!programObject && program != 0)
5336             {
5337                 if (context->getShader(program))
5338                 {
5339                     return error(GL_INVALID_OPERATION);
5340                 }
5341                 else
5342                 {
5343                     return error(GL_INVALID_VALUE);
5344                 }
5345             }
5346 
5347             if (program != 0 && !programObject->isLinked())
5348             {
5349                 return error(GL_INVALID_OPERATION);
5350             }
5351 
5352             context->useProgram(program);
5353         }
5354     }
5355     catch(std::bad_alloc&)
5356     {
5357         return error(GL_OUT_OF_MEMORY);
5358     }
5359 }
5360 
glValidateProgram(GLuint program)5361 void __stdcall glValidateProgram(GLuint program)
5362 {
5363     TRACE("(GLuint program = %d)", program);
5364 
5365     try
5366     {
5367         gl::Context *context = gl::getContext();
5368 
5369         if (context)
5370         {
5371             gl::Program *programObject = context->getProgram(program);
5372 
5373             if (!programObject)
5374             {
5375                 if (context->getShader(program))
5376                 {
5377                     return error(GL_INVALID_OPERATION);
5378                 }
5379                 else
5380                 {
5381                     return error(GL_INVALID_VALUE);
5382                 }
5383             }
5384 
5385             programObject->validate();
5386         }
5387     }
5388     catch(std::bad_alloc&)
5389     {
5390         return error(GL_OUT_OF_MEMORY);
5391     }
5392 }
5393 
glVertexAttrib1f(GLuint index,GLfloat x)5394 void __stdcall glVertexAttrib1f(GLuint index, GLfloat x)
5395 {
5396     TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
5397 
5398     try
5399     {
5400         if (index >= gl::MAX_VERTEX_ATTRIBS)
5401         {
5402             return error(GL_INVALID_VALUE);
5403         }
5404 
5405         gl::Context *context = gl::getContext();
5406 
5407         if (context)
5408         {
5409             GLfloat vals[4] = { x, 0, 0, 1 };
5410             context->setVertexAttrib(index, vals);
5411         }
5412     }
5413     catch(std::bad_alloc&)
5414     {
5415         return error(GL_OUT_OF_MEMORY);
5416     }
5417 }
5418 
glVertexAttrib1fv(GLuint index,const GLfloat * values)5419 void __stdcall glVertexAttrib1fv(GLuint index, const GLfloat* values)
5420 {
5421     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5422 
5423     try
5424     {
5425         if (index >= gl::MAX_VERTEX_ATTRIBS)
5426         {
5427             return error(GL_INVALID_VALUE);
5428         }
5429 
5430         gl::Context *context = gl::getContext();
5431 
5432         if (context)
5433         {
5434             GLfloat vals[4] = { values[0], 0, 0, 1 };
5435             context->setVertexAttrib(index, vals);
5436         }
5437     }
5438     catch(std::bad_alloc&)
5439     {
5440         return error(GL_OUT_OF_MEMORY);
5441     }
5442 }
5443 
glVertexAttrib2f(GLuint index,GLfloat x,GLfloat y)5444 void __stdcall glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
5445 {
5446     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
5447 
5448     try
5449     {
5450         if (index >= gl::MAX_VERTEX_ATTRIBS)
5451         {
5452             return error(GL_INVALID_VALUE);
5453         }
5454 
5455         gl::Context *context = gl::getContext();
5456 
5457         if (context)
5458         {
5459             GLfloat vals[4] = { x, y, 0, 1 };
5460             context->setVertexAttrib(index, vals);
5461         }
5462     }
5463     catch(std::bad_alloc&)
5464     {
5465         return error(GL_OUT_OF_MEMORY);
5466     }
5467 }
5468 
glVertexAttrib2fv(GLuint index,const GLfloat * values)5469 void __stdcall glVertexAttrib2fv(GLuint index, const GLfloat* values)
5470 {
5471     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5472 
5473     try
5474     {
5475         if (index >= gl::MAX_VERTEX_ATTRIBS)
5476         {
5477             return error(GL_INVALID_VALUE);
5478         }
5479 
5480         gl::Context *context = gl::getContext();
5481 
5482         if (context)
5483         {
5484             GLfloat vals[4] = { values[0], values[1], 0, 1 };
5485             context->setVertexAttrib(index, vals);
5486         }
5487     }
5488     catch(std::bad_alloc&)
5489     {
5490         return error(GL_OUT_OF_MEMORY);
5491     }
5492 }
5493 
glVertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)5494 void __stdcall glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
5495 {
5496     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
5497 
5498     try
5499     {
5500         if (index >= gl::MAX_VERTEX_ATTRIBS)
5501         {
5502             return error(GL_INVALID_VALUE);
5503         }
5504 
5505         gl::Context *context = gl::getContext();
5506 
5507         if (context)
5508         {
5509             GLfloat vals[4] = { x, y, z, 1 };
5510             context->setVertexAttrib(index, vals);
5511         }
5512     }
5513     catch(std::bad_alloc&)
5514     {
5515         return error(GL_OUT_OF_MEMORY);
5516     }
5517 }
5518 
glVertexAttrib3fv(GLuint index,const GLfloat * values)5519 void __stdcall glVertexAttrib3fv(GLuint index, const GLfloat* values)
5520 {
5521     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5522 
5523     try
5524     {
5525         if (index >= gl::MAX_VERTEX_ATTRIBS)
5526         {
5527             return error(GL_INVALID_VALUE);
5528         }
5529 
5530         gl::Context *context = gl::getContext();
5531 
5532         if (context)
5533         {
5534             GLfloat vals[4] = { values[0], values[1], values[2], 1 };
5535             context->setVertexAttrib(index, vals);
5536         }
5537     }
5538     catch(std::bad_alloc&)
5539     {
5540         return error(GL_OUT_OF_MEMORY);
5541     }
5542 }
5543 
glVertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)5544 void __stdcall glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5545 {
5546     TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
5547 
5548     try
5549     {
5550         if (index >= gl::MAX_VERTEX_ATTRIBS)
5551         {
5552             return error(GL_INVALID_VALUE);
5553         }
5554 
5555         gl::Context *context = gl::getContext();
5556 
5557         if (context)
5558         {
5559             GLfloat vals[4] = { x, y, z, w };
5560             context->setVertexAttrib(index, vals);
5561         }
5562     }
5563     catch(std::bad_alloc&)
5564     {
5565         return error(GL_OUT_OF_MEMORY);
5566     }
5567 }
5568 
glVertexAttrib4fv(GLuint index,const GLfloat * values)5569 void __stdcall glVertexAttrib4fv(GLuint index, const GLfloat* values)
5570 {
5571     TRACE("(GLuint index = %d, const GLfloat* values = 0x%0.8p)", index, values);
5572 
5573     try
5574     {
5575         if (index >= gl::MAX_VERTEX_ATTRIBS)
5576         {
5577             return error(GL_INVALID_VALUE);
5578         }
5579 
5580         gl::Context *context = gl::getContext();
5581 
5582         if (context)
5583         {
5584             context->setVertexAttrib(index, values);
5585         }
5586     }
5587     catch(std::bad_alloc&)
5588     {
5589         return error(GL_OUT_OF_MEMORY);
5590     }
5591 }
5592 
glVertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)5593 void __stdcall glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
5594 {
5595     TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
5596           "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = 0x%0.8p)",
5597           index, size, type, normalized, stride, ptr);
5598 
5599     try
5600     {
5601         if (index >= gl::MAX_VERTEX_ATTRIBS)
5602         {
5603             return error(GL_INVALID_VALUE);
5604         }
5605 
5606         if (size < 1 || size > 4)
5607         {
5608             return error(GL_INVALID_VALUE);
5609         }
5610 
5611         switch (type)
5612         {
5613           case GL_BYTE:
5614           case GL_UNSIGNED_BYTE:
5615           case GL_SHORT:
5616           case GL_UNSIGNED_SHORT:
5617           case GL_FIXED:
5618           case GL_FLOAT:
5619             break;
5620           default:
5621             return error(GL_INVALID_ENUM);
5622         }
5623 
5624         if (stride < 0)
5625         {
5626             return error(GL_INVALID_VALUE);
5627         }
5628 
5629         gl::Context *context = gl::getContext();
5630 
5631         if (context)
5632         {
5633             context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
5634         }
5635     }
5636     catch(std::bad_alloc&)
5637     {
5638         return error(GL_OUT_OF_MEMORY);
5639     }
5640 }
5641 
glViewport(GLint x,GLint y,GLsizei width,GLsizei height)5642 void __stdcall glViewport(GLint x, GLint y, GLsizei width, GLsizei height)
5643 {
5644     TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
5645 
5646     try
5647     {
5648         if (width < 0 || height < 0)
5649         {
5650             return error(GL_INVALID_VALUE);
5651         }
5652 
5653         gl::Context *context = gl::getContext();
5654 
5655         if (context)
5656         {
5657             context->setViewportParams(x, y, width, height);
5658         }
5659     }
5660     catch(std::bad_alloc&)
5661     {
5662         return error(GL_OUT_OF_MEMORY);
5663     }
5664 }
5665 
glBlitFramebufferANGLE(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)5666 void __stdcall glBlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
5667                                       GLbitfield mask, GLenum filter)
5668 {
5669     TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
5670           "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
5671           "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
5672           srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
5673 
5674     try
5675     {
5676         switch (filter)
5677         {
5678           case GL_NEAREST:
5679             break;
5680           default:
5681             return error(GL_INVALID_ENUM);
5682         }
5683 
5684         if ((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
5685         {
5686             return error(GL_INVALID_VALUE);
5687         }
5688 
5689         if (srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
5690         {
5691             ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
5692             return error(GL_INVALID_OPERATION);
5693         }
5694 
5695         gl::Context *context = gl::getContext();
5696 
5697         if (context)
5698         {
5699             if (context->getReadFramebufferHandle() == context->getDrawFramebufferHandle())
5700             {
5701                 ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
5702                 return error(GL_INVALID_OPERATION);
5703             }
5704 
5705             context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
5706         }
5707     }
5708     catch(std::bad_alloc&)
5709     {
5710         return error(GL_OUT_OF_MEMORY);
5711     }
5712 }
5713 
glTexImage3DOES(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)5714 void __stdcall glTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
5715                                GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5716 {
5717     TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
5718           "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
5719           "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = 0x%0.8p)",
5720           target, level, internalformat, width, height, depth, border, format, type, pixels);
5721 
5722     try
5723     {
5724         UNIMPLEMENTED();   // FIXME
5725     }
5726     catch(std::bad_alloc&)
5727     {
5728         return error(GL_OUT_OF_MEMORY);
5729     }
5730 }
5731 
glGetProcAddress(const char * procname)5732 __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname)
5733 {
5734     struct Extension
5735     {
5736         const char *name;
5737         __eglMustCastToProperFunctionPointerType address;
5738     };
5739 
5740     static const Extension glExtensions[] =
5741     {
5742         {"glTexImage3DOES", (__eglMustCastToProperFunctionPointerType)glTexImage3DOES},
5743         {"glBlitFramebufferANGLE", (__eglMustCastToProperFunctionPointerType)glBlitFramebufferANGLE},
5744         {"glRenderbufferStorageMultisampleANGLE", (__eglMustCastToProperFunctionPointerType)glRenderbufferStorageMultisampleANGLE},
5745         {"glDeleteFencesNV", (__eglMustCastToProperFunctionPointerType)glDeleteFencesNV},
5746         {"glGenFencesNV", (__eglMustCastToProperFunctionPointerType)glGenFencesNV},
5747         {"glIsFenceNV", (__eglMustCastToProperFunctionPointerType)glIsFenceNV},
5748         {"glTestFenceNV", (__eglMustCastToProperFunctionPointerType)glTestFenceNV},
5749         {"glGetFenceivNV", (__eglMustCastToProperFunctionPointerType)glGetFenceivNV},
5750         {"glFinishFenceNV", (__eglMustCastToProperFunctionPointerType)glFinishFenceNV},
5751         {"glSetFenceNV", (__eglMustCastToProperFunctionPointerType)glSetFenceNV},
5752     };
5753 
5754     for (int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
5755     {
5756         if (strcmp(procname, glExtensions[ext].name) == 0)
5757         {
5758             return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
5759         }
5760     }
5761 
5762     return NULL;
5763 }
5764 
5765 }
5766