OSDN Git Service

Fix framebuffer attachment parameter query error.
[android-x86/external-swiftshader.git] / src / OpenGL / libGLESv2 / libGLESv2.cpp
1 // SwiftShader Software Renderer\r
2 //\r
3 // Copyright(c) 2005-2013 TransGaming Inc.\r
4 //\r
5 // All rights reserved. No part of this software may be copied, distributed, transmitted,\r
6 // transcribed, stored in a retrieval system, translated into any human or computer\r
7 // language by any means, or disclosed to third parties without the explicit written\r
8 // agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express\r
9 // or implied, including but not limited to any patent rights, are granted to you.\r
10 //\r
11 // libGLESv2.cpp: Implements the exported OpenGL ES 2.0 functions.\r
12 \r
13 #include "main.h"\r
14 #include "mathutil.h"\r
15 #include "utilities.h"\r
16 #include "Buffer.h"\r
17 #include "Context.h"\r
18 #include "Fence.h"\r
19 #include "Framebuffer.h"\r
20 #include "Program.h"\r
21 #include "Renderbuffer.h"\r
22 #include "Shader.h"\r
23 #include "Texture.h"\r
24 #include "Query.h"\r
25 #include "common/debug.h"\r
26 #include "Common/Version.h"\r
27 \r
28 #include <GLES2/gl2.h>\r
29 #include <GLES2/gl2ext.h>\r
30 #include <GLES3/gl3.h>\r
31 \r
32 #include <limits>\r
33 \r
34 #ifdef ANDROID\r
35 #include <cutils/log.h>\r
36 #endif\r
37 \r
38 namespace es2\r
39 {\r
40 \r
41 static bool validImageSize(GLint level, GLsizei width, GLsizei height)\r
42 {\r
43         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)\r
44         {\r
45                 return false;\r
46         }\r
47 \r
48         return true;\r
49 }\r
50 \r
51 static bool validateColorBufferFormat(GLenum textureFormat, GLenum colorbufferFormat)\r
52 {\r
53         GLenum validationError = ValidateCompressedFormat(textureFormat, egl::getClientVersion(), false);\r
54         if(validationError != GL_NONE)\r
55         {\r
56                 return error(validationError, false);\r
57         }\r
58 \r
59         // [OpenGL ES 2.0.24] table 3.9\r
60         switch(textureFormat)\r
61         {\r
62         case GL_ALPHA:\r
63                 if(colorbufferFormat != GL_ALPHA &&\r
64                    colorbufferFormat != GL_RGBA &&\r
65                    colorbufferFormat != GL_RGBA4 &&\r
66                    colorbufferFormat != GL_RGB5_A1 &&\r
67                    colorbufferFormat != GL_RGBA8_OES &&\r
68                    colorbufferFormat != GL_RGBA16F_EXT &&\r
69                    colorbufferFormat != GL_RGBA32F_EXT)\r
70                 {\r
71                         return error(GL_INVALID_OPERATION, false);\r
72                 }\r
73                 break;\r
74         case GL_LUMINANCE:\r
75         case GL_RGB:\r
76                 if(colorbufferFormat != GL_RGB &&\r
77                    colorbufferFormat != GL_RGB565 &&\r
78                    colorbufferFormat != GL_RGB8_OES &&\r
79                    colorbufferFormat != GL_RGBA &&\r
80                    colorbufferFormat != GL_RGBA4 &&\r
81                    colorbufferFormat != GL_RGB5_A1 &&\r
82                    colorbufferFormat != GL_RGBA8_OES &&\r
83                    colorbufferFormat != GL_RGB16F_EXT &&\r
84                    colorbufferFormat != GL_RGB32F_EXT &&\r
85                    colorbufferFormat != GL_RGBA16F_EXT &&\r
86                    colorbufferFormat != GL_RGBA32F_EXT)\r
87                 {\r
88                         return error(GL_INVALID_OPERATION, false);\r
89                 }\r
90                 break;\r
91         case GL_LUMINANCE_ALPHA:\r
92         case GL_RGBA:\r
93                 if(colorbufferFormat != GL_RGBA &&\r
94                    colorbufferFormat != GL_RGBA4 &&\r
95                    colorbufferFormat != GL_RGB5_A1 &&\r
96                    colorbufferFormat != GL_RGBA8_OES &&\r
97                    colorbufferFormat != GL_RGBA16F_EXT &&\r
98                    colorbufferFormat != GL_RGBA32F_EXT)\r
99                 {\r
100                         return error(GL_INVALID_OPERATION, false);\r
101                 }\r
102                 break;\r
103         case GL_DEPTH_COMPONENT:\r
104         case GL_DEPTH_STENCIL_OES:\r
105                 return error(GL_INVALID_OPERATION, false);\r
106         default:\r
107                 return error(GL_INVALID_ENUM, false);\r
108         }\r
109         return true;\r
110 }\r
111 \r
112 void ActiveTexture(GLenum texture)\r
113 {\r
114         TRACE("(GLenum texture = 0x%X)", texture);\r
115 \r
116         es2::Context *context = es2::getContext();\r
117 \r
118         if(context)\r
119         {\r
120                 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1)\r
121                 {\r
122                         return error(GL_INVALID_ENUM);\r
123                 }\r
124 \r
125                 context->setActiveSampler(texture - GL_TEXTURE0);\r
126         }\r
127 }\r
128 \r
129 void AttachShader(GLuint program, GLuint shader)\r
130 {\r
131         TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);\r
132 \r
133         es2::Context *context = es2::getContext();\r
134 \r
135         if(context)\r
136         {\r
137                 es2::Program *programObject = context->getProgram(program);\r
138                 es2::Shader *shaderObject = context->getShader(shader);\r
139 \r
140                 if(!programObject)\r
141                 {\r
142                         if(context->getShader(program))\r
143                         {\r
144                                 return error(GL_INVALID_OPERATION);\r
145                         }\r
146                         else\r
147                         {\r
148                                 return error(GL_INVALID_VALUE);\r
149                         }\r
150                 }\r
151 \r
152                 if(!shaderObject)\r
153                 {\r
154                         if(context->getProgram(shader))\r
155                         {\r
156                                 return error(GL_INVALID_OPERATION);\r
157                         }\r
158                         else\r
159                         {\r
160                                 return error(GL_INVALID_VALUE);\r
161                         }\r
162                 }\r
163 \r
164                 if(!programObject->attachShader(shaderObject))\r
165                 {\r
166                         return error(GL_INVALID_OPERATION);\r
167                 }\r
168         }\r
169 }\r
170 \r
171 void BeginQueryEXT(GLenum target, GLuint name)\r
172 {\r
173         TRACE("(GLenum target = 0x%X, GLuint name = %d)", target, name);\r
174 \r
175         switch(target)\r
176         {\r
177         case GL_ANY_SAMPLES_PASSED_EXT:\r
178         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:\r
179                 break;\r
180         default:\r
181                 return error(GL_INVALID_ENUM);\r
182         }\r
183 \r
184         if(name == 0)\r
185         {\r
186                 return error(GL_INVALID_OPERATION);\r
187         }\r
188 \r
189         es2::Context *context = es2::getContext();\r
190 \r
191         if(context)\r
192         {\r
193                 context->beginQuery(target, name);\r
194         }\r
195 }\r
196 \r
197 void BindAttribLocation(GLuint program, GLuint index, const GLchar* name)\r
198 {\r
199         TRACE("(GLuint program = %d, GLuint index = %d, const GLchar* name = %s)", program, index, name);\r
200 \r
201         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
202         {\r
203                 return error(GL_INVALID_VALUE);\r
204         }\r
205 \r
206         es2::Context *context = es2::getContext();\r
207 \r
208         if(context)\r
209         {\r
210                 es2::Program *programObject = context->getProgram(program);\r
211 \r
212                 if(!programObject)\r
213                 {\r
214                         if(context->getShader(program))\r
215                         {\r
216                                 return error(GL_INVALID_OPERATION);\r
217                         }\r
218                         else\r
219                         {\r
220                                 return error(GL_INVALID_VALUE);\r
221                         }\r
222                 }\r
223 \r
224                 if(strncmp(name, "gl_", 3) == 0)\r
225                 {\r
226                         return error(GL_INVALID_OPERATION);\r
227                 }\r
228 \r
229                 programObject->bindAttributeLocation(index, name);\r
230         }\r
231 }\r
232 \r
233 void BindBuffer(GLenum target, GLuint buffer)\r
234 {\r
235         TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);\r
236 \r
237         es2::Context *context = es2::getContext();\r
238 \r
239         if(context)\r
240         {\r
241                 GLint clientVersion = egl::getClientVersion();\r
242 \r
243                 switch(target)\r
244                 {\r
245                 case GL_ARRAY_BUFFER:\r
246                         context->bindArrayBuffer(buffer);\r
247                         return;\r
248                 case GL_ELEMENT_ARRAY_BUFFER:\r
249                         context->bindElementArrayBuffer(buffer);\r
250                         return;\r
251                 case GL_COPY_READ_BUFFER:\r
252                         if(clientVersion >= 3)\r
253                         {\r
254                                 context->bindCopyReadBuffer(buffer);\r
255                                 return;\r
256                         }\r
257                         else return error(GL_INVALID_ENUM);\r
258                 case GL_COPY_WRITE_BUFFER:\r
259                         if(clientVersion >= 3)\r
260                         {\r
261                                 context->bindCopyWriteBuffer(buffer);\r
262                                 return;\r
263                         }\r
264                         else return error(GL_INVALID_ENUM);\r
265                 case GL_PIXEL_PACK_BUFFER:\r
266                         if(clientVersion >= 3)\r
267                         {\r
268                                 context->bindPixelPackBuffer(buffer);\r
269                                 return;\r
270                         }\r
271                         else return error(GL_INVALID_ENUM);\r
272                 case GL_PIXEL_UNPACK_BUFFER:\r
273                         if(clientVersion >= 3)\r
274                         {\r
275                                 context->bindPixelUnpackBuffer(buffer);\r
276                                 return;\r
277                         }\r
278                         else return error(GL_INVALID_ENUM);\r
279                 case GL_TRANSFORM_FEEDBACK_BUFFER:\r
280                         if(clientVersion >= 3)\r
281                         {\r
282                                 context->bindTransformFeedbackBuffer(buffer);\r
283                                 return;\r
284                         }\r
285                         else return error(GL_INVALID_ENUM);\r
286                 case GL_UNIFORM_BUFFER:\r
287                         if(clientVersion >= 3)\r
288                         {\r
289                                 context->bindGenericUniformBuffer(buffer);\r
290                                 return;\r
291                         }\r
292                         else return error(GL_INVALID_ENUM);\r
293                 default:\r
294                         return error(GL_INVALID_ENUM);\r
295                 }\r
296         }\r
297 }\r
298 \r
299 void BindFramebuffer(GLenum target, GLuint framebuffer)\r
300 {\r
301         TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);\r
302 \r
303         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
304         {\r
305                 return error(GL_INVALID_ENUM);\r
306         }\r
307 \r
308         es2::Context *context = es2::getContext();\r
309 \r
310         if(context)\r
311         {\r
312                 if(target == GL_READ_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)\r
313                 {\r
314                         context->bindReadFramebuffer(framebuffer);\r
315                 }\r
316 \r
317                 if(target == GL_DRAW_FRAMEBUFFER_ANGLE || target == GL_FRAMEBUFFER)\r
318                 {\r
319                         context->bindDrawFramebuffer(framebuffer);\r
320                 }\r
321         }\r
322 }\r
323 \r
324 void BindRenderbuffer(GLenum target, GLuint renderbuffer)\r
325 {\r
326         TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);\r
327 \r
328         if(target != GL_RENDERBUFFER)\r
329         {\r
330                 return error(GL_INVALID_ENUM);\r
331         }\r
332 \r
333         es2::Context *context = es2::getContext();\r
334 \r
335         if(context)\r
336         {\r
337                 // [OpenGL ES 2.0.25] Section 4.4.3 page 110\r
338                 // [OpenGL ES 3.0.4] Section 4.4.2 page 204\r
339                 // If renderbuffer is not zero, then the resulting renderbuffer object\r
340                 // is a new state vector, initialized with a zero-sized memory buffer.\r
341                 context->bindRenderbuffer(renderbuffer);\r
342         }\r
343 }\r
344 \r
345 void BindTexture(GLenum target, GLuint texture)\r
346 {\r
347         TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);\r
348 \r
349         es2::Context *context = es2::getContext();\r
350 \r
351         if(context)\r
352         {\r
353                 es2::Texture *textureObject = context->getTexture(texture);\r
354 \r
355                 if(textureObject && textureObject->getTarget() != target && texture != 0)\r
356                 {\r
357                         return error(GL_INVALID_OPERATION);\r
358                 }\r
359 \r
360                 GLint clientVersion = context->getClientVersion();\r
361 \r
362                 switch(target)\r
363                 {\r
364                 case GL_TEXTURE_2D:\r
365                         context->bindTexture2D(texture);\r
366                         break;\r
367                 case GL_TEXTURE_CUBE_MAP:\r
368                         context->bindTextureCubeMap(texture);\r
369                         break;\r
370                 case GL_TEXTURE_EXTERNAL_OES:\r
371                         context->bindTextureExternal(texture);\r
372                         break;\r
373                 case GL_TEXTURE_2D_ARRAY:\r
374                         if(clientVersion < 3)\r
375                         {\r
376                                 return error(GL_INVALID_ENUM);\r
377                         }\r
378                         context->bindTexture2DArray(texture);\r
379                         break;\r
380                 case GL_TEXTURE_3D_OES:\r
381                         context->bindTexture3D(texture);\r
382                         break;\r
383                 default:\r
384                         return error(GL_INVALID_ENUM);\r
385                 }\r
386         }\r
387 }\r
388 \r
389 void BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)\r
390 {\r
391         TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",\r
392                 red, green, blue, alpha);\r
393 \r
394         es2::Context* context = es2::getContext();\r
395 \r
396         if(context)\r
397         {\r
398                 context->setBlendColor(es2::clamp01(red), es2::clamp01(green), es2::clamp01(blue), es2::clamp01(alpha));\r
399         }\r
400 }\r
401 \r
402 void BlendEquation(GLenum mode)\r
403 {\r
404         glBlendEquationSeparate(mode, mode);\r
405 }\r
406 \r
407 void BlendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)\r
408 {\r
409         TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);\r
410 \r
411         switch(modeRGB)\r
412         {\r
413         case GL_FUNC_ADD:\r
414         case GL_FUNC_SUBTRACT:\r
415         case GL_FUNC_REVERSE_SUBTRACT:\r
416         case GL_MIN_EXT:\r
417         case GL_MAX_EXT:\r
418                 break;\r
419         default:\r
420                 return error(GL_INVALID_ENUM);\r
421         }\r
422 \r
423         switch(modeAlpha)\r
424         {\r
425         case GL_FUNC_ADD:\r
426         case GL_FUNC_SUBTRACT:\r
427         case GL_FUNC_REVERSE_SUBTRACT:\r
428         case GL_MIN_EXT:\r
429         case GL_MAX_EXT:\r
430                 break;\r
431         default:\r
432                 return error(GL_INVALID_ENUM);\r
433         }\r
434 \r
435         es2::Context *context = es2::getContext();\r
436 \r
437         if(context)\r
438         {\r
439                 context->setBlendEquation(modeRGB, modeAlpha);\r
440         }\r
441 }\r
442 \r
443 void BlendFunc(GLenum sfactor, GLenum dfactor)\r
444 {\r
445         glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor);\r
446 }\r
447 \r
448 void BlendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)\r
449 {\r
450         TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",\r
451               srcRGB, dstRGB, srcAlpha, dstAlpha);\r
452 \r
453         GLint clientVersion = egl::getClientVersion();\r
454 \r
455         switch(srcRGB)\r
456         {\r
457         case GL_ZERO:\r
458         case GL_ONE:\r
459         case GL_SRC_COLOR:\r
460         case GL_ONE_MINUS_SRC_COLOR:\r
461         case GL_DST_COLOR:\r
462         case GL_ONE_MINUS_DST_COLOR:\r
463         case GL_SRC_ALPHA:\r
464         case GL_ONE_MINUS_SRC_ALPHA:\r
465         case GL_DST_ALPHA:\r
466         case GL_ONE_MINUS_DST_ALPHA:\r
467         case GL_CONSTANT_COLOR:\r
468         case GL_ONE_MINUS_CONSTANT_COLOR:\r
469         case GL_CONSTANT_ALPHA:\r
470         case GL_ONE_MINUS_CONSTANT_ALPHA:\r
471         case GL_SRC_ALPHA_SATURATE:\r
472                 break;\r
473         default:\r
474                 return error(GL_INVALID_ENUM);\r
475         }\r
476 \r
477         switch(dstRGB)\r
478         {\r
479         case GL_ZERO:\r
480         case GL_ONE:\r
481         case GL_SRC_COLOR:\r
482         case GL_ONE_MINUS_SRC_COLOR:\r
483         case GL_DST_COLOR:\r
484         case GL_ONE_MINUS_DST_COLOR:\r
485         case GL_SRC_ALPHA:\r
486         case GL_ONE_MINUS_SRC_ALPHA:\r
487         case GL_DST_ALPHA:\r
488         case GL_ONE_MINUS_DST_ALPHA:\r
489         case GL_CONSTANT_COLOR:\r
490         case GL_ONE_MINUS_CONSTANT_COLOR:\r
491         case GL_CONSTANT_ALPHA:\r
492         case GL_ONE_MINUS_CONSTANT_ALPHA:\r
493                 break;\r
494         case GL_SRC_ALPHA_SATURATE:\r
495                 if(clientVersion < 3)\r
496                 {\r
497                         return error(GL_INVALID_ENUM);\r
498                 }\r
499                 break;\r
500         default:\r
501                 return error(GL_INVALID_ENUM);\r
502         }\r
503 \r
504         switch(srcAlpha)\r
505         {\r
506         case GL_ZERO:\r
507         case GL_ONE:\r
508         case GL_SRC_COLOR:\r
509         case GL_ONE_MINUS_SRC_COLOR:\r
510         case GL_DST_COLOR:\r
511         case GL_ONE_MINUS_DST_COLOR:\r
512         case GL_SRC_ALPHA:\r
513         case GL_ONE_MINUS_SRC_ALPHA:\r
514         case GL_DST_ALPHA:\r
515         case GL_ONE_MINUS_DST_ALPHA:\r
516         case GL_CONSTANT_COLOR:\r
517         case GL_ONE_MINUS_CONSTANT_COLOR:\r
518         case GL_CONSTANT_ALPHA:\r
519         case GL_ONE_MINUS_CONSTANT_ALPHA:\r
520         case GL_SRC_ALPHA_SATURATE:\r
521                 break;\r
522         default:\r
523                 return error(GL_INVALID_ENUM);\r
524         }\r
525 \r
526         switch(dstAlpha)\r
527         {\r
528         case GL_ZERO:\r
529         case GL_ONE:\r
530         case GL_SRC_COLOR:\r
531         case GL_ONE_MINUS_SRC_COLOR:\r
532         case GL_DST_COLOR:\r
533         case GL_ONE_MINUS_DST_COLOR:\r
534         case GL_SRC_ALPHA:\r
535         case GL_ONE_MINUS_SRC_ALPHA:\r
536         case GL_DST_ALPHA:\r
537         case GL_ONE_MINUS_DST_ALPHA:\r
538         case GL_CONSTANT_COLOR:\r
539         case GL_ONE_MINUS_CONSTANT_COLOR:\r
540         case GL_CONSTANT_ALPHA:\r
541         case GL_ONE_MINUS_CONSTANT_ALPHA:\r
542                 break;\r
543         case GL_SRC_ALPHA_SATURATE:\r
544                 if(clientVersion < 3)\r
545                 {\r
546                         return error(GL_INVALID_ENUM);\r
547                 }\r
548                 break;\r
549         default:\r
550                 return error(GL_INVALID_ENUM);\r
551         }\r
552 \r
553         es2::Context *context = es2::getContext();\r
554 \r
555         if(context)\r
556         {\r
557                 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);\r
558         }\r
559 }\r
560 \r
561 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)\r
562 {\r
563         size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications\r
564 \r
565         TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",\r
566               target, size, data, usage);\r
567 \r
568         if(size < 0)\r
569         {\r
570                 return error(GL_INVALID_VALUE);\r
571         }\r
572 \r
573         GLint clientVersion = egl::getClientVersion();\r
574 \r
575         switch(usage)\r
576         {\r
577         case GL_STREAM_DRAW:\r
578         case GL_STATIC_DRAW:\r
579         case GL_DYNAMIC_DRAW:\r
580                 break;\r
581         case GL_STREAM_READ:\r
582         case GL_STREAM_COPY:\r
583         case GL_STATIC_READ:\r
584         case GL_STATIC_COPY:\r
585         case GL_DYNAMIC_READ:\r
586         case GL_DYNAMIC_COPY:\r
587                 if(clientVersion < 3)\r
588                 {\r
589                         return error(GL_INVALID_ENUM);\r
590                 }\r
591                 break;\r
592         default:\r
593                 return error(GL_INVALID_ENUM);\r
594         }\r
595 \r
596         es2::Context *context = es2::getContext();\r
597 \r
598         if(context)\r
599         {\r
600                 es2::Buffer *buffer = nullptr;\r
601                 if(!context->getBuffer(target, &buffer))\r
602                 {\r
603                         return error(GL_INVALID_ENUM);\r
604                 }\r
605 \r
606                 if(!buffer)\r
607                 {\r
608                         // A null buffer means that "0" is bound to the requested buffer target\r
609                         return error(GL_INVALID_OPERATION);\r
610                 }\r
611 \r
612                 buffer->bufferData(data, size, usage);\r
613         }\r
614 }\r
615 \r
616 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)\r
617 {\r
618         size = static_cast<GLint>(size);   // Work around issues with some 64-bit applications\r
619         offset = static_cast<GLint>(offset);\r
620 \r
621         TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",\r
622               target, offset, size, data);\r
623 \r
624         if(size < 0 || offset < 0)\r
625         {\r
626                 return error(GL_INVALID_VALUE);\r
627         }\r
628 \r
629         es2::Context *context = es2::getContext();\r
630 \r
631         if(context)\r
632         {\r
633                 es2::Buffer *buffer = nullptr;\r
634                 if(!context->getBuffer(target, &buffer))\r
635                 {\r
636                         return error(GL_INVALID_ENUM);\r
637                 }\r
638 \r
639                 if(!buffer)\r
640                 {\r
641                         // A null buffer means that "0" is bound to the requested buffer target\r
642                         return error(GL_INVALID_OPERATION);\r
643                 }\r
644 \r
645                 if((size_t)size + offset > buffer->size())\r
646                 {\r
647                         return error(GL_INVALID_VALUE);\r
648                 }\r
649 \r
650                 buffer->bufferSubData(data, size, offset);\r
651         }\r
652 }\r
653 \r
654 GLenum CheckFramebufferStatus(GLenum target)\r
655 {\r
656         TRACE("(GLenum target = 0x%X)", target);\r
657 \r
658         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
659         {\r
660                 return error(GL_INVALID_ENUM, 0);\r
661         }\r
662 \r
663         es2::Context *context = es2::getContext();\r
664 \r
665         if(context)\r
666         {\r
667                 es2::Framebuffer *framebuffer = NULL;\r
668                 if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
669                 {\r
670                         framebuffer = context->getReadFramebuffer();\r
671                 }\r
672                 else\r
673                 {\r
674                         framebuffer = context->getDrawFramebuffer();\r
675                 }\r
676 \r
677                 return framebuffer->completeness();\r
678         }\r
679 \r
680         return 0;\r
681 }\r
682 \r
683 void Clear(GLbitfield mask)\r
684 {\r
685         TRACE("(GLbitfield mask = %X)", mask);\r
686 \r
687         if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)\r
688         {\r
689                 return error(GL_INVALID_VALUE);\r
690         }\r
691 \r
692         es2::Context *context = es2::getContext();\r
693 \r
694         if(context)\r
695         {\r
696                 context->clear(mask);\r
697         }\r
698 }\r
699 \r
700 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)\r
701 {\r
702         TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",\r
703               red, green, blue, alpha);\r
704 \r
705         es2::Context *context = es2::getContext();\r
706 \r
707         if(context)\r
708         {\r
709                 context->setClearColor(red, green, blue, alpha);\r
710         }\r
711 }\r
712 \r
713 void ClearDepthf(GLclampf depth)\r
714 {\r
715         TRACE("(GLclampf depth = %f)", depth);\r
716 \r
717         es2::Context *context = es2::getContext();\r
718 \r
719         if(context)\r
720         {\r
721                 context->setClearDepth(depth);\r
722         }\r
723 }\r
724 \r
725 void ClearStencil(GLint s)\r
726 {\r
727         TRACE("(GLint s = %d)", s);\r
728 \r
729         es2::Context *context = es2::getContext();\r
730 \r
731         if(context)\r
732         {\r
733                 context->setClearStencil(s);\r
734         }\r
735 }\r
736 \r
737 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)\r
738 {\r
739         TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",\r
740               red, green, blue, alpha);\r
741 \r
742         es2::Context *context = es2::getContext();\r
743 \r
744         if(context)\r
745         {\r
746                 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);\r
747         }\r
748 }\r
749 \r
750 void CompileShader(GLuint shader)\r
751 {\r
752         TRACE("(GLuint shader = %d)", shader);\r
753 \r
754         es2::Context *context = es2::getContext();\r
755 \r
756         if(context)\r
757         {\r
758                 es2::Shader *shaderObject = context->getShader(shader);\r
759 \r
760                 if(!shaderObject)\r
761                 {\r
762                         if(context->getProgram(shader))\r
763                         {\r
764                                 return error(GL_INVALID_OPERATION);\r
765                         }\r
766                         else\r
767                         {\r
768                                 return error(GL_INVALID_VALUE);\r
769                         }\r
770                 }\r
771 \r
772                 shaderObject->compile();\r
773         }\r
774 }\r
775 \r
776 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,\r
777                           GLint border, GLsizei imageSize, const GLvoid* data)\r
778 {\r
779         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "\r
780               "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",\r
781               target, level, internalformat, width, height, border, imageSize, data);\r
782 \r
783         if(!validImageSize(level, width, height) || border != 0 || imageSize < 0)\r
784         {\r
785                 return error(GL_INVALID_VALUE);\r
786         }\r
787 \r
788         switch(internalformat)\r
789         {\r
790         case GL_DEPTH_COMPONENT:\r
791         case GL_DEPTH_COMPONENT16:\r
792         case GL_DEPTH_COMPONENT32_OES:\r
793         case GL_DEPTH_STENCIL_OES:\r
794         case GL_DEPTH24_STENCIL8_OES:\r
795                 return error(GL_INVALID_OPERATION);\r
796         default:\r
797                 {\r
798                         GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
799                         if(validationError != GL_NONE)\r
800                         {\r
801                                 return error(validationError);\r
802                         }\r
803                 }\r
804                 break;\r
805         }\r
806 \r
807         if(border != 0)\r
808         {\r
809                 return error(GL_INVALID_VALUE);\r
810         }\r
811 \r
812         es2::Context *context = es2::getContext();\r
813 \r
814         if(context)\r
815         {\r
816                 if(level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
817                 {\r
818                         return error(GL_INVALID_VALUE);\r
819                 }\r
820 \r
821                 switch(target)\r
822                 {\r
823                 case GL_TEXTURE_2D:\r
824                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
825                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
826                         {\r
827                                 return error(GL_INVALID_VALUE);\r
828                         }\r
829                         break;\r
830                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
831                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
832                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
833                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
834                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
835                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
836                         if(width != height)\r
837                         {\r
838                                 return error(GL_INVALID_VALUE);\r
839                         }\r
840 \r
841                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
842                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
843                         {\r
844                                 return error(GL_INVALID_VALUE);\r
845                         }\r
846                         break;\r
847                 default:\r
848                         return error(GL_INVALID_ENUM);\r
849                 }\r
850 \r
851                 if(imageSize != egl::ComputeCompressedSize(width, height, internalformat))\r
852                 {\r
853                         return error(GL_INVALID_VALUE);\r
854                 }\r
855 \r
856                 if(target == GL_TEXTURE_2D)\r
857                 {\r
858                         es2::Texture2D *texture = context->getTexture2D();\r
859 \r
860                         if(!texture)\r
861                         {\r
862                                 return error(GL_INVALID_OPERATION);\r
863                         }\r
864 \r
865                         texture->setCompressedImage(level, internalformat, width, height, imageSize, data);\r
866                 }\r
867                 else\r
868                 {\r
869                         es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
870 \r
871                         if(!texture)\r
872                         {\r
873                                 return error(GL_INVALID_OPERATION);\r
874                         }\r
875 \r
876                         switch(target)\r
877                         {\r
878                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
879                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
880                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
881                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
882                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
883                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
884                                 texture->setCompressedImage(target, level, internalformat, width, height, imageSize, data);\r
885                                 break;\r
886                         default: UNREACHABLE(target);\r
887                         }\r
888                 }\r
889         }\r
890 }\r
891 \r
892 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,\r
893                              GLenum format, GLsizei imageSize, const GLvoid* data)\r
894 {\r
895         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
896               "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "\r
897               "GLsizei imageSize = %d, const GLvoid* data = %p)",\r
898               target, level, xoffset, yoffset, width, height, format, imageSize, data);\r
899 \r
900         if(!es2::IsTextureTarget(target))\r
901         {\r
902                 return error(GL_INVALID_ENUM);\r
903         }\r
904 \r
905         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
906         {\r
907                 return error(GL_INVALID_VALUE);\r
908         }\r
909 \r
910         if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)\r
911         {\r
912                 return error(GL_INVALID_VALUE);\r
913         }\r
914 \r
915         GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
916         if(validationError != GL_NONE)\r
917         {\r
918                 return error(validationError);\r
919         }\r
920 \r
921         if(width == 0 || height == 0 || !data)\r
922         {\r
923                 return;\r
924         }\r
925 \r
926         es2::Context *context = es2::getContext();\r
927 \r
928         if(context)\r
929         {\r
930                 if(imageSize != egl::ComputeCompressedSize(width, height, format))\r
931                 {\r
932                         return error(GL_INVALID_VALUE);\r
933                 }\r
934 \r
935                 if(xoffset % 4 != 0 || yoffset % 4 != 0)\r
936                 {\r
937                         // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported\r
938                         return error(GL_INVALID_OPERATION);\r
939                 }\r
940 \r
941                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, GL_NONE);\r
942 \r
943                 if(target == GL_TEXTURE_2D)\r
944                 {\r
945                         es2::Texture2D *texture = context->getTexture2D();\r
946 \r
947                         GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
948 \r
949                         if(validationError == GL_NONE)\r
950                         {\r
951                                 texture->subImageCompressed(level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
952                         }\r
953                         else\r
954                         {\r
955                                 return error(validationError);\r
956                         }\r
957                 }\r
958                 else if(es2::IsCubemapTextureTarget(target))\r
959                 {\r
960                         es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
961 \r
962                         GLenum validationError = ValidateSubImageParams(true, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
963 \r
964                         if(validationError == GL_NONE)\r
965                         {\r
966                                 texture->subImageCompressed(target, level, xoffset, yoffset, width, height, sizedInternalFormat, imageSize, data);\r
967                         }\r
968                         else\r
969                         {\r
970                                 return error(validationError);\r
971                         }\r
972                 }\r
973                 else UNREACHABLE(target);\r
974         }\r
975 }\r
976 \r
977 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)\r
978 {\r
979         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "\r
980               "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",\r
981               target, level, internalformat, x, y, width, height, border);\r
982 \r
983         if(!validImageSize(level, width, height))\r
984         {\r
985                 return error(GL_INVALID_VALUE);\r
986         }\r
987 \r
988         if(border != 0)\r
989         {\r
990                 return error(GL_INVALID_VALUE);\r
991         }\r
992 \r
993         es2::Context *context = es2::getContext();\r
994 \r
995         if(context)\r
996         {\r
997                 switch(target)\r
998                 {\r
999                 case GL_TEXTURE_2D:\r
1000                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
1001                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
1002                         {\r
1003                                 return error(GL_INVALID_VALUE);\r
1004                         }\r
1005                         break;\r
1006                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
1007                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
1008                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
1009                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
1010                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
1011                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
1012                         if(width != height)\r
1013                         {\r
1014                                 return error(GL_INVALID_VALUE);\r
1015                         }\r
1016 \r
1017                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
1018                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
1019                         {\r
1020                                 return error(GL_INVALID_VALUE);\r
1021                         }\r
1022                         break;\r
1023                 default:\r
1024                         return error(GL_INVALID_ENUM);\r
1025                 }\r
1026 \r
1027                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();\r
1028 \r
1029                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)\r
1030                 {\r
1031                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);\r
1032                 }\r
1033 \r
1034                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();\r
1035 \r
1036                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))\r
1037                 {\r
1038                         return error(GL_INVALID_OPERATION);\r
1039                 }\r
1040 \r
1041                 GLenum colorbufferFormat = source->getFormat();\r
1042 \r
1043                 if(!validateColorBufferFormat(internalformat, colorbufferFormat))\r
1044                 {\r
1045                         return;\r
1046                 }\r
1047 \r
1048                 if(target == GL_TEXTURE_2D)\r
1049                 {\r
1050                         es2::Texture2D *texture = context->getTexture2D();\r
1051 \r
1052                         if(!texture)\r
1053                         {\r
1054                                 return error(GL_INVALID_OPERATION);\r
1055                         }\r
1056 \r
1057                         texture->copyImage(level, internalformat, x, y, width, height, framebuffer);\r
1058                 }\r
1059                 else if(es2::IsCubemapTextureTarget(target))\r
1060                 {\r
1061                         es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
1062 \r
1063                         if(!texture)\r
1064                         {\r
1065                                 return error(GL_INVALID_OPERATION);\r
1066                         }\r
1067 \r
1068                         texture->copyImage(target, level, internalformat, x, y, width, height, framebuffer);\r
1069                 }\r
1070                 else UNREACHABLE(target);\r
1071         }\r
1072 }\r
1073 \r
1074 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)\r
1075 {\r
1076         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
1077               "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",\r
1078               target, level, xoffset, yoffset, x, y, width, height);\r
1079 \r
1080         if(!es2::IsTextureTarget(target))\r
1081         {\r
1082                 return error(GL_INVALID_ENUM);\r
1083         }\r
1084 \r
1085         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
1086         {\r
1087                 return error(GL_INVALID_VALUE);\r
1088         }\r
1089 \r
1090         if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)\r
1091         {\r
1092                 return error(GL_INVALID_VALUE);\r
1093         }\r
1094 \r
1095         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)\r
1096         {\r
1097                 return error(GL_INVALID_VALUE);\r
1098         }\r
1099 \r
1100         if(width == 0 || height == 0)\r
1101         {\r
1102                 return;\r
1103         }\r
1104 \r
1105         es2::Context *context = es2::getContext();\r
1106 \r
1107         if(context)\r
1108         {\r
1109                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();\r
1110 \r
1111                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)\r
1112                 {\r
1113                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);\r
1114                 }\r
1115 \r
1116                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();\r
1117 \r
1118                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))\r
1119                 {\r
1120                         return error(GL_INVALID_OPERATION);\r
1121                 }\r
1122 \r
1123                 es2::Texture *texture = nullptr;\r
1124 \r
1125                 if(target == GL_TEXTURE_2D)\r
1126                 {\r
1127                         texture = context->getTexture2D();\r
1128                 }\r
1129                 else if(es2::IsCubemapTextureTarget(target))\r
1130                 {\r
1131                         texture = context->getTextureCubeMap();\r
1132                 }\r
1133                 else UNREACHABLE(target);\r
1134 \r
1135                 GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, GL_NONE, texture);\r
1136                 if(validationError != GL_NONE)\r
1137                 {\r
1138                         return error(validationError);\r
1139                 }\r
1140 \r
1141                 texture->copySubImage(target, level, xoffset, yoffset, 0, x, y, width, height, framebuffer);\r
1142         }\r
1143 }\r
1144 \r
1145 GLuint CreateProgram(void)\r
1146 {\r
1147         TRACE("()");\r
1148 \r
1149         es2::Context *context = es2::getContext();\r
1150 \r
1151         if(context)\r
1152         {\r
1153                 return context->createProgram();\r
1154         }\r
1155 \r
1156         return 0;\r
1157 }\r
1158 \r
1159 GLuint CreateShader(GLenum type)\r
1160 {\r
1161         TRACE("(GLenum type = 0x%X)", type);\r
1162 \r
1163         es2::Context *context = es2::getContext();\r
1164 \r
1165         if(context)\r
1166         {\r
1167                 switch(type)\r
1168                 {\r
1169                 case GL_FRAGMENT_SHADER:\r
1170                 case GL_VERTEX_SHADER:\r
1171                         return context->createShader(type);\r
1172                 default:\r
1173                         return error(GL_INVALID_ENUM, 0);\r
1174                 }\r
1175         }\r
1176 \r
1177         return 0;\r
1178 }\r
1179 \r
1180 void CullFace(GLenum mode)\r
1181 {\r
1182         TRACE("(GLenum mode = 0x%X)", mode);\r
1183 \r
1184         switch(mode)\r
1185         {\r
1186         case GL_FRONT:\r
1187         case GL_BACK:\r
1188         case GL_FRONT_AND_BACK:\r
1189                 {\r
1190                         es2::Context *context = es2::getContext();\r
1191 \r
1192                         if(context)\r
1193                         {\r
1194                                 context->setCullMode(mode);\r
1195                         }\r
1196                 }\r
1197                 break;\r
1198         default:\r
1199                 return error(GL_INVALID_ENUM);\r
1200         }\r
1201 }\r
1202 \r
1203 void DeleteBuffers(GLsizei n, const GLuint* buffers)\r
1204 {\r
1205         TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);\r
1206 \r
1207         if(n < 0)\r
1208         {\r
1209                 return error(GL_INVALID_VALUE);\r
1210         }\r
1211 \r
1212         es2::Context *context = es2::getContext();\r
1213 \r
1214         if(context)\r
1215         {\r
1216                 for(int i = 0; i < n; i++)\r
1217                 {\r
1218                         context->deleteBuffer(buffers[i]);\r
1219                 }\r
1220         }\r
1221 }\r
1222 \r
1223 void DeleteFencesNV(GLsizei n, const GLuint* fences)\r
1224 {\r
1225         TRACE("(GLsizei n = %d, const GLuint* fences = %p)", n, fences);\r
1226 \r
1227         if(n < 0)\r
1228         {\r
1229                 return error(GL_INVALID_VALUE);\r
1230         }\r
1231 \r
1232         es2::Context *context = es2::getContext();\r
1233 \r
1234         if(context)\r
1235         {\r
1236                 for(int i = 0; i < n; i++)\r
1237                 {\r
1238                         context->deleteFence(fences[i]);\r
1239                 }\r
1240         }\r
1241 }\r
1242 \r
1243 void DeleteFramebuffers(GLsizei n, const GLuint* framebuffers)\r
1244 {\r
1245         TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);\r
1246 \r
1247         if(n < 0)\r
1248         {\r
1249                 return error(GL_INVALID_VALUE);\r
1250         }\r
1251 \r
1252         es2::Context *context = es2::getContext();\r
1253 \r
1254         if(context)\r
1255         {\r
1256                 for(int i = 0; i < n; i++)\r
1257                 {\r
1258                         if(framebuffers[i] != 0)\r
1259                         {\r
1260                                 context->deleteFramebuffer(framebuffers[i]);\r
1261                         }\r
1262                 }\r
1263         }\r
1264 }\r
1265 \r
1266 void DeleteProgram(GLuint program)\r
1267 {\r
1268         TRACE("(GLuint program = %d)", program);\r
1269 \r
1270         if(program == 0)\r
1271         {\r
1272                 return;\r
1273         }\r
1274 \r
1275         es2::Context *context = es2::getContext();\r
1276 \r
1277         if(context)\r
1278         {\r
1279                 if(!context->getProgram(program))\r
1280                 {\r
1281                         if(context->getShader(program))\r
1282                         {\r
1283                                 return error(GL_INVALID_OPERATION);\r
1284                         }\r
1285                         else\r
1286                         {\r
1287                                 return error(GL_INVALID_VALUE);\r
1288                         }\r
1289                 }\r
1290 \r
1291                 context->deleteProgram(program);\r
1292         }\r
1293 }\r
1294 \r
1295 void DeleteQueriesEXT(GLsizei n, const GLuint *ids)\r
1296 {\r
1297         TRACE("(GLsizei n = %d, const GLuint *ids = %p)", n, ids);\r
1298 \r
1299         if(n < 0)\r
1300         {\r
1301                 return error(GL_INVALID_VALUE);\r
1302         }\r
1303 \r
1304         es2::Context *context = es2::getContext();\r
1305 \r
1306         if(context)\r
1307         {\r
1308                 for(int i = 0; i < n; i++)\r
1309                 {\r
1310                         context->deleteQuery(ids[i]);\r
1311                 }\r
1312         }\r
1313 }\r
1314 \r
1315 void DeleteRenderbuffers(GLsizei n, const GLuint* renderbuffers)\r
1316 {\r
1317         TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);\r
1318 \r
1319         if(n < 0)\r
1320         {\r
1321                 return error(GL_INVALID_VALUE);\r
1322         }\r
1323 \r
1324         es2::Context *context = es2::getContext();\r
1325 \r
1326         if(context)\r
1327         {\r
1328                 for(int i = 0; i < n; i++)\r
1329                 {\r
1330                         context->deleteRenderbuffer(renderbuffers[i]);\r
1331                 }\r
1332         }\r
1333 }\r
1334 \r
1335 void DeleteShader(GLuint shader)\r
1336 {\r
1337         TRACE("(GLuint shader = %d)", shader);\r
1338 \r
1339         if(shader == 0)\r
1340         {\r
1341                 return;\r
1342         }\r
1343 \r
1344         es2::Context *context = es2::getContext();\r
1345 \r
1346         if(context)\r
1347         {\r
1348                 if(!context->getShader(shader))\r
1349                 {\r
1350                         if(context->getProgram(shader))\r
1351                         {\r
1352                                 return error(GL_INVALID_OPERATION);\r
1353                         }\r
1354                         else\r
1355                         {\r
1356                                 return error(GL_INVALID_VALUE);\r
1357                         }\r
1358                 }\r
1359 \r
1360                 context->deleteShader(shader);\r
1361         }\r
1362 }\r
1363 \r
1364 void DeleteTextures(GLsizei n, const GLuint* textures)\r
1365 {\r
1366         TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);\r
1367 \r
1368         if(n < 0)\r
1369         {\r
1370                 return error(GL_INVALID_VALUE);\r
1371         }\r
1372 \r
1373         es2::Context *context = es2::getContext();\r
1374 \r
1375         if(context)\r
1376         {\r
1377                 for(int i = 0; i < n; i++)\r
1378                 {\r
1379                         if(textures[i] != 0)\r
1380                         {\r
1381                                 context->deleteTexture(textures[i]);\r
1382                         }\r
1383                 }\r
1384         }\r
1385 }\r
1386 \r
1387 void DepthFunc(GLenum func)\r
1388 {\r
1389         TRACE("(GLenum func = 0x%X)", func);\r
1390 \r
1391         switch(func)\r
1392         {\r
1393         case GL_NEVER:\r
1394         case GL_ALWAYS:\r
1395         case GL_LESS:\r
1396         case GL_LEQUAL:\r
1397         case GL_EQUAL:\r
1398         case GL_GREATER:\r
1399         case GL_GEQUAL:\r
1400         case GL_NOTEQUAL:\r
1401                 break;\r
1402         default:\r
1403                 return error(GL_INVALID_ENUM);\r
1404         }\r
1405 \r
1406         es2::Context *context = es2::getContext();\r
1407 \r
1408         if(context)\r
1409         {\r
1410                 context->setDepthFunc(func);\r
1411         }\r
1412 }\r
1413 \r
1414 void DepthMask(GLboolean flag)\r
1415 {\r
1416         TRACE("(GLboolean flag = %d)", flag);\r
1417 \r
1418         es2::Context *context = es2::getContext();\r
1419 \r
1420         if(context)\r
1421         {\r
1422                 context->setDepthMask(flag != GL_FALSE);\r
1423         }\r
1424 }\r
1425 \r
1426 void DepthRangef(GLclampf zNear, GLclampf zFar)\r
1427 {\r
1428         TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);\r
1429 \r
1430         es2::Context *context = es2::getContext();\r
1431 \r
1432         if(context)\r
1433         {\r
1434                 context->setDepthRange(zNear, zFar);\r
1435         }\r
1436 }\r
1437 \r
1438 void DetachShader(GLuint program, GLuint shader)\r
1439 {\r
1440         TRACE("(GLuint program = %d, GLuint shader = %d)", program, shader);\r
1441 \r
1442         es2::Context *context = es2::getContext();\r
1443 \r
1444         if(context)\r
1445         {\r
1446 \r
1447                 es2::Program *programObject = context->getProgram(program);\r
1448                 es2::Shader *shaderObject = context->getShader(shader);\r
1449 \r
1450                 if(!programObject)\r
1451                 {\r
1452                         es2::Shader *shaderByProgramHandle;\r
1453                         shaderByProgramHandle = context->getShader(program);\r
1454                         if(!shaderByProgramHandle)\r
1455                         {\r
1456                                 return error(GL_INVALID_VALUE);\r
1457                         }\r
1458                         else\r
1459                         {\r
1460                                 return error(GL_INVALID_OPERATION);\r
1461                         }\r
1462                 }\r
1463 \r
1464                 if(!shaderObject)\r
1465                 {\r
1466                         es2::Program *programByShaderHandle = context->getProgram(shader);\r
1467                         if(!programByShaderHandle)\r
1468                         {\r
1469                                 return error(GL_INVALID_VALUE);\r
1470                         }\r
1471                         else\r
1472                         {\r
1473                                 return error(GL_INVALID_OPERATION);\r
1474                         }\r
1475                 }\r
1476 \r
1477                 if(!programObject->detachShader(shaderObject))\r
1478                 {\r
1479                         return error(GL_INVALID_OPERATION);\r
1480                 }\r
1481         }\r
1482 }\r
1483 \r
1484 void Disable(GLenum cap)\r
1485 {\r
1486         TRACE("(GLenum cap = 0x%X)", cap);\r
1487 \r
1488         es2::Context *context = es2::getContext();\r
1489 \r
1490         if(context)\r
1491         {\r
1492                 switch(cap)\r
1493                 {\r
1494                 case GL_CULL_FACE:                     context->setCullFaceEnabled(false);                   break;\r
1495                 case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(false);          break;\r
1496                 case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(false);      break;\r
1497                 case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(false);             break;\r
1498                 case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(false);                break;\r
1499                 case GL_STENCIL_TEST:                  context->setStencilTestEnabled(false);                break;\r
1500                 case GL_DEPTH_TEST:                    context->setDepthTestEnabled(false);                  break;\r
1501                 case GL_BLEND:                         context->setBlendEnabled(false);                      break;\r
1502                 case GL_DITHER:                        context->setDitherEnabled(false);                     break;\r
1503                 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(false); break;\r
1504                 case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(false);          break;\r
1505                 default:\r
1506                         return error(GL_INVALID_ENUM);\r
1507                 }\r
1508         }\r
1509 }\r
1510 \r
1511 void DisableVertexAttribArray(GLuint index)\r
1512 {\r
1513         TRACE("(GLuint index = %d)", index);\r
1514 \r
1515         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
1516         {\r
1517                 return error(GL_INVALID_VALUE);\r
1518         }\r
1519 \r
1520         es2::Context *context = es2::getContext();\r
1521 \r
1522         if(context)\r
1523         {\r
1524                 context->setVertexAttribArrayEnabled(index, false);\r
1525         }\r
1526 }\r
1527 \r
1528 void DrawArrays(GLenum mode, GLint first, GLsizei count)\r
1529 {\r
1530         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);\r
1531 \r
1532         switch(mode)\r
1533         {\r
1534         case GL_POINTS:\r
1535         case GL_LINES:\r
1536         case GL_LINE_LOOP:\r
1537         case GL_LINE_STRIP:\r
1538         case GL_TRIANGLES:\r
1539         case GL_TRIANGLE_FAN:\r
1540         case GL_TRIANGLE_STRIP:\r
1541                 break;\r
1542         default:\r
1543                 return error(GL_INVALID_ENUM);\r
1544         }\r
1545 \r
1546         if(count < 0 || first < 0)\r
1547         {\r
1548                 return error(GL_INVALID_VALUE);\r
1549         }\r
1550 \r
1551         es2::Context *context = es2::getContext();\r
1552 \r
1553         if(context)\r
1554         {\r
1555                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1556                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))\r
1557                 {\r
1558                         return error(GL_INVALID_OPERATION);\r
1559                 }\r
1560 \r
1561                 context->drawArrays(mode, first, count);\r
1562         }\r
1563 }\r
1564 \r
1565 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)\r
1566 {\r
1567         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",\r
1568               mode, count, type, indices);\r
1569 \r
1570         switch(mode)\r
1571         {\r
1572         case GL_POINTS:\r
1573         case GL_LINES:\r
1574         case GL_LINE_LOOP:\r
1575         case GL_LINE_STRIP:\r
1576         case GL_TRIANGLES:\r
1577         case GL_TRIANGLE_FAN:\r
1578         case GL_TRIANGLE_STRIP:\r
1579                 break;\r
1580         default:\r
1581                 return error(GL_INVALID_ENUM);\r
1582         }\r
1583 \r
1584         if(count < 0)\r
1585         {\r
1586                 return error(GL_INVALID_VALUE);\r
1587         }\r
1588 \r
1589         es2::Context *context = es2::getContext();\r
1590 \r
1591         if(context)\r
1592         {\r
1593                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1594                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())\r
1595                 {\r
1596                         return error(GL_INVALID_OPERATION);\r
1597                 }\r
1598 \r
1599                 switch(type)\r
1600                 {\r
1601                 case GL_UNSIGNED_BYTE:\r
1602                 case GL_UNSIGNED_SHORT:\r
1603                 case GL_UNSIGNED_INT:\r
1604                         break;\r
1605                 default:\r
1606                         return error(GL_INVALID_ENUM);\r
1607                 }\r
1608 \r
1609                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices);\r
1610         }\r
1611 }\r
1612 \r
1613 void DrawArraysInstancedEXT(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)\r
1614 {\r
1615         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",\r
1616                 mode, first, count, instanceCount);\r
1617 \r
1618         switch(mode)\r
1619         {\r
1620         case GL_POINTS:\r
1621         case GL_LINES:\r
1622         case GL_LINE_LOOP:\r
1623         case GL_LINE_STRIP:\r
1624         case GL_TRIANGLES:\r
1625         case GL_TRIANGLE_FAN:\r
1626         case GL_TRIANGLE_STRIP:\r
1627                 break;\r
1628         default:\r
1629                 return error(GL_INVALID_ENUM);\r
1630         }\r
1631 \r
1632         if(count < 0 || instanceCount < 0)\r
1633         {\r
1634                 return error(GL_INVALID_VALUE);\r
1635         }\r
1636 \r
1637         es2::Context *context = es2::getContext();\r
1638 \r
1639         if(context)\r
1640         {\r
1641                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1642                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))\r
1643                 {\r
1644                         return error(GL_INVALID_OPERATION);\r
1645                 }\r
1646 \r
1647                 context->drawArrays(mode, first, count, instanceCount);\r
1648         }\r
1649 }\r
1650 \r
1651 void DrawElementsInstancedEXT(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)\r
1652 {\r
1653         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",\r
1654                 mode, count, type, indices, instanceCount);\r
1655 \r
1656         switch(mode)\r
1657         {\r
1658         case GL_POINTS:\r
1659         case GL_LINES:\r
1660         case GL_LINE_LOOP:\r
1661         case GL_LINE_STRIP:\r
1662         case GL_TRIANGLES:\r
1663         case GL_TRIANGLE_FAN:\r
1664         case GL_TRIANGLE_STRIP:\r
1665                 break;\r
1666         default:\r
1667                 return error(GL_INVALID_ENUM);\r
1668         }\r
1669 \r
1670         switch(type)\r
1671         {\r
1672         case GL_UNSIGNED_BYTE:\r
1673         case GL_UNSIGNED_SHORT:\r
1674         case GL_UNSIGNED_INT:\r
1675                 break;\r
1676         default:\r
1677                 return error(GL_INVALID_ENUM);\r
1678         }\r
1679 \r
1680         if(count < 0 || instanceCount < 0)\r
1681         {\r
1682                 return error(GL_INVALID_VALUE);\r
1683         }\r
1684 \r
1685         es2::Context *context = es2::getContext();\r
1686 \r
1687         if(context)\r
1688         {\r
1689                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1690                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())\r
1691                 {\r
1692                         return error(GL_INVALID_OPERATION);\r
1693                 }\r
1694 \r
1695                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);\r
1696         }\r
1697 }\r
1698 \r
1699 void VertexAttribDivisorEXT(GLuint index, GLuint divisor)\r
1700 {\r
1701         TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);\r
1702 \r
1703         es2::Context *context = es2::getContext();\r
1704 \r
1705         if(context)\r
1706         {\r
1707                 if(index >= es2::MAX_VERTEX_ATTRIBS)\r
1708                 {\r
1709                         return error(GL_INVALID_VALUE);\r
1710                 }\r
1711 \r
1712                 context->setVertexAttribDivisor(index, divisor);\r
1713         }\r
1714 }\r
1715 \r
1716 void DrawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount)\r
1717 {\r
1718         TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d, GLsizei instanceCount = %d)",\r
1719                 mode, first, count, instanceCount);\r
1720 \r
1721         switch(mode)\r
1722         {\r
1723         case GL_POINTS:\r
1724         case GL_LINES:\r
1725         case GL_LINE_LOOP:\r
1726         case GL_LINE_STRIP:\r
1727         case GL_TRIANGLES:\r
1728         case GL_TRIANGLE_FAN:\r
1729         case GL_TRIANGLE_STRIP:\r
1730                 break;\r
1731         default:\r
1732                 return error(GL_INVALID_ENUM);\r
1733         }\r
1734 \r
1735         if(count < 0 || instanceCount < 0)\r
1736         {\r
1737                 return error(GL_INVALID_VALUE);\r
1738         }\r
1739 \r
1740         es2::Context *context = es2::getContext();\r
1741 \r
1742         if(context)\r
1743         {\r
1744                 if(!context->hasZeroDivisor())\r
1745                 {\r
1746                         return error(GL_INVALID_OPERATION);\r
1747                 }\r
1748 \r
1749                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1750                 if(transformFeedback && transformFeedback->isActive() && (mode != transformFeedback->primitiveMode()))\r
1751                 {\r
1752                         return error(GL_INVALID_OPERATION);\r
1753                 }\r
1754 \r
1755                 context->drawArrays(mode, first, count, instanceCount);\r
1756         }\r
1757 }\r
1758 \r
1759 void DrawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount)\r
1760 {\r
1761         TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const void *indices = %p, GLsizei instanceCount = %d)",\r
1762                 mode, count, type, indices, instanceCount);\r
1763 \r
1764         switch(mode)\r
1765         {\r
1766         case GL_POINTS:\r
1767         case GL_LINES:\r
1768         case GL_LINE_LOOP:\r
1769         case GL_LINE_STRIP:\r
1770         case GL_TRIANGLES:\r
1771         case GL_TRIANGLE_FAN:\r
1772         case GL_TRIANGLE_STRIP:\r
1773                 break;\r
1774         default:\r
1775                 return error(GL_INVALID_ENUM);\r
1776         }\r
1777 \r
1778         switch(type)\r
1779         {\r
1780         case GL_UNSIGNED_BYTE:\r
1781         case GL_UNSIGNED_SHORT:\r
1782         case GL_UNSIGNED_INT:\r
1783                 break;\r
1784         default:\r
1785                 return error(GL_INVALID_ENUM);\r
1786         }\r
1787 \r
1788         if(count < 0 || instanceCount < 0)\r
1789         {\r
1790                 return error(GL_INVALID_VALUE);\r
1791         }\r
1792 \r
1793         es2::Context *context = es2::getContext();\r
1794 \r
1795         if(context)\r
1796         {\r
1797                 if(!context->hasZeroDivisor())\r
1798                 {\r
1799                         return error(GL_INVALID_OPERATION);\r
1800                 }\r
1801 \r
1802                 es2::TransformFeedback* transformFeedback = context->getTransformFeedback();\r
1803                 if(transformFeedback && transformFeedback->isActive() && !transformFeedback->isPaused())\r
1804                 {\r
1805                         return error(GL_INVALID_OPERATION);\r
1806                 }\r
1807 \r
1808                 context->drawElements(mode, 0, MAX_ELEMENT_INDEX, count, type, indices, instanceCount);\r
1809         }\r
1810 }\r
1811 \r
1812 void VertexAttribDivisorANGLE(GLuint index, GLuint divisor)\r
1813 {\r
1814         TRACE("(GLuint index = %d, GLuint divisor = %d)", index, divisor);\r
1815 \r
1816         es2::Context *context = es2::getContext();\r
1817 \r
1818         if(context)\r
1819         {\r
1820                 if(index >= MAX_VERTEX_ATTRIBS)\r
1821                 {\r
1822                         return error(GL_INVALID_VALUE);\r
1823                 }\r
1824 \r
1825                 context->setVertexAttribDivisor(index, divisor);\r
1826         }\r
1827 }\r
1828 \r
1829 void Enable(GLenum cap)\r
1830 {\r
1831         TRACE("(GLenum cap = 0x%X)", cap);\r
1832 \r
1833         es2::Context *context = es2::getContext();\r
1834 \r
1835         if(context)\r
1836         {\r
1837                 switch(cap)\r
1838                 {\r
1839                 case GL_CULL_FACE:                     context->setCullFaceEnabled(true);                   break;\r
1840                 case GL_POLYGON_OFFSET_FILL:           context->setPolygonOffsetFillEnabled(true);          break;\r
1841                 case GL_SAMPLE_ALPHA_TO_COVERAGE:      context->setSampleAlphaToCoverageEnabled(true);      break;\r
1842                 case GL_SAMPLE_COVERAGE:               context->setSampleCoverageEnabled(true);             break;\r
1843                 case GL_SCISSOR_TEST:                  context->setScissorTestEnabled(true);                break;\r
1844                 case GL_STENCIL_TEST:                  context->setStencilTestEnabled(true);                break;\r
1845                 case GL_DEPTH_TEST:                    context->setDepthTestEnabled(true);                  break;\r
1846                 case GL_BLEND:                         context->setBlendEnabled(true);                      break;\r
1847                 case GL_DITHER:                        context->setDitherEnabled(true);                     break;\r
1848                 case GL_PRIMITIVE_RESTART_FIXED_INDEX: context->setPrimitiveRestartFixedIndexEnabled(true); break;\r
1849                 case GL_RASTERIZER_DISCARD:            context->setRasterizerDiscardEnabled(true);          break;\r
1850                 default:\r
1851                         return error(GL_INVALID_ENUM);\r
1852                 }\r
1853         }\r
1854 }\r
1855 \r
1856 void EnableVertexAttribArray(GLuint index)\r
1857 {\r
1858         TRACE("(GLuint index = %d)", index);\r
1859 \r
1860         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
1861         {\r
1862                 return error(GL_INVALID_VALUE);\r
1863         }\r
1864 \r
1865         es2::Context *context = es2::getContext();\r
1866 \r
1867         if(context)\r
1868         {\r
1869                 context->setVertexAttribArrayEnabled(index, true);\r
1870         }\r
1871 }\r
1872 \r
1873 void EndQueryEXT(GLenum target)\r
1874 {\r
1875         TRACE("GLenum target = 0x%X)", target);\r
1876 \r
1877         switch(target)\r
1878         {\r
1879         case GL_ANY_SAMPLES_PASSED_EXT:\r
1880         case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT:\r
1881                 break;\r
1882         default:\r
1883                 return error(GL_INVALID_ENUM);\r
1884         }\r
1885 \r
1886         es2::Context *context = es2::getContext();\r
1887 \r
1888         if(context)\r
1889         {\r
1890                 context->endQuery(target);\r
1891         }\r
1892 }\r
1893 \r
1894 void FinishFenceNV(GLuint fence)\r
1895 {\r
1896         TRACE("(GLuint fence = %d)", fence);\r
1897 \r
1898         es2::Context *context = es2::getContext();\r
1899 \r
1900         if(context)\r
1901         {\r
1902                 es2::Fence* fenceObject = context->getFence(fence);\r
1903 \r
1904                 if(fenceObject == NULL)\r
1905                 {\r
1906                         return error(GL_INVALID_OPERATION);\r
1907                 }\r
1908 \r
1909                 fenceObject->finishFence();\r
1910         }\r
1911 }\r
1912 \r
1913 void Finish(void)\r
1914 {\r
1915         TRACE("()");\r
1916 \r
1917         es2::Context *context = es2::getContext();\r
1918 \r
1919         if(context)\r
1920         {\r
1921                 context->finish();\r
1922         }\r
1923 }\r
1924 \r
1925 void Flush(void)\r
1926 {\r
1927         TRACE("()");\r
1928 \r
1929         es2::Context *context = es2::getContext();\r
1930 \r
1931         if(context)\r
1932         {\r
1933                 context->flush();\r
1934         }\r
1935 }\r
1936 \r
1937 void FramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)\r
1938 {\r
1939         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "\r
1940               "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);\r
1941 \r
1942         if((target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE) ||\r
1943            (renderbuffertarget != GL_RENDERBUFFER && renderbuffer != 0))\r
1944         {\r
1945                 return error(GL_INVALID_ENUM);\r
1946         }\r
1947 \r
1948         es2::Context *context = es2::getContext();\r
1949 \r
1950         if(context)\r
1951         {\r
1952                 es2::Framebuffer *framebuffer = NULL;\r
1953                 GLuint framebufferName = 0;\r
1954                 if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
1955                 {\r
1956                         framebuffer = context->getReadFramebuffer();\r
1957                         framebufferName = context->getReadFramebufferName();\r
1958                 }\r
1959                 else\r
1960                 {\r
1961                         framebuffer = context->getDrawFramebuffer();\r
1962                         framebufferName = context->getDrawFramebufferName();\r
1963                 }\r
1964 \r
1965                 if(!framebuffer || framebufferName == 0)\r
1966                 {\r
1967                         return error(GL_INVALID_OPERATION);\r
1968                 }\r
1969 \r
1970                 // [OpenGL ES 2.0.25] Section 4.4.3 page 112\r
1971                 // [OpenGL ES 3.0.2] Section 4.4.2 page 201\r
1972                 // 'renderbuffer' must be either zero or the name of an existing renderbuffer object of\r
1973                 // type 'renderbuffertarget', otherwise an INVALID_OPERATION error is generated.\r
1974                 if(renderbuffer != 0)\r
1975                 {\r
1976                         if(!context->getRenderbuffer(renderbuffer))\r
1977                         {\r
1978                                 return error(GL_INVALID_OPERATION);\r
1979                         }\r
1980                 }\r
1981 \r
1982                 GLint clientVersion = context->getClientVersion();\r
1983 \r
1984                 switch(attachment)\r
1985                 {\r
1986                 case GL_COLOR_ATTACHMENT1:\r
1987                 case GL_COLOR_ATTACHMENT2:\r
1988                 case GL_COLOR_ATTACHMENT3:\r
1989                 case GL_COLOR_ATTACHMENT4:\r
1990                 case GL_COLOR_ATTACHMENT5:\r
1991                 case GL_COLOR_ATTACHMENT6:\r
1992                 case GL_COLOR_ATTACHMENT7:\r
1993                 case GL_COLOR_ATTACHMENT8:\r
1994                 case GL_COLOR_ATTACHMENT9:\r
1995                 case GL_COLOR_ATTACHMENT10:\r
1996                 case GL_COLOR_ATTACHMENT11:\r
1997                 case GL_COLOR_ATTACHMENT12:\r
1998                 case GL_COLOR_ATTACHMENT13:\r
1999                 case GL_COLOR_ATTACHMENT14:\r
2000                 case GL_COLOR_ATTACHMENT15:\r
2001                 case GL_COLOR_ATTACHMENT16:\r
2002                 case GL_COLOR_ATTACHMENT17:\r
2003                 case GL_COLOR_ATTACHMENT18:\r
2004                 case GL_COLOR_ATTACHMENT19:\r
2005                 case GL_COLOR_ATTACHMENT20:\r
2006                 case GL_COLOR_ATTACHMENT21:\r
2007                 case GL_COLOR_ATTACHMENT22:\r
2008                 case GL_COLOR_ATTACHMENT23:\r
2009                 case GL_COLOR_ATTACHMENT24:\r
2010                 case GL_COLOR_ATTACHMENT25:\r
2011                 case GL_COLOR_ATTACHMENT26:\r
2012                 case GL_COLOR_ATTACHMENT27:\r
2013                 case GL_COLOR_ATTACHMENT28:\r
2014                 case GL_COLOR_ATTACHMENT29:\r
2015                 case GL_COLOR_ATTACHMENT30:\r
2016                 case GL_COLOR_ATTACHMENT31:\r
2017                         if(clientVersion < 3)\r
2018                         {\r
2019                                 return error(GL_INVALID_ENUM);\r
2020                         }\r
2021                         // fall through\r
2022                 case GL_COLOR_ATTACHMENT0:\r
2023                         if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)\r
2024                         {\r
2025                                 return error(GL_INVALID_ENUM);\r
2026                         }\r
2027                         framebuffer->setColorbuffer(GL_RENDERBUFFER, renderbuffer, attachment - GL_COLOR_ATTACHMENT0);\r
2028                         break;\r
2029                 case GL_DEPTH_ATTACHMENT:\r
2030                         framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);\r
2031                         break;\r
2032                 case GL_STENCIL_ATTACHMENT:\r
2033                         framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);\r
2034                         break;\r
2035                 case GL_DEPTH_STENCIL_ATTACHMENT:\r
2036                         if(clientVersion >= 3)\r
2037                         {\r
2038                                 framebuffer->setDepthbuffer(GL_RENDERBUFFER, renderbuffer);\r
2039                                 framebuffer->setStencilbuffer(GL_RENDERBUFFER, renderbuffer);\r
2040                                 break;\r
2041                         }\r
2042                         else return error(GL_INVALID_ENUM);\r
2043                 default:\r
2044                         return error(GL_INVALID_ENUM);\r
2045                 }\r
2046         }\r
2047 }\r
2048 \r
2049 void FramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)\r
2050 {\r
2051         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "\r
2052               "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);\r
2053 \r
2054         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
2055         {\r
2056                 return error(GL_INVALID_ENUM);\r
2057         }\r
2058 \r
2059         es2::Context *context = es2::getContext();\r
2060 \r
2061         if(context)\r
2062         {\r
2063                 if(texture == 0)\r
2064                 {\r
2065                         textarget = GL_NONE;\r
2066                 }\r
2067                 else\r
2068                 {\r
2069                         es2::Texture *tex = context->getTexture(texture);\r
2070 \r
2071                         if(tex == NULL)\r
2072                         {\r
2073                                 return error(GL_INVALID_OPERATION);\r
2074                         }\r
2075 \r
2076                         switch(textarget)\r
2077                         {\r
2078                         case GL_TEXTURE_2D:\r
2079                                 if(tex->getTarget() != GL_TEXTURE_2D)\r
2080                                 {\r
2081                                         return error(GL_INVALID_OPERATION);\r
2082                                 }\r
2083                                 break;\r
2084                         case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
2085                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
2086                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
2087                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
2088                         case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
2089                         case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
2090                                 if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)\r
2091                                 {\r
2092                                         return error(GL_INVALID_OPERATION);\r
2093                                 }\r
2094                                 break;\r
2095                         default:\r
2096                                 return error(GL_INVALID_ENUM);\r
2097                         }\r
2098 \r
2099                         if(tex->isCompressed(textarget, level))\r
2100                         {\r
2101                                 return error(GL_INVALID_OPERATION);\r
2102                         }\r
2103 \r
2104                         if((level != 0) && (context->getClientVersion() < 3))\r
2105                         {\r
2106                                 return error(GL_INVALID_VALUE);\r
2107                         }\r
2108 \r
2109                         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
2110                         {\r
2111                                 return error(GL_INVALID_VALUE);\r
2112                         }\r
2113                 }\r
2114 \r
2115                 es2::Framebuffer *framebuffer = NULL;\r
2116                 GLuint framebufferName = 0;\r
2117                 if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
2118                 {\r
2119                         framebuffer = context->getReadFramebuffer();\r
2120                         framebufferName = context->getReadFramebufferName();\r
2121                 }\r
2122                 else\r
2123                 {\r
2124                         framebuffer = context->getDrawFramebuffer();\r
2125                         framebufferName = context->getDrawFramebufferName();\r
2126                 }\r
2127 \r
2128                 if(framebufferName == 0 || !framebuffer)\r
2129                 {\r
2130                         return error(GL_INVALID_OPERATION);\r
2131                 }\r
2132 \r
2133                 GLint clientVersion = context->getClientVersion();\r
2134 \r
2135                 switch(attachment)\r
2136                 {\r
2137                 case GL_COLOR_ATTACHMENT1:\r
2138                 case GL_COLOR_ATTACHMENT2:\r
2139                 case GL_COLOR_ATTACHMENT3:\r
2140                 case GL_COLOR_ATTACHMENT4:\r
2141                 case GL_COLOR_ATTACHMENT5:\r
2142                 case GL_COLOR_ATTACHMENT6:\r
2143                 case GL_COLOR_ATTACHMENT7:\r
2144                 case GL_COLOR_ATTACHMENT8:\r
2145                 case GL_COLOR_ATTACHMENT9:\r
2146                 case GL_COLOR_ATTACHMENT10:\r
2147                 case GL_COLOR_ATTACHMENT11:\r
2148                 case GL_COLOR_ATTACHMENT12:\r
2149                 case GL_COLOR_ATTACHMENT13:\r
2150                 case GL_COLOR_ATTACHMENT14:\r
2151                 case GL_COLOR_ATTACHMENT15:\r
2152                 case GL_COLOR_ATTACHMENT16:\r
2153                 case GL_COLOR_ATTACHMENT17:\r
2154                 case GL_COLOR_ATTACHMENT18:\r
2155                 case GL_COLOR_ATTACHMENT19:\r
2156                 case GL_COLOR_ATTACHMENT20:\r
2157                 case GL_COLOR_ATTACHMENT21:\r
2158                 case GL_COLOR_ATTACHMENT22:\r
2159                 case GL_COLOR_ATTACHMENT23:\r
2160                 case GL_COLOR_ATTACHMENT24:\r
2161                 case GL_COLOR_ATTACHMENT25:\r
2162                 case GL_COLOR_ATTACHMENT26:\r
2163                 case GL_COLOR_ATTACHMENT27:\r
2164                 case GL_COLOR_ATTACHMENT28:\r
2165                 case GL_COLOR_ATTACHMENT29:\r
2166                 case GL_COLOR_ATTACHMENT30:\r
2167                 case GL_COLOR_ATTACHMENT31:\r
2168                         if(clientVersion < 3)\r
2169                         {\r
2170                                 return error(GL_INVALID_ENUM);\r
2171                         }\r
2172                         // fall through\r
2173                 case GL_COLOR_ATTACHMENT0:\r
2174                         if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)\r
2175                         {\r
2176                                 return error(GL_INVALID_ENUM);\r
2177                         }\r
2178                         framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);\r
2179                         break;\r
2180                 case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;\r
2181                 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;\r
2182                 default:\r
2183                         return error(GL_INVALID_ENUM);\r
2184                 }\r
2185         }\r
2186 }\r
2187 \r
2188 void FrontFace(GLenum mode)\r
2189 {\r
2190         TRACE("(GLenum mode = 0x%X)", mode);\r
2191 \r
2192         switch(mode)\r
2193         {\r
2194         case GL_CW:\r
2195         case GL_CCW:\r
2196                 {\r
2197                         es2::Context *context = es2::getContext();\r
2198 \r
2199                         if(context)\r
2200                         {\r
2201                                 context->setFrontFace(mode);\r
2202                         }\r
2203                 }\r
2204                 break;\r
2205         default:\r
2206                 return error(GL_INVALID_ENUM);\r
2207         }\r
2208 }\r
2209 \r
2210 void GenBuffers(GLsizei n, GLuint* buffers)\r
2211 {\r
2212         TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);\r
2213 \r
2214         if(n < 0)\r
2215         {\r
2216                 return error(GL_INVALID_VALUE);\r
2217         }\r
2218 \r
2219         es2::Context *context = es2::getContext();\r
2220 \r
2221         if(context)\r
2222         {\r
2223                 for(int i = 0; i < n; i++)\r
2224                 {\r
2225                         buffers[i] = context->createBuffer();\r
2226                 }\r
2227         }\r
2228 }\r
2229 \r
2230 void GenerateMipmap(GLenum target)\r
2231 {\r
2232         TRACE("(GLenum target = 0x%X)", target);\r
2233 \r
2234         es2::Context *context = es2::getContext();\r
2235 \r
2236         if(context)\r
2237         {\r
2238                 es2::Texture *texture = nullptr;\r
2239 \r
2240                 GLint clientVersion = context->getClientVersion();\r
2241 \r
2242                 switch(target)\r
2243                 {\r
2244                 case GL_TEXTURE_2D:\r
2245                         texture = context->getTexture2D();\r
2246                         break;\r
2247                 case GL_TEXTURE_CUBE_MAP:\r
2248                         texture = context->getTextureCubeMap();\r
2249                         break;\r
2250                 case GL_TEXTURE_2D_ARRAY:\r
2251                         if(clientVersion < 3)\r
2252                         {\r
2253                                 return error(GL_INVALID_ENUM);\r
2254                         }\r
2255                         else\r
2256                         {\r
2257                                 texture = context->getTexture2DArray();\r
2258                         }\r
2259                         break;\r
2260                 case GL_TEXTURE_3D_OES:\r
2261                         texture = context->getTexture3D();\r
2262                         break;\r
2263                 default:\r
2264                         return error(GL_INVALID_ENUM);\r
2265                 }\r
2266 \r
2267                 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))\r
2268                 {\r
2269                         return error(GL_INVALID_OPERATION);\r
2270                 }\r
2271 \r
2272                 texture->generateMipmaps();\r
2273         }\r
2274 }\r
2275 \r
2276 void GenFencesNV(GLsizei n, GLuint* fences)\r
2277 {\r
2278         TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);\r
2279 \r
2280         if(n < 0)\r
2281         {\r
2282                 return error(GL_INVALID_VALUE);\r
2283         }\r
2284 \r
2285         es2::Context *context = es2::getContext();\r
2286 \r
2287         if(context)\r
2288         {\r
2289                 for(int i = 0; i < n; i++)\r
2290                 {\r
2291                         fences[i] = context->createFence();\r
2292                 }\r
2293         }\r
2294 }\r
2295 \r
2296 void GenFramebuffers(GLsizei n, GLuint* framebuffers)\r
2297 {\r
2298         TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);\r
2299 \r
2300         if(n < 0)\r
2301         {\r
2302                 return error(GL_INVALID_VALUE);\r
2303         }\r
2304 \r
2305         es2::Context *context = es2::getContext();\r
2306 \r
2307         if(context)\r
2308         {\r
2309                 for(int i = 0; i < n; i++)\r
2310                 {\r
2311                         framebuffers[i] = context->createFramebuffer();\r
2312                 }\r
2313         }\r
2314 }\r
2315 \r
2316 void GenQueriesEXT(GLsizei n, GLuint* ids)\r
2317 {\r
2318         TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);\r
2319 \r
2320         if(n < 0)\r
2321         {\r
2322                 return error(GL_INVALID_VALUE);\r
2323         }\r
2324 \r
2325         es2::Context *context = es2::getContext();\r
2326 \r
2327         if(context)\r
2328         {\r
2329                 for(int i = 0; i < n; i++)\r
2330                 {\r
2331                         ids[i] = context->createQuery();\r
2332                 }\r
2333         }\r
2334 }\r
2335 \r
2336 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)\r
2337 {\r
2338         TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);\r
2339 \r
2340         if(n < 0)\r
2341         {\r
2342                 return error(GL_INVALID_VALUE);\r
2343         }\r
2344 \r
2345         es2::Context *context = es2::getContext();\r
2346 \r
2347         if(context)\r
2348         {\r
2349                 for(int i = 0; i < n; i++)\r
2350                 {\r
2351                         renderbuffers[i] = context->createRenderbuffer();\r
2352                 }\r
2353         }\r
2354 }\r
2355 \r
2356 void GenTextures(GLsizei n, GLuint* textures)\r
2357 {\r
2358         TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);\r
2359 \r
2360         if(n < 0)\r
2361         {\r
2362                 return error(GL_INVALID_VALUE);\r
2363         }\r
2364 \r
2365         es2::Context *context = es2::getContext();\r
2366 \r
2367         if(context)\r
2368         {\r
2369                 for(int i = 0; i < n; i++)\r
2370                 {\r
2371                         textures[i] = context->createTexture();\r
2372                 }\r
2373         }\r
2374 }\r
2375 \r
2376 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)\r
2377 {\r
2378         TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "\r
2379               "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",\r
2380               program, index, bufsize, length, size, type, name);\r
2381 \r
2382         if(bufsize < 0)\r
2383         {\r
2384                 return error(GL_INVALID_VALUE);\r
2385         }\r
2386 \r
2387         es2::Context *context = es2::getContext();\r
2388 \r
2389         if(context)\r
2390         {\r
2391                 es2::Program *programObject = context->getProgram(program);\r
2392 \r
2393                 if(!programObject)\r
2394                 {\r
2395                         if(context->getShader(program))\r
2396                         {\r
2397                                 return error(GL_INVALID_OPERATION);\r
2398                         }\r
2399                         else\r
2400                         {\r
2401                                 return error(GL_INVALID_VALUE);\r
2402                         }\r
2403                 }\r
2404 \r
2405                 if(index >= programObject->getActiveAttributeCount())\r
2406                 {\r
2407                         return error(GL_INVALID_VALUE);\r
2408                 }\r
2409 \r
2410                 programObject->getActiveAttribute(index, bufsize, length, size, type, name);\r
2411         }\r
2412 }\r
2413 \r
2414 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)\r
2415 {\r
2416         TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "\r
2417               "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",\r
2418               program, index, bufsize, length, size, type, name);\r
2419 \r
2420         if(bufsize < 0)\r
2421         {\r
2422                 return error(GL_INVALID_VALUE);\r
2423         }\r
2424 \r
2425         es2::Context *context = es2::getContext();\r
2426 \r
2427         if(context)\r
2428         {\r
2429                 es2::Program *programObject = context->getProgram(program);\r
2430 \r
2431                 if(!programObject)\r
2432                 {\r
2433                         if(context->getShader(program))\r
2434                         {\r
2435                                 return error(GL_INVALID_OPERATION);\r
2436                         }\r
2437                         else\r
2438                         {\r
2439                                 return error(GL_INVALID_VALUE);\r
2440                         }\r
2441                 }\r
2442 \r
2443                 if(index >= programObject->getActiveUniformCount())\r
2444                 {\r
2445                         return error(GL_INVALID_VALUE);\r
2446                 }\r
2447 \r
2448                 programObject->getActiveUniform(index, bufsize, length, size, type, name);\r
2449         }\r
2450 }\r
2451 \r
2452 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)\r
2453 {\r
2454         TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",\r
2455               program, maxcount, count, shaders);\r
2456 \r
2457         if(maxcount < 0)\r
2458         {\r
2459                 return error(GL_INVALID_VALUE);\r
2460         }\r
2461 \r
2462         es2::Context *context = es2::getContext();\r
2463 \r
2464         if(context)\r
2465         {\r
2466                 es2::Program *programObject = context->getProgram(program);\r
2467 \r
2468                 if(!programObject)\r
2469                 {\r
2470                         if(context->getShader(program))\r
2471                         {\r
2472                                 return error(GL_INVALID_OPERATION);\r
2473                         }\r
2474                         else\r
2475                         {\r
2476                                 return error(GL_INVALID_VALUE);\r
2477                         }\r
2478                 }\r
2479 \r
2480                 return programObject->getAttachedShaders(maxcount, count, shaders);\r
2481         }\r
2482 }\r
2483 \r
2484 int GetAttribLocation(GLuint program, const GLchar* name)\r
2485 {\r
2486         TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);\r
2487 \r
2488         es2::Context *context = es2::getContext();\r
2489 \r
2490         if(context)\r
2491         {\r
2492 \r
2493                 es2::Program *programObject = context->getProgram(program);\r
2494 \r
2495                 if(!programObject)\r
2496                 {\r
2497                         if(context->getShader(program))\r
2498                         {\r
2499                                 return error(GL_INVALID_OPERATION, -1);\r
2500                         }\r
2501                         else\r
2502                         {\r
2503                                 return error(GL_INVALID_VALUE, -1);\r
2504                         }\r
2505                 }\r
2506 \r
2507                 if(!programObject->isLinked())\r
2508                 {\r
2509                         return error(GL_INVALID_OPERATION, -1);\r
2510                 }\r
2511 \r
2512                 return programObject->getAttributeLocation(name);\r
2513         }\r
2514 \r
2515         return -1;\r
2516 }\r
2517 \r
2518 void GetBooleanv(GLenum pname, GLboolean* params)\r
2519 {\r
2520         TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);\r
2521 \r
2522         es2::Context *context = es2::getContext();\r
2523 \r
2524         if(context)\r
2525         {\r
2526                 if(!(context->getBooleanv(pname, params)))\r
2527                 {\r
2528                         GLenum nativeType;\r
2529                         unsigned int numParams = 0;\r
2530                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
2531                                 return error(GL_INVALID_ENUM);\r
2532 \r
2533                         if(numParams == 0)\r
2534                                 return; // it is known that the pname is valid, but there are no parameters to return\r
2535 \r
2536                         if(nativeType == GL_FLOAT)\r
2537                         {\r
2538                                 GLfloat *floatParams = NULL;\r
2539                                 floatParams = new GLfloat[numParams];\r
2540 \r
2541                                 context->getFloatv(pname, floatParams);\r
2542 \r
2543                                 for(unsigned int i = 0; i < numParams; ++i)\r
2544                                 {\r
2545                                         if(floatParams[i] == 0.0f)\r
2546                                                 params[i] = GL_FALSE;\r
2547                                         else\r
2548                                                 params[i] = GL_TRUE;\r
2549                                 }\r
2550 \r
2551                                 delete [] floatParams;\r
2552                         }\r
2553                         else if(nativeType == GL_INT)\r
2554                         {\r
2555                                 GLint *intParams = NULL;\r
2556                                 intParams = new GLint[numParams];\r
2557 \r
2558                                 context->getIntegerv(pname, intParams);\r
2559 \r
2560                                 for(unsigned int i = 0; i < numParams; ++i)\r
2561                                 {\r
2562                                         if(intParams[i] == 0)\r
2563                                                 params[i] = GL_FALSE;\r
2564                                         else\r
2565                                                 params[i] = GL_TRUE;\r
2566                                 }\r
2567 \r
2568                                 delete [] intParams;\r
2569                         }\r
2570                 }\r
2571         }\r
2572 }\r
2573 \r
2574 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)\r
2575 {\r
2576         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);\r
2577 \r
2578         es2::Context *context = es2::getContext();\r
2579 \r
2580         if(context)\r
2581         {\r
2582                 es2::Buffer *buffer;\r
2583                 if(!context->getBuffer(target, &buffer))\r
2584                 {\r
2585                         return error(GL_INVALID_ENUM);\r
2586                 }\r
2587 \r
2588                 if(!buffer)\r
2589                 {\r
2590                         // A null buffer means that "0" is bound to the requested buffer target\r
2591                         return error(GL_INVALID_OPERATION);\r
2592                 }\r
2593 \r
2594                 GLint clientVersion = context->getClientVersion();\r
2595 \r
2596                 switch(pname)\r
2597                 {\r
2598                 case GL_BUFFER_USAGE:\r
2599                         *params = buffer->usage();\r
2600                         break;\r
2601                 case GL_BUFFER_SIZE:\r
2602                         *params = buffer->size();\r
2603                         break;\r
2604                 case GL_BUFFER_ACCESS_FLAGS:\r
2605                         if(clientVersion >= 3)\r
2606                         {\r
2607                                 *params = buffer->access();\r
2608                                 break;\r
2609                         }\r
2610                         else return error(GL_INVALID_ENUM);\r
2611                 case GL_BUFFER_MAPPED:\r
2612                         if(clientVersion >= 3)\r
2613                         {\r
2614                                 *params = buffer->isMapped();\r
2615                                 break;\r
2616                         }\r
2617                         else return error(GL_INVALID_ENUM);\r
2618                 case GL_BUFFER_MAP_LENGTH:\r
2619                         if(clientVersion >= 3)\r
2620                         {\r
2621                                 *params = buffer->length();\r
2622                                 break;\r
2623                         }\r
2624                         else return error(GL_INVALID_ENUM);\r
2625                 case GL_BUFFER_MAP_OFFSET:\r
2626                         if(clientVersion >= 3)\r
2627                         {\r
2628                                 *params = buffer->offset();\r
2629                                 break;\r
2630                         }\r
2631                         else return error(GL_INVALID_ENUM);\r
2632                 default:\r
2633                         return error(GL_INVALID_ENUM);\r
2634                 }\r
2635         }\r
2636 }\r
2637 \r
2638 GLenum GetError(void)\r
2639 {\r
2640         TRACE("()");\r
2641 \r
2642         es2::Context *context = es2::getContext();\r
2643 \r
2644         if(context)\r
2645         {\r
2646                 return context->getError();\r
2647         }\r
2648 \r
2649         return GL_NO_ERROR;\r
2650 }\r
2651 \r
2652 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)\r
2653 {\r
2654         TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);\r
2655 \r
2656         es2::Context *context = es2::getContext();\r
2657 \r
2658         if(context)\r
2659         {\r
2660                 es2::Fence *fenceObject = context->getFence(fence);\r
2661 \r
2662                 if(fenceObject == NULL)\r
2663                 {\r
2664                         return error(GL_INVALID_OPERATION);\r
2665                 }\r
2666 \r
2667                 fenceObject->getFenceiv(pname, params);\r
2668         }\r
2669 }\r
2670 \r
2671 void GetFloatv(GLenum pname, GLfloat* params)\r
2672 {\r
2673         TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);\r
2674 \r
2675         es2::Context *context = es2::getContext();\r
2676 \r
2677         if(context)\r
2678         {\r
2679                 if(!(context->getFloatv(pname, params)))\r
2680                 {\r
2681                         GLenum nativeType;\r
2682                         unsigned int numParams = 0;\r
2683                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
2684                                 return error(GL_INVALID_ENUM);\r
2685 \r
2686                         if(numParams == 0)\r
2687                                 return; // it is known that the pname is valid, but that there are no parameters to return.\r
2688 \r
2689                         if(nativeType == GL_BOOL)\r
2690                         {\r
2691                                 GLboolean *boolParams = NULL;\r
2692                                 boolParams = new GLboolean[numParams];\r
2693 \r
2694                                 context->getBooleanv(pname, boolParams);\r
2695 \r
2696                                 for(unsigned int i = 0; i < numParams; ++i)\r
2697                                 {\r
2698                                         if(boolParams[i] == GL_FALSE)\r
2699                                                 params[i] = 0.0f;\r
2700                                         else\r
2701                                                 params[i] = 1.0f;\r
2702                                 }\r
2703 \r
2704                                 delete [] boolParams;\r
2705                         }\r
2706                         else if(nativeType == GL_INT)\r
2707                         {\r
2708                                 GLint *intParams = NULL;\r
2709                                 intParams = new GLint[numParams];\r
2710 \r
2711                                 context->getIntegerv(pname, intParams);\r
2712 \r
2713                                 for(unsigned int i = 0; i < numParams; ++i)\r
2714                                 {\r
2715                                         params[i] = (GLfloat)intParams[i];\r
2716                                 }\r
2717 \r
2718                                 delete [] intParams;\r
2719                         }\r
2720                 }\r
2721         }\r
2722 }\r
2723 \r
2724 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)\r
2725 {\r
2726         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",\r
2727               target, attachment, pname, params);\r
2728 \r
2729         es2::Context *context = es2::getContext();\r
2730 \r
2731         if(context)\r
2732         {\r
2733                 if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)\r
2734                 {\r
2735                         return error(GL_INVALID_ENUM);\r
2736                 }\r
2737 \r
2738                 GLint clientVersion = context->getClientVersion();\r
2739 \r
2740                 es2::Framebuffer *framebuffer = nullptr;\r
2741                 if(target == GL_READ_FRAMEBUFFER)\r
2742                 {\r
2743                         if(context->getReadFramebufferName() == 0)\r
2744                         {\r
2745                                 if(clientVersion < 3)\r
2746                                 {\r
2747                                         return error(GL_INVALID_OPERATION);\r
2748                                 }\r
2749                                 else\r
2750                                 {\r
2751                                         switch(attachment)\r
2752                                         {\r
2753                                         case GL_BACK:\r
2754                                         case GL_DEPTH:\r
2755                                         case GL_STENCIL:\r
2756                                                 break;\r
2757                                         default:\r
2758                                                 return error(GL_INVALID_ENUM);\r
2759                                         }\r
2760                                 }\r
2761                         }\r
2762 \r
2763                         framebuffer = context->getReadFramebuffer();\r
2764                 }\r
2765                 else\r
2766                 {\r
2767                         if(context->getDrawFramebufferName() == 0)\r
2768                         {\r
2769                                 if(clientVersion < 3)\r
2770                                 {\r
2771                                         return error(GL_INVALID_OPERATION);\r
2772                                 }\r
2773                                 else\r
2774                                 {\r
2775                                         switch(attachment)\r
2776                                         {\r
2777                                         case GL_BACK:\r
2778                                         case GL_DEPTH:\r
2779                                         case GL_STENCIL:\r
2780                                                 break;\r
2781                                         default:\r
2782                                                 return error(GL_INVALID_ENUM);\r
2783                                         }\r
2784                                 }\r
2785                         }\r
2786 \r
2787                         framebuffer = context->getDrawFramebuffer();\r
2788                 }\r
2789 \r
2790                 GLenum attachmentType;\r
2791                 GLuint attachmentHandle;\r
2792                 GLint attachmentLayer;\r
2793                 Renderbuffer* renderbuffer = nullptr;\r
2794                 switch(attachment)\r
2795                 {\r
2796                 case GL_BACK:\r
2797                         if(clientVersion >= 3)\r
2798                         {\r
2799                                 attachmentType = framebuffer->getColorbufferType(0);\r
2800                                 attachmentHandle = framebuffer->getColorbufferName(0);\r
2801                                 attachmentLayer = framebuffer->getColorbufferLayer(0);\r
2802                                 renderbuffer = framebuffer->getColorbuffer(0);\r
2803                         }\r
2804                         else return error(GL_INVALID_ENUM);\r
2805                         break;\r
2806                 case GL_COLOR_ATTACHMENT1:\r
2807                 case GL_COLOR_ATTACHMENT2:\r
2808                 case GL_COLOR_ATTACHMENT3:\r
2809                 case GL_COLOR_ATTACHMENT4:\r
2810                 case GL_COLOR_ATTACHMENT5:\r
2811                 case GL_COLOR_ATTACHMENT6:\r
2812                 case GL_COLOR_ATTACHMENT7:\r
2813                 case GL_COLOR_ATTACHMENT8:\r
2814                 case GL_COLOR_ATTACHMENT9:\r
2815                 case GL_COLOR_ATTACHMENT10:\r
2816                 case GL_COLOR_ATTACHMENT11:\r
2817                 case GL_COLOR_ATTACHMENT12:\r
2818                 case GL_COLOR_ATTACHMENT13:\r
2819                 case GL_COLOR_ATTACHMENT14:\r
2820                 case GL_COLOR_ATTACHMENT15:\r
2821                 case GL_COLOR_ATTACHMENT16:\r
2822                 case GL_COLOR_ATTACHMENT17:\r
2823                 case GL_COLOR_ATTACHMENT18:\r
2824                 case GL_COLOR_ATTACHMENT19:\r
2825                 case GL_COLOR_ATTACHMENT20:\r
2826                 case GL_COLOR_ATTACHMENT21:\r
2827                 case GL_COLOR_ATTACHMENT22:\r
2828                 case GL_COLOR_ATTACHMENT23:\r
2829                 case GL_COLOR_ATTACHMENT24:\r
2830                 case GL_COLOR_ATTACHMENT25:\r
2831                 case GL_COLOR_ATTACHMENT26:\r
2832                 case GL_COLOR_ATTACHMENT27:\r
2833                 case GL_COLOR_ATTACHMENT28:\r
2834                 case GL_COLOR_ATTACHMENT29:\r
2835                 case GL_COLOR_ATTACHMENT30:\r
2836                 case GL_COLOR_ATTACHMENT31:\r
2837                         if(clientVersion < 3)\r
2838                         {\r
2839                                 return error(GL_INVALID_ENUM);\r
2840                         }\r
2841                         // fall through\r
2842                 case GL_COLOR_ATTACHMENT0:\r
2843                         if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)\r
2844                         {\r
2845                                 return error(GL_INVALID_ENUM);\r
2846                         }\r
2847                         attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);\r
2848                         attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);\r
2849                         attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);\r
2850                         renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);\r
2851                         break;\r
2852                 case GL_DEPTH:\r
2853                         if(clientVersion < 3)\r
2854                         {\r
2855                                 return error(GL_INVALID_ENUM);\r
2856                         }\r
2857                         // fall through\r
2858                 case GL_DEPTH_ATTACHMENT:\r
2859                         attachmentType = framebuffer->getDepthbufferType();\r
2860                         attachmentHandle = framebuffer->getDepthbufferName();\r
2861                         attachmentLayer = framebuffer->getDepthbufferLayer();\r
2862                         renderbuffer = framebuffer->getDepthbuffer();\r
2863                         break;\r
2864                 case GL_STENCIL:\r
2865                         if(clientVersion < 3)\r
2866                         {\r
2867                                 return error(GL_INVALID_ENUM);\r
2868                         }\r
2869                         // fall through\r
2870                 case GL_STENCIL_ATTACHMENT:\r
2871                         attachmentType = framebuffer->getStencilbufferType();\r
2872                         attachmentHandle = framebuffer->getStencilbufferName();\r
2873                         attachmentLayer = framebuffer->getStencilbufferLayer();\r
2874                         renderbuffer = framebuffer->getStencilbuffer();\r
2875                         break;\r
2876                 case GL_DEPTH_STENCIL_ATTACHMENT:\r
2877                         if(clientVersion >= 3)\r
2878                         {\r
2879                                 attachmentType = framebuffer->getDepthbufferType();\r
2880                                 attachmentHandle = framebuffer->getDepthbufferName();\r
2881                                 attachmentLayer = framebuffer->getDepthbufferLayer();\r
2882                                 if(attachmentHandle != framebuffer->getStencilbufferName())\r
2883                                 {\r
2884                                         // Different attachments to DEPTH and STENCIL, query fails\r
2885                                         return error(GL_INVALID_OPERATION);\r
2886                                 }\r
2887                                 renderbuffer = framebuffer->getDepthbuffer();\r
2888                         }\r
2889                         else return error(GL_INVALID_ENUM);\r
2890                         break;\r
2891                 default:\r
2892                         return error(GL_INVALID_ENUM);\r
2893                 }\r
2894 \r
2895                 GLenum attachmentObjectType = GL_NONE;   // Type category\r
2896                 if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))\r
2897                 {\r
2898                         attachmentObjectType = attachmentType;\r
2899                 }\r
2900                 else if(es2::IsTextureTarget(attachmentType))\r
2901                 {\r
2902                         attachmentObjectType = GL_TEXTURE;\r
2903                 }\r
2904                 else UNREACHABLE(attachmentType);\r
2905 \r
2906                 if(attachmentObjectType != GL_NONE)\r
2907                 {\r
2908                         switch(pname)\r
2909                         {\r
2910                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:\r
2911                                 *params = attachmentObjectType;\r
2912                                 break;\r
2913                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:\r
2914                                 if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)\r
2915                                 {\r
2916                                         *params = attachmentHandle;\r
2917                                 }\r
2918                                 else\r
2919                                 {\r
2920                                         return error(GL_INVALID_ENUM);\r
2921                                 }\r
2922                                 break;\r
2923                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:\r
2924                                 if(attachmentObjectType == GL_TEXTURE)\r
2925                                 {\r
2926                                         *params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0\r
2927                                 }\r
2928                                 else\r
2929                                 {\r
2930                                         return error(GL_INVALID_ENUM);\r
2931                                 }\r
2932                                 break;\r
2933                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:\r
2934                                 if(attachmentObjectType == GL_TEXTURE)\r
2935                                 {\r
2936                                         if(es2::IsCubemapTextureTarget(attachmentType))\r
2937                                         {\r
2938                                                 *params = attachmentType;\r
2939                                         }\r
2940                                         else\r
2941                                         {\r
2942                                                 *params = 0;\r
2943                                         }\r
2944                                 }\r
2945                                 else\r
2946                                 {\r
2947                                         return error(GL_INVALID_ENUM);\r
2948                                 }\r
2949                                 break;\r
2950                         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:\r
2951                                 if(clientVersion >= 3)\r
2952                                 {\r
2953                                         *params = attachmentLayer;\r
2954                                 }\r
2955                                 else return error(GL_INVALID_ENUM);\r
2956                                 break;\r
2957                         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:\r
2958                                 if(clientVersion >= 3)\r
2959                                 {\r
2960                                         *params = renderbuffer->getRedSize();\r
2961                                 }\r
2962                                 else return error(GL_INVALID_ENUM);\r
2963                                 break;\r
2964                         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:\r
2965                                 if(clientVersion >= 3)\r
2966                                 {\r
2967                                         *params = renderbuffer->getGreenSize();\r
2968                                 }\r
2969                                 else return error(GL_INVALID_ENUM);\r
2970                                 break;\r
2971                         case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:\r
2972                                 if(clientVersion >= 3)\r
2973                                 {\r
2974                                         *params = renderbuffer->getBlueSize();\r
2975                                 }\r
2976                                 else return error(GL_INVALID_ENUM);\r
2977                                 break;\r
2978                         case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:\r
2979                                 if(clientVersion >= 3)\r
2980                                 {\r
2981                                         *params = renderbuffer->getAlphaSize();\r
2982                                 }\r
2983                                 else return error(GL_INVALID_ENUM);\r
2984                                 break;\r
2985                         case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:\r
2986                                 if(clientVersion >= 3)\r
2987                                 {\r
2988                                         *params = renderbuffer->getDepthSize();\r
2989                                 }\r
2990                                 else return error(GL_INVALID_ENUM);\r
2991                                 break;\r
2992                         case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:\r
2993                                 if(clientVersion >= 3)\r
2994                                 {\r
2995                                         *params = renderbuffer->getStencilSize();\r
2996                                 }\r
2997                                 else return error(GL_INVALID_ENUM);\r
2998                                 break;\r
2999                         case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:\r
3000                                 if(clientVersion >= 3)\r
3001                                 {\r
3002                                         if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)\r
3003                                         {\r
3004                                                 return error(GL_INVALID_OPERATION);\r
3005                                         }\r
3006 \r
3007                                         *params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);\r
3008                                 }\r
3009                                 else return error(GL_INVALID_ENUM);\r
3010                                 break;\r
3011                         case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:\r
3012                                 if(clientVersion >= 3)\r
3013                                 {\r
3014                                         *params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added\r
3015                                 }\r
3016                                 else return error(GL_INVALID_ENUM);\r
3017                                 break;\r
3018                         default:\r
3019                                 return error(GL_INVALID_ENUM);\r
3020                         }\r
3021                 }\r
3022                 else\r
3023                 {\r
3024                         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE\r
3025                         // is NONE, then querying any other pname will generate INVALID_ENUM.\r
3026 \r
3027                         // ES 3.0.2 spec pg 235 states that if the attachment type is none,\r
3028                         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an\r
3029                         // INVALID_OPERATION for all other pnames\r
3030 \r
3031                         switch(pname)\r
3032                         {\r
3033                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:\r
3034                                 *params = GL_NONE;\r
3035                                 break;\r
3036 \r
3037                         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:\r
3038                                 if(clientVersion < 3)\r
3039                                 {\r
3040                                         return error(GL_INVALID_ENUM);\r
3041                                 }\r
3042                                 *params = 0;\r
3043                                 break;\r
3044 \r
3045                         default:\r
3046                                 if(clientVersion < 3)\r
3047                                 {\r
3048                                         return error(GL_INVALID_ENUM);\r
3049                                 }\r
3050                                 else\r
3051                                 {\r
3052                                         return error(GL_INVALID_OPERATION);\r
3053                                 }\r
3054                         }\r
3055                 }\r
3056         }\r
3057 }\r
3058 \r
3059 GLenum GetGraphicsResetStatusEXT(void)\r
3060 {\r
3061         TRACE("()");\r
3062 \r
3063         return GL_NO_ERROR;\r
3064 }\r
3065 \r
3066 void GetIntegerv(GLenum pname, GLint* params)\r
3067 {\r
3068         TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);\r
3069 \r
3070         es2::Context *context = es2::getContext();\r
3071 \r
3072         if(!context)\r
3073         {\r
3074                 // Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior\r
3075                 #ifdef __ANDROID__\r
3076                         ALOGI("expected_badness glGetIntegerv() called without current context.");\r
3077                 #else\r
3078                         ERR("glGetIntegerv() called without current context.");\r
3079                 #endif\r
3080 \r
3081                 // This is not spec compliant! When there is no current GL context, functions should\r
3082                 // have no side effects. Google Maps queries these values before creating a context,\r
3083                 // so we need this as a bug-compatible workaround.\r
3084                 switch(pname)\r
3085                 {\r
3086                 case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;\r
3087                 case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;\r
3088                 case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;\r
3089                 case GL_STENCIL_BITS:                     *params = 8;                                     return;\r
3090                 case GL_ALIASED_LINE_WIDTH_RANGE:\r
3091                         params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;\r
3092                         params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;\r
3093                         return;\r
3094                 }\r
3095         }\r
3096 \r
3097         if(context)\r
3098         {\r
3099                 if(!(context->getIntegerv(pname, params)))\r
3100                 {\r
3101                         GLenum nativeType;\r
3102                         unsigned int numParams = 0;\r
3103                         if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))\r
3104                                 return error(GL_INVALID_ENUM);\r
3105 \r
3106                         if(numParams == 0)\r
3107                                 return; // it is known that pname is valid, but there are no parameters to return\r
3108 \r
3109                         if(nativeType == GL_BOOL)\r
3110                         {\r
3111                                 GLboolean *boolParams = NULL;\r
3112                                 boolParams = new GLboolean[numParams];\r
3113 \r
3114                                 context->getBooleanv(pname, boolParams);\r
3115 \r
3116                                 for(unsigned int i = 0; i < numParams; ++i)\r
3117                                 {\r
3118                                         params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;\r
3119                                 }\r
3120 \r
3121                                 delete [] boolParams;\r
3122                         }\r
3123                         else if(nativeType == GL_FLOAT)\r
3124                         {\r
3125                                 GLfloat *floatParams = NULL;\r
3126                                 floatParams = new GLfloat[numParams];\r
3127 \r
3128                                 context->getFloatv(pname, floatParams);\r
3129 \r
3130                                 for(unsigned int i = 0; i < numParams; ++i)\r
3131                                 {\r
3132                                         if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)\r
3133                                         {\r
3134                                                 params[i] = es2::floatToInt(floatParams[i]);\r
3135                                         }\r
3136                                         else\r
3137                                         {\r
3138                                                 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));\r
3139                                         }\r
3140                                 }\r
3141 \r
3142                                 delete [] floatParams;\r
3143                         }\r
3144                 }\r
3145         }\r
3146 }\r
3147 \r
3148 void GetProgramiv(GLuint program, GLenum pname, GLint* params)\r
3149 {\r
3150         TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);\r
3151 \r
3152         es2::Context *context = es2::getContext();\r
3153 \r
3154         if(context)\r
3155         {\r
3156                 es2::Program *programObject = context->getProgram(program);\r
3157 \r
3158                 if(!programObject)\r
3159                 {\r
3160                         return error(GL_INVALID_VALUE);\r
3161                 }\r
3162 \r
3163                 GLint clientVersion = egl::getClientVersion();\r
3164 \r
3165                 switch(pname)\r
3166                 {\r
3167                 case GL_DELETE_STATUS:\r
3168                         *params = programObject->isFlaggedForDeletion();\r
3169                         return;\r
3170                 case GL_LINK_STATUS:\r
3171                         *params = programObject->isLinked();\r
3172                         return;\r
3173                 case GL_VALIDATE_STATUS:\r
3174                         *params = programObject->isValidated();\r
3175                         return;\r
3176                 case GL_INFO_LOG_LENGTH:\r
3177                         *params = programObject->getInfoLogLength();\r
3178                         return;\r
3179                 case GL_ATTACHED_SHADERS:\r
3180                         *params = programObject->getAttachedShadersCount();\r
3181                         return;\r
3182                 case GL_ACTIVE_ATTRIBUTES:\r
3183                         *params = programObject->getActiveAttributeCount();\r
3184                         return;\r
3185                 case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:\r
3186                         *params = programObject->getActiveAttributeMaxLength();\r
3187                         return;\r
3188                 case GL_ACTIVE_UNIFORMS:\r
3189                         *params = programObject->getActiveUniformCount();\r
3190                         return;\r
3191                 case GL_ACTIVE_UNIFORM_MAX_LENGTH:\r
3192                         *params = programObject->getActiveUniformMaxLength();\r
3193                         return;\r
3194                 case GL_ACTIVE_UNIFORM_BLOCKS:\r
3195                         if(clientVersion >= 3)\r
3196                         {\r
3197                                 *params = programObject->getActiveUniformBlockCount();\r
3198                                 return;\r
3199                         }\r
3200                         else return error(GL_INVALID_ENUM);\r
3201                 case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:\r
3202                         if(clientVersion >= 3)\r
3203                         {\r
3204                                 *params = programObject->getActiveUniformBlockMaxLength();\r
3205                                 return;\r
3206                         }\r
3207                         else return error(GL_INVALID_ENUM);\r
3208                 case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:\r
3209                         if(clientVersion >= 3)\r
3210                         {\r
3211                                 *params = programObject->getTransformFeedbackBufferMode();\r
3212                                 return;\r
3213                         }\r
3214                         else return error(GL_INVALID_ENUM);\r
3215                 case GL_TRANSFORM_FEEDBACK_VARYINGS:\r
3216                         if(clientVersion >= 3)\r
3217                         {\r
3218                                 *params = programObject->getTransformFeedbackVaryingCount();\r
3219                                 return;\r
3220                         }\r
3221                         else return error(GL_INVALID_ENUM);\r
3222                 case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:\r
3223                         if(clientVersion >= 3)\r
3224                         {\r
3225                                 *params = programObject->getTransformFeedbackVaryingMaxLength();\r
3226                                 return;\r
3227                         }\r
3228                         else return error(GL_INVALID_ENUM);\r
3229                 case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:\r
3230                         if(clientVersion >= 3)\r
3231                         {\r
3232                                 *params = programObject->getBinaryRetrievableHint();\r
3233                                 return;\r
3234                         }\r
3235                         else return error(GL_INVALID_ENUM);\r
3236                 case GL_PROGRAM_BINARY_LENGTH:\r
3237                         if(clientVersion >= 3)\r
3238                         {\r
3239                                 *params = programObject->getBinaryLength();\r
3240                                 return;\r
3241                         }\r
3242                         else return error(GL_INVALID_ENUM);\r
3243                 default:\r
3244                         return error(GL_INVALID_ENUM);\r
3245                 }\r
3246         }\r
3247 }\r
3248 \r
3249 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)\r
3250 {\r
3251         TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",\r
3252               program, bufsize, length, infolog);\r
3253 \r
3254         if(bufsize < 0)\r
3255         {\r
3256                 return error(GL_INVALID_VALUE);\r
3257         }\r
3258 \r
3259         es2::Context *context = es2::getContext();\r
3260 \r
3261         if(context)\r
3262         {\r
3263                 es2::Program *programObject = context->getProgram(program);\r
3264 \r
3265                 if(!programObject)\r
3266                 {\r
3267                         return error(GL_INVALID_VALUE);\r
3268                 }\r
3269 \r
3270                 programObject->getInfoLog(bufsize, length, infolog);\r
3271         }\r
3272 }\r
3273 \r
3274 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)\r
3275 {\r
3276         TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);\r
3277 \r
3278         switch(pname)\r
3279         {\r
3280         case GL_CURRENT_QUERY_EXT:\r
3281                 break;\r
3282         default:\r
3283                 return error(GL_INVALID_ENUM);\r
3284         }\r
3285 \r
3286         es2::Context *context = es2::getContext();\r
3287 \r
3288         if(context)\r
3289         {\r
3290                 params[0] = context->getActiveQuery(target);\r
3291         }\r
3292 }\r
3293 \r
3294 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)\r
3295 {\r
3296         TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);\r
3297 \r
3298         switch(pname)\r
3299         {\r
3300         case GL_QUERY_RESULT_EXT:\r
3301         case GL_QUERY_RESULT_AVAILABLE_EXT:\r
3302                 break;\r
3303         default:\r
3304                 return error(GL_INVALID_ENUM);\r
3305         }\r
3306 \r
3307         es2::Context *context = es2::getContext();\r
3308 \r
3309         if(context)\r
3310         {\r
3311                 es2::Query *queryObject = context->getQuery(name);\r
3312 \r
3313                 if(!queryObject)\r
3314                 {\r
3315                         return error(GL_INVALID_OPERATION);\r
3316                 }\r
3317 \r
3318                 if(context->getActiveQuery(queryObject->getType()) == name)\r
3319                 {\r
3320                         return error(GL_INVALID_OPERATION);\r
3321                 }\r
3322 \r
3323                 switch(pname)\r
3324                 {\r
3325                 case GL_QUERY_RESULT_EXT:\r
3326                         params[0] = queryObject->getResult();\r
3327                         break;\r
3328                 case GL_QUERY_RESULT_AVAILABLE_EXT:\r
3329                         params[0] = queryObject->isResultAvailable();\r
3330                         break;\r
3331                 default:\r
3332                         ASSERT(false);\r
3333                 }\r
3334         }\r
3335 }\r
3336 \r
3337 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)\r
3338 {\r
3339         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);\r
3340 \r
3341         es2::Context *context = es2::getContext();\r
3342 \r
3343         if(context)\r
3344         {\r
3345                 if(target != GL_RENDERBUFFER)\r
3346                 {\r
3347                         return error(GL_INVALID_ENUM);\r
3348                 }\r
3349 \r
3350                 if(context->getRenderbufferName() == 0)\r
3351                 {\r
3352                         return error(GL_INVALID_OPERATION);\r
3353                 }\r
3354 \r
3355                 es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());\r
3356 \r
3357                 switch(pname)\r
3358                 {\r
3359                 case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;\r
3360                 case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;\r
3361                 case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;\r
3362                 case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;\r
3363                 case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;\r
3364                 case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;\r
3365                 case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;\r
3366                 case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;\r
3367                 case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;\r
3368                 case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;\r
3369                 default:\r
3370                         return error(GL_INVALID_ENUM);\r
3371                 }\r
3372         }\r
3373 }\r
3374 \r
3375 void GetShaderiv(GLuint shader, GLenum pname, GLint* params)\r
3376 {\r
3377         TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);\r
3378 \r
3379         es2::Context *context = es2::getContext();\r
3380 \r
3381         if(context)\r
3382         {\r
3383                 es2::Shader *shaderObject = context->getShader(shader);\r
3384 \r
3385                 if(!shaderObject)\r
3386                 {\r
3387                         return error(GL_INVALID_VALUE);\r
3388                 }\r
3389 \r
3390                 switch(pname)\r
3391                 {\r
3392                 case GL_SHADER_TYPE:\r
3393                         *params = shaderObject->getType();\r
3394                         return;\r
3395                 case GL_DELETE_STATUS:\r
3396                         *params = shaderObject->isFlaggedForDeletion();\r
3397                         return;\r
3398                 case GL_COMPILE_STATUS:\r
3399                         *params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;\r
3400                         return;\r
3401                 case GL_INFO_LOG_LENGTH:\r
3402                         *params = shaderObject->getInfoLogLength();\r
3403                         return;\r
3404                 case GL_SHADER_SOURCE_LENGTH:\r
3405                         *params = shaderObject->getSourceLength();\r
3406                         return;\r
3407                 default:\r
3408                         return error(GL_INVALID_ENUM);\r
3409                 }\r
3410         }\r
3411 }\r
3412 \r
3413 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)\r
3414 {\r
3415         TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",\r
3416               shader, bufsize, length, infolog);\r
3417 \r
3418         if(bufsize < 0)\r
3419         {\r
3420                 return error(GL_INVALID_VALUE);\r
3421         }\r
3422 \r
3423         es2::Context *context = es2::getContext();\r
3424 \r
3425         if(context)\r
3426         {\r
3427                 es2::Shader *shaderObject = context->getShader(shader);\r
3428 \r
3429                 if(!shaderObject)\r
3430                 {\r
3431                         return error(GL_INVALID_VALUE);\r
3432                 }\r
3433 \r
3434                 shaderObject->getInfoLog(bufsize, length, infolog);\r
3435         }\r
3436 }\r
3437 \r
3438 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)\r
3439 {\r
3440         TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",\r
3441               shadertype, precisiontype, range, precision);\r
3442 \r
3443         switch(shadertype)\r
3444         {\r
3445         case GL_VERTEX_SHADER:\r
3446         case GL_FRAGMENT_SHADER:\r
3447                 break;\r
3448         default:\r
3449                 return error(GL_INVALID_ENUM);\r
3450         }\r
3451 \r
3452         switch(precisiontype)\r
3453         {\r
3454         case GL_LOW_FLOAT:\r
3455         case GL_MEDIUM_FLOAT:\r
3456         case GL_HIGH_FLOAT:\r
3457                 // IEEE 754 single-precision\r
3458                 range[0] = 127;\r
3459                 range[1] = 127;\r
3460                 *precision = 23;\r
3461                 break;\r
3462         case GL_LOW_INT:\r
3463         case GL_MEDIUM_INT:\r
3464         case GL_HIGH_INT:\r
3465                 // Full integer precision is supported\r
3466                 range[0] = 31;\r
3467                 range[1] = 30;\r
3468                 *precision = 0;\r
3469                 break;\r
3470         default:\r
3471                 return error(GL_INVALID_ENUM);\r
3472         }\r
3473 }\r
3474 \r
3475 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)\r
3476 {\r
3477         TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",\r
3478               shader, bufsize, length, source);\r
3479 \r
3480         if(bufsize < 0)\r
3481         {\r
3482                 return error(GL_INVALID_VALUE);\r
3483         }\r
3484 \r
3485         es2::Context *context = es2::getContext();\r
3486 \r
3487         if(context)\r
3488         {\r
3489                 es2::Shader *shaderObject = context->getShader(shader);\r
3490 \r
3491                 if(!shaderObject)\r
3492                 {\r
3493                         return error(GL_INVALID_OPERATION);\r
3494                 }\r
3495 \r
3496                 shaderObject->getSource(bufsize, length, source);\r
3497         }\r
3498 }\r
3499 \r
3500 const GLubyte* GetString(GLenum name)\r
3501 {\r
3502         TRACE("(GLenum name = 0x%X)", name);\r
3503 \r
3504         switch(name)\r
3505         {\r
3506         case GL_VENDOR:\r
3507                 return (GLubyte*)"Google Inc.";\r
3508         case GL_RENDERER:\r
3509                 return (GLubyte*)"Google SwiftShader";\r
3510         case GL_VERSION:\r
3511         {\r
3512                 es2::Context *context = es2::getContext();\r
3513                 return (context && (context->getClientVersion() >= 3)) ?\r
3514                        (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :\r
3515                        (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;\r
3516         }\r
3517         case GL_SHADING_LANGUAGE_VERSION:\r
3518         {\r
3519                 es2::Context *context = es2::getContext();\r
3520                 return (context && (context->getClientVersion() >= 3)) ?\r
3521                        (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :\r
3522                        (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;\r
3523         }\r
3524         case GL_EXTENSIONS:\r
3525         {\r
3526                 es2::Context *context = es2::getContext();\r
3527                 return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)NULL;\r
3528         }\r
3529         default:\r
3530                 return error(GL_INVALID_ENUM, (GLubyte*)NULL);\r
3531         }\r
3532 }\r
3533 \r
3534 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)\r
3535 {\r
3536         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);\r
3537 \r
3538         es2::Context *context = es2::getContext();\r
3539 \r
3540         if(context)\r
3541         {\r
3542                 es2::Texture *texture;\r
3543 \r
3544                 GLint clientVersion = context->getClientVersion();\r
3545 \r
3546                 switch(target)\r
3547                 {\r
3548                 case GL_TEXTURE_2D:\r
3549                         texture = context->getTexture2D();\r
3550                         break;\r
3551                 case GL_TEXTURE_CUBE_MAP:\r
3552                         texture = context->getTextureCubeMap();\r
3553                         break;\r
3554                 case GL_TEXTURE_EXTERNAL_OES:\r
3555                         texture = context->getTextureExternal();\r
3556                         break;\r
3557                 case GL_TEXTURE_2D_ARRAY:\r
3558                         if(clientVersion < 3)\r
3559                         {\r
3560                                 return error(GL_INVALID_ENUM);\r
3561                         }\r
3562                         else\r
3563                         {\r
3564                                 texture = context->getTexture2DArray();\r
3565                         }\r
3566                         break;\r
3567                 case GL_TEXTURE_3D_OES:\r
3568                         texture = context->getTexture3D();\r
3569                         break;\r
3570                 default:\r
3571                         return error(GL_INVALID_ENUM);\r
3572                 }\r
3573 \r
3574                 switch(pname)\r
3575                 {\r
3576                 case GL_TEXTURE_MAG_FILTER:\r
3577                         *params = (GLfloat)texture->getMagFilter();\r
3578                         break;\r
3579                 case GL_TEXTURE_MIN_FILTER:\r
3580                         *params = (GLfloat)texture->getMinFilter();\r
3581                         break;\r
3582                 case GL_TEXTURE_WRAP_S:\r
3583                         *params = (GLfloat)texture->getWrapS();\r
3584                         break;\r
3585                 case GL_TEXTURE_WRAP_T:\r
3586                         *params = (GLfloat)texture->getWrapT();\r
3587                         break;\r
3588                 case GL_TEXTURE_WRAP_R_OES:\r
3589                         *params = (GLfloat)texture->getWrapR();\r
3590                         break;\r
3591                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
3592                         *params = texture->getMaxAnisotropy();\r
3593                         break;\r
3594                 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:\r
3595                         *params = (GLfloat)1;\r
3596                         break;\r
3597                 case GL_TEXTURE_BASE_LEVEL:\r
3598                         if(clientVersion >= 3)\r
3599                         {\r
3600                                 *params = (GLfloat)texture->getBaseLevel();\r
3601                                 break;\r
3602                         }\r
3603                         else return error(GL_INVALID_ENUM);\r
3604                 case GL_TEXTURE_COMPARE_FUNC:\r
3605                         if(clientVersion >= 3)\r
3606                         {\r
3607                                 *params = (GLfloat)texture->getCompareFunc();\r
3608                                 break;\r
3609                         }\r
3610                         else return error(GL_INVALID_ENUM);\r
3611                 case GL_TEXTURE_COMPARE_MODE:\r
3612                         if(clientVersion >= 3)\r
3613                         {\r
3614                                 *params = (GLfloat)texture->getCompareMode();\r
3615                                 break;\r
3616                         }\r
3617                         else return error(GL_INVALID_ENUM);\r
3618                 case GL_TEXTURE_IMMUTABLE_FORMAT:\r
3619                         if(clientVersion >= 3)\r
3620                         {\r
3621                                 *params = (GLfloat)texture->getImmutableFormat();\r
3622                                 break;\r
3623                         }\r
3624                         else return error(GL_INVALID_ENUM);\r
3625                 case GL_TEXTURE_IMMUTABLE_LEVELS:\r
3626                         if(clientVersion >= 3)\r
3627                         {\r
3628                                 *params = (GLfloat)texture->getImmutableLevels();\r
3629                                 break;\r
3630                         }\r
3631                         else return error(GL_INVALID_ENUM);\r
3632                 case GL_TEXTURE_MAX_LEVEL:\r
3633                         if(clientVersion >= 3)\r
3634                         {\r
3635                                 *params = (GLfloat)texture->getMaxLevel();\r
3636                                 break;\r
3637                         }\r
3638                         else return error(GL_INVALID_ENUM);\r
3639                 case GL_TEXTURE_MAX_LOD:\r
3640                         if(clientVersion >= 3)\r
3641                         {\r
3642                                 *params = texture->getMaxLOD();\r
3643                                 break;\r
3644                         }\r
3645                         else return error(GL_INVALID_ENUM);\r
3646                 case GL_TEXTURE_MIN_LOD:\r
3647                         if(clientVersion >= 3)\r
3648                         {\r
3649                                 *params = texture->getMinLOD();\r
3650                                 break;\r
3651                         }\r
3652                         else return error(GL_INVALID_ENUM);\r
3653                 case GL_TEXTURE_SWIZZLE_R:\r
3654                         if(clientVersion >= 3)\r
3655                         {\r
3656                                 *params = (GLfloat)texture->getSwizzleR();\r
3657                                 break;\r
3658                         }\r
3659                         else return error(GL_INVALID_ENUM);\r
3660                 case GL_TEXTURE_SWIZZLE_G:\r
3661                         if(clientVersion >= 3)\r
3662                         {\r
3663                                 *params = (GLfloat)texture->getSwizzleG();\r
3664                                 break;\r
3665                         }\r
3666                         else return error(GL_INVALID_ENUM);\r
3667                 case GL_TEXTURE_SWIZZLE_B:\r
3668                         if(clientVersion >= 3)\r
3669                         {\r
3670                                 *params = (GLfloat)texture->getSwizzleB();\r
3671                                 break;\r
3672                         }\r
3673                         else return error(GL_INVALID_ENUM);\r
3674                 case GL_TEXTURE_SWIZZLE_A:\r
3675                         if(clientVersion >= 3)\r
3676                         {\r
3677                                 *params = (GLfloat)texture->getSwizzleA();\r
3678                                 break;\r
3679                         }\r
3680                         else return error(GL_INVALID_ENUM);\r
3681                 default:\r
3682                         return error(GL_INVALID_ENUM);\r
3683                 }\r
3684         }\r
3685 }\r
3686 \r
3687 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)\r
3688 {\r
3689         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);\r
3690 \r
3691         es2::Context *context = es2::getContext();\r
3692 \r
3693         if(context)\r
3694         {\r
3695                 es2::Texture *texture;\r
3696 \r
3697                 GLint clientVersion = context->getClientVersion();\r
3698 \r
3699                 switch(target)\r
3700                 {\r
3701                 case GL_TEXTURE_2D:\r
3702                         texture = context->getTexture2D();\r
3703                         break;\r
3704                 case GL_TEXTURE_CUBE_MAP:\r
3705                         texture = context->getTextureCubeMap();\r
3706                         break;\r
3707                 case GL_TEXTURE_EXTERNAL_OES:\r
3708                         texture = context->getTextureExternal();\r
3709                         break;\r
3710                 case GL_TEXTURE_2D_ARRAY:\r
3711                         if(clientVersion < 3)\r
3712                         {\r
3713                                 return error(GL_INVALID_ENUM);\r
3714                         }\r
3715                         else\r
3716                         {\r
3717                                 texture = context->getTexture2DArray();\r
3718                         }\r
3719                         break;\r
3720                 case GL_TEXTURE_3D_OES:\r
3721                         texture = context->getTexture3D();\r
3722                         break;\r
3723                 default:\r
3724                         return error(GL_INVALID_ENUM);\r
3725                 }\r
3726 \r
3727                 switch(pname)\r
3728                 {\r
3729                 case GL_TEXTURE_MAG_FILTER:\r
3730                         *params = texture->getMagFilter();\r
3731                         break;\r
3732                 case GL_TEXTURE_MIN_FILTER:\r
3733                         *params = texture->getMinFilter();\r
3734                         break;\r
3735                 case GL_TEXTURE_WRAP_S:\r
3736                         *params = texture->getWrapS();\r
3737                         break;\r
3738                 case GL_TEXTURE_WRAP_T:\r
3739                         *params = texture->getWrapT();\r
3740                         break;\r
3741                 case GL_TEXTURE_WRAP_R_OES:\r
3742                         *params = texture->getWrapR();\r
3743                         break;\r
3744                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
3745                         *params = (GLint)texture->getMaxAnisotropy();\r
3746                         break;\r
3747                 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:\r
3748                         *params = 1;\r
3749                         break;\r
3750                 case GL_TEXTURE_BASE_LEVEL:\r
3751                         if(clientVersion >= 3)\r
3752                         {\r
3753                                 *params = texture->getBaseLevel();\r
3754                                 break;\r
3755                         }\r
3756                         else return error(GL_INVALID_ENUM);\r
3757                 case GL_TEXTURE_COMPARE_FUNC:\r
3758                         if(clientVersion >= 3)\r
3759                         {\r
3760                                 *params = (GLint)texture->getCompareFunc();\r
3761                                 break;\r
3762                         }\r
3763                         else return error(GL_INVALID_ENUM);\r
3764                 case GL_TEXTURE_COMPARE_MODE:\r
3765                         if(clientVersion >= 3)\r
3766                         {\r
3767                                 *params = (GLint)texture->getCompareMode();\r
3768                                 break;\r
3769                         }\r
3770                         else return error(GL_INVALID_ENUM);\r
3771                 case GL_TEXTURE_IMMUTABLE_FORMAT:\r
3772                         if(clientVersion >= 3)\r
3773                         {\r
3774                                 *params = (GLint)texture->getImmutableFormat();\r
3775                                 break;\r
3776                         }\r
3777                         else return error(GL_INVALID_ENUM);\r
3778                 case GL_TEXTURE_IMMUTABLE_LEVELS:\r
3779                         if(clientVersion >= 3)\r
3780                         {\r
3781                                 *params = (GLint)texture->getImmutableLevels();\r
3782                                 break;\r
3783                         }\r
3784                         else return error(GL_INVALID_ENUM);\r
3785                 case GL_TEXTURE_MAX_LEVEL:\r
3786                         if(clientVersion >= 3)\r
3787                         {\r
3788                                 *params = texture->getMaxLevel();\r
3789                                 break;\r
3790                         }\r
3791                         else return error(GL_INVALID_ENUM);\r
3792                 case GL_TEXTURE_MAX_LOD:\r
3793                         if(clientVersion >= 3)\r
3794                         {\r
3795                                 *params = (GLint)roundf(texture->getMaxLOD());\r
3796                                 break;\r
3797                         }\r
3798                         else return error(GL_INVALID_ENUM);\r
3799                 case GL_TEXTURE_MIN_LOD:\r
3800                         if(clientVersion >= 3)\r
3801                         {\r
3802                                 *params = (GLint)roundf(texture->getMinLOD());\r
3803                                 break;\r
3804                         }\r
3805                         else return error(GL_INVALID_ENUM);\r
3806                 case GL_TEXTURE_SWIZZLE_R:\r
3807                         if(clientVersion >= 3)\r
3808                         {\r
3809                                 *params = (GLint)texture->getSwizzleR();\r
3810                                 break;\r
3811                         }\r
3812                         else return error(GL_INVALID_ENUM);\r
3813                 case GL_TEXTURE_SWIZZLE_G:\r
3814                         if(clientVersion >= 3)\r
3815                         {\r
3816                                 *params = (GLint)texture->getSwizzleG();\r
3817                                 break;\r
3818                         }\r
3819                         else return error(GL_INVALID_ENUM);\r
3820                 case GL_TEXTURE_SWIZZLE_B:\r
3821                         if(clientVersion >= 3)\r
3822                         {\r
3823                                 *params = (GLint)texture->getSwizzleB();\r
3824                                 break;\r
3825                         }\r
3826                         else return error(GL_INVALID_ENUM);\r
3827                 case GL_TEXTURE_SWIZZLE_A:\r
3828                         if(clientVersion >= 3)\r
3829                         {\r
3830                                 *params = (GLint)texture->getSwizzleA();\r
3831                                 break;\r
3832                         }\r
3833                         else return error(GL_INVALID_ENUM);\r
3834                 default:\r
3835                         return error(GL_INVALID_ENUM);\r
3836                 }\r
3837         }\r
3838 }\r
3839 \r
3840 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)\r
3841 {\r
3842         TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",\r
3843               program, location, bufSize, params);\r
3844 \r
3845         if(bufSize < 0)\r
3846         {\r
3847                 return error(GL_INVALID_VALUE);\r
3848         }\r
3849 \r
3850         es2::Context *context = es2::getContext();\r
3851 \r
3852         if(context)\r
3853         {\r
3854                 if(program == 0)\r
3855                 {\r
3856                         return error(GL_INVALID_VALUE);\r
3857                 }\r
3858 \r
3859                 es2::Program *programObject = context->getProgram(program);\r
3860 \r
3861                 if(!programObject || !programObject->isLinked())\r
3862                 {\r
3863                         return error(GL_INVALID_OPERATION);\r
3864                 }\r
3865 \r
3866                 if(!programObject->getUniformfv(location, &bufSize, params))\r
3867                 {\r
3868                         return error(GL_INVALID_OPERATION);\r
3869                 }\r
3870         }\r
3871 }\r
3872 \r
3873 void GetUniformfv(GLuint program, GLint location, GLfloat* params)\r
3874 {\r
3875         TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);\r
3876 \r
3877         es2::Context *context = es2::getContext();\r
3878 \r
3879         if(context)\r
3880         {\r
3881                 if(program == 0)\r
3882                 {\r
3883                         return error(GL_INVALID_VALUE);\r
3884                 }\r
3885 \r
3886                 es2::Program *programObject = context->getProgram(program);\r
3887 \r
3888                 if(!programObject || !programObject->isLinked())\r
3889                 {\r
3890                         return error(GL_INVALID_OPERATION);\r
3891                 }\r
3892 \r
3893                 if(!programObject->getUniformfv(location, NULL, params))\r
3894                 {\r
3895                         return error(GL_INVALID_OPERATION);\r
3896                 }\r
3897         }\r
3898 }\r
3899 \r
3900 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)\r
3901 {\r
3902         TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",\r
3903               program, location, bufSize, params);\r
3904 \r
3905         if(bufSize < 0)\r
3906         {\r
3907                 return error(GL_INVALID_VALUE);\r
3908         }\r
3909 \r
3910         es2::Context *context = es2::getContext();\r
3911 \r
3912         if(context)\r
3913         {\r
3914                 if(program == 0)\r
3915                 {\r
3916                         return error(GL_INVALID_VALUE);\r
3917                 }\r
3918 \r
3919                 es2::Program *programObject = context->getProgram(program);\r
3920 \r
3921                 if(!programObject || !programObject->isLinked())\r
3922                 {\r
3923                         return error(GL_INVALID_OPERATION);\r
3924                 }\r
3925 \r
3926                 if(!programObject)\r
3927                 {\r
3928                         return error(GL_INVALID_OPERATION);\r
3929                 }\r
3930 \r
3931                 if(!programObject->getUniformiv(location, &bufSize, params))\r
3932                 {\r
3933                         return error(GL_INVALID_OPERATION);\r
3934                 }\r
3935         }\r
3936 }\r
3937 \r
3938 void GetUniformiv(GLuint program, GLint location, GLint* params)\r
3939 {\r
3940         TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);\r
3941 \r
3942         es2::Context *context = es2::getContext();\r
3943 \r
3944         if(context)\r
3945         {\r
3946                 if(program == 0)\r
3947                 {\r
3948                         return error(GL_INVALID_VALUE);\r
3949                 }\r
3950 \r
3951                 es2::Program *programObject = context->getProgram(program);\r
3952 \r
3953                 if(!programObject || !programObject->isLinked())\r
3954                 {\r
3955                         return error(GL_INVALID_OPERATION);\r
3956                 }\r
3957 \r
3958                 if(!programObject)\r
3959                 {\r
3960                         return error(GL_INVALID_OPERATION);\r
3961                 }\r
3962 \r
3963                 if(!programObject->getUniformiv(location, NULL, params))\r
3964                 {\r
3965                         return error(GL_INVALID_OPERATION);\r
3966                 }\r
3967         }\r
3968 }\r
3969 \r
3970 int GetUniformLocation(GLuint program, const GLchar* name)\r
3971 {\r
3972         TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);\r
3973 \r
3974         es2::Context *context = es2::getContext();\r
3975 \r
3976         if(strstr(name, "gl_") == name)\r
3977         {\r
3978                 return -1;\r
3979         }\r
3980 \r
3981         if(context)\r
3982         {\r
3983                 es2::Program *programObject = context->getProgram(program);\r
3984 \r
3985                 if(!programObject)\r
3986                 {\r
3987                         if(context->getShader(program))\r
3988                         {\r
3989                                 return error(GL_INVALID_OPERATION, -1);\r
3990                         }\r
3991                         else\r
3992                         {\r
3993                                 return error(GL_INVALID_VALUE, -1);\r
3994                         }\r
3995                 }\r
3996 \r
3997                 if(!programObject->isLinked())\r
3998                 {\r
3999                         return error(GL_INVALID_OPERATION, -1);\r
4000                 }\r
4001 \r
4002                 return programObject->getUniformLocation(name);\r
4003         }\r
4004 \r
4005         return -1;\r
4006 }\r
4007 \r
4008 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)\r
4009 {\r
4010         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);\r
4011 \r
4012         es2::Context *context = es2::getContext();\r
4013 \r
4014         if(context)\r
4015         {\r
4016                 if(index >= es2::MAX_VERTEX_ATTRIBS)\r
4017                 {\r
4018                         return error(GL_INVALID_VALUE);\r
4019                 }\r
4020 \r
4021                 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);\r
4022 \r
4023                 GLint clientVersion = context->getClientVersion();\r
4024 \r
4025                 switch(pname)\r
4026                 {\r
4027                 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:\r
4028                         *params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);\r
4029                         break;\r
4030                 case GL_VERTEX_ATTRIB_ARRAY_SIZE:\r
4031                         *params = (GLfloat)attribState.mSize;\r
4032                         break;\r
4033                 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:\r
4034                         *params = (GLfloat)attribState.mStride;\r
4035                         break;\r
4036                 case GL_VERTEX_ATTRIB_ARRAY_TYPE:\r
4037                         *params = (GLfloat)attribState.mType;\r
4038                         break;\r
4039                 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:\r
4040                         *params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);\r
4041                         break;\r
4042                 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
4043                         *params = (GLfloat)attribState.mBoundBuffer.name();\r
4044                         break;\r
4045                 case GL_CURRENT_VERTEX_ATTRIB:\r
4046                         {\r
4047                                 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];\r
4048                                 for(int i = 0; i < 4; ++i)\r
4049                                 {\r
4050                                         params[i] = attrib.getCurrentValueF(i);\r
4051                                 }\r
4052                         }\r
4053                         break;\r
4054                 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:\r
4055                         if(clientVersion >= 3)\r
4056                         {\r
4057                                 switch(attribState.mType)\r
4058                                 {\r
4059                                 case GL_BYTE:\r
4060                                 case GL_UNSIGNED_BYTE:\r
4061                                 case GL_SHORT:\r
4062                                 case GL_UNSIGNED_SHORT:\r
4063                                 case GL_INT:\r
4064                                 case GL_INT_2_10_10_10_REV:\r
4065                                 case GL_UNSIGNED_INT:\r
4066                                 case GL_FIXED:\r
4067                                         *params = (GLfloat)GL_TRUE;\r
4068                                         break;\r
4069                                 default:\r
4070                                         *params = (GLfloat)GL_FALSE;\r
4071                                         break;\r
4072                                 }\r
4073                                 break;\r
4074                         }\r
4075                         else return error(GL_INVALID_ENUM);\r
4076                 default: return error(GL_INVALID_ENUM);\r
4077                 }\r
4078         }\r
4079 }\r
4080 \r
4081 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)\r
4082 {\r
4083         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);\r
4084 \r
4085         es2::Context *context = es2::getContext();\r
4086 \r
4087         if(context)\r
4088         {\r
4089                 if(index >= es2::MAX_VERTEX_ATTRIBS)\r
4090                 {\r
4091                         return error(GL_INVALID_VALUE);\r
4092                 }\r
4093 \r
4094                 const es2::VertexAttribute &attribState = context->getVertexAttribState(index);\r
4095 \r
4096                 GLint clientVersion = context->getClientVersion();\r
4097 \r
4098                 switch(pname)\r
4099                 {\r
4100                 case GL_VERTEX_ATTRIB_ARRAY_ENABLED:\r
4101                         *params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);\r
4102                         break;\r
4103                 case GL_VERTEX_ATTRIB_ARRAY_SIZE:\r
4104                         *params = attribState.mSize;\r
4105                         break;\r
4106                 case GL_VERTEX_ATTRIB_ARRAY_STRIDE:\r
4107                         *params = attribState.mStride;\r
4108                         break;\r
4109                 case GL_VERTEX_ATTRIB_ARRAY_TYPE:\r
4110                         *params = attribState.mType;\r
4111                         break;\r
4112                 case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:\r
4113                         *params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);\r
4114                         break;\r
4115                 case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:\r
4116                         *params = attribState.mBoundBuffer.name();\r
4117                         break;\r
4118                 case GL_CURRENT_VERTEX_ATTRIB:\r
4119                         {\r
4120                                 const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];\r
4121                                 for(int i = 0; i < 4; ++i)\r
4122                                 {\r
4123                                         float currentValue = attrib.getCurrentValueF(i);\r
4124                                         params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));\r
4125                                 }\r
4126                         }\r
4127                         break;\r
4128                 case GL_VERTEX_ATTRIB_ARRAY_INTEGER:\r
4129                         if(clientVersion >= 3)\r
4130                         {\r
4131                                 switch(attribState.mType)\r
4132                                 {\r
4133                                 case GL_BYTE:\r
4134                                 case GL_UNSIGNED_BYTE:\r
4135                                 case GL_SHORT:\r
4136                                 case GL_UNSIGNED_SHORT:\r
4137                                 case GL_INT:\r
4138                                 case GL_INT_2_10_10_10_REV:\r
4139                                 case GL_UNSIGNED_INT:\r
4140                                 case GL_FIXED:\r
4141                                         *params = GL_TRUE;\r
4142                                         break;\r
4143                                 default:\r
4144                                         *params = GL_FALSE;\r
4145                                         break;\r
4146                                 }\r
4147                                 break;\r
4148                         }\r
4149                         else return error(GL_INVALID_ENUM);\r
4150                 default: return error(GL_INVALID_ENUM);\r
4151                 }\r
4152         }\r
4153 }\r
4154 \r
4155 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)\r
4156 {\r
4157         TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);\r
4158 \r
4159         es2::Context *context = es2::getContext();\r
4160 \r
4161         if(context)\r
4162         {\r
4163                 if(index >= es2::MAX_VERTEX_ATTRIBS)\r
4164                 {\r
4165                         return error(GL_INVALID_VALUE);\r
4166                 }\r
4167 \r
4168                 if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)\r
4169                 {\r
4170                         return error(GL_INVALID_ENUM);\r
4171                 }\r
4172 \r
4173                 *pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));\r
4174         }\r
4175 }\r
4176 \r
4177 void Hint(GLenum target, GLenum mode)\r
4178 {\r
4179         TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);\r
4180 \r
4181         switch(mode)\r
4182         {\r
4183         case GL_FASTEST:\r
4184         case GL_NICEST:\r
4185         case GL_DONT_CARE:\r
4186                 break;\r
4187         default:\r
4188                 return error(GL_INVALID_ENUM);\r
4189         }\r
4190 \r
4191         es2::Context *context = es2::getContext();\r
4192         switch(target)\r
4193         {\r
4194         case GL_GENERATE_MIPMAP_HINT:\r
4195                 if(context) context->setGenerateMipmapHint(mode);\r
4196                 break;\r
4197         case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:\r
4198                 if(context) context->setFragmentShaderDerivativeHint(mode);\r
4199                 break;\r
4200         default:\r
4201                 return error(GL_INVALID_ENUM);\r
4202         }\r
4203 }\r
4204 \r
4205 GLboolean IsBuffer(GLuint buffer)\r
4206 {\r
4207         TRACE("(GLuint buffer = %d)", buffer);\r
4208 \r
4209         es2::Context *context = es2::getContext();\r
4210 \r
4211         if(context && buffer)\r
4212         {\r
4213                 es2::Buffer *bufferObject = context->getBuffer(buffer);\r
4214 \r
4215                 if(bufferObject)\r
4216                 {\r
4217                         return GL_TRUE;\r
4218                 }\r
4219         }\r
4220 \r
4221         return GL_FALSE;\r
4222 }\r
4223 \r
4224 GLboolean IsEnabled(GLenum cap)\r
4225 {\r
4226         TRACE("(GLenum cap = 0x%X)", cap);\r
4227 \r
4228         es2::Context *context = es2::getContext();\r
4229 \r
4230         if(context)\r
4231         {\r
4232                 GLint clientVersion = context->getClientVersion();\r
4233 \r
4234                 switch(cap)\r
4235                 {\r
4236                 case GL_CULL_FACE:                return context->isCullFaceEnabled();\r
4237                 case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();\r
4238                 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();\r
4239                 case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();\r
4240                 case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();\r
4241                 case GL_STENCIL_TEST:             return context->isStencilTestEnabled();\r
4242                 case GL_DEPTH_TEST:               return context->isDepthTestEnabled();\r
4243                 case GL_BLEND:                    return context->isBlendEnabled();\r
4244                 case GL_DITHER:                   return context->isDitherEnabled();\r
4245                 case GL_PRIMITIVE_RESTART_FIXED_INDEX:\r
4246                         if(clientVersion >= 3)\r
4247                         {\r
4248                                 return context->isPrimitiveRestartFixedIndexEnabled();\r
4249                         }\r
4250                         else return error(GL_INVALID_ENUM, false);\r
4251                 case GL_RASTERIZER_DISCARD:\r
4252                         if(clientVersion >= 3)\r
4253                         {\r
4254                                 return context->isRasterizerDiscardEnabled();\r
4255                         }\r
4256                         else return error(GL_INVALID_ENUM, false);\r
4257                 default:\r
4258                         return error(GL_INVALID_ENUM, false);\r
4259                 }\r
4260         }\r
4261 \r
4262         return false;\r
4263 }\r
4264 \r
4265 GLboolean IsFenceNV(GLuint fence)\r
4266 {\r
4267         TRACE("(GLuint fence = %d)", fence);\r
4268 \r
4269         es2::Context *context = es2::getContext();\r
4270 \r
4271         if(context)\r
4272         {\r
4273                 es2::Fence *fenceObject = context->getFence(fence);\r
4274 \r
4275                 if(fenceObject == NULL)\r
4276                 {\r
4277                         return GL_FALSE;\r
4278                 }\r
4279 \r
4280                 return fenceObject->isFence();\r
4281         }\r
4282 \r
4283         return GL_FALSE;\r
4284 }\r
4285 \r
4286 GLboolean IsFramebuffer(GLuint framebuffer)\r
4287 {\r
4288         TRACE("(GLuint framebuffer = %d)", framebuffer);\r
4289 \r
4290         es2::Context *context = es2::getContext();\r
4291 \r
4292         if(context && framebuffer)\r
4293         {\r
4294                 es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);\r
4295 \r
4296                 if(framebufferObject)\r
4297                 {\r
4298                         return GL_TRUE;\r
4299                 }\r
4300         }\r
4301 \r
4302         return GL_FALSE;\r
4303 }\r
4304 \r
4305 GLboolean IsProgram(GLuint program)\r
4306 {\r
4307         TRACE("(GLuint program = %d)", program);\r
4308 \r
4309         es2::Context *context = es2::getContext();\r
4310 \r
4311         if(context && program)\r
4312         {\r
4313                 es2::Program *programObject = context->getProgram(program);\r
4314 \r
4315                 if(programObject)\r
4316                 {\r
4317                         return GL_TRUE;\r
4318                 }\r
4319         }\r
4320 \r
4321         return GL_FALSE;\r
4322 }\r
4323 \r
4324 GLboolean IsQueryEXT(GLuint name)\r
4325 {\r
4326         TRACE("(GLuint name = %d)", name);\r
4327 \r
4328         if(name == 0)\r
4329         {\r
4330                 return GL_FALSE;\r
4331         }\r
4332 \r
4333         es2::Context *context = es2::getContext();\r
4334 \r
4335         if(context)\r
4336         {\r
4337                 es2::Query *queryObject = context->getQuery(name);\r
4338 \r
4339                 if(queryObject)\r
4340                 {\r
4341                         return GL_TRUE;\r
4342                 }\r
4343         }\r
4344 \r
4345         return GL_FALSE;\r
4346 }\r
4347 \r
4348 GLboolean IsRenderbuffer(GLuint renderbuffer)\r
4349 {\r
4350         TRACE("(GLuint renderbuffer = %d)", renderbuffer);\r
4351 \r
4352         es2::Context *context = es2::getContext();\r
4353 \r
4354         if(context && renderbuffer)\r
4355         {\r
4356                 es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);\r
4357 \r
4358                 if(renderbufferObject)\r
4359                 {\r
4360                         return GL_TRUE;\r
4361                 }\r
4362         }\r
4363 \r
4364         return GL_FALSE;\r
4365 }\r
4366 \r
4367 GLboolean IsShader(GLuint shader)\r
4368 {\r
4369         TRACE("(GLuint shader = %d)", shader);\r
4370 \r
4371         es2::Context *context = es2::getContext();\r
4372 \r
4373         if(context && shader)\r
4374         {\r
4375                 es2::Shader *shaderObject = context->getShader(shader);\r
4376 \r
4377                 if(shaderObject)\r
4378                 {\r
4379                         return GL_TRUE;\r
4380                 }\r
4381         }\r
4382 \r
4383         return GL_FALSE;\r
4384 }\r
4385 \r
4386 GLboolean IsTexture(GLuint texture)\r
4387 {\r
4388         TRACE("(GLuint texture = %d)", texture);\r
4389 \r
4390         es2::Context *context = es2::getContext();\r
4391 \r
4392         if(context && texture)\r
4393         {\r
4394                 es2::Texture *textureObject = context->getTexture(texture);\r
4395 \r
4396                 if(textureObject)\r
4397                 {\r
4398                         return GL_TRUE;\r
4399                 }\r
4400         }\r
4401 \r
4402         return GL_FALSE;\r
4403 }\r
4404 \r
4405 void LineWidth(GLfloat width)\r
4406 {\r
4407         TRACE("(GLfloat width = %f)", width);\r
4408 \r
4409         if(width <= 0.0f)\r
4410         {\r
4411                 return error(GL_INVALID_VALUE);\r
4412         }\r
4413 \r
4414         es2::Context *context = es2::getContext();\r
4415 \r
4416         if(context)\r
4417         {\r
4418                 context->setLineWidth(width);\r
4419         }\r
4420 }\r
4421 \r
4422 void LinkProgram(GLuint program)\r
4423 {\r
4424         TRACE("(GLuint program = %d)", program);\r
4425 \r
4426         es2::Context *context = es2::getContext();\r
4427 \r
4428         if(context)\r
4429         {\r
4430                 es2::Program *programObject = context->getProgram(program);\r
4431 \r
4432                 if(!programObject)\r
4433                 {\r
4434                         if(context->getShader(program))\r
4435                         {\r
4436                                 return error(GL_INVALID_OPERATION);\r
4437                         }\r
4438                         else\r
4439                         {\r
4440                                 return error(GL_INVALID_VALUE);\r
4441                         }\r
4442                 }\r
4443 \r
4444                 programObject->link();\r
4445         }\r
4446 }\r
4447 \r
4448 void PixelStorei(GLenum pname, GLint param)\r
4449 {\r
4450         TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);\r
4451 \r
4452         es2::Context *context = es2::getContext();\r
4453 \r
4454         if(context)\r
4455         {\r
4456                 GLint clientVersion = context->getClientVersion();\r
4457 \r
4458                 switch(pname)\r
4459                 {\r
4460                 case GL_UNPACK_ALIGNMENT:\r
4461                         if(param != 1 && param != 2 && param != 4 && param != 8)\r
4462                         {\r
4463                                 return error(GL_INVALID_VALUE);\r
4464                         }\r
4465                         context->setUnpackAlignment(param);\r
4466                         break;\r
4467                 case GL_PACK_ALIGNMENT:\r
4468                         if(param != 1 && param != 2 && param != 4 && param != 8)\r
4469                         {\r
4470                                 return error(GL_INVALID_VALUE);\r
4471                         }\r
4472                         context->setPackAlignment(param);\r
4473                         break;\r
4474                 case GL_PACK_ROW_LENGTH:\r
4475                         if(clientVersion >= 3)\r
4476                         {\r
4477                                 if(param < 0)\r
4478                                 {\r
4479                                         return error(GL_INVALID_VALUE);\r
4480                                 }\r
4481                                 context->setPackRowLength(param);\r
4482                                 break;\r
4483                         }\r
4484                         else return error(GL_INVALID_ENUM);\r
4485                 case GL_PACK_SKIP_PIXELS:\r
4486                         if(clientVersion >= 3)\r
4487                         {\r
4488                                 if(param < 0)\r
4489                                 {\r
4490                                         return error(GL_INVALID_VALUE);\r
4491                                 }\r
4492                                 context->setPackSkipPixels(param);\r
4493                                 break;\r
4494                         }\r
4495                         else return error(GL_INVALID_ENUM);\r
4496                 case GL_PACK_SKIP_ROWS:\r
4497                         if(clientVersion >= 3)\r
4498                         {\r
4499                                 if(param < 0)\r
4500                                 {\r
4501                                         return error(GL_INVALID_VALUE);\r
4502                                 }\r
4503                                 context->setPackSkipRows(param);\r
4504                                 break;\r
4505                         }\r
4506                         else return error(GL_INVALID_ENUM);\r
4507                 case GL_UNPACK_ROW_LENGTH:\r
4508                         if(clientVersion >= 3)\r
4509                         {\r
4510                                 if(param < 0)\r
4511                                 {\r
4512                                         return error(GL_INVALID_VALUE);\r
4513                                 }\r
4514                                 context->setUnpackRowLength(param);\r
4515                                 break;\r
4516                         }\r
4517                         else return error(GL_INVALID_ENUM);\r
4518                 case GL_UNPACK_IMAGE_HEIGHT:\r
4519                         if(clientVersion >= 3)\r
4520                         {\r
4521                                 if(param < 0)\r
4522                                 {\r
4523                                         return error(GL_INVALID_VALUE);\r
4524                                 }\r
4525                                 context->setUnpackImageHeight(param);\r
4526                                 break;\r
4527                         }\r
4528                         else return error(GL_INVALID_ENUM);\r
4529                 case GL_UNPACK_SKIP_PIXELS:\r
4530                         if(clientVersion >= 3)\r
4531                         {\r
4532                                 if(param < 0)\r
4533                                 {\r
4534                                         return error(GL_INVALID_VALUE);\r
4535                                 }\r
4536                                 context->setUnpackSkipPixels(param);\r
4537                                 break;\r
4538                         }\r
4539                         else return error(GL_INVALID_ENUM);\r
4540                 case GL_UNPACK_SKIP_ROWS:\r
4541                         if(clientVersion >= 3)\r
4542                         {\r
4543                                 if(param < 0)\r
4544                                 {\r
4545                                         return error(GL_INVALID_VALUE);\r
4546                                 }\r
4547                                 context->setUnpackSkipRows(param);\r
4548                                 break;\r
4549                         }\r
4550                         else return error(GL_INVALID_ENUM);\r
4551                 case GL_UNPACK_SKIP_IMAGES:\r
4552                         if(clientVersion >= 3) {\r
4553                                 if(param < 0)\r
4554                                 {\r
4555                                         return error(GL_INVALID_VALUE);\r
4556                                 }\r
4557                                 context->setUnpackSkipImages(param);\r
4558                                 break;\r
4559                         }\r
4560                         else return error(GL_INVALID_ENUM);\r
4561                 default:\r
4562                         return error(GL_INVALID_ENUM);\r
4563                 }\r
4564         }\r
4565 }\r
4566 \r
4567 void PolygonOffset(GLfloat factor, GLfloat units)\r
4568 {\r
4569         TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);\r
4570 \r
4571         es2::Context *context = es2::getContext();\r
4572 \r
4573         if(context)\r
4574         {\r
4575                 context->setPolygonOffsetParams(factor, units);\r
4576         }\r
4577 }\r
4578 \r
4579 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,\r
4580                     GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)\r
4581 {\r
4582         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "\r
4583               "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",\r
4584               x, y, width, height, format, type, bufSize, data);\r
4585 \r
4586         if(width < 0 || height < 0 || bufSize < 0)\r
4587         {\r
4588                 return error(GL_INVALID_VALUE);\r
4589         }\r
4590 \r
4591         es2::Context *context = es2::getContext();\r
4592 \r
4593         if(context)\r
4594         {\r
4595                 context->readPixels(x, y, width, height, format, type, &bufSize, data);\r
4596         }\r
4597 }\r
4598 \r
4599 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)\r
4600 {\r
4601         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "\r
4602               "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",\r
4603               x, y, width, height, format, type,  pixels);\r
4604 \r
4605         if(width < 0 || height < 0)\r
4606         {\r
4607                 return error(GL_INVALID_VALUE);\r
4608         }\r
4609 \r
4610         es2::Context *context = es2::getContext();\r
4611 \r
4612         if(context)\r
4613         {\r
4614                 context->readPixels(x, y, width, height, format, type, NULL, pixels);\r
4615         }\r
4616 }\r
4617 \r
4618 void ReleaseShaderCompiler(void)\r
4619 {\r
4620         TRACE("()");\r
4621 \r
4622         es2::Shader::releaseCompiler();\r
4623 }\r
4624 \r
4625 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)\r
4626 {\r
4627         TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",\r
4628               target, samples, internalformat, width, height);\r
4629 \r
4630         switch(target)\r
4631         {\r
4632         case GL_RENDERBUFFER:\r
4633                 break;\r
4634         default:\r
4635                 return error(GL_INVALID_ENUM);\r
4636         }\r
4637 \r
4638         if(width < 0 || height < 0 || samples < 0)\r
4639         {\r
4640                 return error(GL_INVALID_VALUE);\r
4641         }\r
4642 \r
4643         es2::Context *context = es2::getContext();\r
4644 \r
4645         if(context)\r
4646         {\r
4647                 if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||\r
4648                    height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||\r
4649                    samples > es2::IMPLEMENTATION_MAX_SAMPLES)\r
4650                 {\r
4651                         return error(GL_INVALID_VALUE);\r
4652                 }\r
4653 \r
4654                 GLuint handle = context->getRenderbufferName();\r
4655                 if(handle == 0)\r
4656                 {\r
4657                         return error(GL_INVALID_OPERATION);\r
4658                 }\r
4659 \r
4660                 GLint clientVersion = context->getClientVersion();\r
4661                 switch(internalformat)\r
4662                 {\r
4663                 case GL_DEPTH_COMPONENT32F:\r
4664                         if(clientVersion < 3)\r
4665                         {\r
4666                                 return error(GL_INVALID_ENUM);\r
4667                         }\r
4668                         // fall through\r
4669                 case GL_DEPTH_COMPONENT16:\r
4670                 case GL_DEPTH_COMPONENT24:\r
4671                 case GL_DEPTH_COMPONENT32_OES:\r
4672                         context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));\r
4673                         break;\r
4674                 case GL_R8:\r
4675                 case GL_R8UI:\r
4676                 case GL_R8I:\r
4677                 case GL_R16UI:\r
4678                 case GL_R16I:\r
4679                 case GL_R32UI:\r
4680                 case GL_R32I:\r
4681                 case GL_RG8:\r
4682                 case GL_RG8UI:\r
4683                 case GL_RG8I:\r
4684                 case GL_RG16UI:\r
4685                 case GL_RG16I:\r
4686                 case GL_RG32UI:\r
4687                 case GL_RG32I:\r
4688                 case GL_SRGB8_ALPHA8:\r
4689                 case GL_RGB10_A2:\r
4690                 case GL_RGBA8UI:\r
4691                 case GL_RGBA8I:\r
4692                 case GL_RGB10_A2UI:\r
4693                 case GL_RGBA16UI:\r
4694                 case GL_RGBA16I:\r
4695                 case GL_RGBA32I:\r
4696                 case GL_RGBA32UI:\r
4697                 case GL_R16F:\r
4698                 case GL_RG16F:\r
4699                 case GL_R11F_G11F_B10F:\r
4700                 case GL_RGBA16F:\r
4701                 case GL_R32F:\r
4702                 case GL_RG32F:\r
4703                 case GL_RGB32F:\r
4704                 case GL_RGBA32F:\r
4705                         if(clientVersion < 3)\r
4706                         {\r
4707                                 return error(GL_INVALID_ENUM);\r
4708                         }\r
4709                         // fall through\r
4710                 case GL_RGBA4:\r
4711                 case GL_RGB5_A1:\r
4712                 case GL_RGB565:\r
4713                 case GL_RGB8_OES:\r
4714                 case GL_RGBA8_OES:\r
4715                         context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));\r
4716                         break;\r
4717                 case GL_STENCIL_INDEX8:\r
4718                         context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));\r
4719                         break;\r
4720                 case GL_DEPTH32F_STENCIL8:\r
4721                         if(clientVersion < 3)\r
4722                         {\r
4723                                 return error(GL_INVALID_ENUM);\r
4724                         }\r
4725                         // fall through\r
4726                 case GL_DEPTH24_STENCIL8_OES:\r
4727                         context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));\r
4728                         break;\r
4729                 default:\r
4730                         return error(GL_INVALID_ENUM);\r
4731                 }\r
4732         }\r
4733 }\r
4734 \r
4735 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)\r
4736 {\r
4737         glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);\r
4738 }\r
4739 \r
4740 void SampleCoverage(GLclampf value, GLboolean invert)\r
4741 {\r
4742         TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);\r
4743 \r
4744         es2::Context* context = es2::getContext();\r
4745 \r
4746         if(context)\r
4747         {\r
4748                 context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);\r
4749         }\r
4750 }\r
4751 \r
4752 void SetFenceNV(GLuint fence, GLenum condition)\r
4753 {\r
4754         TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);\r
4755 \r
4756         if(condition != GL_ALL_COMPLETED_NV)\r
4757         {\r
4758                 return error(GL_INVALID_ENUM);\r
4759         }\r
4760 \r
4761         es2::Context *context = es2::getContext();\r
4762 \r
4763         if(context)\r
4764         {\r
4765                 es2::Fence *fenceObject = context->getFence(fence);\r
4766 \r
4767                 if(fenceObject == NULL)\r
4768                 {\r
4769                         return error(GL_INVALID_OPERATION);\r
4770                 }\r
4771 \r
4772                 fenceObject->setFence(condition);\r
4773         }\r
4774 }\r
4775 \r
4776 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)\r
4777 {\r
4778         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);\r
4779 \r
4780         if(width < 0 || height < 0)\r
4781         {\r
4782                 return error(GL_INVALID_VALUE);\r
4783         }\r
4784 \r
4785         es2::Context* context = es2::getContext();\r
4786 \r
4787         if(context)\r
4788         {\r
4789                 context->setScissorParams(x, y, width, height);\r
4790         }\r
4791 }\r
4792 \r
4793 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)\r
4794 {\r
4795         TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "\r
4796               "const GLvoid* binary = %p, GLsizei length = %d)",\r
4797               n, shaders, binaryformat, binary, length);\r
4798 \r
4799         // No binary shader formats are supported.\r
4800         return error(GL_INVALID_ENUM);\r
4801 }\r
4802 \r
4803 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)\r
4804 {\r
4805         TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",\r
4806               shader, count, string, length);\r
4807 \r
4808         if(count < 0)\r
4809         {\r
4810                 return error(GL_INVALID_VALUE);\r
4811         }\r
4812 \r
4813         es2::Context *context = es2::getContext();\r
4814 \r
4815         if(context)\r
4816         {\r
4817                 es2::Shader *shaderObject = context->getShader(shader);\r
4818 \r
4819                 if(!shaderObject)\r
4820                 {\r
4821                         if(context->getProgram(shader))\r
4822                         {\r
4823                                 return error(GL_INVALID_OPERATION);\r
4824                         }\r
4825                         else\r
4826                         {\r
4827                                 return error(GL_INVALID_VALUE);\r
4828                         }\r
4829                 }\r
4830 \r
4831                 shaderObject->setSource(count, string, length);\r
4832         }\r
4833 }\r
4834 \r
4835 void StencilFunc(GLenum func, GLint ref, GLuint mask)\r
4836 {\r
4837         glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);\r
4838 }\r
4839 \r
4840 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)\r
4841 {\r
4842         TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);\r
4843 \r
4844         switch(face)\r
4845         {\r
4846         case GL_FRONT:\r
4847         case GL_BACK:\r
4848         case GL_FRONT_AND_BACK:\r
4849                 break;\r
4850         default:\r
4851                 return error(GL_INVALID_ENUM);\r
4852         }\r
4853 \r
4854         switch(func)\r
4855         {\r
4856         case GL_NEVER:\r
4857         case GL_ALWAYS:\r
4858         case GL_LESS:\r
4859         case GL_LEQUAL:\r
4860         case GL_EQUAL:\r
4861         case GL_GEQUAL:\r
4862         case GL_GREATER:\r
4863         case GL_NOTEQUAL:\r
4864                 break;\r
4865         default:\r
4866                 return error(GL_INVALID_ENUM);\r
4867         }\r
4868 \r
4869         es2::Context *context = es2::getContext();\r
4870 \r
4871         if(context)\r
4872         {\r
4873                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4874                 {\r
4875                         context->setStencilParams(func, ref, mask);\r
4876                 }\r
4877 \r
4878                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4879                 {\r
4880                         context->setStencilBackParams(func, ref, mask);\r
4881                 }\r
4882         }\r
4883 }\r
4884 \r
4885 void StencilMask(GLuint mask)\r
4886 {\r
4887         glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);\r
4888 }\r
4889 \r
4890 void StencilMaskSeparate(GLenum face, GLuint mask)\r
4891 {\r
4892         TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);\r
4893 \r
4894         switch(face)\r
4895         {\r
4896         case GL_FRONT:\r
4897         case GL_BACK:\r
4898         case GL_FRONT_AND_BACK:\r
4899                 break;\r
4900         default:\r
4901                 return error(GL_INVALID_ENUM);\r
4902         }\r
4903 \r
4904         es2::Context *context = es2::getContext();\r
4905 \r
4906         if(context)\r
4907         {\r
4908                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4909                 {\r
4910                         context->setStencilWritemask(mask);\r
4911                 }\r
4912 \r
4913                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4914                 {\r
4915                         context->setStencilBackWritemask(mask);\r
4916                 }\r
4917         }\r
4918 }\r
4919 \r
4920 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)\r
4921 {\r
4922         glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);\r
4923 }\r
4924 \r
4925 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)\r
4926 {\r
4927         TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",\r
4928               face, fail, zfail, zpass);\r
4929 \r
4930         switch(face)\r
4931         {\r
4932         case GL_FRONT:\r
4933         case GL_BACK:\r
4934         case GL_FRONT_AND_BACK:\r
4935                 break;\r
4936         default:\r
4937                 return error(GL_INVALID_ENUM);\r
4938         }\r
4939 \r
4940         switch(fail)\r
4941         {\r
4942         case GL_ZERO:\r
4943         case GL_KEEP:\r
4944         case GL_REPLACE:\r
4945         case GL_INCR:\r
4946         case GL_DECR:\r
4947         case GL_INVERT:\r
4948         case GL_INCR_WRAP:\r
4949         case GL_DECR_WRAP:\r
4950                 break;\r
4951         default:\r
4952                 return error(GL_INVALID_ENUM);\r
4953         }\r
4954 \r
4955         switch(zfail)\r
4956         {\r
4957         case GL_ZERO:\r
4958         case GL_KEEP:\r
4959         case GL_REPLACE:\r
4960         case GL_INCR:\r
4961         case GL_DECR:\r
4962         case GL_INVERT:\r
4963         case GL_INCR_WRAP:\r
4964         case GL_DECR_WRAP:\r
4965                 break;\r
4966         default:\r
4967                 return error(GL_INVALID_ENUM);\r
4968         }\r
4969 \r
4970         switch(zpass)\r
4971         {\r
4972         case GL_ZERO:\r
4973         case GL_KEEP:\r
4974         case GL_REPLACE:\r
4975         case GL_INCR:\r
4976         case GL_DECR:\r
4977         case GL_INVERT:\r
4978         case GL_INCR_WRAP:\r
4979         case GL_DECR_WRAP:\r
4980                 break;\r
4981         default:\r
4982                 return error(GL_INVALID_ENUM);\r
4983         }\r
4984 \r
4985         es2::Context *context = es2::getContext();\r
4986 \r
4987         if(context)\r
4988         {\r
4989                 if(face == GL_FRONT || face == GL_FRONT_AND_BACK)\r
4990                 {\r
4991                         context->setStencilOperations(fail, zfail, zpass);\r
4992                 }\r
4993 \r
4994                 if(face == GL_BACK || face == GL_FRONT_AND_BACK)\r
4995                 {\r
4996                         context->setStencilBackOperations(fail, zfail, zpass);\r
4997                 }\r
4998         }\r
4999 }\r
5000 \r
5001 GLboolean TestFenceNV(GLuint fence)\r
5002 {\r
5003         TRACE("(GLuint fence = %d)", fence);\r
5004 \r
5005         es2::Context *context = es2::getContext();\r
5006 \r
5007         if(context)\r
5008         {\r
5009                 es2::Fence *fenceObject = context->getFence(fence);\r
5010 \r
5011                 if(fenceObject == NULL)\r
5012                 {\r
5013                         return error(GL_INVALID_OPERATION, GL_TRUE);\r
5014                 }\r
5015 \r
5016                 return fenceObject->testFence();\r
5017         }\r
5018 \r
5019         return GL_TRUE;\r
5020 }\r
5021 \r
5022 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,\r
5023                 GLint border, GLenum format, GLenum type, const GLvoid* pixels)\r
5024 {\r
5025         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "\r
5026               "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",\r
5027               target, level, internalformat, width, height, border, format, type, pixels);\r
5028 \r
5029         if(!validImageSize(level, width, height))\r
5030         {\r
5031                 return error(GL_INVALID_VALUE);\r
5032         }\r
5033 \r
5034         es2::Context *context = es2::getContext();\r
5035 \r
5036         if(context)\r
5037         {\r
5038                 GLint clientVersion = context->getClientVersion();\r
5039                 if(clientVersion < 3)\r
5040                 {\r
5041                         if(internalformat != (GLint)format)\r
5042                         {\r
5043                                 return error(GL_INVALID_OPERATION);\r
5044                         }\r
5045                 }\r
5046 \r
5047                 GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);\r
5048                 if(validationError != GL_NONE)\r
5049                 {\r
5050                         return error(validationError);\r
5051                 }\r
5052 \r
5053                 if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))\r
5054                 {\r
5055                         return;\r
5056                 }\r
5057 \r
5058                 if(border != 0)\r
5059                 {\r
5060                         return error(GL_INVALID_VALUE);\r
5061                 }\r
5062 \r
5063                 switch(target)\r
5064                 {\r
5065                 case GL_TEXTURE_2D:\r
5066                         if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||\r
5067                            height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))\r
5068                         {\r
5069                                 return error(GL_INVALID_VALUE);\r
5070                         }\r
5071                         break;\r
5072                 case GL_TEXTURE_CUBE_MAP_POSITIVE_X:\r
5073                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:\r
5074                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:\r
5075                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:\r
5076                 case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:\r
5077                 case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:\r
5078                         if(width != height)\r
5079                         {\r
5080                                 return error(GL_INVALID_VALUE);\r
5081                         }\r
5082 \r
5083                         if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||\r
5084                            height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))\r
5085                         {\r
5086                                 return error(GL_INVALID_VALUE);\r
5087                         }\r
5088                         break;\r
5089                 default:\r
5090                         return error(GL_INVALID_ENUM);\r
5091                 }\r
5092 \r
5093                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
5094 \r
5095                 if(target == GL_TEXTURE_2D)\r
5096                 {\r
5097                         es2::Texture2D *texture = context->getTexture2D();\r
5098 \r
5099                         if(!texture)\r
5100                         {\r
5101                                 return error(GL_INVALID_OPERATION);\r
5102                         }\r
5103 \r
5104                         texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
5105                 }\r
5106                 else\r
5107                 {\r
5108                         es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
5109 \r
5110                         if(!texture)\r
5111                         {\r
5112                                 return error(GL_INVALID_OPERATION);\r
5113                         }\r
5114 \r
5115                         texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
5116                 }\r
5117         }\r
5118 }\r
5119 \r
5120 void TexParameterf(GLenum target, GLenum pname, GLfloat param)\r
5121 {\r
5122         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);\r
5123 \r
5124         es2::Context *context = es2::getContext();\r
5125 \r
5126         if(context)\r
5127         {\r
5128                 es2::Texture *texture;\r
5129 \r
5130                 GLint clientVersion = context->getClientVersion();\r
5131 \r
5132                 switch(target)\r
5133                 {\r
5134                 case GL_TEXTURE_2D:\r
5135                         texture = context->getTexture2D();\r
5136                         break;\r
5137                 case GL_TEXTURE_2D_ARRAY:\r
5138                         if(clientVersion < 3)\r
5139                         {\r
5140                                 return error(GL_INVALID_ENUM);\r
5141                         }\r
5142                         else\r
5143                         {\r
5144                                 texture = context->getTexture2DArray();\r
5145                         }\r
5146                         break;\r
5147                 case GL_TEXTURE_3D_OES:\r
5148                         texture = context->getTexture3D();\r
5149                         break;\r
5150                 case GL_TEXTURE_CUBE_MAP:\r
5151                         texture = context->getTextureCubeMap();\r
5152                         break;\r
5153                 case GL_TEXTURE_EXTERNAL_OES:\r
5154                         texture = context->getTextureExternal();\r
5155                         break;\r
5156                 default:\r
5157                         return error(GL_INVALID_ENUM);\r
5158                 }\r
5159 \r
5160                 switch(pname)\r
5161                 {\r
5162                 case GL_TEXTURE_WRAP_S:\r
5163                         if(!texture->setWrapS((GLenum)param))\r
5164                         {\r
5165                                 return error(GL_INVALID_ENUM);\r
5166                         }\r
5167                         break;\r
5168                 case GL_TEXTURE_WRAP_T:\r
5169                         if(!texture->setWrapT((GLenum)param))\r
5170                         {\r
5171                                 return error(GL_INVALID_ENUM);\r
5172                         }\r
5173                         break;\r
5174                 case GL_TEXTURE_WRAP_R_OES:\r
5175                         if(!texture->setWrapR((GLenum)param))\r
5176                         {\r
5177                                 return error(GL_INVALID_ENUM);\r
5178                         }\r
5179                         break;\r
5180                 case GL_TEXTURE_MIN_FILTER:\r
5181                         if(!texture->setMinFilter((GLenum)param))\r
5182                         {\r
5183                                 return error(GL_INVALID_ENUM);\r
5184                         }\r
5185                         break;\r
5186                 case GL_TEXTURE_MAG_FILTER:\r
5187                         if(!texture->setMagFilter((GLenum)param))\r
5188                         {\r
5189                                 return error(GL_INVALID_ENUM);\r
5190                         }\r
5191                         break;\r
5192                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
5193                         if(!texture->setMaxAnisotropy(param))\r
5194                         {\r
5195                                 return error(GL_INVALID_VALUE);\r
5196                         }\r
5197                         break;\r
5198                 case GL_TEXTURE_BASE_LEVEL:\r
5199                         if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))\r
5200                         {\r
5201                                 return error(GL_INVALID_VALUE);\r
5202                         }\r
5203                         break;\r
5204                 case GL_TEXTURE_COMPARE_FUNC:\r
5205                         if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))\r
5206                         {\r
5207                                 return error(GL_INVALID_VALUE);\r
5208                         }\r
5209                         break;\r
5210                 case GL_TEXTURE_COMPARE_MODE:\r
5211                         if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))\r
5212                         {\r
5213                                 return error(GL_INVALID_VALUE);\r
5214                         }\r
5215                         break;\r
5216                 case GL_TEXTURE_MAX_LEVEL:\r
5217                         if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))\r
5218                         {\r
5219                                 return error(GL_INVALID_VALUE);\r
5220                         }\r
5221                         break;\r
5222                 case GL_TEXTURE_MAX_LOD:\r
5223                         if(clientVersion < 3 || !texture->setMaxLOD(param))\r
5224                         {\r
5225                                 return error(GL_INVALID_VALUE);\r
5226                         }\r
5227                         break;\r
5228                 case GL_TEXTURE_MIN_LOD:\r
5229                         if(clientVersion < 3 || !texture->setMinLOD(param))\r
5230                         {\r
5231                                 return error(GL_INVALID_VALUE);\r
5232                         }\r
5233                         break;\r
5234                 case GL_TEXTURE_SWIZZLE_R:\r
5235                         if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))\r
5236                         {\r
5237                                 return error(GL_INVALID_VALUE);\r
5238                         }\r
5239                         break;\r
5240                 case GL_TEXTURE_SWIZZLE_G:\r
5241                         if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))\r
5242                         {\r
5243                                 return error(GL_INVALID_VALUE);\r
5244                         }\r
5245                         break;\r
5246                 case GL_TEXTURE_SWIZZLE_B:\r
5247                         if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))\r
5248                         {\r
5249                                 return error(GL_INVALID_VALUE);\r
5250                         }\r
5251                         break;\r
5252                 case GL_TEXTURE_SWIZZLE_A:\r
5253                         if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))\r
5254                         {\r
5255                                 return error(GL_INVALID_VALUE);\r
5256                         }\r
5257                         break;\r
5258                 default:\r
5259                         return error(GL_INVALID_ENUM);\r
5260                 }\r
5261         }\r
5262 }\r
5263 \r
5264 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)\r
5265 {\r
5266         glTexParameterf(target, pname, *params);\r
5267 }\r
5268 \r
5269 void TexParameteri(GLenum target, GLenum pname, GLint param)\r
5270 {\r
5271         TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);\r
5272 \r
5273         es2::Context *context = es2::getContext();\r
5274 \r
5275         if(context)\r
5276         {\r
5277                 es2::Texture *texture;\r
5278 \r
5279                 GLint clientVersion = context->getClientVersion();\r
5280 \r
5281                 switch(target)\r
5282                 {\r
5283                 case GL_TEXTURE_2D:\r
5284                         texture = context->getTexture2D();\r
5285                         break;\r
5286                 case GL_TEXTURE_2D_ARRAY:\r
5287                         if(clientVersion < 3)\r
5288                         {\r
5289                                 return error(GL_INVALID_ENUM);\r
5290                         }\r
5291                         else\r
5292                         {\r
5293                                 texture = context->getTexture2DArray();\r
5294                         }\r
5295                         break;\r
5296                 case GL_TEXTURE_3D_OES:\r
5297                         texture = context->getTexture3D();\r
5298                         break;\r
5299                 case GL_TEXTURE_CUBE_MAP:\r
5300                         texture = context->getTextureCubeMap();\r
5301                         break;\r
5302                 case GL_TEXTURE_EXTERNAL_OES:\r
5303                         texture = context->getTextureExternal();\r
5304                         break;\r
5305                 default:\r
5306                         return error(GL_INVALID_ENUM);\r
5307                 }\r
5308 \r
5309                 switch(pname)\r
5310                 {\r
5311                 case GL_TEXTURE_WRAP_S:\r
5312                         if(!texture->setWrapS((GLenum)param))\r
5313                         {\r
5314                                 return error(GL_INVALID_ENUM);\r
5315                         }\r
5316                         break;\r
5317                 case GL_TEXTURE_WRAP_T:\r
5318                         if(!texture->setWrapT((GLenum)param))\r
5319                         {\r
5320                                 return error(GL_INVALID_ENUM);\r
5321                         }\r
5322                         break;\r
5323                 case GL_TEXTURE_WRAP_R_OES:\r
5324                         if(!texture->setWrapR((GLenum)param))\r
5325                         {\r
5326                                 return error(GL_INVALID_ENUM);\r
5327                         }\r
5328                         break;\r
5329                 case GL_TEXTURE_MIN_FILTER:\r
5330                         if(!texture->setMinFilter((GLenum)param))\r
5331                         {\r
5332                                 return error(GL_INVALID_ENUM);\r
5333                         }\r
5334                         break;\r
5335                 case GL_TEXTURE_MAG_FILTER:\r
5336                         if(!texture->setMagFilter((GLenum)param))\r
5337                         {\r
5338                                 return error(GL_INVALID_ENUM);\r
5339                         }\r
5340                         break;\r
5341                 case GL_TEXTURE_MAX_ANISOTROPY_EXT:\r
5342                         if(!texture->setMaxAnisotropy((GLfloat)param))\r
5343                         {\r
5344                                 return error(GL_INVALID_VALUE);\r
5345                         }\r
5346                         break;\r
5347                 case GL_TEXTURE_BASE_LEVEL:\r
5348                         if(clientVersion < 3 || !texture->setBaseLevel(param))\r
5349                         {\r
5350                                 return error(GL_INVALID_VALUE);\r
5351                         }\r
5352                         break;\r
5353                 case GL_TEXTURE_COMPARE_FUNC:\r
5354                         if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))\r
5355                         {\r
5356                                 return error(GL_INVALID_VALUE);\r
5357                         }\r
5358                         break;\r
5359                 case GL_TEXTURE_COMPARE_MODE:\r
5360                         if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))\r
5361                         {\r
5362                                 return error(GL_INVALID_VALUE);\r
5363                         }\r
5364                         break;\r
5365                 case GL_TEXTURE_MAX_LEVEL:\r
5366                         if(clientVersion < 3 || !texture->setMaxLevel(param))\r
5367                         {\r
5368                                 return error(GL_INVALID_VALUE);\r
5369                         }\r
5370                         break;\r
5371                 case GL_TEXTURE_MAX_LOD:\r
5372                         if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))\r
5373                         {\r
5374                                 return error(GL_INVALID_VALUE);\r
5375                         }\r
5376                         break;\r
5377                 case GL_TEXTURE_MIN_LOD:\r
5378                         if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))\r
5379                         {\r
5380                                 return error(GL_INVALID_VALUE);\r
5381                         }\r
5382                         break;\r
5383                 case GL_TEXTURE_SWIZZLE_R:\r
5384                         if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))\r
5385                         {\r
5386                                 return error(GL_INVALID_VALUE);\r
5387                         }\r
5388                         break;\r
5389                 case GL_TEXTURE_SWIZZLE_G:\r
5390                         if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))\r
5391                         {\r
5392                                 return error(GL_INVALID_VALUE);\r
5393                         }\r
5394                         break;\r
5395                 case GL_TEXTURE_SWIZZLE_B:\r
5396                         if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))\r
5397                         {\r
5398                                 return error(GL_INVALID_VALUE);\r
5399                         }\r
5400                         break;\r
5401                 case GL_TEXTURE_SWIZZLE_A:\r
5402                         if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))\r
5403                         {\r
5404                                 return error(GL_INVALID_VALUE);\r
5405                         }\r
5406                         break;\r
5407                 default:\r
5408                         return error(GL_INVALID_ENUM);\r
5409                 }\r
5410         }\r
5411 }\r
5412 \r
5413 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)\r
5414 {\r
5415         glTexParameteri(target, pname, *params);\r
5416 }\r
5417 \r
5418 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,\r
5419                    GLenum format, GLenum type, const GLvoid* pixels)\r
5420 {\r
5421         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
5422               "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "\r
5423               "const GLvoid* pixels = %p)",\r
5424               target, level, xoffset, yoffset, width, height, format, type, pixels);\r
5425 \r
5426         if(!es2::IsTextureTarget(target))\r
5427         {\r
5428                 return error(GL_INVALID_ENUM);\r
5429         }\r
5430 \r
5431         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
5432         {\r
5433                 return error(GL_INVALID_VALUE);\r
5434         }\r
5435 \r
5436         if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)\r
5437         {\r
5438                 return error(GL_INVALID_VALUE);\r
5439         }\r
5440 \r
5441         if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)\r
5442         {\r
5443                 return error(GL_INVALID_VALUE);\r
5444         }\r
5445 \r
5446         if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))\r
5447         {\r
5448                 return;\r
5449         }\r
5450 \r
5451         if(width == 0 || height == 0 || !pixels)\r
5452         {\r
5453                 return;\r
5454         }\r
5455 \r
5456         es2::Context *context = es2::getContext();\r
5457 \r
5458         if(context)\r
5459         {\r
5460                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
5461 \r
5462                 if(target == GL_TEXTURE_2D)\r
5463                 {\r
5464                         es2::Texture2D *texture = context->getTexture2D();\r
5465 \r
5466                         GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
5467 \r
5468                         if(validationError == GL_NONE)\r
5469                         {\r
5470                                 texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
5471                         }\r
5472                         else\r
5473                         {\r
5474                                 return error(validationError);\r
5475                         }\r
5476                 }\r
5477                 else if(es2::IsCubemapTextureTarget(target))\r
5478                 {\r
5479                         es2::TextureCubeMap *texture = context->getTextureCubeMap();\r
5480 \r
5481                         GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);\r
5482 \r
5483                         if(validationError == GL_NONE)\r
5484                         {\r
5485                                 texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
5486                         }\r
5487                         else\r
5488                         {\r
5489                                 return error(validationError);\r
5490                         }\r
5491                 }\r
5492                 else UNREACHABLE(target);\r
5493         }\r
5494 }\r
5495 \r
5496 void Uniform1f(GLint location, GLfloat x)\r
5497 {\r
5498         glUniform1fv(location, 1, &x);\r
5499 }\r
5500 \r
5501 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)\r
5502 {\r
5503         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);\r
5504 \r
5505         if(count < 0)\r
5506         {\r
5507                 return error(GL_INVALID_VALUE);\r
5508         }\r
5509 \r
5510         if(location == -1)\r
5511         {\r
5512                 return;\r
5513         }\r
5514 \r
5515         es2::Context *context = es2::getContext();\r
5516 \r
5517         if(context)\r
5518         {\r
5519                 es2::Program *program = context->getCurrentProgram();\r
5520 \r
5521                 if(!program)\r
5522                 {\r
5523                         return error(GL_INVALID_OPERATION);\r
5524                 }\r
5525 \r
5526                 if(!program->setUniform1fv(location, count, v))\r
5527                 {\r
5528                         return error(GL_INVALID_OPERATION);\r
5529                 }\r
5530         }\r
5531 }\r
5532 \r
5533 void Uniform1i(GLint location, GLint x)\r
5534 {\r
5535         glUniform1iv(location, 1, &x);\r
5536 }\r
5537 \r
5538 void Uniform1iv(GLint location, GLsizei count, const GLint* v)\r
5539 {\r
5540         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);\r
5541 \r
5542         if(count < 0)\r
5543         {\r
5544                 return error(GL_INVALID_VALUE);\r
5545         }\r
5546 \r
5547         if(location == -1)\r
5548         {\r
5549                 return;\r
5550         }\r
5551 \r
5552         es2::Context *context = es2::getContext();\r
5553 \r
5554         if(context)\r
5555         {\r
5556                 es2::Program *program = context->getCurrentProgram();\r
5557 \r
5558                 if(!program)\r
5559                 {\r
5560                         return error(GL_INVALID_OPERATION);\r
5561                 }\r
5562 \r
5563                 if(!program->setUniform1iv(location, count, v))\r
5564                 {\r
5565                         return error(GL_INVALID_OPERATION);\r
5566                 }\r
5567         }\r
5568 }\r
5569 \r
5570 void Uniform2f(GLint location, GLfloat x, GLfloat y)\r
5571 {\r
5572         GLfloat xy[2] = {x, y};\r
5573 \r
5574         glUniform2fv(location, 1, (GLfloat*)&xy);\r
5575 }\r
5576 \r
5577 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)\r
5578 {\r
5579         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);\r
5580 \r
5581         if(count < 0)\r
5582         {\r
5583                 return error(GL_INVALID_VALUE);\r
5584         }\r
5585 \r
5586         if(location == -1)\r
5587         {\r
5588                 return;\r
5589         }\r
5590 \r
5591         es2::Context *context = es2::getContext();\r
5592 \r
5593         if(context)\r
5594         {\r
5595                 es2::Program *program = context->getCurrentProgram();\r
5596 \r
5597                 if(!program)\r
5598                 {\r
5599                         return error(GL_INVALID_OPERATION);\r
5600                 }\r
5601 \r
5602                 if(!program->setUniform2fv(location, count, v))\r
5603                 {\r
5604                         return error(GL_INVALID_OPERATION);\r
5605                 }\r
5606         }\r
5607 }\r
5608 \r
5609 void Uniform2i(GLint location, GLint x, GLint y)\r
5610 {\r
5611         GLint xy[4] = {x, y};\r
5612 \r
5613         glUniform2iv(location, 1, (GLint*)&xy);\r
5614 }\r
5615 \r
5616 void Uniform2iv(GLint location, GLsizei count, const GLint* v)\r
5617 {\r
5618         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);\r
5619 \r
5620         if(count < 0)\r
5621         {\r
5622                 return error(GL_INVALID_VALUE);\r
5623         }\r
5624 \r
5625         if(location == -1)\r
5626         {\r
5627                 return;\r
5628         }\r
5629 \r
5630         es2::Context *context = es2::getContext();\r
5631 \r
5632         if(context)\r
5633         {\r
5634                 es2::Program *program = context->getCurrentProgram();\r
5635 \r
5636                 if(!program)\r
5637                 {\r
5638                         return error(GL_INVALID_OPERATION);\r
5639                 }\r
5640 \r
5641                 if(!program->setUniform2iv(location, count, v))\r
5642                 {\r
5643                         return error(GL_INVALID_OPERATION);\r
5644                 }\r
5645         }\r
5646 }\r
5647 \r
5648 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)\r
5649 {\r
5650         GLfloat xyz[3] = {x, y, z};\r
5651 \r
5652         glUniform3fv(location, 1, (GLfloat*)&xyz);\r
5653 }\r
5654 \r
5655 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)\r
5656 {\r
5657         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);\r
5658 \r
5659         if(count < 0)\r
5660         {\r
5661                 return error(GL_INVALID_VALUE);\r
5662         }\r
5663 \r
5664         if(location == -1)\r
5665         {\r
5666                 return;\r
5667         }\r
5668 \r
5669         es2::Context *context = es2::getContext();\r
5670 \r
5671         if(context)\r
5672         {\r
5673                 es2::Program *program = context->getCurrentProgram();\r
5674 \r
5675                 if(!program)\r
5676                 {\r
5677                         return error(GL_INVALID_OPERATION);\r
5678                 }\r
5679 \r
5680                 if(!program->setUniform3fv(location, count, v))\r
5681                 {\r
5682                         return error(GL_INVALID_OPERATION);\r
5683                 }\r
5684         }\r
5685 }\r
5686 \r
5687 void Uniform3i(GLint location, GLint x, GLint y, GLint z)\r
5688 {\r
5689         GLint xyz[3] = {x, y, z};\r
5690 \r
5691         glUniform3iv(location, 1, (GLint*)&xyz);\r
5692 }\r
5693 \r
5694 void Uniform3iv(GLint location, GLsizei count, const GLint* v)\r
5695 {\r
5696         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);\r
5697 \r
5698         if(count < 0)\r
5699         {\r
5700                 return error(GL_INVALID_VALUE);\r
5701         }\r
5702 \r
5703         if(location == -1)\r
5704         {\r
5705                 return;\r
5706         }\r
5707 \r
5708         es2::Context *context = es2::getContext();\r
5709 \r
5710         if(context)\r
5711         {\r
5712                 es2::Program *program = context->getCurrentProgram();\r
5713 \r
5714                 if(!program)\r
5715                 {\r
5716                         return error(GL_INVALID_OPERATION);\r
5717                 }\r
5718 \r
5719                 if(!program->setUniform3iv(location, count, v))\r
5720                 {\r
5721                         return error(GL_INVALID_OPERATION);\r
5722                 }\r
5723         }\r
5724 }\r
5725 \r
5726 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)\r
5727 {\r
5728         GLfloat xyzw[4] = {x, y, z, w};\r
5729 \r
5730         glUniform4fv(location, 1, (GLfloat*)&xyzw);\r
5731 }\r
5732 \r
5733 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)\r
5734 {\r
5735         TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);\r
5736 \r
5737         if(count < 0)\r
5738         {\r
5739                 return error(GL_INVALID_VALUE);\r
5740         }\r
5741 \r
5742         if(location == -1)\r
5743         {\r
5744                 return;\r
5745         }\r
5746 \r
5747         es2::Context *context = es2::getContext();\r
5748 \r
5749         if(context)\r
5750         {\r
5751                 es2::Program *program = context->getCurrentProgram();\r
5752 \r
5753                 if(!program)\r
5754                 {\r
5755                         return error(GL_INVALID_OPERATION);\r
5756                 }\r
5757 \r
5758                 if(!program->setUniform4fv(location, count, v))\r
5759                 {\r
5760                         return error(GL_INVALID_OPERATION);\r
5761                 }\r
5762         }\r
5763 }\r
5764 \r
5765 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)\r
5766 {\r
5767         GLint xyzw[4] = {x, y, z, w};\r
5768 \r
5769         glUniform4iv(location, 1, (GLint*)&xyzw);\r
5770 }\r
5771 \r
5772 void Uniform4iv(GLint location, GLsizei count, const GLint* v)\r
5773 {\r
5774         TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);\r
5775 \r
5776         if(count < 0)\r
5777         {\r
5778                 return error(GL_INVALID_VALUE);\r
5779         }\r
5780 \r
5781         if(location == -1)\r
5782         {\r
5783                 return;\r
5784         }\r
5785 \r
5786         es2::Context *context = es2::getContext();\r
5787 \r
5788         if(context)\r
5789         {\r
5790                 es2::Program *program = context->getCurrentProgram();\r
5791 \r
5792                 if(!program)\r
5793                 {\r
5794                         return error(GL_INVALID_OPERATION);\r
5795                 }\r
5796 \r
5797                 if(!program->setUniform4iv(location, count, v))\r
5798                 {\r
5799                         return error(GL_INVALID_OPERATION);\r
5800                 }\r
5801         }\r
5802 }\r
5803 \r
5804 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5805 {\r
5806         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",\r
5807               location, count, transpose, value);\r
5808 \r
5809         if(count < 0)\r
5810         {\r
5811                 return error(GL_INVALID_VALUE);\r
5812         }\r
5813 \r
5814         if(location == -1)\r
5815         {\r
5816                 return;\r
5817         }\r
5818 \r
5819         es2::Context *context = es2::getContext();\r
5820 \r
5821         if(context)\r
5822         {\r
5823                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)\r
5824                 {\r
5825                         return error(GL_INVALID_VALUE);\r
5826                 }\r
5827 \r
5828                 es2::Program *program = context->getCurrentProgram();\r
5829 \r
5830                 if(!program)\r
5831                 {\r
5832                         return error(GL_INVALID_OPERATION);\r
5833                 }\r
5834 \r
5835                 if(!program->setUniformMatrix2fv(location, count, transpose, value))\r
5836                 {\r
5837                         return error(GL_INVALID_OPERATION);\r
5838                 }\r
5839         }\r
5840 }\r
5841 \r
5842 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5843 {\r
5844         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",\r
5845               location, count, transpose, value);\r
5846 \r
5847         if(count < 0)\r
5848         {\r
5849                 return error(GL_INVALID_VALUE);\r
5850         }\r
5851 \r
5852         if(location == -1)\r
5853         {\r
5854                 return;\r
5855         }\r
5856 \r
5857         es2::Context *context = es2::getContext();\r
5858 \r
5859         if(context)\r
5860         {\r
5861                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)\r
5862                 {\r
5863                         return error(GL_INVALID_VALUE);\r
5864                 }\r
5865 \r
5866                 es2::Program *program = context->getCurrentProgram();\r
5867 \r
5868                 if(!program)\r
5869                 {\r
5870                         return error(GL_INVALID_OPERATION);\r
5871                 }\r
5872 \r
5873                 if(!program->setUniformMatrix3fv(location, count, transpose, value))\r
5874                 {\r
5875                         return error(GL_INVALID_OPERATION);\r
5876                 }\r
5877         }\r
5878 }\r
5879 \r
5880 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)\r
5881 {\r
5882         TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",\r
5883               location, count, transpose, value);\r
5884 \r
5885         if(count < 0)\r
5886         {\r
5887                 return error(GL_INVALID_VALUE);\r
5888         }\r
5889 \r
5890         if(location == -1)\r
5891         {\r
5892                 return;\r
5893         }\r
5894 \r
5895         es2::Context *context = es2::getContext();\r
5896 \r
5897         if(context)\r
5898         {\r
5899                 if(context->getClientVersion() < 3 && transpose != GL_FALSE)\r
5900                 {\r
5901                         return error(GL_INVALID_VALUE);\r
5902                 }\r
5903 \r
5904                 es2::Program *program = context->getCurrentProgram();\r
5905 \r
5906                 if(!program)\r
5907                 {\r
5908                         return error(GL_INVALID_OPERATION);\r
5909                 }\r
5910 \r
5911                 if(!program->setUniformMatrix4fv(location, count, transpose, value))\r
5912                 {\r
5913                         return error(GL_INVALID_OPERATION);\r
5914                 }\r
5915         }\r
5916 }\r
5917 \r
5918 void UseProgram(GLuint program)\r
5919 {\r
5920         TRACE("(GLuint program = %d)", program);\r
5921 \r
5922         es2::Context *context = es2::getContext();\r
5923 \r
5924         if(context)\r
5925         {\r
5926                 es2::Program *programObject = context->getProgram(program);\r
5927 \r
5928                 if(!programObject && program != 0)\r
5929                 {\r
5930                         if(context->getShader(program))\r
5931                         {\r
5932                                 return error(GL_INVALID_OPERATION);\r
5933                         }\r
5934                         else\r
5935                         {\r
5936                                 return error(GL_INVALID_VALUE);\r
5937                         }\r
5938                 }\r
5939 \r
5940                 if(program != 0 && !programObject->isLinked())\r
5941                 {\r
5942                         return error(GL_INVALID_OPERATION);\r
5943                 }\r
5944 \r
5945                 context->useProgram(program);\r
5946         }\r
5947 }\r
5948 \r
5949 void ValidateProgram(GLuint program)\r
5950 {\r
5951         TRACE("(GLuint program = %d)", program);\r
5952 \r
5953         es2::Context *context = es2::getContext();\r
5954 \r
5955         if(context)\r
5956         {\r
5957                 es2::Program *programObject = context->getProgram(program);\r
5958 \r
5959                 if(!programObject)\r
5960                 {\r
5961                         if(context->getShader(program))\r
5962                         {\r
5963                                 return error(GL_INVALID_OPERATION);\r
5964                         }\r
5965                         else\r
5966                         {\r
5967                                 return error(GL_INVALID_VALUE);\r
5968                         }\r
5969                 }\r
5970 \r
5971                 programObject->validate();\r
5972         }\r
5973 }\r
5974 \r
5975 void VertexAttrib1f(GLuint index, GLfloat x)\r
5976 {\r
5977         TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);\r
5978 \r
5979         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
5980         {\r
5981                 return error(GL_INVALID_VALUE);\r
5982         }\r
5983 \r
5984         es2::Context *context = es2::getContext();\r
5985 \r
5986         if(context)\r
5987         {\r
5988                 GLfloat vals[4] = { x, 0, 0, 1 };\r
5989                 context->setVertexAttrib(index, vals);\r
5990         }\r
5991 }\r
5992 \r
5993 void VertexAttrib1fv(GLuint index, const GLfloat* values)\r
5994 {\r
5995         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);\r
5996 \r
5997         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
5998         {\r
5999                 return error(GL_INVALID_VALUE);\r
6000         }\r
6001 \r
6002         es2::Context *context = es2::getContext();\r
6003 \r
6004         if(context)\r
6005         {\r
6006                 GLfloat vals[4] = { values[0], 0, 0, 1 };\r
6007                 context->setVertexAttrib(index, vals);\r
6008         }\r
6009 }\r
6010 \r
6011 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)\r
6012 {\r
6013         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);\r
6014 \r
6015         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6016         {\r
6017                 return error(GL_INVALID_VALUE);\r
6018         }\r
6019 \r
6020         es2::Context *context = es2::getContext();\r
6021 \r
6022         if(context)\r
6023         {\r
6024                 GLfloat vals[4] = { x, y, 0, 1 };\r
6025                 context->setVertexAttrib(index, vals);\r
6026         }\r
6027 }\r
6028 \r
6029 void VertexAttrib2fv(GLuint index, const GLfloat* values)\r
6030 {\r
6031         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);\r
6032 \r
6033         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6034         {\r
6035                 return error(GL_INVALID_VALUE);\r
6036         }\r
6037 \r
6038         es2::Context *context = es2::getContext();\r
6039 \r
6040         if(context)\r
6041         {\r
6042                 GLfloat vals[4] = { values[0], values[1], 0, 1 };\r
6043                 context->setVertexAttrib(index, vals);\r
6044         }\r
6045 }\r
6046 \r
6047 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)\r
6048 {\r
6049         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);\r
6050 \r
6051         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6052         {\r
6053                 return error(GL_INVALID_VALUE);\r
6054         }\r
6055 \r
6056         es2::Context *context = es2::getContext();\r
6057 \r
6058         if(context)\r
6059         {\r
6060                 GLfloat vals[4] = { x, y, z, 1 };\r
6061                 context->setVertexAttrib(index, vals);\r
6062         }\r
6063 }\r
6064 \r
6065 void VertexAttrib3fv(GLuint index, const GLfloat* values)\r
6066 {\r
6067         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);\r
6068 \r
6069         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6070         {\r
6071                 return error(GL_INVALID_VALUE);\r
6072         }\r
6073 \r
6074         es2::Context *context = es2::getContext();\r
6075 \r
6076         if(context)\r
6077         {\r
6078                 GLfloat vals[4] = { values[0], values[1], values[2], 1 };\r
6079                 context->setVertexAttrib(index, vals);\r
6080         }\r
6081 }\r
6082 \r
6083 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)\r
6084 {\r
6085         TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);\r
6086 \r
6087         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6088         {\r
6089                 return error(GL_INVALID_VALUE);\r
6090         }\r
6091 \r
6092         es2::Context *context = es2::getContext();\r
6093 \r
6094         if(context)\r
6095         {\r
6096                 GLfloat vals[4] = { x, y, z, w };\r
6097                 context->setVertexAttrib(index, vals);\r
6098         }\r
6099 }\r
6100 \r
6101 void VertexAttrib4fv(GLuint index, const GLfloat* values)\r
6102 {\r
6103         TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);\r
6104 \r
6105         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6106         {\r
6107                 return error(GL_INVALID_VALUE);\r
6108         }\r
6109 \r
6110         es2::Context *context = es2::getContext();\r
6111 \r
6112         if(context)\r
6113         {\r
6114                 context->setVertexAttrib(index, values);\r
6115         }\r
6116 }\r
6117 \r
6118 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)\r
6119 {\r
6120         TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "\r
6121               "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",\r
6122               index, size, type, normalized, stride, ptr);\r
6123 \r
6124         if(index >= es2::MAX_VERTEX_ATTRIBS)\r
6125         {\r
6126                 return error(GL_INVALID_VALUE);\r
6127         }\r
6128 \r
6129         if(size < 1 || size > 4)\r
6130         {\r
6131                 return error(GL_INVALID_VALUE);\r
6132         }\r
6133 \r
6134         GLint clientVersion = egl::getClientVersion();\r
6135 \r
6136         switch(type)\r
6137         {\r
6138         case GL_BYTE:\r
6139         case GL_UNSIGNED_BYTE:\r
6140         case GL_SHORT:\r
6141         case GL_UNSIGNED_SHORT:\r
6142         case GL_FIXED:\r
6143         case GL_FLOAT:\r
6144                 break;\r
6145         case GL_INT_2_10_10_10_REV:\r
6146         case GL_UNSIGNED_INT_2_10_10_10_REV:\r
6147                 if(clientVersion >= 3)\r
6148                 {\r
6149                         if(size != 4)\r
6150                         {\r
6151                                 return error(GL_INVALID_OPERATION);\r
6152                         }\r
6153                         break;\r
6154                 }\r
6155                 else return error(GL_INVALID_ENUM);\r
6156         case GL_INT:\r
6157         case GL_UNSIGNED_INT:\r
6158         case GL_HALF_FLOAT:\r
6159                 if(clientVersion >= 3)\r
6160                 {\r
6161                         break;\r
6162                 }\r
6163                 else return error(GL_INVALID_ENUM);\r
6164         default:\r
6165                 return error(GL_INVALID_ENUM);\r
6166         }\r
6167 \r
6168         if(stride < 0)\r
6169         {\r
6170                 return error(GL_INVALID_VALUE);\r
6171         }\r
6172 \r
6173         es2::Context *context = es2::getContext();\r
6174 \r
6175         if(context)\r
6176         {\r
6177                 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);\r
6178         }\r
6179 }\r
6180 \r
6181 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)\r
6182 {\r
6183         TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);\r
6184 \r
6185         if(width < 0 || height < 0)\r
6186         {\r
6187                 return error(GL_INVALID_VALUE);\r
6188         }\r
6189 \r
6190         es2::Context *context = es2::getContext();\r
6191 \r
6192         if(context)\r
6193         {\r
6194                 context->setViewportParams(x, y, width, height);\r
6195         }\r
6196 }\r
6197 \r
6198 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)\r
6199 {\r
6200         TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "\r
6201               "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "\r
6202               "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",\r
6203               srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);\r
6204 \r
6205         switch(filter)\r
6206         {\r
6207         case GL_NEAREST:\r
6208                 break;\r
6209         default:\r
6210                 return error(GL_INVALID_ENUM);\r
6211         }\r
6212 \r
6213         if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)\r
6214         {\r
6215                 return error(GL_INVALID_VALUE);\r
6216         }\r
6217 \r
6218         es2::Context *context = es2::getContext();\r
6219 \r
6220         if(context)\r
6221         {\r
6222                 if(context->getReadFramebufferName() == context->getDrawFramebufferName())\r
6223                 {\r
6224                         ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");\r
6225                         return error(GL_INVALID_OPERATION);\r
6226                 }\r
6227 \r
6228                 context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);\r
6229         }\r
6230 }\r
6231 \r
6232 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,\r
6233                           GLbitfield mask, GLenum filter)\r
6234 {\r
6235         if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)\r
6236         {\r
6237                 ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");\r
6238                 return error(GL_INVALID_OPERATION);\r
6239         }\r
6240 \r
6241         glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);\r
6242 }\r
6243 \r
6244 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,\r
6245                    GLint border, GLenum format, GLenum type, const GLvoid* pixels)\r
6246 {\r
6247         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "\r
6248               "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "\r
6249               "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",\r
6250               target, level, internalformat, width, height, depth, border, format, type, pixels);\r
6251 \r
6252         switch(target)\r
6253         {\r
6254         case GL_TEXTURE_3D_OES:\r
6255                 switch(format)\r
6256                 {\r
6257                 case GL_DEPTH_COMPONENT:\r
6258                 case GL_DEPTH_STENCIL_OES:\r
6259                         return error(GL_INVALID_OPERATION);\r
6260                 default:\r
6261                         break;\r
6262                 }\r
6263                 break;\r
6264         default:\r
6265                 return error(GL_INVALID_ENUM);\r
6266         }\r
6267 \r
6268         if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))\r
6269         {\r
6270                 return;\r
6271         }\r
6272 \r
6273         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
6274         {\r
6275                 return error(GL_INVALID_VALUE);\r
6276         }\r
6277 \r
6278         const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;\r
6279         if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))\r
6280         {\r
6281                 return error(GL_INVALID_VALUE);\r
6282         }\r
6283 \r
6284         if(border != 0)\r
6285         {\r
6286                 return error(GL_INVALID_VALUE);\r
6287         }\r
6288 \r
6289         es2::Context *context = es2::getContext();\r
6290 \r
6291         if(context)\r
6292         {\r
6293                 es2::Texture3D *texture = context->getTexture3D();\r
6294 \r
6295                 if(!texture)\r
6296                 {\r
6297                         return error(GL_INVALID_OPERATION);\r
6298                 }\r
6299 \r
6300                 texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);\r
6301         }\r
6302 }\r
6303 \r
6304 void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)\r
6305 {\r
6306         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
6307               "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "\r
6308               "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",\r
6309               target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);\r
6310 \r
6311         switch(target)\r
6312         {\r
6313         case GL_TEXTURE_3D_OES:\r
6314                 break;\r
6315         default:\r
6316                 return error(GL_INVALID_ENUM);\r
6317         }\r
6318 \r
6319         if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))\r
6320         {\r
6321                 return;\r
6322         }\r
6323 \r
6324         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
6325         {\r
6326                 return error(GL_INVALID_VALUE);\r
6327         }\r
6328 \r
6329         if((width < 0) || (height < 0) || (depth < 0))\r
6330         {\r
6331                 return error(GL_INVALID_VALUE);\r
6332         }\r
6333 \r
6334         es2::Context *context = es2::getContext();\r
6335 \r
6336         if(context)\r
6337         {\r
6338                 es2::Texture3D *texture = context->getTexture3D();\r
6339 \r
6340                 GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);\r
6341 \r
6342                 GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);\r
6343                 if(validationError == GL_NONE)\r
6344                 {\r
6345                         texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);\r
6346                 }\r
6347                 else\r
6348                 {\r
6349                         return error(validationError);\r
6350                 }\r
6351         }\r
6352 }\r
6353 \r
6354 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)\r
6355 {\r
6356         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
6357               "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",\r
6358               target, level, xoffset, yoffset, zoffset, x, y, width, height);\r
6359 \r
6360         switch(target)\r
6361         {\r
6362         case GL_TEXTURE_3D_OES:\r
6363                 break;\r
6364         default:\r
6365                 return error(GL_INVALID_ENUM);\r
6366         }\r
6367 \r
6368         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
6369         {\r
6370                 return error(GL_INVALID_VALUE);\r
6371         }\r
6372 \r
6373         es2::Context *context = es2::getContext();\r
6374 \r
6375         if(context)\r
6376         {\r
6377                 es2::Framebuffer *framebuffer = context->getReadFramebuffer();\r
6378 \r
6379                 if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)\r
6380                 {\r
6381                         return error(GL_INVALID_FRAMEBUFFER_OPERATION);\r
6382                 }\r
6383 \r
6384                 es2::Renderbuffer *source = framebuffer->getReadColorbuffer();\r
6385 \r
6386                 if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))\r
6387                 {\r
6388                         return error(GL_INVALID_OPERATION);\r
6389                 }\r
6390 \r
6391                 es2::Texture3D *texture = context->getTexture3D();\r
6392 \r
6393                 GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);\r
6394 \r
6395                 if(validationError != GL_NONE)\r
6396                 {\r
6397                         return error(validationError);\r
6398                 }\r
6399 \r
6400                 texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);\r
6401         }\r
6402 }\r
6403 \r
6404 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)\r
6405 {\r
6406         TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "\r
6407               "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",\r
6408               target, level, internalformat, width, height, depth, border, imageSize, data);\r
6409 \r
6410         switch(target)\r
6411         {\r
6412         case GL_TEXTURE_3D_OES:\r
6413                 break;\r
6414         default:\r
6415                 return error(GL_INVALID_ENUM);\r
6416         }\r
6417 \r
6418         if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))\r
6419         {\r
6420                 return error(GL_INVALID_VALUE);\r
6421         }\r
6422 \r
6423         const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;\r
6424         if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))\r
6425         {\r
6426                 return error(GL_INVALID_VALUE);\r
6427         }\r
6428 \r
6429         switch(internalformat)\r
6430         {\r
6431         case GL_DEPTH_COMPONENT:\r
6432         case GL_DEPTH_COMPONENT16:\r
6433         case GL_DEPTH_COMPONENT32_OES:\r
6434         case GL_DEPTH_STENCIL_OES:\r
6435         case GL_DEPTH24_STENCIL8_OES:\r
6436                 return error(GL_INVALID_OPERATION);\r
6437         default:\r
6438                 {\r
6439                         GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);\r
6440                         if(validationError != GL_NONE)\r
6441                         {\r
6442                                 return error(validationError);\r
6443                         }\r
6444                 }\r
6445         }\r
6446 \r
6447         if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)\r
6448         {\r
6449                 return error(GL_INVALID_VALUE);\r
6450         }\r
6451 \r
6452         es2::Context *context = es2::getContext();\r
6453 \r
6454         if(context)\r
6455         {\r
6456                 es2::Texture3D *texture = context->getTexture3D();\r
6457 \r
6458                 if(!texture)\r
6459                 {\r
6460                         return error(GL_INVALID_OPERATION);\r
6461                 }\r
6462 \r
6463                 texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);\r
6464         }\r
6465 }\r
6466 \r
6467 void CompressedTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data)\r
6468 {\r
6469         TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "\r
6470               "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "\r
6471               "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",\r
6472               target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);\r
6473 \r
6474         switch(target)\r
6475         {\r
6476         case GL_TEXTURE_3D_OES:\r
6477                 break;\r
6478         default:\r
6479                 return error(GL_INVALID_ENUM);\r
6480         }\r
6481 \r
6482         if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)\r
6483         {\r
6484                 return error(GL_INVALID_VALUE);\r
6485         }\r
6486 \r
6487         if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)\r
6488         {\r
6489                 return error(GL_INVALID_VALUE);\r
6490         }\r
6491 \r
6492         GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);\r
6493         if(validationError != GL_NONE)\r
6494         {\r
6495                 return error(validationError);\r
6496         }\r
6497 \r
6498         if(width == 0 || height == 0 || depth == 0 || !data)\r
6499         {\r
6500                 return;\r
6501         }\r
6502 \r
6503         es2::Context *context = es2::getContext();\r
6504 \r
6505         if(context)\r
6506         {\r
6507                 es2::Texture3D *texture = context->getTexture3D();\r
6508 \r
6509                 if(!texture)\r
6510                 {\r
6511                         return error(GL_INVALID_OPERATION);\r
6512                 }\r
6513 \r
6514                 texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);\r
6515         }\r
6516 }\r
6517 \r
6518 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)\r
6519 {\r
6520         TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "\r
6521               "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);\r
6522 \r
6523         if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)\r
6524         {\r
6525                 return error(GL_INVALID_ENUM);\r
6526         }\r
6527 \r
6528         es2::Context *context = es2::getContext();\r
6529 \r
6530         if(context)\r
6531         {\r
6532                 if(texture == 0)\r
6533                 {\r
6534                         textarget = GL_NONE;\r
6535                 }\r
6536                 else\r
6537                 {\r
6538                         es2::Texture *tex = context->getTexture(texture);\r
6539 \r
6540                         if(tex == NULL)\r
6541                         {\r
6542                                 return error(GL_INVALID_OPERATION);\r
6543                         }\r
6544 \r
6545                         if(tex->isCompressed(textarget, level))\r
6546                         {\r
6547                                 return error(GL_INVALID_OPERATION);\r
6548                         }\r
6549 \r
6550                         switch(textarget)\r
6551                         {\r
6552                         case GL_TEXTURE_3D_OES:\r
6553                                 if(tex->getTarget() != GL_TEXTURE_3D_OES)\r
6554                                 {\r
6555                                         return error(GL_INVALID_OPERATION);\r
6556                                 }\r
6557                                 break;\r
6558                         default:\r
6559                                 return error(GL_INVALID_ENUM);\r
6560                         }\r
6561 \r
6562                         if(level != 0)\r
6563                         {\r
6564                                 return error(GL_INVALID_VALUE);\r
6565                         }\r
6566                 }\r
6567 \r
6568                 es2::Framebuffer *framebuffer = NULL;\r
6569                 GLuint framebufferName = 0;\r
6570                 if(target == GL_READ_FRAMEBUFFER_ANGLE)\r
6571                 {\r
6572                         framebuffer = context->getReadFramebuffer();\r
6573                         framebufferName = context->getReadFramebufferName();\r
6574                 }\r
6575                 else\r
6576                 {\r
6577                         framebuffer = context->getDrawFramebuffer();\r
6578                         framebufferName = context->getDrawFramebufferName();\r
6579                 }\r
6580 \r
6581                 if(framebufferName == 0 || !framebuffer)\r
6582                 {\r
6583                         return error(GL_INVALID_OPERATION);\r
6584                 }\r
6585 \r
6586                 GLint clientVersion = context->getClientVersion();\r
6587 \r
6588                 switch(attachment)\r
6589                 {\r
6590                 case GL_COLOR_ATTACHMENT1:\r
6591                 case GL_COLOR_ATTACHMENT2:\r
6592                 case GL_COLOR_ATTACHMENT3:\r
6593                 case GL_COLOR_ATTACHMENT4:\r
6594                 case GL_COLOR_ATTACHMENT5:\r
6595                 case GL_COLOR_ATTACHMENT6:\r
6596                 case GL_COLOR_ATTACHMENT7:\r
6597                 case GL_COLOR_ATTACHMENT8:\r
6598                 case GL_COLOR_ATTACHMENT9:\r
6599                 case GL_COLOR_ATTACHMENT10:\r
6600                 case GL_COLOR_ATTACHMENT11:\r
6601                 case GL_COLOR_ATTACHMENT12:\r
6602                 case GL_COLOR_ATTACHMENT13:\r
6603                 case GL_COLOR_ATTACHMENT14:\r
6604                 case GL_COLOR_ATTACHMENT15:\r
6605                 case GL_COLOR_ATTACHMENT16:\r
6606                 case GL_COLOR_ATTACHMENT17:\r
6607                 case GL_COLOR_ATTACHMENT18:\r
6608                 case GL_COLOR_ATTACHMENT19:\r
6609                 case GL_COLOR_ATTACHMENT20:\r
6610                 case GL_COLOR_ATTACHMENT21:\r
6611                 case GL_COLOR_ATTACHMENT22:\r
6612                 case GL_COLOR_ATTACHMENT23:\r
6613                 case GL_COLOR_ATTACHMENT24:\r
6614                 case GL_COLOR_ATTACHMENT25:\r
6615                 case GL_COLOR_ATTACHMENT26:\r
6616                 case GL_COLOR_ATTACHMENT27:\r
6617                 case GL_COLOR_ATTACHMENT28:\r
6618                 case GL_COLOR_ATTACHMENT29:\r
6619                 case GL_COLOR_ATTACHMENT30:\r
6620                 case GL_COLOR_ATTACHMENT31:\r
6621                         if(clientVersion < 3)\r
6622                         {\r
6623                                 return error(GL_INVALID_ENUM);\r
6624                         }\r
6625                         // fall through\r
6626                 case GL_COLOR_ATTACHMENT0:\r
6627                         if((attachment - GL_COLOR_ATTACHMENT0) >= es2::IMPLEMENTATION_MAX_COLOR_ATTACHMENTS)\r
6628                         {\r
6629                                 return error(GL_INVALID_ENUM);\r
6630                         }\r
6631                         framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);\r
6632                         break;\r
6633                 case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;\r
6634                 case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;\r
6635                 default:\r
6636                         return error(GL_INVALID_ENUM);\r
6637                 }\r
6638         }\r
6639 }\r
6640 \r
6641 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)\r
6642 {\r
6643         if(egl::getClientVersion() == 1)\r
6644         {\r
6645                 return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);\r
6646         }\r
6647 \r
6648         TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);\r
6649 \r
6650         switch(target)\r
6651         {\r
6652         case GL_TEXTURE_2D:\r
6653         case GL_TEXTURE_EXTERNAL_OES:\r
6654                 break;\r
6655         default:\r
6656                 return error(GL_INVALID_ENUM);\r
6657         }\r
6658 \r
6659         if(!image)\r
6660         {\r
6661                 return error(GL_INVALID_OPERATION);\r
6662         }\r
6663 \r
6664         es2::Context *context = es2::getContext();\r
6665 \r
6666         if(context)\r
6667         {\r
6668                 es2::Texture2D *texture = 0;\r
6669 \r
6670                 switch(target)\r
6671                 {\r
6672                 case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;\r
6673                 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;\r
6674                 default:                      UNREACHABLE(target);\r
6675                 }\r
6676 \r
6677                 if(!texture)\r
6678                 {\r
6679                         return error(GL_INVALID_OPERATION);\r
6680                 }\r
6681 \r
6682                 egl::Image *glImage = static_cast<egl::Image*>(image);\r
6683 \r
6684                 texture->setImage(glImage);\r
6685         }\r
6686 }\r
6687 \r
6688 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)\r
6689 {\r
6690         TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);\r
6691 \r
6692         UNIMPLEMENTED();\r
6693 }\r
6694 \r
6695 GLboolean IsRenderbufferOES(GLuint renderbuffer)\r
6696 {\r
6697         return IsRenderbuffer(renderbuffer);\r
6698 }\r
6699 \r
6700 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)\r
6701 {\r
6702         BindRenderbuffer(target, renderbuffer);\r
6703 }\r
6704 \r
6705 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)\r
6706 {\r
6707         DeleteRenderbuffers(n, renderbuffers);\r
6708 }\r
6709 \r
6710 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)\r
6711 {\r
6712         GenRenderbuffers(n, renderbuffers);\r
6713 }\r
6714 \r
6715 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)\r
6716 {\r
6717         RenderbufferStorage(target, internalformat, width, height);\r
6718 }\r
6719 \r
6720 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)\r
6721 {\r
6722         GetRenderbufferParameteriv(target, pname, params);\r
6723 }\r
6724 \r
6725 GLboolean IsFramebufferOES(GLuint framebuffer)\r
6726 {\r
6727         return IsFramebuffer(framebuffer);\r
6728 }\r
6729 \r
6730 void BindFramebufferOES(GLenum target, GLuint framebuffer)\r
6731 {\r
6732         BindFramebuffer(target, framebuffer);\r
6733 }\r
6734 \r
6735 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)\r
6736 {\r
6737         DeleteFramebuffers(n, framebuffers);\r
6738 }\r
6739 \r
6740 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)\r
6741 {\r
6742         GenFramebuffers(n, framebuffers);\r
6743 }\r
6744 \r
6745 GLenum CheckFramebufferStatusOES(GLenum target)\r
6746 {\r
6747         return CheckFramebufferStatus(target);\r
6748 }\r
6749 \r
6750 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)\r
6751 {\r
6752         FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);\r
6753 }\r
6754 \r
6755 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)\r
6756 {\r
6757         FramebufferTexture2D(target, attachment, textarget, texture, level);\r
6758 }\r
6759 \r
6760 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)\r
6761 {\r
6762         GetFramebufferAttachmentParameteriv(target, attachment, pname, params);\r
6763 }\r
6764 \r
6765 void GenerateMipmapOES(GLenum target)\r
6766 {\r
6767         GenerateMipmap(target);\r
6768 }\r
6769 \r
6770 }\r
6771 \r
6772 extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)\r
6773 {\r
6774         struct Extension\r
6775         {\r
6776                 const char *name;\r
6777                 __eglMustCastToProperFunctionPointerType address;\r
6778         };\r
6779 \r
6780         static const Extension glExtensions[] =\r
6781         {\r
6782                 #define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}\r
6783 \r
6784                 EXTENSION(glTexImage3DOES),\r
6785                 EXTENSION(glBlitFramebufferANGLE),\r
6786                 EXTENSION(glBlitFramebufferNV),\r
6787                 EXTENSION(glRenderbufferStorageMultisampleANGLE),\r
6788                 EXTENSION(glDeleteFencesNV),\r
6789                 EXTENSION(glGenFencesNV),\r
6790                 EXTENSION(glIsFenceNV),\r
6791                 EXTENSION(glTestFenceNV),\r
6792                 EXTENSION(glGetFenceivNV),\r
6793                 EXTENSION(glFinishFenceNV),\r
6794                 EXTENSION(glSetFenceNV),\r
6795                 EXTENSION(glGetGraphicsResetStatusEXT),\r
6796                 EXTENSION(glReadnPixelsEXT),\r
6797                 EXTENSION(glGetnUniformfvEXT),\r
6798                 EXTENSION(glGetnUniformivEXT),\r
6799                 EXTENSION(glGenQueriesEXT),\r
6800                 EXTENSION(glDeleteQueriesEXT),\r
6801                 EXTENSION(glIsQueryEXT),\r
6802                 EXTENSION(glBeginQueryEXT),\r
6803                 EXTENSION(glEndQueryEXT),\r
6804                 EXTENSION(glGetQueryivEXT),\r
6805                 EXTENSION(glGetQueryObjectuivEXT),\r
6806                 EXTENSION(glEGLImageTargetTexture2DOES),\r
6807                 EXTENSION(glEGLImageTargetRenderbufferStorageOES),\r
6808                 EXTENSION(glDrawElementsInstancedEXT),\r
6809                 EXTENSION(glDrawArraysInstancedEXT),\r
6810                 EXTENSION(glVertexAttribDivisorEXT),\r
6811                 EXTENSION(glDrawArraysInstancedANGLE),\r
6812                 EXTENSION(glDrawElementsInstancedANGLE),\r
6813                 EXTENSION(glVertexAttribDivisorANGLE),\r
6814                 EXTENSION(glIsRenderbufferOES),\r
6815                 EXTENSION(glBindRenderbufferOES),\r
6816                 EXTENSION(glDeleteRenderbuffersOES),\r
6817                 EXTENSION(glGenRenderbuffersOES),\r
6818                 EXTENSION(glRenderbufferStorageOES),\r
6819                 EXTENSION(glGetRenderbufferParameterivOES),\r
6820                 EXTENSION(glIsFramebufferOES),\r
6821                 EXTENSION(glBindFramebufferOES),\r
6822                 EXTENSION(glDeleteFramebuffersOES),\r
6823                 EXTENSION(glGenFramebuffersOES),\r
6824                 EXTENSION(glCheckFramebufferStatusOES),\r
6825                 EXTENSION(glFramebufferRenderbufferOES),\r
6826                 EXTENSION(glFramebufferTexture2DOES),\r
6827                 EXTENSION(glGetFramebufferAttachmentParameterivOES),\r
6828                 EXTENSION(glGenerateMipmapOES),\r
6829 \r
6830                 #undef EXTENSION\r
6831         };\r
6832 \r
6833         for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)\r
6834         {\r
6835                 if(strcmp(procname, glExtensions[ext].name) == 0)\r
6836                 {\r
6837                         return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;\r
6838                 }\r
6839         }\r
6840 \r
6841         return NULL;\r
6842 }\r