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