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