• 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, 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, 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 		if(texture == 0)
2066 		{
2067 			textarget = GL_NONE;
2068 		}
2069 		else
2070 		{
2071 			es2::Texture *tex = context->getTexture(texture);
2072 
2073 			if(!tex)
2074 			{
2075 				return error(GL_INVALID_OPERATION);
2076 			}
2077 
2078 			switch(textarget)
2079 			{
2080 			case GL_TEXTURE_2D:
2081 				if(tex->getTarget() != GL_TEXTURE_2D)
2082 				{
2083 					return error(GL_INVALID_OPERATION);
2084 				}
2085 				break;
2086 			case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
2087 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
2088 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
2089 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
2090 			case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
2091 			case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
2092 				if(tex->getTarget() != GL_TEXTURE_CUBE_MAP)
2093 				{
2094 					return error(GL_INVALID_OPERATION);
2095 				}
2096 				break;
2097 			default:
2098 				return error(GL_INVALID_ENUM);
2099 			}
2100 
2101 			if(tex->isCompressed(textarget, level))
2102 			{
2103 				return error(GL_INVALID_OPERATION);
2104 			}
2105 
2106 			if((level != 0) && (context->getClientVersion() < 3))
2107 			{
2108 				return error(GL_INVALID_VALUE);
2109 			}
2110 
2111 			if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
2112 			{
2113 				return error(GL_INVALID_VALUE);
2114 			}
2115 		}
2116 
2117 		es2::Framebuffer *framebuffer = nullptr;
2118 		GLuint framebufferName = 0;
2119 		if(target == GL_READ_FRAMEBUFFER_ANGLE)
2120 		{
2121 			framebuffer = context->getReadFramebuffer();
2122 			framebufferName = context->getReadFramebufferName();
2123 		}
2124 		else
2125 		{
2126 			framebuffer = context->getDrawFramebuffer();
2127 			framebufferName = context->getDrawFramebufferName();
2128 		}
2129 
2130 		if(framebufferName == 0 || !framebuffer)
2131 		{
2132 			return error(GL_INVALID_OPERATION);
2133 		}
2134 
2135 		switch(attachment)
2136 		{
2137 		case GL_COLOR_ATTACHMENT0:
2138 		case GL_COLOR_ATTACHMENT1:
2139 		case GL_COLOR_ATTACHMENT2:
2140 		case GL_COLOR_ATTACHMENT3:
2141 		case GL_COLOR_ATTACHMENT4:
2142 		case GL_COLOR_ATTACHMENT5:
2143 		case GL_COLOR_ATTACHMENT6:
2144 		case GL_COLOR_ATTACHMENT7:
2145 		case GL_COLOR_ATTACHMENT8:
2146 		case GL_COLOR_ATTACHMENT9:
2147 		case GL_COLOR_ATTACHMENT10:
2148 		case GL_COLOR_ATTACHMENT11:
2149 		case GL_COLOR_ATTACHMENT12:
2150 		case GL_COLOR_ATTACHMENT13:
2151 		case GL_COLOR_ATTACHMENT14:
2152 		case GL_COLOR_ATTACHMENT15:
2153 		case GL_COLOR_ATTACHMENT16:
2154 		case GL_COLOR_ATTACHMENT17:
2155 		case GL_COLOR_ATTACHMENT18:
2156 		case GL_COLOR_ATTACHMENT19:
2157 		case GL_COLOR_ATTACHMENT20:
2158 		case GL_COLOR_ATTACHMENT21:
2159 		case GL_COLOR_ATTACHMENT22:
2160 		case GL_COLOR_ATTACHMENT23:
2161 		case GL_COLOR_ATTACHMENT24:
2162 		case GL_COLOR_ATTACHMENT25:
2163 		case GL_COLOR_ATTACHMENT26:
2164 		case GL_COLOR_ATTACHMENT27:
2165 		case GL_COLOR_ATTACHMENT28:
2166 		case GL_COLOR_ATTACHMENT29:
2167 		case GL_COLOR_ATTACHMENT30:
2168 		case GL_COLOR_ATTACHMENT31:
2169 			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2170 			{
2171 				return error(GL_INVALID_ENUM);
2172 			}
2173 			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0, level);
2174 			break;
2175 		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture, level);   break;
2176 		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture, level); break;
2177 		default:
2178 			return error(GL_INVALID_ENUM);
2179 		}
2180 	}
2181 }
2182 
FrontFace(GLenum mode)2183 void FrontFace(GLenum mode)
2184 {
2185 	TRACE("(GLenum mode = 0x%X)", mode);
2186 
2187 	switch(mode)
2188 	{
2189 	case GL_CW:
2190 	case GL_CCW:
2191 		{
2192 			es2::Context *context = es2::getContext();
2193 
2194 			if(context)
2195 			{
2196 				context->setFrontFace(mode);
2197 			}
2198 		}
2199 		break;
2200 	default:
2201 		return error(GL_INVALID_ENUM);
2202 	}
2203 }
2204 
GenBuffers(GLsizei n,GLuint * buffers)2205 void GenBuffers(GLsizei n, GLuint* buffers)
2206 {
2207 	TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
2208 
2209 	if(n < 0)
2210 	{
2211 		return error(GL_INVALID_VALUE);
2212 	}
2213 
2214 	es2::Context *context = es2::getContext();
2215 
2216 	if(context)
2217 	{
2218 		for(int i = 0; i < n; i++)
2219 		{
2220 			buffers[i] = context->createBuffer();
2221 		}
2222 	}
2223 }
2224 
GenerateMipmap(GLenum target)2225 void GenerateMipmap(GLenum target)
2226 {
2227 	TRACE("(GLenum target = 0x%X)", target);
2228 
2229 	es2::Context *context = es2::getContext();
2230 
2231 	if(context)
2232 	{
2233 		es2::Texture *texture = nullptr;
2234 
2235 		GLint clientVersion = context->getClientVersion();
2236 
2237 		switch(target)
2238 		{
2239 		case GL_TEXTURE_2D:
2240 			texture = context->getTexture2D();
2241 			break;
2242 		case GL_TEXTURE_CUBE_MAP:
2243 			texture = context->getTextureCubeMap();
2244 			break;
2245 		case GL_TEXTURE_2D_ARRAY:
2246 			if(clientVersion < 3)
2247 			{
2248 				return error(GL_INVALID_ENUM);
2249 			}
2250 			else
2251 			{
2252 				texture = context->getTexture2DArray();
2253 			}
2254 			break;
2255 		case GL_TEXTURE_3D_OES:
2256 			texture = context->getTexture3D();
2257 			break;
2258 		default:
2259 			return error(GL_INVALID_ENUM);
2260 		}
2261 
2262 		if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
2263 		{
2264 			return error(GL_INVALID_OPERATION);
2265 		}
2266 
2267 		texture->generateMipmaps();
2268 	}
2269 }
2270 
GenFencesNV(GLsizei n,GLuint * fences)2271 void GenFencesNV(GLsizei n, GLuint* fences)
2272 {
2273 	TRACE("(GLsizei n = %d, GLuint* fences = %p)", n, fences);
2274 
2275 	if(n < 0)
2276 	{
2277 		return error(GL_INVALID_VALUE);
2278 	}
2279 
2280 	es2::Context *context = es2::getContext();
2281 
2282 	if(context)
2283 	{
2284 		for(int i = 0; i < n; i++)
2285 		{
2286 			fences[i] = context->createFence();
2287 		}
2288 	}
2289 }
2290 
GenFramebuffers(GLsizei n,GLuint * framebuffers)2291 void GenFramebuffers(GLsizei n, GLuint* framebuffers)
2292 {
2293 	TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
2294 
2295 	if(n < 0)
2296 	{
2297 		return error(GL_INVALID_VALUE);
2298 	}
2299 
2300 	es2::Context *context = es2::getContext();
2301 
2302 	if(context)
2303 	{
2304 		for(int i = 0; i < n; i++)
2305 		{
2306 			framebuffers[i] = context->createFramebuffer();
2307 		}
2308 	}
2309 }
2310 
GenQueriesEXT(GLsizei n,GLuint * ids)2311 void GenQueriesEXT(GLsizei n, GLuint* ids)
2312 {
2313 	TRACE("(GLsizei n = %d, GLuint* ids = %p)", n, ids);
2314 
2315 	if(n < 0)
2316 	{
2317 		return error(GL_INVALID_VALUE);
2318 	}
2319 
2320 	es2::Context *context = es2::getContext();
2321 
2322 	if(context)
2323 	{
2324 		for(int i = 0; i < n; i++)
2325 		{
2326 			ids[i] = context->createQuery();
2327 		}
2328 	}
2329 }
2330 
GenRenderbuffers(GLsizei n,GLuint * renderbuffers)2331 void GenRenderbuffers(GLsizei n, GLuint* renderbuffers)
2332 {
2333 	TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
2334 
2335 	if(n < 0)
2336 	{
2337 		return error(GL_INVALID_VALUE);
2338 	}
2339 
2340 	es2::Context *context = es2::getContext();
2341 
2342 	if(context)
2343 	{
2344 		for(int i = 0; i < n; i++)
2345 		{
2346 			renderbuffers[i] = context->createRenderbuffer();
2347 		}
2348 	}
2349 }
2350 
GenTextures(GLsizei n,GLuint * textures)2351 void GenTextures(GLsizei n, GLuint* textures)
2352 {
2353 	TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
2354 
2355 	if(n < 0)
2356 	{
2357 		return error(GL_INVALID_VALUE);
2358 	}
2359 
2360 	es2::Context *context = es2::getContext();
2361 
2362 	if(context)
2363 	{
2364 		for(int i = 0; i < n; i++)
2365 		{
2366 			textures[i] = context->createTexture();
2367 		}
2368 	}
2369 }
2370 
GetActiveAttrib(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)2371 void GetActiveAttrib(GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
2372 {
2373 	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, GLsizei *length = %p, "
2374 	      "GLint *size = %p, GLenum *type = %p, GLchar *name = %p)",
2375 	      program, index, bufsize, length, size, type, name);
2376 
2377 	if(bufsize < 0)
2378 	{
2379 		return error(GL_INVALID_VALUE);
2380 	}
2381 
2382 	es2::Context *context = es2::getContext();
2383 
2384 	if(context)
2385 	{
2386 		es2::Program *programObject = context->getProgram(program);
2387 
2388 		if(!programObject)
2389 		{
2390 			if(context->getShader(program))
2391 			{
2392 				return error(GL_INVALID_OPERATION);
2393 			}
2394 			else
2395 			{
2396 				return error(GL_INVALID_VALUE);
2397 			}
2398 		}
2399 
2400 		if(index >= programObject->getActiveAttributeCount())
2401 		{
2402 			return error(GL_INVALID_VALUE);
2403 		}
2404 
2405 		programObject->getActiveAttribute(index, bufsize, length, size, type, name);
2406 	}
2407 }
2408 
GetActiveUniform(GLuint program,GLuint index,GLsizei bufsize,GLsizei * length,GLint * size,GLenum * type,GLchar * name)2409 void GetActiveUniform(GLuint program, GLuint index, GLsizei bufsize, GLsizei* length, GLint* size, GLenum* type, GLchar* name)
2410 {
2411 	TRACE("(GLuint program = %d, GLuint index = %d, GLsizei bufsize = %d, "
2412 	      "GLsizei* length = %p, GLint* size = %p, GLenum* type = %p, GLchar* name = %s)",
2413 	      program, index, bufsize, length, size, type, name);
2414 
2415 	if(bufsize < 0)
2416 	{
2417 		return error(GL_INVALID_VALUE);
2418 	}
2419 
2420 	es2::Context *context = es2::getContext();
2421 
2422 	if(context)
2423 	{
2424 		es2::Program *programObject = context->getProgram(program);
2425 
2426 		if(!programObject)
2427 		{
2428 			if(context->getShader(program))
2429 			{
2430 				return error(GL_INVALID_OPERATION);
2431 			}
2432 			else
2433 			{
2434 				return error(GL_INVALID_VALUE);
2435 			}
2436 		}
2437 
2438 		if(index >= programObject->getActiveUniformCount())
2439 		{
2440 			return error(GL_INVALID_VALUE);
2441 		}
2442 
2443 		programObject->getActiveUniform(index, bufsize, length, size, type, name);
2444 	}
2445 }
2446 
GetAttachedShaders(GLuint program,GLsizei maxcount,GLsizei * count,GLuint * shaders)2447 void GetAttachedShaders(GLuint program, GLsizei maxcount, GLsizei* count, GLuint* shaders)
2448 {
2449 	TRACE("(GLuint program = %d, GLsizei maxcount = %d, GLsizei* count = %p, GLuint* shaders = %p)",
2450 	      program, maxcount, count, shaders);
2451 
2452 	if(maxcount < 0)
2453 	{
2454 		return error(GL_INVALID_VALUE);
2455 	}
2456 
2457 	es2::Context *context = es2::getContext();
2458 
2459 	if(context)
2460 	{
2461 		es2::Program *programObject = context->getProgram(program);
2462 
2463 		if(!programObject)
2464 		{
2465 			if(context->getShader(program))
2466 			{
2467 				return error(GL_INVALID_OPERATION);
2468 			}
2469 			else
2470 			{
2471 				return error(GL_INVALID_VALUE);
2472 			}
2473 		}
2474 
2475 		return programObject->getAttachedShaders(maxcount, count, shaders);
2476 	}
2477 }
2478 
GetAttribLocation(GLuint program,const GLchar * name)2479 int GetAttribLocation(GLuint program, const GLchar* name)
2480 {
2481 	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
2482 
2483 	es2::Context *context = es2::getContext();
2484 
2485 	if(context)
2486 	{
2487 
2488 		es2::Program *programObject = context->getProgram(program);
2489 
2490 		if(!programObject)
2491 		{
2492 			if(context->getShader(program))
2493 			{
2494 				return error(GL_INVALID_OPERATION, -1);
2495 			}
2496 			else
2497 			{
2498 				return error(GL_INVALID_VALUE, -1);
2499 			}
2500 		}
2501 
2502 		if(!programObject->isLinked())
2503 		{
2504 			return error(GL_INVALID_OPERATION, -1);
2505 		}
2506 
2507 		return programObject->getAttributeLocation(name);
2508 	}
2509 
2510 	return -1;
2511 }
2512 
GetBooleanv(GLenum pname,GLboolean * params)2513 void GetBooleanv(GLenum pname, GLboolean* params)
2514 {
2515 	TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)",  pname, params);
2516 
2517 	es2::Context *context = es2::getContext();
2518 
2519 	if(context)
2520 	{
2521 		if(!(context->getBooleanv(pname, params)))
2522 		{
2523 			GLenum nativeType;
2524 			unsigned int numParams = 0;
2525 			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2526 				return error(GL_INVALID_ENUM);
2527 
2528 			if(numParams == 0)
2529 				return; // it is known that the pname is valid, but there are no parameters to return
2530 
2531 			if(nativeType == GL_FLOAT)
2532 			{
2533 				GLfloat *floatParams = nullptr;
2534 				floatParams = new GLfloat[numParams];
2535 
2536 				context->getFloatv(pname, floatParams);
2537 
2538 				for(unsigned int i = 0; i < numParams; ++i)
2539 				{
2540 					if(floatParams[i] == 0.0f)
2541 						params[i] = GL_FALSE;
2542 					else
2543 						params[i] = GL_TRUE;
2544 				}
2545 
2546 				delete [] floatParams;
2547 			}
2548 			else if(nativeType == GL_INT)
2549 			{
2550 				GLint *intParams = nullptr;
2551 				intParams = new GLint[numParams];
2552 
2553 				context->getIntegerv(pname, intParams);
2554 
2555 				for(unsigned int i = 0; i < numParams; ++i)
2556 				{
2557 					if(intParams[i] == 0)
2558 						params[i] = GL_FALSE;
2559 					else
2560 						params[i] = GL_TRUE;
2561 				}
2562 
2563 				delete [] intParams;
2564 			}
2565 		}
2566 	}
2567 }
2568 
GetBufferParameteriv(GLenum target,GLenum pname,GLint * params)2569 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
2570 {
2571 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2572 
2573 	es2::Context *context = es2::getContext();
2574 
2575 	if(context)
2576 	{
2577 		es2::Buffer *buffer;
2578 		if(!context->getBuffer(target, &buffer))
2579 		{
2580 			return error(GL_INVALID_ENUM);
2581 		}
2582 
2583 		if(!buffer)
2584 		{
2585 			// A null buffer means that "0" is bound to the requested buffer target
2586 			return error(GL_INVALID_OPERATION);
2587 		}
2588 
2589 		GLint clientVersion = context->getClientVersion();
2590 
2591 		switch(pname)
2592 		{
2593 		case GL_BUFFER_USAGE:
2594 			*params = buffer->usage();
2595 			break;
2596 		case GL_BUFFER_SIZE:
2597 			*params = (GLint)buffer->size();
2598 			break;
2599 		case GL_BUFFER_ACCESS_FLAGS:
2600 			if(clientVersion >= 3)
2601 			{
2602 				*params = buffer->access();
2603 				break;
2604 			}
2605 			else return error(GL_INVALID_ENUM);
2606 		case GL_BUFFER_MAPPED:
2607 			if(clientVersion >= 3)
2608 			{
2609 				*params = buffer->isMapped();
2610 				break;
2611 			}
2612 			else return error(GL_INVALID_ENUM);
2613 		case GL_BUFFER_MAP_LENGTH:
2614 			if(clientVersion >= 3)
2615 			{
2616 				*params = (GLint)buffer->length();
2617 				break;
2618 			}
2619 			else return error(GL_INVALID_ENUM);
2620 		case GL_BUFFER_MAP_OFFSET:
2621 			if(clientVersion >= 3)
2622 			{
2623 				*params = (GLint)buffer->offset();
2624 				break;
2625 			}
2626 			else return error(GL_INVALID_ENUM);
2627 		default:
2628 			return error(GL_INVALID_ENUM);
2629 		}
2630 	}
2631 }
2632 
GetError(void)2633 GLenum GetError(void)
2634 {
2635 	TRACE("()");
2636 
2637 	es2::Context *context = es2::getContext();
2638 
2639 	if(context)
2640 	{
2641 		return context->getError();
2642 	}
2643 
2644 	return GL_NO_ERROR;
2645 }
2646 
GetFenceivNV(GLuint fence,GLenum pname,GLint * params)2647 void GetFenceivNV(GLuint fence, GLenum pname, GLint *params)
2648 {
2649 	TRACE("(GLuint fence = %d, GLenum pname = 0x%X, GLint *params = %p)", fence, pname, params);
2650 
2651 	es2::Context *context = es2::getContext();
2652 
2653 	if(context)
2654 	{
2655 		es2::Fence *fenceObject = context->getFence(fence);
2656 
2657 		if(!fenceObject)
2658 		{
2659 			return error(GL_INVALID_OPERATION);
2660 		}
2661 
2662 		fenceObject->getFenceiv(pname, params);
2663 	}
2664 }
2665 
GetFloatv(GLenum pname,GLfloat * params)2666 void GetFloatv(GLenum pname, GLfloat* params)
2667 {
2668 	TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2669 
2670 	es2::Context *context = es2::getContext();
2671 
2672 	if(context)
2673 	{
2674 		if(!(context->getFloatv(pname, params)))
2675 		{
2676 			GLenum nativeType;
2677 			unsigned int numParams = 0;
2678 			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
2679 				return error(GL_INVALID_ENUM);
2680 
2681 			if(numParams == 0)
2682 				return; // it is known that the pname is valid, but that there are no parameters to return.
2683 
2684 			if(nativeType == GL_BOOL)
2685 			{
2686 				GLboolean *boolParams = nullptr;
2687 				boolParams = new GLboolean[numParams];
2688 
2689 				context->getBooleanv(pname, boolParams);
2690 
2691 				for(unsigned int i = 0; i < numParams; ++i)
2692 				{
2693 					if(boolParams[i] == GL_FALSE)
2694 						params[i] = 0.0f;
2695 					else
2696 						params[i] = 1.0f;
2697 				}
2698 
2699 				delete [] boolParams;
2700 			}
2701 			else if(nativeType == GL_INT)
2702 			{
2703 				GLint *intParams = nullptr;
2704 				intParams = new GLint[numParams];
2705 
2706 				context->getIntegerv(pname, intParams);
2707 
2708 				for(unsigned int i = 0; i < numParams; ++i)
2709 				{
2710 					params[i] = (GLfloat)intParams[i];
2711 				}
2712 
2713 				delete [] intParams;
2714 			}
2715 		}
2716 	}
2717 }
2718 
GetFramebufferAttachmentParameteriv(GLenum target,GLenum attachment,GLenum pname,GLint * params)2719 void GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2720 {
2721 	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2722 	      target, attachment, pname, params);
2723 
2724 	es2::Context *context = es2::getContext();
2725 
2726 	if(context)
2727 	{
2728 		if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER && target != GL_READ_FRAMEBUFFER)
2729 		{
2730 			return error(GL_INVALID_ENUM);
2731 		}
2732 
2733 		GLint clientVersion = context->getClientVersion();
2734 
2735 		es2::Framebuffer *framebuffer = nullptr;
2736 		if(target == GL_READ_FRAMEBUFFER)
2737 		{
2738 			if(context->getReadFramebufferName() == 0)
2739 			{
2740 				if(clientVersion < 3)
2741 				{
2742 					return error(GL_INVALID_OPERATION);
2743 				}
2744 				else
2745 				{
2746 					switch(attachment)
2747 					{
2748 					case GL_BACK:
2749 					case GL_DEPTH:
2750 					case GL_STENCIL:
2751 						break;
2752 					default:
2753 						return error(GL_INVALID_ENUM);
2754 					}
2755 				}
2756 			}
2757 
2758 			framebuffer = context->getReadFramebuffer();
2759 		}
2760 		else
2761 		{
2762 			if(context->getDrawFramebufferName() == 0)
2763 			{
2764 				if(clientVersion < 3)
2765 				{
2766 					return error(GL_INVALID_OPERATION);
2767 				}
2768 				else
2769 				{
2770 					switch(attachment)
2771 					{
2772 					case GL_BACK:
2773 					case GL_DEPTH:
2774 					case GL_STENCIL:
2775 						break;
2776 					default:
2777 						return error(GL_INVALID_ENUM);
2778 					}
2779 				}
2780 			}
2781 
2782 			framebuffer = context->getDrawFramebuffer();
2783 		}
2784 
2785 		GLenum attachmentType;
2786 		GLuint attachmentHandle;
2787 		GLint attachmentLayer;
2788 		Renderbuffer* renderbuffer = nullptr;
2789 		switch(attachment)
2790 		{
2791 		case GL_BACK:
2792 			if(clientVersion >= 3)
2793 			{
2794 				attachmentType = framebuffer->getColorbufferType(0);
2795 				attachmentHandle = framebuffer->getColorbufferName(0);
2796 				attachmentLayer = framebuffer->getColorbufferLayer(0);
2797 				renderbuffer = framebuffer->getColorbuffer(0);
2798 			}
2799 			else return error(GL_INVALID_ENUM);
2800 			break;
2801 		case GL_COLOR_ATTACHMENT0:
2802 		case GL_COLOR_ATTACHMENT1:
2803 		case GL_COLOR_ATTACHMENT2:
2804 		case GL_COLOR_ATTACHMENT3:
2805 		case GL_COLOR_ATTACHMENT4:
2806 		case GL_COLOR_ATTACHMENT5:
2807 		case GL_COLOR_ATTACHMENT6:
2808 		case GL_COLOR_ATTACHMENT7:
2809 		case GL_COLOR_ATTACHMENT8:
2810 		case GL_COLOR_ATTACHMENT9:
2811 		case GL_COLOR_ATTACHMENT10:
2812 		case GL_COLOR_ATTACHMENT11:
2813 		case GL_COLOR_ATTACHMENT12:
2814 		case GL_COLOR_ATTACHMENT13:
2815 		case GL_COLOR_ATTACHMENT14:
2816 		case GL_COLOR_ATTACHMENT15:
2817 		case GL_COLOR_ATTACHMENT16:
2818 		case GL_COLOR_ATTACHMENT17:
2819 		case GL_COLOR_ATTACHMENT18:
2820 		case GL_COLOR_ATTACHMENT19:
2821 		case GL_COLOR_ATTACHMENT20:
2822 		case GL_COLOR_ATTACHMENT21:
2823 		case GL_COLOR_ATTACHMENT22:
2824 		case GL_COLOR_ATTACHMENT23:
2825 		case GL_COLOR_ATTACHMENT24:
2826 		case GL_COLOR_ATTACHMENT25:
2827 		case GL_COLOR_ATTACHMENT26:
2828 		case GL_COLOR_ATTACHMENT27:
2829 		case GL_COLOR_ATTACHMENT28:
2830 		case GL_COLOR_ATTACHMENT29:
2831 		case GL_COLOR_ATTACHMENT30:
2832 		case GL_COLOR_ATTACHMENT31:
2833 			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
2834 			{
2835 				return error(GL_INVALID_ENUM);
2836 			}
2837 			attachmentType = framebuffer->getColorbufferType(attachment - GL_COLOR_ATTACHMENT0);
2838 			attachmentHandle = framebuffer->getColorbufferName(attachment - GL_COLOR_ATTACHMENT0);
2839 			attachmentLayer = framebuffer->getColorbufferLayer(attachment - GL_COLOR_ATTACHMENT0);
2840 			renderbuffer = framebuffer->getColorbuffer(attachment - GL_COLOR_ATTACHMENT0);
2841 			break;
2842 		case GL_DEPTH:
2843 			if(clientVersion < 3)
2844 			{
2845 				return error(GL_INVALID_ENUM);
2846 			}
2847 			// fall through
2848 		case GL_DEPTH_ATTACHMENT:
2849 			attachmentType = framebuffer->getDepthbufferType();
2850 			attachmentHandle = framebuffer->getDepthbufferName();
2851 			attachmentLayer = framebuffer->getDepthbufferLayer();
2852 			renderbuffer = framebuffer->getDepthbuffer();
2853 			break;
2854 		case GL_STENCIL:
2855 			if(clientVersion < 3)
2856 			{
2857 				return error(GL_INVALID_ENUM);
2858 			}
2859 			// fall through
2860 		case GL_STENCIL_ATTACHMENT:
2861 			attachmentType = framebuffer->getStencilbufferType();
2862 			attachmentHandle = framebuffer->getStencilbufferName();
2863 			attachmentLayer = framebuffer->getStencilbufferLayer();
2864 			renderbuffer = framebuffer->getStencilbuffer();
2865 			break;
2866 		case GL_DEPTH_STENCIL_ATTACHMENT:
2867 			if(clientVersion >= 3)
2868 			{
2869 				attachmentType = framebuffer->getDepthbufferType();
2870 				attachmentHandle = framebuffer->getDepthbufferName();
2871 				attachmentLayer = framebuffer->getDepthbufferLayer();
2872 				if(attachmentHandle != framebuffer->getStencilbufferName())
2873 				{
2874 					// Different attachments to DEPTH and STENCIL, query fails
2875 					return error(GL_INVALID_OPERATION);
2876 				}
2877 				renderbuffer = framebuffer->getDepthbuffer();
2878 			}
2879 			else return error(GL_INVALID_ENUM);
2880 			break;
2881 		default:
2882 			return error(GL_INVALID_ENUM);
2883 		}
2884 
2885 		GLenum attachmentObjectType = GL_NONE;   // Type category
2886 		if(attachmentType == GL_NONE || Framebuffer::IsRenderbuffer(attachmentType))
2887 		{
2888 			attachmentObjectType = attachmentType;
2889 		}
2890 		else if(es2::IsTextureTarget(attachmentType))
2891 		{
2892 			attachmentObjectType = GL_TEXTURE;
2893 		}
2894 		else UNREACHABLE(attachmentType);
2895 
2896 		if(attachmentObjectType != GL_NONE)
2897 		{
2898 			switch(pname)
2899 			{
2900 			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
2901 				*params = attachmentObjectType;
2902 				break;
2903 			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
2904 				if(Framebuffer::IsRenderbuffer(attachmentObjectType) || attachmentObjectType == GL_TEXTURE)
2905 				{
2906 					*params = attachmentHandle;
2907 				}
2908 				else
2909 				{
2910 					return error(GL_INVALID_ENUM);
2911 				}
2912 				break;
2913 			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
2914 				if(attachmentObjectType == GL_TEXTURE)
2915 				{
2916 					*params = clientVersion < 3 ? 0 : renderbuffer->getLevel(); // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2917 				}
2918 				else
2919 				{
2920 					return error(GL_INVALID_ENUM);
2921 				}
2922 				break;
2923 			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
2924 				if(attachmentObjectType == GL_TEXTURE)
2925 				{
2926 					if(es2::IsCubemapTextureTarget(attachmentType))
2927 					{
2928 						*params = attachmentType;
2929 					}
2930 					else
2931 					{
2932 						*params = 0;
2933 					}
2934 				}
2935 				else
2936 				{
2937 					return error(GL_INVALID_ENUM);
2938 				}
2939 				break;
2940 			case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
2941 				if(clientVersion >= 3)
2942 				{
2943 					*params = attachmentLayer;
2944 				}
2945 				else return error(GL_INVALID_ENUM);
2946 				break;
2947 			case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
2948 				if(clientVersion >= 3)
2949 				{
2950 					*params = renderbuffer->getRedSize();
2951 				}
2952 				else return error(GL_INVALID_ENUM);
2953 				break;
2954 			case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
2955 				if(clientVersion >= 3)
2956 				{
2957 					*params = renderbuffer->getGreenSize();
2958 				}
2959 				else return error(GL_INVALID_ENUM);
2960 				break;
2961 			case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
2962 				if(clientVersion >= 3)
2963 				{
2964 					*params = renderbuffer->getBlueSize();
2965 				}
2966 				else return error(GL_INVALID_ENUM);
2967 				break;
2968 			case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
2969 				if(clientVersion >= 3)
2970 				{
2971 					*params = renderbuffer->getAlphaSize();
2972 				}
2973 				else return error(GL_INVALID_ENUM);
2974 				break;
2975 			case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
2976 				if(clientVersion >= 3)
2977 				{
2978 					*params = renderbuffer->getDepthSize();
2979 				}
2980 				else return error(GL_INVALID_ENUM);
2981 				break;
2982 			case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
2983 				if(clientVersion >= 3)
2984 				{
2985 					*params = renderbuffer->getStencilSize();
2986 				}
2987 				else return error(GL_INVALID_ENUM);
2988 				break;
2989 			case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
2990 				if(clientVersion >= 3)
2991 				{
2992 					if(attachment == GL_DEPTH_STENCIL_ATTACHMENT)
2993 					{
2994 						return error(GL_INVALID_OPERATION);
2995 					}
2996 
2997 					*params = sw2es::GetComponentType(renderbuffer->getInternalFormat(), attachment);
2998 				}
2999 				else return error(GL_INVALID_ENUM);
3000 				break;
3001 			case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
3002 				if(clientVersion >= 3)
3003 				{
3004 					*params = GL_LINEAR; // FIXME: GL_SRGB will also be possible, when sRGB is added
3005 				}
3006 				else return error(GL_INVALID_ENUM);
3007 				break;
3008 			default:
3009 				return error(GL_INVALID_ENUM);
3010 			}
3011 		}
3012 		else
3013 		{
3014 			// ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
3015 			// is NONE, then querying any other pname will generate INVALID_ENUM.
3016 
3017 			// ES 3.0.2 spec pg 235 states that if the attachment type is none,
3018 			// GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
3019 			// INVALID_OPERATION for all other pnames
3020 
3021 			switch(pname)
3022 			{
3023 			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
3024 				*params = GL_NONE;
3025 				break;
3026 
3027 			case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
3028 				if(clientVersion < 3)
3029 				{
3030 					return error(GL_INVALID_ENUM);
3031 				}
3032 				*params = 0;
3033 				break;
3034 
3035 			default:
3036 				if(clientVersion < 3)
3037 				{
3038 					return error(GL_INVALID_ENUM);
3039 				}
3040 				else
3041 				{
3042 					return error(GL_INVALID_OPERATION);
3043 				}
3044 			}
3045 		}
3046 	}
3047 }
3048 
GetGraphicsResetStatusEXT(void)3049 GLenum GetGraphicsResetStatusEXT(void)
3050 {
3051 	TRACE("()");
3052 
3053 	return GL_NO_ERROR;
3054 }
3055 
GetIntegerv(GLenum pname,GLint * params)3056 void GetIntegerv(GLenum pname, GLint* params)
3057 {
3058 	TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
3059 
3060 	es2::Context *context = es2::getContext();
3061 
3062 	if(!context)
3063 	{
3064 		// Not strictly an error, but probably unintended or attempting to rely on non-compliant behavior
3065 		#ifdef __ANDROID__
3066 			ALOGI("expected_badness glGetIntegerv() called without current context.");
3067 		#else
3068 			ERR("glGetIntegerv() called without current context.");
3069 		#endif
3070 
3071 		// This is not spec compliant! When there is no current GL context, functions should
3072 		// have no side effects. Google Maps queries these values before creating a context,
3073 		// so we need this as a bug-compatible workaround.
3074 		switch(pname)
3075 		{
3076 		case GL_MAX_TEXTURE_SIZE:                 *params = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE;  return;
3077 		case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:   *params = es2::MAX_VERTEX_TEXTURE_IMAGE_UNITS;   return;
3078 		case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS: *params = es2::MAX_COMBINED_TEXTURE_IMAGE_UNITS; return;
3079 		case GL_STENCIL_BITS:                     *params = 8;                                     return;
3080 		case GL_ALIASED_LINE_WIDTH_RANGE:
3081 			params[0] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MIN;
3082 			params[1] = (GLint)es2::ALIASED_LINE_WIDTH_RANGE_MAX;
3083 			return;
3084 		}
3085 	}
3086 
3087 	if(context)
3088 	{
3089 		if(!(context->getIntegerv(pname, params)))
3090 		{
3091 			GLenum nativeType;
3092 			unsigned int numParams = 0;
3093 			if(!context->getQueryParameterInfo(pname, &nativeType, &numParams))
3094 				return error(GL_INVALID_ENUM);
3095 
3096 			if(numParams == 0)
3097 				return; // it is known that pname is valid, but there are no parameters to return
3098 
3099 			if(nativeType == GL_BOOL)
3100 			{
3101 				GLboolean *boolParams = nullptr;
3102 				boolParams = new GLboolean[numParams];
3103 
3104 				context->getBooleanv(pname, boolParams);
3105 
3106 				for(unsigned int i = 0; i < numParams; ++i)
3107 				{
3108 					params[i] = (boolParams[i] == GL_FALSE) ? 0 : 1;
3109 				}
3110 
3111 				delete [] boolParams;
3112 			}
3113 			else if(nativeType == GL_FLOAT)
3114 			{
3115 				GLfloat *floatParams = nullptr;
3116 				floatParams = new GLfloat[numParams];
3117 
3118 				context->getFloatv(pname, floatParams);
3119 
3120 				for(unsigned int i = 0; i < numParams; ++i)
3121 				{
3122 					if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE || pname == GL_BLEND_COLOR)
3123 					{
3124 						params[i] = convert_float_int(floatParams[i]);
3125 					}
3126 					else
3127 					{
3128 						params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
3129 					}
3130 				}
3131 
3132 				delete [] floatParams;
3133 			}
3134 		}
3135 	}
3136 }
3137 
GetProgramiv(GLuint program,GLenum pname,GLint * params)3138 void GetProgramiv(GLuint program, GLenum pname, GLint* params)
3139 {
3140 	TRACE("(GLuint program = %d, GLenum pname = 0x%X, GLint* params = %p)", program, pname, params);
3141 
3142 	es2::Context *context = es2::getContext();
3143 
3144 	if(context)
3145 	{
3146 		es2::Program *programObject = context->getProgram(program);
3147 
3148 		if(!programObject)
3149 		{
3150 			if(context->getShader(program))
3151 			{
3152 				return error(GL_INVALID_OPERATION);
3153 			}
3154 			else
3155 			{
3156 				return error(GL_INVALID_VALUE);
3157 			}
3158 		}
3159 
3160 		GLint clientVersion = egl::getClientVersion();
3161 
3162 		switch(pname)
3163 		{
3164 		case GL_DELETE_STATUS:
3165 			*params = programObject->isFlaggedForDeletion();
3166 			return;
3167 		case GL_LINK_STATUS:
3168 			*params = programObject->isLinked();
3169 			return;
3170 		case GL_VALIDATE_STATUS:
3171 			*params = programObject->isValidated();
3172 			return;
3173 		case GL_INFO_LOG_LENGTH:
3174 			*params = (GLint)programObject->getInfoLogLength();
3175 			return;
3176 		case GL_ATTACHED_SHADERS:
3177 			*params = programObject->getAttachedShadersCount();
3178 			return;
3179 		case GL_ACTIVE_ATTRIBUTES:
3180 			*params = (GLint)programObject->getActiveAttributeCount();
3181 			return;
3182 		case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
3183 			*params = programObject->getActiveAttributeMaxLength();
3184 			return;
3185 		case GL_ACTIVE_UNIFORMS:
3186 			*params = (GLint)programObject->getActiveUniformCount();
3187 			return;
3188 		case GL_ACTIVE_UNIFORM_MAX_LENGTH:
3189 			*params = programObject->getActiveUniformMaxLength();
3190 			return;
3191 		case GL_ACTIVE_UNIFORM_BLOCKS:
3192 			if(clientVersion >= 3)
3193 			{
3194 				*params = (GLint)programObject->getActiveUniformBlockCount();
3195 				return;
3196 			}
3197 			else return error(GL_INVALID_ENUM);
3198 		case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
3199 			if(clientVersion >= 3)
3200 			{
3201 				*params = programObject->getActiveUniformBlockMaxLength();
3202 				return;
3203 			}
3204 			else return error(GL_INVALID_ENUM);
3205 		case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
3206 			if(clientVersion >= 3)
3207 			{
3208 				*params = programObject->getTransformFeedbackBufferMode();
3209 				return;
3210 			}
3211 			else return error(GL_INVALID_ENUM);
3212 		case GL_TRANSFORM_FEEDBACK_VARYINGS:
3213 			if(clientVersion >= 3)
3214 			{
3215 				*params = programObject->getTransformFeedbackVaryingCount();
3216 				return;
3217 			}
3218 			else return error(GL_INVALID_ENUM);
3219 		case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
3220 			if(clientVersion >= 3)
3221 			{
3222 				*params = programObject->getTransformFeedbackVaryingMaxLength();
3223 				return;
3224 			}
3225 			else return error(GL_INVALID_ENUM);
3226 		case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
3227 			if(clientVersion >= 3)
3228 			{
3229 				*params = programObject->getBinaryRetrievableHint();
3230 				return;
3231 			}
3232 			else return error(GL_INVALID_ENUM);
3233 		case GL_PROGRAM_BINARY_LENGTH:
3234 			if(clientVersion >= 3)
3235 			{
3236 				*params = programObject->getBinaryLength();
3237 				return;
3238 			}
3239 			else return error(GL_INVALID_ENUM);
3240 		default:
3241 			return error(GL_INVALID_ENUM);
3242 		}
3243 	}
3244 }
3245 
GetProgramInfoLog(GLuint program,GLsizei bufsize,GLsizei * length,GLchar * infolog)3246 void GetProgramInfoLog(GLuint program, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3247 {
3248 	TRACE("(GLuint program = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3249 	      program, bufsize, length, infolog);
3250 
3251 	if(bufsize < 0)
3252 	{
3253 		return error(GL_INVALID_VALUE);
3254 	}
3255 
3256 	es2::Context *context = es2::getContext();
3257 
3258 	if(context)
3259 	{
3260 		es2::Program *programObject = context->getProgram(program);
3261 
3262 		if(!programObject)
3263 		{
3264 			if(context->getShader(program))
3265 			{
3266 				return error(GL_INVALID_OPERATION);
3267 			}
3268 			else
3269 			{
3270 				return error(GL_INVALID_VALUE);
3271 			}
3272 		}
3273 
3274 		programObject->getInfoLog(bufsize, length, infolog);
3275 	}
3276 }
3277 
GetQueryivEXT(GLenum target,GLenum pname,GLint * params)3278 void GetQueryivEXT(GLenum target, GLenum pname, GLint *params)
3279 {
3280 	TRACE("GLenum target = 0x%X, GLenum pname = 0x%X, GLint *params = %p)", target, pname, params);
3281 
3282 	switch(pname)
3283 	{
3284 	case GL_CURRENT_QUERY_EXT:
3285 		break;
3286 	default:
3287 		return error(GL_INVALID_ENUM);
3288 	}
3289 
3290 	es2::Context *context = es2::getContext();
3291 
3292 	if(context)
3293 	{
3294 		params[0] = context->getActiveQuery(target);
3295 	}
3296 }
3297 
GetQueryObjectuivEXT(GLuint name,GLenum pname,GLuint * params)3298 void GetQueryObjectuivEXT(GLuint name, GLenum pname, GLuint *params)
3299 {
3300 	TRACE("(GLuint name = %d, GLenum pname = 0x%X, GLuint *params = %p)", name, pname, params);
3301 
3302 	switch(pname)
3303 	{
3304 	case GL_QUERY_RESULT_EXT:
3305 	case GL_QUERY_RESULT_AVAILABLE_EXT:
3306 		break;
3307 	default:
3308 		return error(GL_INVALID_ENUM);
3309 	}
3310 
3311 	es2::Context *context = es2::getContext();
3312 
3313 	if(context)
3314 	{
3315 		es2::Query *queryObject = context->getQuery(name);
3316 
3317 		if(!queryObject)
3318 		{
3319 			return error(GL_INVALID_OPERATION);
3320 		}
3321 
3322 		if(context->getActiveQuery(queryObject->getType()) == name)
3323 		{
3324 			return error(GL_INVALID_OPERATION);
3325 		}
3326 
3327 		switch(pname)
3328 		{
3329 		case GL_QUERY_RESULT_EXT:
3330 			params[0] = queryObject->getResult();
3331 			break;
3332 		case GL_QUERY_RESULT_AVAILABLE_EXT:
3333 			params[0] = queryObject->isResultAvailable();
3334 			break;
3335 		default:
3336 			ASSERT(false);
3337 		}
3338 	}
3339 }
3340 
GetRenderbufferParameteriv(GLenum target,GLenum pname,GLint * params)3341 void GetRenderbufferParameteriv(GLenum target, GLenum pname, GLint* params)
3342 {
3343 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3344 
3345 	es2::Context *context = es2::getContext();
3346 
3347 	if(context)
3348 	{
3349 		if(target != GL_RENDERBUFFER)
3350 		{
3351 			return error(GL_INVALID_ENUM);
3352 		}
3353 
3354 		if(context->getRenderbufferName() == 0)
3355 		{
3356 			return error(GL_INVALID_OPERATION);
3357 		}
3358 
3359 		es2::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
3360 
3361 		switch(pname)
3362 		{
3363 		case GL_RENDERBUFFER_WIDTH:           *params = renderbuffer->getWidth();       break;
3364 		case GL_RENDERBUFFER_HEIGHT:          *params = renderbuffer->getHeight();      break;
3365 		case GL_RENDERBUFFER_INTERNAL_FORMAT: *params = renderbuffer->getFormat();      break;
3366 		case GL_RENDERBUFFER_RED_SIZE:        *params = renderbuffer->getRedSize();     break;
3367 		case GL_RENDERBUFFER_GREEN_SIZE:      *params = renderbuffer->getGreenSize();   break;
3368 		case GL_RENDERBUFFER_BLUE_SIZE:       *params = renderbuffer->getBlueSize();    break;
3369 		case GL_RENDERBUFFER_ALPHA_SIZE:      *params = renderbuffer->getAlphaSize();   break;
3370 		case GL_RENDERBUFFER_DEPTH_SIZE:      *params = renderbuffer->getDepthSize();   break;
3371 		case GL_RENDERBUFFER_STENCIL_SIZE:    *params = renderbuffer->getStencilSize(); break;
3372 		case GL_RENDERBUFFER_SAMPLES_ANGLE:   *params = renderbuffer->getSamples();     break;
3373 		default:
3374 			return error(GL_INVALID_ENUM);
3375 		}
3376 	}
3377 }
3378 
GetShaderiv(GLuint shader,GLenum pname,GLint * params)3379 void GetShaderiv(GLuint shader, GLenum pname, GLint* params)
3380 {
3381 	TRACE("(GLuint shader = %d, GLenum pname = %d, GLint* params = %p)", shader, pname, params);
3382 
3383 	es2::Context *context = es2::getContext();
3384 
3385 	if(context)
3386 	{
3387 		es2::Shader *shaderObject = context->getShader(shader);
3388 
3389 		if(!shaderObject)
3390 		{
3391 			if(context->getProgram(shader))
3392 			{
3393 				return error(GL_INVALID_OPERATION);
3394 			}
3395 			else
3396 			{
3397 				return error(GL_INVALID_VALUE);
3398 			}
3399 		}
3400 
3401 		switch(pname)
3402 		{
3403 		case GL_SHADER_TYPE:
3404 			*params = shaderObject->getType();
3405 			return;
3406 		case GL_DELETE_STATUS:
3407 			*params = shaderObject->isFlaggedForDeletion();
3408 			return;
3409 		case GL_COMPILE_STATUS:
3410 			*params = shaderObject->isCompiled() ? GL_TRUE : GL_FALSE;
3411 			return;
3412 		case GL_INFO_LOG_LENGTH:
3413 			*params = (GLint)shaderObject->getInfoLogLength();
3414 			return;
3415 		case GL_SHADER_SOURCE_LENGTH:
3416 			*params = (GLint)shaderObject->getSourceLength();
3417 			return;
3418 		default:
3419 			return error(GL_INVALID_ENUM);
3420 		}
3421 	}
3422 }
3423 
GetShaderInfoLog(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * infolog)3424 void GetShaderInfoLog(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* infolog)
3425 {
3426 	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* infolog = %p)",
3427 	      shader, bufsize, length, infolog);
3428 
3429 	if(bufsize < 0)
3430 	{
3431 		return error(GL_INVALID_VALUE);
3432 	}
3433 
3434 	es2::Context *context = es2::getContext();
3435 
3436 	if(context)
3437 	{
3438 		es2::Shader *shaderObject = context->getShader(shader);
3439 
3440 		if(!shaderObject)
3441 		{
3442 			if(context->getProgram(shader))
3443 			{
3444 				return error(GL_INVALID_OPERATION);
3445 			}
3446 			else
3447 			{
3448 				return error(GL_INVALID_VALUE);
3449 			}
3450 		}
3451 
3452 		shaderObject->getInfoLog(bufsize, length, infolog);
3453 	}
3454 }
3455 
GetShaderPrecisionFormat(GLenum shadertype,GLenum precisiontype,GLint * range,GLint * precision)3456 void GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision)
3457 {
3458 	TRACE("(GLenum shadertype = 0x%X, GLenum precisiontype = 0x%X, GLint* range = %p, GLint* precision = %p)",
3459 	      shadertype, precisiontype, range, precision);
3460 
3461 	switch(shadertype)
3462 	{
3463 	case GL_VERTEX_SHADER:
3464 	case GL_FRAGMENT_SHADER:
3465 		break;
3466 	default:
3467 		return error(GL_INVALID_ENUM);
3468 	}
3469 
3470 	switch(precisiontype)
3471 	{
3472 	case GL_LOW_FLOAT:
3473 	case GL_MEDIUM_FLOAT:
3474 	case GL_HIGH_FLOAT:
3475 		// IEEE 754 single-precision
3476 		range[0] = 127;
3477 		range[1] = 127;
3478 		*precision = 23;
3479 		break;
3480 	case GL_LOW_INT:
3481 	case GL_MEDIUM_INT:
3482 	case GL_HIGH_INT:
3483 		// Full integer precision is supported
3484 		range[0] = 31;
3485 		range[1] = 30;
3486 		*precision = 0;
3487 		break;
3488 	default:
3489 		return error(GL_INVALID_ENUM);
3490 	}
3491 }
3492 
GetShaderSource(GLuint shader,GLsizei bufsize,GLsizei * length,GLchar * source)3493 void GetShaderSource(GLuint shader, GLsizei bufsize, GLsizei* length, GLchar* source)
3494 {
3495 	TRACE("(GLuint shader = %d, GLsizei bufsize = %d, GLsizei* length = %p, GLchar* source = %p)",
3496 	      shader, bufsize, length, source);
3497 
3498 	if(bufsize < 0)
3499 	{
3500 		return error(GL_INVALID_VALUE);
3501 	}
3502 
3503 	es2::Context *context = es2::getContext();
3504 
3505 	if(context)
3506 	{
3507 		es2::Shader *shaderObject = context->getShader(shader);
3508 
3509 		if(!shaderObject)
3510 		{
3511 			if(context->getProgram(shader))
3512 			{
3513 				return error(GL_INVALID_OPERATION);
3514 			}
3515 			else
3516 			{
3517 				return error(GL_INVALID_VALUE);
3518 			}
3519 		}
3520 
3521 		shaderObject->getSource(bufsize, length, source);
3522 	}
3523 }
3524 
GetString(GLenum name)3525 const GLubyte* GetString(GLenum name)
3526 {
3527 	TRACE("(GLenum name = 0x%X)", name);
3528 
3529 	switch(name)
3530 	{
3531 	case GL_VENDOR:
3532 		return (GLubyte*)"Google Inc.";
3533 	case GL_RENDERER:
3534 		return (GLubyte*)"Google SwiftShader";
3535 	case GL_VERSION:
3536 	{
3537 		es2::Context *context = es2::getContext();
3538 		return (context && (context->getClientVersion() >= 3)) ?
3539 		       (GLubyte*)"OpenGL ES 3.0 SwiftShader " VERSION_STRING :
3540 		       (GLubyte*)"OpenGL ES 2.0 SwiftShader " VERSION_STRING;
3541 	}
3542 	case GL_SHADING_LANGUAGE_VERSION:
3543 	{
3544 		es2::Context *context = es2::getContext();
3545 		return (context && (context->getClientVersion() >= 3)) ?
3546 		       (GLubyte*)"OpenGL ES GLSL ES 3.00 SwiftShader " VERSION_STRING :
3547 		       (GLubyte*)"OpenGL ES GLSL ES 1.00 SwiftShader " VERSION_STRING;
3548 	}
3549 	case GL_EXTENSIONS:
3550 	{
3551 		es2::Context *context = es2::getContext();
3552 		return context ? context->getExtensions(GL_INVALID_INDEX) : (GLubyte*)nullptr;
3553 	}
3554 	default:
3555 		return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
3556 	}
3557 }
3558 
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)3559 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
3560 {
3561 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
3562 
3563 	es2::Context *context = es2::getContext();
3564 
3565 	if(context)
3566 	{
3567 		es2::Texture *texture;
3568 
3569 		GLint clientVersion = context->getClientVersion();
3570 
3571 		switch(target)
3572 		{
3573 		case GL_TEXTURE_2D:
3574 			texture = context->getTexture2D();
3575 			break;
3576 		case GL_TEXTURE_CUBE_MAP:
3577 			texture = context->getTextureCubeMap();
3578 			break;
3579 		case GL_TEXTURE_EXTERNAL_OES:
3580 			texture = context->getTextureExternal();
3581 			break;
3582 		case GL_TEXTURE_2D_ARRAY:
3583 			if(clientVersion < 3)
3584 			{
3585 				return error(GL_INVALID_ENUM);
3586 			}
3587 			else
3588 			{
3589 				texture = context->getTexture2DArray();
3590 			}
3591 			break;
3592 		case GL_TEXTURE_3D_OES:
3593 			texture = context->getTexture3D();
3594 			break;
3595 		default:
3596 			return error(GL_INVALID_ENUM);
3597 		}
3598 
3599 		switch(pname)
3600 		{
3601 		case GL_TEXTURE_MAG_FILTER:
3602 			*params = (GLfloat)texture->getMagFilter();
3603 			break;
3604 		case GL_TEXTURE_MIN_FILTER:
3605 			*params = (GLfloat)texture->getMinFilter();
3606 			break;
3607 		case GL_TEXTURE_WRAP_S:
3608 			*params = (GLfloat)texture->getWrapS();
3609 			break;
3610 		case GL_TEXTURE_WRAP_T:
3611 			*params = (GLfloat)texture->getWrapT();
3612 			break;
3613 		case GL_TEXTURE_WRAP_R_OES:
3614 			*params = (GLfloat)texture->getWrapR();
3615 			break;
3616 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3617 			*params = texture->getMaxAnisotropy();
3618 			break;
3619 		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3620 			*params = (GLfloat)1;
3621 			break;
3622 		case GL_TEXTURE_BASE_LEVEL:
3623 			if(clientVersion >= 3)
3624 			{
3625 				*params = (GLfloat)texture->getBaseLevel();
3626 				break;
3627 			}
3628 			else return error(GL_INVALID_ENUM);
3629 		case GL_TEXTURE_COMPARE_FUNC:
3630 			if(clientVersion >= 3)
3631 			{
3632 				*params = (GLfloat)texture->getCompareFunc();
3633 				break;
3634 			}
3635 			else return error(GL_INVALID_ENUM);
3636 		case GL_TEXTURE_COMPARE_MODE:
3637 			if(clientVersion >= 3)
3638 			{
3639 				*params = (GLfloat)texture->getCompareMode();
3640 				break;
3641 			}
3642 			else return error(GL_INVALID_ENUM);
3643 		case GL_TEXTURE_IMMUTABLE_FORMAT:
3644 			if(clientVersion >= 3)
3645 			{
3646 				*params = (GLfloat)texture->getImmutableFormat();
3647 				break;
3648 			}
3649 			else return error(GL_INVALID_ENUM);
3650 		case GL_TEXTURE_IMMUTABLE_LEVELS:
3651 			if(clientVersion >= 3)
3652 			{
3653 				*params = (GLfloat)texture->getImmutableLevels();
3654 				break;
3655 			}
3656 			else return error(GL_INVALID_ENUM);
3657 		case GL_TEXTURE_MAX_LEVEL:
3658 			if(clientVersion >= 3)
3659 			{
3660 				*params = (GLfloat)texture->getMaxLevel();
3661 				break;
3662 			}
3663 			else return error(GL_INVALID_ENUM);
3664 		case GL_TEXTURE_MAX_LOD:
3665 			if(clientVersion >= 3)
3666 			{
3667 				*params = texture->getMaxLOD();
3668 				break;
3669 			}
3670 			else return error(GL_INVALID_ENUM);
3671 		case GL_TEXTURE_MIN_LOD:
3672 			if(clientVersion >= 3)
3673 			{
3674 				*params = texture->getMinLOD();
3675 				break;
3676 			}
3677 			else return error(GL_INVALID_ENUM);
3678 		case GL_TEXTURE_SWIZZLE_R:
3679 			if(clientVersion >= 3)
3680 			{
3681 				*params = (GLfloat)texture->getSwizzleR();
3682 				break;
3683 			}
3684 			else return error(GL_INVALID_ENUM);
3685 		case GL_TEXTURE_SWIZZLE_G:
3686 			if(clientVersion >= 3)
3687 			{
3688 				*params = (GLfloat)texture->getSwizzleG();
3689 				break;
3690 			}
3691 			else return error(GL_INVALID_ENUM);
3692 		case GL_TEXTURE_SWIZZLE_B:
3693 			if(clientVersion >= 3)
3694 			{
3695 				*params = (GLfloat)texture->getSwizzleB();
3696 				break;
3697 			}
3698 			else return error(GL_INVALID_ENUM);
3699 		case GL_TEXTURE_SWIZZLE_A:
3700 			if(clientVersion >= 3)
3701 			{
3702 				*params = (GLfloat)texture->getSwizzleA();
3703 				break;
3704 			}
3705 			else return error(GL_INVALID_ENUM);
3706 		default:
3707 			return error(GL_INVALID_ENUM);
3708 		}
3709 	}
3710 }
3711 
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)3712 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
3713 {
3714 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
3715 
3716 	es2::Context *context = es2::getContext();
3717 
3718 	if(context)
3719 	{
3720 		es2::Texture *texture;
3721 
3722 		GLint clientVersion = context->getClientVersion();
3723 
3724 		switch(target)
3725 		{
3726 		case GL_TEXTURE_2D:
3727 			texture = context->getTexture2D();
3728 			break;
3729 		case GL_TEXTURE_CUBE_MAP:
3730 			texture = context->getTextureCubeMap();
3731 			break;
3732 		case GL_TEXTURE_EXTERNAL_OES:
3733 			texture = context->getTextureExternal();
3734 			break;
3735 		case GL_TEXTURE_2D_ARRAY:
3736 			if(clientVersion < 3)
3737 			{
3738 				return error(GL_INVALID_ENUM);
3739 			}
3740 			else
3741 			{
3742 				texture = context->getTexture2DArray();
3743 			}
3744 			break;
3745 		case GL_TEXTURE_3D_OES:
3746 			texture = context->getTexture3D();
3747 			break;
3748 		default:
3749 			return error(GL_INVALID_ENUM);
3750 		}
3751 
3752 		switch(pname)
3753 		{
3754 		case GL_TEXTURE_MAG_FILTER:
3755 			*params = texture->getMagFilter();
3756 			break;
3757 		case GL_TEXTURE_MIN_FILTER:
3758 			*params = texture->getMinFilter();
3759 			break;
3760 		case GL_TEXTURE_WRAP_S:
3761 			*params = texture->getWrapS();
3762 			break;
3763 		case GL_TEXTURE_WRAP_T:
3764 			*params = texture->getWrapT();
3765 			break;
3766 		case GL_TEXTURE_WRAP_R_OES:
3767 			*params = texture->getWrapR();
3768 			break;
3769 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3770 			*params = (GLint)texture->getMaxAnisotropy();
3771 			break;
3772 		case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3773 			*params = 1;
3774 			break;
3775 		case GL_TEXTURE_BASE_LEVEL:
3776 			if(clientVersion >= 3)
3777 			{
3778 				*params = texture->getBaseLevel();
3779 				break;
3780 			}
3781 			else return error(GL_INVALID_ENUM);
3782 		case GL_TEXTURE_COMPARE_FUNC:
3783 			if(clientVersion >= 3)
3784 			{
3785 				*params = (GLint)texture->getCompareFunc();
3786 				break;
3787 			}
3788 			else return error(GL_INVALID_ENUM);
3789 		case GL_TEXTURE_COMPARE_MODE:
3790 			if(clientVersion >= 3)
3791 			{
3792 				*params = (GLint)texture->getCompareMode();
3793 				break;
3794 			}
3795 			else return error(GL_INVALID_ENUM);
3796 		case GL_TEXTURE_IMMUTABLE_FORMAT:
3797 			if(clientVersion >= 3)
3798 			{
3799 				*params = (GLint)texture->getImmutableFormat();
3800 				break;
3801 			}
3802 			else return error(GL_INVALID_ENUM);
3803 		case GL_TEXTURE_IMMUTABLE_LEVELS:
3804 			if(clientVersion >= 3)
3805 			{
3806 				*params = (GLint)texture->getImmutableLevels();
3807 				break;
3808 			}
3809 			else return error(GL_INVALID_ENUM);
3810 		case GL_TEXTURE_MAX_LEVEL:
3811 			if(clientVersion >= 3)
3812 			{
3813 				*params = texture->getMaxLevel();
3814 				break;
3815 			}
3816 			else return error(GL_INVALID_ENUM);
3817 		case GL_TEXTURE_MAX_LOD:
3818 			if(clientVersion >= 3)
3819 			{
3820 				*params = (GLint)roundf(texture->getMaxLOD());
3821 				break;
3822 			}
3823 			else return error(GL_INVALID_ENUM);
3824 		case GL_TEXTURE_MIN_LOD:
3825 			if(clientVersion >= 3)
3826 			{
3827 				*params = (GLint)roundf(texture->getMinLOD());
3828 				break;
3829 			}
3830 			else return error(GL_INVALID_ENUM);
3831 		case GL_TEXTURE_SWIZZLE_R:
3832 			if(clientVersion >= 3)
3833 			{
3834 				*params = (GLint)texture->getSwizzleR();
3835 				break;
3836 			}
3837 			else return error(GL_INVALID_ENUM);
3838 		case GL_TEXTURE_SWIZZLE_G:
3839 			if(clientVersion >= 3)
3840 			{
3841 				*params = (GLint)texture->getSwizzleG();
3842 				break;
3843 			}
3844 			else return error(GL_INVALID_ENUM);
3845 		case GL_TEXTURE_SWIZZLE_B:
3846 			if(clientVersion >= 3)
3847 			{
3848 				*params = (GLint)texture->getSwizzleB();
3849 				break;
3850 			}
3851 			else return error(GL_INVALID_ENUM);
3852 		case GL_TEXTURE_SWIZZLE_A:
3853 			if(clientVersion >= 3)
3854 			{
3855 				*params = (GLint)texture->getSwizzleA();
3856 				break;
3857 			}
3858 			else return error(GL_INVALID_ENUM);
3859 		default:
3860 			return error(GL_INVALID_ENUM);
3861 		}
3862 	}
3863 }
3864 
GetnUniformfvEXT(GLuint program,GLint location,GLsizei bufSize,GLfloat * params)3865 void GetnUniformfvEXT(GLuint program, GLint location, GLsizei bufSize, GLfloat* params)
3866 {
3867 	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLfloat* params = %p)",
3868 	      program, location, bufSize, params);
3869 
3870 	if(bufSize < 0)
3871 	{
3872 		return error(GL_INVALID_VALUE);
3873 	}
3874 
3875 	es2::Context *context = es2::getContext();
3876 
3877 	if(context)
3878 	{
3879 		if(program == 0)
3880 		{
3881 			return error(GL_INVALID_VALUE);
3882 		}
3883 
3884 		es2::Program *programObject = context->getProgram(program);
3885 
3886 		if(!programObject || !programObject->isLinked())
3887 		{
3888 			return error(GL_INVALID_OPERATION);
3889 		}
3890 
3891 		if(!programObject->getUniformfv(location, &bufSize, params))
3892 		{
3893 			return error(GL_INVALID_OPERATION);
3894 		}
3895 	}
3896 }
3897 
GetUniformfv(GLuint program,GLint location,GLfloat * params)3898 void GetUniformfv(GLuint program, GLint location, GLfloat* params)
3899 {
3900 	TRACE("(GLuint program = %d, GLint location = %d, GLfloat* params = %p)", program, location, params);
3901 
3902 	es2::Context *context = es2::getContext();
3903 
3904 	if(context)
3905 	{
3906 		if(program == 0)
3907 		{
3908 			return error(GL_INVALID_VALUE);
3909 		}
3910 
3911 		es2::Program *programObject = context->getProgram(program);
3912 
3913 		if(!programObject || !programObject->isLinked())
3914 		{
3915 			return error(GL_INVALID_OPERATION);
3916 		}
3917 
3918 		if(!programObject->getUniformfv(location, nullptr, params))
3919 		{
3920 			return error(GL_INVALID_OPERATION);
3921 		}
3922 	}
3923 }
3924 
GetnUniformivEXT(GLuint program,GLint location,GLsizei bufSize,GLint * params)3925 void GetnUniformivEXT(GLuint program, GLint location, GLsizei bufSize, GLint* params)
3926 {
3927 	TRACE("(GLuint program = %d, GLint location = %d, GLsizei bufSize = %d, GLint* params = %p)",
3928 	      program, location, bufSize, params);
3929 
3930 	if(bufSize < 0)
3931 	{
3932 		return error(GL_INVALID_VALUE);
3933 	}
3934 
3935 	es2::Context *context = es2::getContext();
3936 
3937 	if(context)
3938 	{
3939 		if(program == 0)
3940 		{
3941 			return error(GL_INVALID_VALUE);
3942 		}
3943 
3944 		es2::Program *programObject = context->getProgram(program);
3945 
3946 		if(!programObject || !programObject->isLinked())
3947 		{
3948 			return error(GL_INVALID_OPERATION);
3949 		}
3950 
3951 		if(!programObject)
3952 		{
3953 			return error(GL_INVALID_OPERATION);
3954 		}
3955 
3956 		if(!programObject->getUniformiv(location, &bufSize, params))
3957 		{
3958 			return error(GL_INVALID_OPERATION);
3959 		}
3960 	}
3961 }
3962 
GetUniformiv(GLuint program,GLint location,GLint * params)3963 void GetUniformiv(GLuint program, GLint location, GLint* params)
3964 {
3965 	TRACE("(GLuint program = %d, GLint location = %d, GLint* params = %p)", program, location, params);
3966 
3967 	es2::Context *context = es2::getContext();
3968 
3969 	if(context)
3970 	{
3971 		if(program == 0)
3972 		{
3973 			return error(GL_INVALID_VALUE);
3974 		}
3975 
3976 		es2::Program *programObject = context->getProgram(program);
3977 
3978 		if(!programObject || !programObject->isLinked())
3979 		{
3980 			return error(GL_INVALID_OPERATION);
3981 		}
3982 
3983 		if(!programObject)
3984 		{
3985 			return error(GL_INVALID_OPERATION);
3986 		}
3987 
3988 		if(!programObject->getUniformiv(location, nullptr, params))
3989 		{
3990 			return error(GL_INVALID_OPERATION);
3991 		}
3992 	}
3993 }
3994 
GetUniformLocation(GLuint program,const GLchar * name)3995 int GetUniformLocation(GLuint program, const GLchar* name)
3996 {
3997 	TRACE("(GLuint program = %d, const GLchar* name = %s)", program, name);
3998 
3999 	es2::Context *context = es2::getContext();
4000 
4001 	if(strstr(name, "gl_") == name)
4002 	{
4003 		return -1;
4004 	}
4005 
4006 	if(context)
4007 	{
4008 		es2::Program *programObject = context->getProgram(program);
4009 
4010 		if(!programObject)
4011 		{
4012 			if(context->getShader(program))
4013 			{
4014 				return error(GL_INVALID_OPERATION, -1);
4015 			}
4016 			else
4017 			{
4018 				return error(GL_INVALID_VALUE, -1);
4019 			}
4020 		}
4021 
4022 		if(!programObject->isLinked())
4023 		{
4024 			return error(GL_INVALID_OPERATION, -1);
4025 		}
4026 
4027 		return programObject->getUniformLocation(name);
4028 	}
4029 
4030 	return -1;
4031 }
4032 
GetVertexAttribfv(GLuint index,GLenum pname,GLfloat * params)4033 void GetVertexAttribfv(GLuint index, GLenum pname, GLfloat* params)
4034 {
4035 	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLfloat* params = %p)", index, pname, params);
4036 
4037 	es2::Context *context = es2::getContext();
4038 
4039 	if(context)
4040 	{
4041 		if(index >= es2::MAX_VERTEX_ATTRIBS)
4042 		{
4043 			return error(GL_INVALID_VALUE);
4044 		}
4045 
4046 		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4047 
4048 		GLint clientVersion = context->getClientVersion();
4049 
4050 		switch(pname)
4051 		{
4052 		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4053 			*params = (GLfloat)(attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4054 			break;
4055 		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4056 			*params = (GLfloat)attribState.mSize;
4057 			break;
4058 		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4059 			*params = (GLfloat)attribState.mStride;
4060 			break;
4061 		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4062 			*params = (GLfloat)attribState.mType;
4063 			break;
4064 		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4065 			*params = (GLfloat)(attribState.mNormalized ? GL_TRUE : GL_FALSE);
4066 			break;
4067 		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4068 			*params = (GLfloat)attribState.mBoundBuffer.name();
4069 			break;
4070 		case GL_CURRENT_VERTEX_ATTRIB:
4071 			{
4072 				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4073 				for(int i = 0; i < 4; ++i)
4074 				{
4075 					params[i] = attrib.getCurrentValueF(i);
4076 				}
4077 			}
4078 			break;
4079 		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4080 			if(clientVersion >= 3)
4081 			{
4082 				switch(attribState.mType)
4083 				{
4084 				case GL_BYTE:
4085 				case GL_UNSIGNED_BYTE:
4086 				case GL_SHORT:
4087 				case GL_UNSIGNED_SHORT:
4088 				case GL_INT:
4089 				case GL_INT_2_10_10_10_REV:
4090 				case GL_UNSIGNED_INT:
4091 				case GL_FIXED:
4092 					*params = (GLfloat)GL_TRUE;
4093 					break;
4094 				default:
4095 					*params = (GLfloat)GL_FALSE;
4096 					break;
4097 				}
4098 				break;
4099 			}
4100 			else return error(GL_INVALID_ENUM);
4101 		default: return error(GL_INVALID_ENUM);
4102 		}
4103 	}
4104 }
4105 
GetVertexAttribiv(GLuint index,GLenum pname,GLint * params)4106 void GetVertexAttribiv(GLuint index, GLenum pname, GLint* params)
4107 {
4108 	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLint* params = %p)", index, pname, params);
4109 
4110 	es2::Context *context = es2::getContext();
4111 
4112 	if(context)
4113 	{
4114 		if(index >= es2::MAX_VERTEX_ATTRIBS)
4115 		{
4116 			return error(GL_INVALID_VALUE);
4117 		}
4118 
4119 		const es2::VertexAttribute &attribState = context->getVertexAttribState(index);
4120 
4121 		GLint clientVersion = context->getClientVersion();
4122 
4123 		switch(pname)
4124 		{
4125 		case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
4126 			*params = (attribState.mArrayEnabled ? GL_TRUE : GL_FALSE);
4127 			break;
4128 		case GL_VERTEX_ATTRIB_ARRAY_SIZE:
4129 			*params = attribState.mSize;
4130 			break;
4131 		case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
4132 			*params = attribState.mStride;
4133 			break;
4134 		case GL_VERTEX_ATTRIB_ARRAY_TYPE:
4135 			*params = attribState.mType;
4136 			break;
4137 		case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
4138 			*params = (attribState.mNormalized ? GL_TRUE : GL_FALSE);
4139 			break;
4140 		case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
4141 			*params = attribState.mBoundBuffer.name();
4142 			break;
4143 		case GL_CURRENT_VERTEX_ATTRIB:
4144 			{
4145 				const VertexAttribute& attrib = context->getCurrentVertexAttributes()[index];
4146 				for(int i = 0; i < 4; ++i)
4147 				{
4148 					float currentValue = attrib.getCurrentValueF(i);
4149 					params[i] = (GLint)(currentValue > 0.0f ? floor(currentValue + 0.5f) : ceil(currentValue - 0.5f));
4150 				}
4151 			}
4152 			break;
4153 		case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
4154 			if(clientVersion >= 3)
4155 			{
4156 				switch(attribState.mType)
4157 				{
4158 				case GL_BYTE:
4159 				case GL_UNSIGNED_BYTE:
4160 				case GL_SHORT:
4161 				case GL_UNSIGNED_SHORT:
4162 				case GL_INT:
4163 				case GL_INT_2_10_10_10_REV:
4164 				case GL_UNSIGNED_INT:
4165 				case GL_FIXED:
4166 					*params = GL_TRUE;
4167 					break;
4168 				default:
4169 					*params = GL_FALSE;
4170 					break;
4171 				}
4172 				break;
4173 			}
4174 			else return error(GL_INVALID_ENUM);
4175 		default: return error(GL_INVALID_ENUM);
4176 		}
4177 	}
4178 }
4179 
GetVertexAttribPointerv(GLuint index,GLenum pname,GLvoid ** pointer)4180 void GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid** pointer)
4181 {
4182 	TRACE("(GLuint index = %d, GLenum pname = 0x%X, GLvoid** pointer = %p)", index, pname, pointer);
4183 
4184 	es2::Context *context = es2::getContext();
4185 
4186 	if(context)
4187 	{
4188 		if(index >= es2::MAX_VERTEX_ATTRIBS)
4189 		{
4190 			return error(GL_INVALID_VALUE);
4191 		}
4192 
4193 		if(pname != GL_VERTEX_ATTRIB_ARRAY_POINTER)
4194 		{
4195 			return error(GL_INVALID_ENUM);
4196 		}
4197 
4198 		*pointer = const_cast<GLvoid*>(context->getVertexAttribPointer(index));
4199 	}
4200 }
4201 
Hint(GLenum target,GLenum mode)4202 void Hint(GLenum target, GLenum mode)
4203 {
4204 	TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
4205 
4206 	switch(mode)
4207 	{
4208 	case GL_FASTEST:
4209 	case GL_NICEST:
4210 	case GL_DONT_CARE:
4211 		break;
4212 	default:
4213 		return error(GL_INVALID_ENUM);
4214 	}
4215 
4216 	es2::Context *context = es2::getContext();
4217 	switch(target)
4218 	{
4219 	case GL_GENERATE_MIPMAP_HINT:
4220 		if(context) context->setGenerateMipmapHint(mode);
4221 		break;
4222 	case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES:
4223 		if(context) context->setFragmentShaderDerivativeHint(mode);
4224 		break;
4225 	default:
4226 		return error(GL_INVALID_ENUM);
4227 	}
4228 }
4229 
IsBuffer(GLuint buffer)4230 GLboolean IsBuffer(GLuint buffer)
4231 {
4232 	TRACE("(GLuint buffer = %d)", buffer);
4233 
4234 	es2::Context *context = es2::getContext();
4235 
4236 	if(context && buffer)
4237 	{
4238 		es2::Buffer *bufferObject = context->getBuffer(buffer);
4239 
4240 		if(bufferObject)
4241 		{
4242 			return GL_TRUE;
4243 		}
4244 	}
4245 
4246 	return GL_FALSE;
4247 }
4248 
IsEnabled(GLenum cap)4249 GLboolean IsEnabled(GLenum cap)
4250 {
4251 	TRACE("(GLenum cap = 0x%X)", cap);
4252 
4253 	es2::Context *context = es2::getContext();
4254 
4255 	if(context)
4256 	{
4257 		GLint clientVersion = context->getClientVersion();
4258 
4259 		switch(cap)
4260 		{
4261 		case GL_CULL_FACE:                return context->isCullFaceEnabled();
4262 		case GL_POLYGON_OFFSET_FILL:      return context->isPolygonOffsetFillEnabled();
4263 		case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled();
4264 		case GL_SAMPLE_COVERAGE:          return context->isSampleCoverageEnabled();
4265 		case GL_SCISSOR_TEST:             return context->isScissorTestEnabled();
4266 		case GL_STENCIL_TEST:             return context->isStencilTestEnabled();
4267 		case GL_DEPTH_TEST:               return context->isDepthTestEnabled();
4268 		case GL_BLEND:                    return context->isBlendEnabled();
4269 		case GL_DITHER:                   return context->isDitherEnabled();
4270 		case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4271 			if(clientVersion >= 3)
4272 			{
4273 				return context->isPrimitiveRestartFixedIndexEnabled();
4274 			}
4275 			else return error(GL_INVALID_ENUM, false);
4276 		case GL_RASTERIZER_DISCARD:
4277 			if(clientVersion >= 3)
4278 			{
4279 				return context->isRasterizerDiscardEnabled();
4280 			}
4281 			else return error(GL_INVALID_ENUM, false);
4282 		default:
4283 			return error(GL_INVALID_ENUM, false);
4284 		}
4285 	}
4286 
4287 	return false;
4288 }
4289 
IsFenceNV(GLuint fence)4290 GLboolean IsFenceNV(GLuint fence)
4291 {
4292 	TRACE("(GLuint fence = %d)", fence);
4293 
4294 	es2::Context *context = es2::getContext();
4295 
4296 	if(context)
4297 	{
4298 		es2::Fence *fenceObject = context->getFence(fence);
4299 
4300 		if(!fenceObject)
4301 		{
4302 			return GL_FALSE;
4303 		}
4304 
4305 		return fenceObject->isFence();
4306 	}
4307 
4308 	return GL_FALSE;
4309 }
4310 
IsFramebuffer(GLuint framebuffer)4311 GLboolean IsFramebuffer(GLuint framebuffer)
4312 {
4313 	TRACE("(GLuint framebuffer = %d)", framebuffer);
4314 
4315 	es2::Context *context = es2::getContext();
4316 
4317 	if(context && framebuffer)
4318 	{
4319 		es2::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
4320 
4321 		if(framebufferObject)
4322 		{
4323 			return GL_TRUE;
4324 		}
4325 	}
4326 
4327 	return GL_FALSE;
4328 }
4329 
IsProgram(GLuint program)4330 GLboolean IsProgram(GLuint program)
4331 {
4332 	TRACE("(GLuint program = %d)", program);
4333 
4334 	es2::Context *context = es2::getContext();
4335 
4336 	if(context && program)
4337 	{
4338 		es2::Program *programObject = context->getProgram(program);
4339 
4340 		if(programObject)
4341 		{
4342 			return GL_TRUE;
4343 		}
4344 	}
4345 
4346 	return GL_FALSE;
4347 }
4348 
IsQueryEXT(GLuint name)4349 GLboolean IsQueryEXT(GLuint name)
4350 {
4351 	TRACE("(GLuint name = %d)", name);
4352 
4353 	if(name == 0)
4354 	{
4355 		return GL_FALSE;
4356 	}
4357 
4358 	es2::Context *context = es2::getContext();
4359 
4360 	if(context)
4361 	{
4362 		es2::Query *queryObject = context->getQuery(name);
4363 
4364 		if(queryObject)
4365 		{
4366 			return GL_TRUE;
4367 		}
4368 	}
4369 
4370 	return GL_FALSE;
4371 }
4372 
IsRenderbuffer(GLuint renderbuffer)4373 GLboolean IsRenderbuffer(GLuint renderbuffer)
4374 {
4375 	TRACE("(GLuint renderbuffer = %d)", renderbuffer);
4376 
4377 	es2::Context *context = es2::getContext();
4378 
4379 	if(context && renderbuffer)
4380 	{
4381 		es2::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
4382 
4383 		if(renderbufferObject)
4384 		{
4385 			return GL_TRUE;
4386 		}
4387 	}
4388 
4389 	return GL_FALSE;
4390 }
4391 
IsShader(GLuint shader)4392 GLboolean IsShader(GLuint shader)
4393 {
4394 	TRACE("(GLuint shader = %d)", shader);
4395 
4396 	es2::Context *context = es2::getContext();
4397 
4398 	if(context && shader)
4399 	{
4400 		es2::Shader *shaderObject = context->getShader(shader);
4401 
4402 		if(shaderObject)
4403 		{
4404 			return GL_TRUE;
4405 		}
4406 	}
4407 
4408 	return GL_FALSE;
4409 }
4410 
IsTexture(GLuint texture)4411 GLboolean IsTexture(GLuint texture)
4412 {
4413 	TRACE("(GLuint texture = %d)", texture);
4414 
4415 	es2::Context *context = es2::getContext();
4416 
4417 	if(context && texture)
4418 	{
4419 		es2::Texture *textureObject = context->getTexture(texture);
4420 
4421 		if(textureObject)
4422 		{
4423 			return GL_TRUE;
4424 		}
4425 	}
4426 
4427 	return GL_FALSE;
4428 }
4429 
LineWidth(GLfloat width)4430 void LineWidth(GLfloat width)
4431 {
4432 	TRACE("(GLfloat width = %f)", width);
4433 
4434 	if(width <= 0.0f)
4435 	{
4436 		return error(GL_INVALID_VALUE);
4437 	}
4438 
4439 	es2::Context *context = es2::getContext();
4440 
4441 	if(context)
4442 	{
4443 		context->setLineWidth(width);
4444 	}
4445 }
4446 
LinkProgram(GLuint program)4447 void LinkProgram(GLuint program)
4448 {
4449 	TRACE("(GLuint program = %d)", program);
4450 
4451 	es2::Context *context = es2::getContext();
4452 
4453 	if(context)
4454 	{
4455 		es2::Program *programObject = context->getProgram(program);
4456 
4457 		if(!programObject)
4458 		{
4459 			if(context->getShader(program))
4460 			{
4461 				return error(GL_INVALID_OPERATION);
4462 			}
4463 			else
4464 			{
4465 				return error(GL_INVALID_VALUE);
4466 			}
4467 		}
4468 
4469 		programObject->link();
4470 	}
4471 }
4472 
PixelStorei(GLenum pname,GLint param)4473 void PixelStorei(GLenum pname, GLint param)
4474 {
4475 	TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
4476 
4477 	es2::Context *context = es2::getContext();
4478 
4479 	if(context)
4480 	{
4481 		GLint clientVersion = context->getClientVersion();
4482 
4483 		switch(pname)
4484 		{
4485 		case GL_UNPACK_ALIGNMENT:
4486 			if(param != 1 && param != 2 && param != 4 && param != 8)
4487 			{
4488 				return error(GL_INVALID_VALUE);
4489 			}
4490 			context->setUnpackAlignment(param);
4491 			break;
4492 		case GL_PACK_ALIGNMENT:
4493 			if(param != 1 && param != 2 && param != 4 && param != 8)
4494 			{
4495 				return error(GL_INVALID_VALUE);
4496 			}
4497 			context->setPackAlignment(param);
4498 			break;
4499 		case GL_PACK_ROW_LENGTH:
4500 			if(clientVersion >= 3)
4501 			{
4502 				if(param < 0)
4503 				{
4504 					return error(GL_INVALID_VALUE);
4505 				}
4506 				context->setPackRowLength(param);
4507 				break;
4508 			}
4509 			else return error(GL_INVALID_ENUM);
4510 		case GL_PACK_SKIP_PIXELS:
4511 			if(clientVersion >= 3)
4512 			{
4513 				if(param < 0)
4514 				{
4515 					return error(GL_INVALID_VALUE);
4516 				}
4517 				context->setPackSkipPixels(param);
4518 				break;
4519 			}
4520 			else return error(GL_INVALID_ENUM);
4521 		case GL_PACK_SKIP_ROWS:
4522 			if(clientVersion >= 3)
4523 			{
4524 				if(param < 0)
4525 				{
4526 					return error(GL_INVALID_VALUE);
4527 				}
4528 				context->setPackSkipRows(param);
4529 				break;
4530 			}
4531 			else return error(GL_INVALID_ENUM);
4532 		case GL_UNPACK_ROW_LENGTH:
4533 			if(clientVersion >= 3)
4534 			{
4535 				if(param < 0)
4536 				{
4537 					return error(GL_INVALID_VALUE);
4538 				}
4539 				context->setUnpackRowLength(param);
4540 				break;
4541 			}
4542 			else return error(GL_INVALID_ENUM);
4543 		case GL_UNPACK_IMAGE_HEIGHT:
4544 			if(clientVersion >= 3)
4545 			{
4546 				if(param < 0)
4547 				{
4548 					return error(GL_INVALID_VALUE);
4549 				}
4550 				context->setUnpackImageHeight(param);
4551 				break;
4552 			}
4553 			else return error(GL_INVALID_ENUM);
4554 		case GL_UNPACK_SKIP_PIXELS:
4555 			if(clientVersion >= 3)
4556 			{
4557 				if(param < 0)
4558 				{
4559 					return error(GL_INVALID_VALUE);
4560 				}
4561 				context->setUnpackSkipPixels(param);
4562 				break;
4563 			}
4564 			else return error(GL_INVALID_ENUM);
4565 		case GL_UNPACK_SKIP_ROWS:
4566 			if(clientVersion >= 3)
4567 			{
4568 				if(param < 0)
4569 				{
4570 					return error(GL_INVALID_VALUE);
4571 				}
4572 				context->setUnpackSkipRows(param);
4573 				break;
4574 			}
4575 			else return error(GL_INVALID_ENUM);
4576 		case GL_UNPACK_SKIP_IMAGES:
4577 			if(clientVersion >= 3) {
4578 				if(param < 0)
4579 				{
4580 					return error(GL_INVALID_VALUE);
4581 				}
4582 				context->setUnpackSkipImages(param);
4583 				break;
4584 			}
4585 			else return error(GL_INVALID_ENUM);
4586 		default:
4587 			return error(GL_INVALID_ENUM);
4588 		}
4589 	}
4590 }
4591 
PolygonOffset(GLfloat factor,GLfloat units)4592 void PolygonOffset(GLfloat factor, GLfloat units)
4593 {
4594 	TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
4595 
4596 	es2::Context *context = es2::getContext();
4597 
4598 	if(context)
4599 	{
4600 		context->setPolygonOffsetParams(factor, units);
4601 	}
4602 }
4603 
ReadnPixelsEXT(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLsizei bufSize,GLvoid * data)4604 void ReadnPixelsEXT(GLint x, GLint y, GLsizei width, GLsizei height,
4605                     GLenum format, GLenum type, GLsizei bufSize, GLvoid *data)
4606 {
4607 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4608 	      "GLenum format = 0x%X, GLenum type = 0x%X, GLsizei bufSize = 0x%d, GLvoid *data = %p)",
4609 	      x, y, width, height, format, type, bufSize, data);
4610 
4611 	if(width < 0 || height < 0 || bufSize < 0)
4612 	{
4613 		return error(GL_INVALID_VALUE);
4614 	}
4615 
4616 	es2::Context *context = es2::getContext();
4617 
4618 	if(context)
4619 	{
4620 		context->readPixels(x, y, width, height, format, type, &bufSize, data);
4621 	}
4622 }
4623 
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)4624 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
4625 {
4626 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
4627 	      "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
4628 	      x, y, width, height, format, type,  pixels);
4629 
4630 	if(width < 0 || height < 0)
4631 	{
4632 		return error(GL_INVALID_VALUE);
4633 	}
4634 
4635 	es2::Context *context = es2::getContext();
4636 
4637 	if(context)
4638 	{
4639 		context->readPixels(x, y, width, height, format, type, nullptr, pixels);
4640 	}
4641 }
4642 
ReleaseShaderCompiler(void)4643 void ReleaseShaderCompiler(void)
4644 {
4645 	TRACE("()");
4646 
4647 	es2::Shader::releaseCompiler();
4648 }
4649 
RenderbufferStorageMultisampleANGLE(GLenum target,GLsizei samples,GLenum internalformat,GLsizei width,GLsizei height)4650 void RenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height)
4651 {
4652 	TRACE("(GLenum target = 0x%X, GLsizei samples = %d, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
4653 	      target, samples, internalformat, width, height);
4654 
4655 	switch(target)
4656 	{
4657 	case GL_RENDERBUFFER:
4658 		break;
4659 	default:
4660 		return error(GL_INVALID_ENUM);
4661 	}
4662 
4663 	if(width < 0 || height < 0 || samples < 0)
4664 	{
4665 		return error(GL_INVALID_VALUE);
4666 	}
4667 
4668 	es2::Context *context = es2::getContext();
4669 
4670 	if(context)
4671 	{
4672 		if(width > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4673 		   height > es2::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
4674 		   samples > es2::IMPLEMENTATION_MAX_SAMPLES)
4675 		{
4676 			return error(GL_INVALID_VALUE);
4677 		}
4678 
4679 		GLuint handle = context->getRenderbufferName();
4680 		if(handle == 0)
4681 		{
4682 			return error(GL_INVALID_OPERATION);
4683 		}
4684 
4685 		GLint clientVersion = context->getClientVersion();
4686 		switch(internalformat)
4687 		{
4688 		case GL_DEPTH_COMPONENT32F:
4689 			if(clientVersion < 3)
4690 			{
4691 				return error(GL_INVALID_ENUM);
4692 			}
4693 			// fall through
4694 		case GL_DEPTH_COMPONENT16:
4695 		case GL_DEPTH_COMPONENT24:
4696 		case GL_DEPTH_COMPONENT32_OES:
4697 			context->setRenderbufferStorage(new es2::Depthbuffer(width, height, internalformat, samples));
4698 			break;
4699 		case GL_R8:
4700 		case GL_R8UI:
4701 		case GL_R8I:
4702 		case GL_R16UI:
4703 		case GL_R16I:
4704 		case GL_R32UI:
4705 		case GL_R32I:
4706 		case GL_RG8:
4707 		case GL_RG8UI:
4708 		case GL_RG8I:
4709 		case GL_RG16UI:
4710 		case GL_RG16I:
4711 		case GL_RG32UI:
4712 		case GL_RG32I:
4713 		case GL_SRGB8_ALPHA8:
4714 		case GL_RGB10_A2:
4715 		case GL_RGBA8UI:
4716 		case GL_RGBA8I:
4717 		case GL_RGB10_A2UI:
4718 		case GL_RGBA16UI:
4719 		case GL_RGBA16I:
4720 		case GL_RGBA32I:
4721 		case GL_RGBA32UI:
4722 		case GL_R11F_G11F_B10F:
4723 		case GL_R32F:
4724 		case GL_RG32F:
4725 		case GL_RGB32F:
4726 		case GL_RGBA32F:
4727 			if(clientVersion < 3)
4728 			{
4729 				return error(GL_INVALID_ENUM);
4730 			}
4731 			// fall through
4732 		case GL_RGBA4:
4733 		case GL_RGB5_A1:
4734 		case GL_RGB565:
4735 		case GL_RGB8_OES:
4736 		case GL_RGBA8_OES:
4737 		case GL_R16F:
4738 		case GL_RG16F:
4739 		case GL_RGB16F:
4740 		case GL_RGBA16F:
4741 			context->setRenderbufferStorage(new es2::Colorbuffer(width, height, internalformat, samples));
4742 			break;
4743 		case GL_STENCIL_INDEX8:
4744 			context->setRenderbufferStorage(new es2::Stencilbuffer(width, height, samples));
4745 			break;
4746 		case GL_DEPTH32F_STENCIL8:
4747 			if(clientVersion < 3)
4748 			{
4749 				return error(GL_INVALID_ENUM);
4750 			}
4751 			// fall through
4752 		case GL_DEPTH24_STENCIL8_OES:
4753 			context->setRenderbufferStorage(new es2::DepthStencilbuffer(width, height, internalformat, samples));
4754 			break;
4755 		default:
4756 			return error(GL_INVALID_ENUM);
4757 		}
4758 	}
4759 }
4760 
RenderbufferStorage(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)4761 void RenderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
4762 {
4763 	glRenderbufferStorageMultisampleANGLE(target, 0, internalformat, width, height);
4764 }
4765 
SampleCoverage(GLclampf value,GLboolean invert)4766 void SampleCoverage(GLclampf value, GLboolean invert)
4767 {
4768 	TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
4769 
4770 	es2::Context* context = es2::getContext();
4771 
4772 	if(context)
4773 	{
4774 		context->setSampleCoverageParams(es2::clamp01(value), invert == GL_TRUE);
4775 	}
4776 }
4777 
SetFenceNV(GLuint fence,GLenum condition)4778 void SetFenceNV(GLuint fence, GLenum condition)
4779 {
4780 	TRACE("(GLuint fence = %d, GLenum condition = 0x%X)", fence, condition);
4781 
4782 	if(condition != GL_ALL_COMPLETED_NV)
4783 	{
4784 		return error(GL_INVALID_ENUM);
4785 	}
4786 
4787 	es2::Context *context = es2::getContext();
4788 
4789 	if(context)
4790 	{
4791 		es2::Fence *fenceObject = context->getFence(fence);
4792 
4793 		if(!fenceObject)
4794 		{
4795 			return error(GL_INVALID_OPERATION);
4796 		}
4797 
4798 		fenceObject->setFence(condition);
4799 	}
4800 }
4801 
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)4802 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
4803 {
4804 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4805 
4806 	if(width < 0 || height < 0)
4807 	{
4808 		return error(GL_INVALID_VALUE);
4809 	}
4810 
4811 	es2::Context* context = es2::getContext();
4812 
4813 	if(context)
4814 	{
4815 		context->setScissorParams(x, y, width, height);
4816 	}
4817 }
4818 
ShaderBinary(GLsizei n,const GLuint * shaders,GLenum binaryformat,const GLvoid * binary,GLsizei length)4819 void ShaderBinary(GLsizei n, const GLuint* shaders, GLenum binaryformat, const GLvoid* binary, GLsizei length)
4820 {
4821 	TRACE("(GLsizei n = %d, const GLuint* shaders = %p, GLenum binaryformat = 0x%X, "
4822 	      "const GLvoid* binary = %p, GLsizei length = %d)",
4823 	      n, shaders, binaryformat, binary, length);
4824 
4825 	// No binary shader formats are supported.
4826 	return error(GL_INVALID_ENUM);
4827 }
4828 
ShaderSource(GLuint shader,GLsizei count,const GLchar * const * string,const GLint * length)4829 void ShaderSource(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length)
4830 {
4831 	TRACE("(GLuint shader = %d, GLsizei count = %d, const GLchar** string = %p, const GLint* length = %p)",
4832 	      shader, count, string, length);
4833 
4834 	if(count < 0)
4835 	{
4836 		return error(GL_INVALID_VALUE);
4837 	}
4838 
4839 	es2::Context *context = es2::getContext();
4840 
4841 	if(context)
4842 	{
4843 		es2::Shader *shaderObject = context->getShader(shader);
4844 
4845 		if(!shaderObject)
4846 		{
4847 			if(context->getProgram(shader))
4848 			{
4849 				return error(GL_INVALID_OPERATION);
4850 			}
4851 			else
4852 			{
4853 				return error(GL_INVALID_VALUE);
4854 			}
4855 		}
4856 
4857 		shaderObject->setSource(count, string, length);
4858 	}
4859 }
4860 
StencilFunc(GLenum func,GLint ref,GLuint mask)4861 void StencilFunc(GLenum func, GLint ref, GLuint mask)
4862 {
4863 	glStencilFuncSeparate(GL_FRONT_AND_BACK, func, ref, mask);
4864 }
4865 
StencilFuncSeparate(GLenum face,GLenum func,GLint ref,GLuint mask)4866 void StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
4867 {
4868 	TRACE("(GLenum face = 0x%X, GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", face, func, ref, mask);
4869 
4870 	switch(face)
4871 	{
4872 	case GL_FRONT:
4873 	case GL_BACK:
4874 	case GL_FRONT_AND_BACK:
4875 		break;
4876 	default:
4877 		return error(GL_INVALID_ENUM);
4878 	}
4879 
4880 	switch(func)
4881 	{
4882 	case GL_NEVER:
4883 	case GL_ALWAYS:
4884 	case GL_LESS:
4885 	case GL_LEQUAL:
4886 	case GL_EQUAL:
4887 	case GL_GEQUAL:
4888 	case GL_GREATER:
4889 	case GL_NOTEQUAL:
4890 		break;
4891 	default:
4892 		return error(GL_INVALID_ENUM);
4893 	}
4894 
4895 	es2::Context *context = es2::getContext();
4896 
4897 	if(context)
4898 	{
4899 		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4900 		{
4901 			context->setStencilParams(func, ref, mask);
4902 		}
4903 
4904 		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4905 		{
4906 			context->setStencilBackParams(func, ref, mask);
4907 		}
4908 	}
4909 }
4910 
StencilMask(GLuint mask)4911 void StencilMask(GLuint mask)
4912 {
4913 	glStencilMaskSeparate(GL_FRONT_AND_BACK, mask);
4914 }
4915 
StencilMaskSeparate(GLenum face,GLuint mask)4916 void StencilMaskSeparate(GLenum face, GLuint mask)
4917 {
4918 	TRACE("(GLenum face = 0x%X, GLuint mask = %d)", face, mask);
4919 
4920 	switch(face)
4921 	{
4922 	case GL_FRONT:
4923 	case GL_BACK:
4924 	case GL_FRONT_AND_BACK:
4925 		break;
4926 	default:
4927 		return error(GL_INVALID_ENUM);
4928 	}
4929 
4930 	es2::Context *context = es2::getContext();
4931 
4932 	if(context)
4933 	{
4934 		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
4935 		{
4936 			context->setStencilWritemask(mask);
4937 		}
4938 
4939 		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
4940 		{
4941 			context->setStencilBackWritemask(mask);
4942 		}
4943 	}
4944 }
4945 
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)4946 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
4947 {
4948 	glStencilOpSeparate(GL_FRONT_AND_BACK, fail, zfail, zpass);
4949 }
4950 
StencilOpSeparate(GLenum face,GLenum fail,GLenum zfail,GLenum zpass)4951 void StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
4952 {
4953 	TRACE("(GLenum face = 0x%X, GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)",
4954 	      face, fail, zfail, zpass);
4955 
4956 	switch(face)
4957 	{
4958 	case GL_FRONT:
4959 	case GL_BACK:
4960 	case GL_FRONT_AND_BACK:
4961 		break;
4962 	default:
4963 		return error(GL_INVALID_ENUM);
4964 	}
4965 
4966 	switch(fail)
4967 	{
4968 	case GL_ZERO:
4969 	case GL_KEEP:
4970 	case GL_REPLACE:
4971 	case GL_INCR:
4972 	case GL_DECR:
4973 	case GL_INVERT:
4974 	case GL_INCR_WRAP:
4975 	case GL_DECR_WRAP:
4976 		break;
4977 	default:
4978 		return error(GL_INVALID_ENUM);
4979 	}
4980 
4981 	switch(zfail)
4982 	{
4983 	case GL_ZERO:
4984 	case GL_KEEP:
4985 	case GL_REPLACE:
4986 	case GL_INCR:
4987 	case GL_DECR:
4988 	case GL_INVERT:
4989 	case GL_INCR_WRAP:
4990 	case GL_DECR_WRAP:
4991 		break;
4992 	default:
4993 		return error(GL_INVALID_ENUM);
4994 	}
4995 
4996 	switch(zpass)
4997 	{
4998 	case GL_ZERO:
4999 	case GL_KEEP:
5000 	case GL_REPLACE:
5001 	case GL_INCR:
5002 	case GL_DECR:
5003 	case GL_INVERT:
5004 	case GL_INCR_WRAP:
5005 	case GL_DECR_WRAP:
5006 		break;
5007 	default:
5008 		return error(GL_INVALID_ENUM);
5009 	}
5010 
5011 	es2::Context *context = es2::getContext();
5012 
5013 	if(context)
5014 	{
5015 		if(face == GL_FRONT || face == GL_FRONT_AND_BACK)
5016 		{
5017 			context->setStencilOperations(fail, zfail, zpass);
5018 		}
5019 
5020 		if(face == GL_BACK || face == GL_FRONT_AND_BACK)
5021 		{
5022 			context->setStencilBackOperations(fail, zfail, zpass);
5023 		}
5024 	}
5025 }
5026 
TestFenceNV(GLuint fence)5027 GLboolean TestFenceNV(GLuint fence)
5028 {
5029 	TRACE("(GLuint fence = %d)", fence);
5030 
5031 	es2::Context *context = es2::getContext();
5032 
5033 	if(context)
5034 	{
5035 		es2::Fence *fenceObject = context->getFence(fence);
5036 
5037 		if(!fenceObject)
5038 		{
5039 			return error(GL_INVALID_OPERATION, GL_TRUE);
5040 		}
5041 
5042 		return fenceObject->testFence();
5043 	}
5044 
5045 	return GL_TRUE;
5046 }
5047 
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)5048 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
5049                 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
5050 {
5051 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
5052 	      "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels =  %p)",
5053 	      target, level, internalformat, width, height, border, format, type, pixels);
5054 
5055 	if(!validImageSize(level, width, height))
5056 	{
5057 		return error(GL_INVALID_VALUE);
5058 	}
5059 
5060 	es2::Context *context = es2::getContext();
5061 
5062 	if(context)
5063 	{
5064 		GLint clientVersion = context->getClientVersion();
5065 		if(clientVersion < 3)
5066 		{
5067 			if(internalformat != (GLint)format)
5068 			{
5069 				return error(GL_INVALID_OPERATION);
5070 			}
5071 		}
5072 
5073 		GLenum validationError = ValidateCompressedFormat(format, clientVersion, false);
5074 		if(validationError != GL_NONE)
5075 		{
5076 			return error(validationError);
5077 		}
5078 
5079 		if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
5080 		{
5081 			return;
5082 		}
5083 
5084 		if(border != 0)
5085 		{
5086 			return error(GL_INVALID_VALUE);
5087 		}
5088 
5089 		switch(target)
5090 		{
5091 		case GL_TEXTURE_2D:
5092 			if(width > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
5093 			   height > (es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
5094 			{
5095 				return error(GL_INVALID_VALUE);
5096 			}
5097 			break;
5098 		case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
5099 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
5100 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
5101 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
5102 		case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
5103 		case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
5104 			if(width != height)
5105 			{
5106 				return error(GL_INVALID_VALUE);
5107 			}
5108 
5109 			if(width > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level) ||
5110 			   height > (es2::IMPLEMENTATION_MAX_CUBE_MAP_TEXTURE_SIZE >> level))
5111 			{
5112 				return error(GL_INVALID_VALUE);
5113 			}
5114 			break;
5115 		default:
5116 			return error(GL_INVALID_ENUM);
5117 		}
5118 
5119 		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5120 
5121 		if(target == GL_TEXTURE_2D)
5122 		{
5123 			es2::Texture2D *texture = context->getTexture2D();
5124 
5125 			if(!texture)
5126 			{
5127 				return error(GL_INVALID_OPERATION);
5128 			}
5129 
5130 			texture->setImage(level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
5131 		}
5132 		else
5133 		{
5134 			es2::TextureCubeMap *texture = context->getTextureCubeMap();
5135 
5136 			if(!texture)
5137 			{
5138 				return error(GL_INVALID_OPERATION);
5139 			}
5140 
5141 			texture->setImage(target, level, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
5142 		}
5143 	}
5144 }
5145 
TexParameterf(GLenum target,GLenum pname,GLfloat param)5146 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
5147 {
5148 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
5149 
5150 	es2::Context *context = es2::getContext();
5151 
5152 	if(context)
5153 	{
5154 		es2::Texture *texture;
5155 
5156 		GLint clientVersion = context->getClientVersion();
5157 
5158 		switch(target)
5159 		{
5160 		case GL_TEXTURE_2D:
5161 			texture = context->getTexture2D();
5162 			break;
5163 		case GL_TEXTURE_2D_ARRAY:
5164 			if(clientVersion < 3)
5165 			{
5166 				return error(GL_INVALID_ENUM);
5167 			}
5168 			else
5169 			{
5170 				texture = context->getTexture2DArray();
5171 			}
5172 			break;
5173 		case GL_TEXTURE_3D_OES:
5174 			texture = context->getTexture3D();
5175 			break;
5176 		case GL_TEXTURE_CUBE_MAP:
5177 			texture = context->getTextureCubeMap();
5178 			break;
5179 		case GL_TEXTURE_EXTERNAL_OES:
5180 			texture = context->getTextureExternal();
5181 			break;
5182 		default:
5183 			return error(GL_INVALID_ENUM);
5184 		}
5185 
5186 		switch(pname)
5187 		{
5188 		case GL_TEXTURE_WRAP_S:
5189 			if(!texture->setWrapS((GLenum)param))
5190 			{
5191 				return error(GL_INVALID_ENUM);
5192 			}
5193 			break;
5194 		case GL_TEXTURE_WRAP_T:
5195 			if(!texture->setWrapT((GLenum)param))
5196 			{
5197 				return error(GL_INVALID_ENUM);
5198 			}
5199 			break;
5200 		case GL_TEXTURE_WRAP_R_OES:
5201 			if(!texture->setWrapR((GLenum)param))
5202 			{
5203 				return error(GL_INVALID_ENUM);
5204 			}
5205 			break;
5206 		case GL_TEXTURE_MIN_FILTER:
5207 			if(!texture->setMinFilter((GLenum)param))
5208 			{
5209 				return error(GL_INVALID_ENUM);
5210 			}
5211 			break;
5212 		case GL_TEXTURE_MAG_FILTER:
5213 			if(!texture->setMagFilter((GLenum)param))
5214 			{
5215 				return error(GL_INVALID_ENUM);
5216 			}
5217 			break;
5218 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5219 			if(!texture->setMaxAnisotropy(param))
5220 			{
5221 				return error(GL_INVALID_VALUE);
5222 			}
5223 			break;
5224 		case GL_TEXTURE_BASE_LEVEL:
5225 			if(clientVersion < 3 || !texture->setBaseLevel((GLint)(roundf(param))))
5226 			{
5227 				return error(GL_INVALID_VALUE);
5228 			}
5229 			break;
5230 		case GL_TEXTURE_COMPARE_FUNC:
5231 			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5232 			{
5233 				return error(GL_INVALID_VALUE);
5234 			}
5235 			break;
5236 		case GL_TEXTURE_COMPARE_MODE:
5237 			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5238 			{
5239 				return error(GL_INVALID_VALUE);
5240 			}
5241 			break;
5242 		case GL_TEXTURE_MAX_LEVEL:
5243 			if(clientVersion < 3 || !texture->setMaxLevel((GLint)(roundf(param))))
5244 			{
5245 				return error(GL_INVALID_VALUE);
5246 			}
5247 			break;
5248 		case GL_TEXTURE_MAX_LOD:
5249 			if(clientVersion < 3 || !texture->setMaxLOD(param))
5250 			{
5251 				return error(GL_INVALID_VALUE);
5252 			}
5253 			break;
5254 		case GL_TEXTURE_MIN_LOD:
5255 			if(clientVersion < 3 || !texture->setMinLOD(param))
5256 			{
5257 				return error(GL_INVALID_VALUE);
5258 			}
5259 			break;
5260 		case GL_TEXTURE_SWIZZLE_R:
5261 			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5262 			{
5263 				return error(GL_INVALID_VALUE);
5264 			}
5265 			break;
5266 		case GL_TEXTURE_SWIZZLE_G:
5267 			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5268 			{
5269 				return error(GL_INVALID_VALUE);
5270 			}
5271 			break;
5272 		case GL_TEXTURE_SWIZZLE_B:
5273 			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5274 			{
5275 				return error(GL_INVALID_VALUE);
5276 			}
5277 			break;
5278 		case GL_TEXTURE_SWIZZLE_A:
5279 			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5280 			{
5281 				return error(GL_INVALID_VALUE);
5282 			}
5283 			break;
5284 		default:
5285 			return error(GL_INVALID_ENUM);
5286 		}
5287 	}
5288 }
5289 
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)5290 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
5291 {
5292 	glTexParameterf(target, pname, *params);
5293 }
5294 
TexParameteri(GLenum target,GLenum pname,GLint param)5295 void TexParameteri(GLenum target, GLenum pname, GLint param)
5296 {
5297 	TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
5298 
5299 	es2::Context *context = es2::getContext();
5300 
5301 	if(context)
5302 	{
5303 		es2::Texture *texture;
5304 
5305 		GLint clientVersion = context->getClientVersion();
5306 
5307 		switch(target)
5308 		{
5309 		case GL_TEXTURE_2D:
5310 			texture = context->getTexture2D();
5311 			break;
5312 		case GL_TEXTURE_2D_ARRAY:
5313 			if(clientVersion < 3)
5314 			{
5315 				return error(GL_INVALID_ENUM);
5316 			}
5317 			else
5318 			{
5319 				texture = context->getTexture2DArray();
5320 			}
5321 			break;
5322 		case GL_TEXTURE_3D_OES:
5323 			texture = context->getTexture3D();
5324 			break;
5325 		case GL_TEXTURE_CUBE_MAP:
5326 			texture = context->getTextureCubeMap();
5327 			break;
5328 		case GL_TEXTURE_EXTERNAL_OES:
5329 			texture = context->getTextureExternal();
5330 			break;
5331 		default:
5332 			return error(GL_INVALID_ENUM);
5333 		}
5334 
5335 		switch(pname)
5336 		{
5337 		case GL_TEXTURE_WRAP_S:
5338 			if(!texture->setWrapS((GLenum)param))
5339 			{
5340 				return error(GL_INVALID_ENUM);
5341 			}
5342 			break;
5343 		case GL_TEXTURE_WRAP_T:
5344 			if(!texture->setWrapT((GLenum)param))
5345 			{
5346 				return error(GL_INVALID_ENUM);
5347 			}
5348 			break;
5349 		case GL_TEXTURE_WRAP_R_OES:
5350 			if(!texture->setWrapR((GLenum)param))
5351 			{
5352 				return error(GL_INVALID_ENUM);
5353 			}
5354 			break;
5355 		case GL_TEXTURE_MIN_FILTER:
5356 			if(!texture->setMinFilter((GLenum)param))
5357 			{
5358 				return error(GL_INVALID_ENUM);
5359 			}
5360 			break;
5361 		case GL_TEXTURE_MAG_FILTER:
5362 			if(!texture->setMagFilter((GLenum)param))
5363 			{
5364 				return error(GL_INVALID_ENUM);
5365 			}
5366 			break;
5367 		case GL_TEXTURE_MAX_ANISOTROPY_EXT:
5368 			if(!texture->setMaxAnisotropy((GLfloat)param))
5369 			{
5370 				return error(GL_INVALID_VALUE);
5371 			}
5372 			break;
5373 		case GL_TEXTURE_BASE_LEVEL:
5374 			if(clientVersion < 3 || !texture->setBaseLevel(param))
5375 			{
5376 				return error(GL_INVALID_VALUE);
5377 			}
5378 			break;
5379 		case GL_TEXTURE_COMPARE_FUNC:
5380 			if(clientVersion < 3 || !texture->setCompareFunc((GLenum)param))
5381 			{
5382 				return error(GL_INVALID_VALUE);
5383 			}
5384 			break;
5385 		case GL_TEXTURE_COMPARE_MODE:
5386 			if(clientVersion < 3 || !texture->setCompareMode((GLenum)param))
5387 			{
5388 				return error(GL_INVALID_VALUE);
5389 			}
5390 			break;
5391 		case GL_TEXTURE_MAX_LEVEL:
5392 			if(clientVersion < 3 || !texture->setMaxLevel(param))
5393 			{
5394 				return error(GL_INVALID_VALUE);
5395 			}
5396 			break;
5397 		case GL_TEXTURE_MAX_LOD:
5398 			if(clientVersion < 3 || !texture->setMaxLOD((GLfloat)param))
5399 			{
5400 				return error(GL_INVALID_VALUE);
5401 			}
5402 			break;
5403 		case GL_TEXTURE_MIN_LOD:
5404 			if(clientVersion < 3 || !texture->setMinLOD((GLfloat)param))
5405 			{
5406 				return error(GL_INVALID_VALUE);
5407 			}
5408 			break;
5409 		case GL_TEXTURE_SWIZZLE_R:
5410 			if(clientVersion < 3 || !texture->setSwizzleR((GLenum)param))
5411 			{
5412 				return error(GL_INVALID_VALUE);
5413 			}
5414 			break;
5415 		case GL_TEXTURE_SWIZZLE_G:
5416 			if(clientVersion < 3 || !texture->setSwizzleG((GLenum)param))
5417 			{
5418 				return error(GL_INVALID_VALUE);
5419 			}
5420 			break;
5421 		case GL_TEXTURE_SWIZZLE_B:
5422 			if(clientVersion < 3 || !texture->setSwizzleB((GLenum)param))
5423 			{
5424 				return error(GL_INVALID_VALUE);
5425 			}
5426 			break;
5427 		case GL_TEXTURE_SWIZZLE_A:
5428 			if(clientVersion < 3 || !texture->setSwizzleA((GLenum)param))
5429 			{
5430 				return error(GL_INVALID_VALUE);
5431 			}
5432 			break;
5433 		default:
5434 			return error(GL_INVALID_ENUM);
5435 		}
5436 	}
5437 }
5438 
TexParameteriv(GLenum target,GLenum pname,const GLint * params)5439 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
5440 {
5441 	glTexParameteri(target, pname, *params);
5442 }
5443 
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)5444 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
5445                    GLenum format, GLenum type, const GLvoid* pixels)
5446 {
5447 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
5448 	      "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
5449 	      "const GLvoid* pixels = %p)",
5450 	      target, level, xoffset, yoffset, width, height, format, type, pixels);
5451 
5452 	if(!es2::IsTextureTarget(target))
5453 	{
5454 		return error(GL_INVALID_ENUM);
5455 	}
5456 
5457 	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
5458 	{
5459 		return error(GL_INVALID_VALUE);
5460 	}
5461 
5462 	if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
5463 	{
5464 		return error(GL_INVALID_VALUE);
5465 	}
5466 
5467 	if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
5468 	{
5469 		return error(GL_INVALID_VALUE);
5470 	}
5471 
5472 	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
5473 	{
5474 		return;
5475 	}
5476 
5477 	if(width == 0 || height == 0 || !pixels)
5478 	{
5479 		return;
5480 	}
5481 
5482 	es2::Context *context = es2::getContext();
5483 
5484 	if(context)
5485 	{
5486 		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
5487 
5488 		if(target == GL_TEXTURE_2D)
5489 		{
5490 			es2::Texture2D *texture = context->getTexture2D();
5491 
5492 			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5493 
5494 			if(validationError == GL_NONE)
5495 			{
5496 				texture->subImage(level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
5497 			}
5498 			else
5499 			{
5500 				return error(validationError);
5501 			}
5502 		}
5503 		else if(es2::IsCubemapTextureTarget(target))
5504 		{
5505 			es2::TextureCubeMap *texture = context->getTextureCubeMap();
5506 
5507 			GLenum validationError = ValidateSubImageParams(false, width, height, xoffset, yoffset, target, level, sizedInternalFormat, texture);
5508 
5509 			if(validationError == GL_NONE)
5510 			{
5511 				texture->subImage(target, level, xoffset, yoffset, width, height, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
5512 			}
5513 			else
5514 			{
5515 				return error(validationError);
5516 			}
5517 		}
5518 		else UNREACHABLE(target);
5519 	}
5520 }
5521 
Uniform1f(GLint location,GLfloat x)5522 void Uniform1f(GLint location, GLfloat x)
5523 {
5524 	glUniform1fv(location, 1, &x);
5525 }
5526 
Uniform1fv(GLint location,GLsizei count,const GLfloat * v)5527 void Uniform1fv(GLint location, GLsizei count, const GLfloat* v)
5528 {
5529 	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5530 
5531 	if(count < 0)
5532 	{
5533 		return error(GL_INVALID_VALUE);
5534 	}
5535 
5536 	if(location == -1)
5537 	{
5538 		return;
5539 	}
5540 
5541 	es2::Context *context = es2::getContext();
5542 
5543 	if(context)
5544 	{
5545 		es2::Program *program = context->getCurrentProgram();
5546 
5547 		if(!program)
5548 		{
5549 			return error(GL_INVALID_OPERATION);
5550 		}
5551 
5552 		if(!program->setUniform1fv(location, count, v))
5553 		{
5554 			return error(GL_INVALID_OPERATION);
5555 		}
5556 	}
5557 }
5558 
Uniform1i(GLint location,GLint x)5559 void Uniform1i(GLint location, GLint x)
5560 {
5561 	glUniform1iv(location, 1, &x);
5562 }
5563 
Uniform1iv(GLint location,GLsizei count,const GLint * v)5564 void Uniform1iv(GLint location, GLsizei count, const GLint* v)
5565 {
5566 	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5567 
5568 	if(count < 0)
5569 	{
5570 		return error(GL_INVALID_VALUE);
5571 	}
5572 
5573 	if(location == -1)
5574 	{
5575 		return;
5576 	}
5577 
5578 	es2::Context *context = es2::getContext();
5579 
5580 	if(context)
5581 	{
5582 		es2::Program *program = context->getCurrentProgram();
5583 
5584 		if(!program)
5585 		{
5586 			return error(GL_INVALID_OPERATION);
5587 		}
5588 
5589 		if(!program->setUniform1iv(location, count, v))
5590 		{
5591 			return error(GL_INVALID_OPERATION);
5592 		}
5593 	}
5594 }
5595 
Uniform2f(GLint location,GLfloat x,GLfloat y)5596 void Uniform2f(GLint location, GLfloat x, GLfloat y)
5597 {
5598 	GLfloat xy[2] = {x, y};
5599 
5600 	glUniform2fv(location, 1, (GLfloat*)&xy);
5601 }
5602 
Uniform2fv(GLint location,GLsizei count,const GLfloat * v)5603 void Uniform2fv(GLint location, GLsizei count, const GLfloat* v)
5604 {
5605 	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5606 
5607 	if(count < 0)
5608 	{
5609 		return error(GL_INVALID_VALUE);
5610 	}
5611 
5612 	if(location == -1)
5613 	{
5614 		return;
5615 	}
5616 
5617 	es2::Context *context = es2::getContext();
5618 
5619 	if(context)
5620 	{
5621 		es2::Program *program = context->getCurrentProgram();
5622 
5623 		if(!program)
5624 		{
5625 			return error(GL_INVALID_OPERATION);
5626 		}
5627 
5628 		if(!program->setUniform2fv(location, count, v))
5629 		{
5630 			return error(GL_INVALID_OPERATION);
5631 		}
5632 	}
5633 }
5634 
Uniform2i(GLint location,GLint x,GLint y)5635 void Uniform2i(GLint location, GLint x, GLint y)
5636 {
5637 	GLint xy[4] = {x, y};
5638 
5639 	glUniform2iv(location, 1, (GLint*)&xy);
5640 }
5641 
Uniform2iv(GLint location,GLsizei count,const GLint * v)5642 void Uniform2iv(GLint location, GLsizei count, const GLint* v)
5643 {
5644 	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5645 
5646 	if(count < 0)
5647 	{
5648 		return error(GL_INVALID_VALUE);
5649 	}
5650 
5651 	if(location == -1)
5652 	{
5653 		return;
5654 	}
5655 
5656 	es2::Context *context = es2::getContext();
5657 
5658 	if(context)
5659 	{
5660 		es2::Program *program = context->getCurrentProgram();
5661 
5662 		if(!program)
5663 		{
5664 			return error(GL_INVALID_OPERATION);
5665 		}
5666 
5667 		if(!program->setUniform2iv(location, count, v))
5668 		{
5669 			return error(GL_INVALID_OPERATION);
5670 		}
5671 	}
5672 }
5673 
Uniform3f(GLint location,GLfloat x,GLfloat y,GLfloat z)5674 void Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z)
5675 {
5676 	GLfloat xyz[3] = {x, y, z};
5677 
5678 	glUniform3fv(location, 1, (GLfloat*)&xyz);
5679 }
5680 
Uniform3fv(GLint location,GLsizei count,const GLfloat * v)5681 void Uniform3fv(GLint location, GLsizei count, const GLfloat* v)
5682 {
5683 	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5684 
5685 	if(count < 0)
5686 	{
5687 		return error(GL_INVALID_VALUE);
5688 	}
5689 
5690 	if(location == -1)
5691 	{
5692 		return;
5693 	}
5694 
5695 	es2::Context *context = es2::getContext();
5696 
5697 	if(context)
5698 	{
5699 		es2::Program *program = context->getCurrentProgram();
5700 
5701 		if(!program)
5702 		{
5703 			return error(GL_INVALID_OPERATION);
5704 		}
5705 
5706 		if(!program->setUniform3fv(location, count, v))
5707 		{
5708 			return error(GL_INVALID_OPERATION);
5709 		}
5710 	}
5711 }
5712 
Uniform3i(GLint location,GLint x,GLint y,GLint z)5713 void Uniform3i(GLint location, GLint x, GLint y, GLint z)
5714 {
5715 	GLint xyz[3] = {x, y, z};
5716 
5717 	glUniform3iv(location, 1, (GLint*)&xyz);
5718 }
5719 
Uniform3iv(GLint location,GLsizei count,const GLint * v)5720 void Uniform3iv(GLint location, GLsizei count, const GLint* v)
5721 {
5722 	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5723 
5724 	if(count < 0)
5725 	{
5726 		return error(GL_INVALID_VALUE);
5727 	}
5728 
5729 	if(location == -1)
5730 	{
5731 		return;
5732 	}
5733 
5734 	es2::Context *context = es2::getContext();
5735 
5736 	if(context)
5737 	{
5738 		es2::Program *program = context->getCurrentProgram();
5739 
5740 		if(!program)
5741 		{
5742 			return error(GL_INVALID_OPERATION);
5743 		}
5744 
5745 		if(!program->setUniform3iv(location, count, v))
5746 		{
5747 			return error(GL_INVALID_OPERATION);
5748 		}
5749 	}
5750 }
5751 
Uniform4f(GLint location,GLfloat x,GLfloat y,GLfloat z,GLfloat w)5752 void Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
5753 {
5754 	GLfloat xyzw[4] = {x, y, z, w};
5755 
5756 	glUniform4fv(location, 1, (GLfloat*)&xyzw);
5757 }
5758 
Uniform4fv(GLint location,GLsizei count,const GLfloat * v)5759 void Uniform4fv(GLint location, GLsizei count, const GLfloat* v)
5760 {
5761 	TRACE("(GLint location = %d, GLsizei count = %d, const GLfloat* v = %p)", location, count, v);
5762 
5763 	if(count < 0)
5764 	{
5765 		return error(GL_INVALID_VALUE);
5766 	}
5767 
5768 	if(location == -1)
5769 	{
5770 		return;
5771 	}
5772 
5773 	es2::Context *context = es2::getContext();
5774 
5775 	if(context)
5776 	{
5777 		es2::Program *program = context->getCurrentProgram();
5778 
5779 		if(!program)
5780 		{
5781 			return error(GL_INVALID_OPERATION);
5782 		}
5783 
5784 		if(!program->setUniform4fv(location, count, v))
5785 		{
5786 			return error(GL_INVALID_OPERATION);
5787 		}
5788 	}
5789 }
5790 
Uniform4i(GLint location,GLint x,GLint y,GLint z,GLint w)5791 void Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w)
5792 {
5793 	GLint xyzw[4] = {x, y, z, w};
5794 
5795 	glUniform4iv(location, 1, (GLint*)&xyzw);
5796 }
5797 
Uniform4iv(GLint location,GLsizei count,const GLint * v)5798 void Uniform4iv(GLint location, GLsizei count, const GLint* v)
5799 {
5800 	TRACE("(GLint location = %d, GLsizei count = %d, const GLint* v = %p)", location, count, v);
5801 
5802 	if(count < 0)
5803 	{
5804 		return error(GL_INVALID_VALUE);
5805 	}
5806 
5807 	if(location == -1)
5808 	{
5809 		return;
5810 	}
5811 
5812 	es2::Context *context = es2::getContext();
5813 
5814 	if(context)
5815 	{
5816 		es2::Program *program = context->getCurrentProgram();
5817 
5818 		if(!program)
5819 		{
5820 			return error(GL_INVALID_OPERATION);
5821 		}
5822 
5823 		if(!program->setUniform4iv(location, count, v))
5824 		{
5825 			return error(GL_INVALID_OPERATION);
5826 		}
5827 	}
5828 }
5829 
UniformMatrix2fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5830 void UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5831 {
5832 	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5833 	      location, count, transpose, value);
5834 
5835 	if(count < 0)
5836 	{
5837 		return error(GL_INVALID_VALUE);
5838 	}
5839 
5840 	if(location == -1)
5841 	{
5842 		return;
5843 	}
5844 
5845 	es2::Context *context = es2::getContext();
5846 
5847 	if(context)
5848 	{
5849 		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5850 		{
5851 			return error(GL_INVALID_VALUE);
5852 		}
5853 
5854 		es2::Program *program = context->getCurrentProgram();
5855 
5856 		if(!program)
5857 		{
5858 			return error(GL_INVALID_OPERATION);
5859 		}
5860 
5861 		if(!program->setUniformMatrix2fv(location, count, transpose, value))
5862 		{
5863 			return error(GL_INVALID_OPERATION);
5864 		}
5865 	}
5866 }
5867 
UniformMatrix3fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5868 void UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5869 {
5870 	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5871 	      location, count, transpose, value);
5872 
5873 	if(count < 0)
5874 	{
5875 		return error(GL_INVALID_VALUE);
5876 	}
5877 
5878 	if(location == -1)
5879 	{
5880 		return;
5881 	}
5882 
5883 	es2::Context *context = es2::getContext();
5884 
5885 	if(context)
5886 	{
5887 		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5888 		{
5889 			return error(GL_INVALID_VALUE);
5890 		}
5891 
5892 		es2::Program *program = context->getCurrentProgram();
5893 
5894 		if(!program)
5895 		{
5896 			return error(GL_INVALID_OPERATION);
5897 		}
5898 
5899 		if(!program->setUniformMatrix3fv(location, count, transpose, value))
5900 		{
5901 			return error(GL_INVALID_OPERATION);
5902 		}
5903 	}
5904 }
5905 
UniformMatrix4fv(GLint location,GLsizei count,GLboolean transpose,const GLfloat * value)5906 void UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat* value)
5907 {
5908 	TRACE("(GLint location = %d, GLsizei count = %d, GLboolean transpose = %d, const GLfloat* value = %p)",
5909 	      location, count, transpose, value);
5910 
5911 	if(count < 0)
5912 	{
5913 		return error(GL_INVALID_VALUE);
5914 	}
5915 
5916 	if(location == -1)
5917 	{
5918 		return;
5919 	}
5920 
5921 	es2::Context *context = es2::getContext();
5922 
5923 	if(context)
5924 	{
5925 		if(context->getClientVersion() < 3 && transpose != GL_FALSE)
5926 		{
5927 			return error(GL_INVALID_VALUE);
5928 		}
5929 
5930 		es2::Program *program = context->getCurrentProgram();
5931 
5932 		if(!program)
5933 		{
5934 			return error(GL_INVALID_OPERATION);
5935 		}
5936 
5937 		if(!program->setUniformMatrix4fv(location, count, transpose, value))
5938 		{
5939 			return error(GL_INVALID_OPERATION);
5940 		}
5941 	}
5942 }
5943 
UseProgram(GLuint program)5944 void UseProgram(GLuint program)
5945 {
5946 	TRACE("(GLuint program = %d)", program);
5947 
5948 	es2::Context *context = es2::getContext();
5949 
5950 	if(context)
5951 	{
5952 		es2::Program *programObject = context->getProgram(program);
5953 
5954 		if(!programObject && program != 0)
5955 		{
5956 			if(context->getShader(program))
5957 			{
5958 				return error(GL_INVALID_OPERATION);
5959 			}
5960 			else
5961 			{
5962 				return error(GL_INVALID_VALUE);
5963 			}
5964 		}
5965 
5966 		if(program != 0 && !programObject->isLinked())
5967 		{
5968 			return error(GL_INVALID_OPERATION);
5969 		}
5970 
5971 		context->useProgram(program);
5972 	}
5973 }
5974 
ValidateProgram(GLuint program)5975 void ValidateProgram(GLuint program)
5976 {
5977 	TRACE("(GLuint program = %d)", program);
5978 
5979 	es2::Context *context = es2::getContext();
5980 
5981 	if(context)
5982 	{
5983 		es2::Program *programObject = context->getProgram(program);
5984 
5985 		if(!programObject)
5986 		{
5987 			if(context->getShader(program))
5988 			{
5989 				return error(GL_INVALID_OPERATION);
5990 			}
5991 			else
5992 			{
5993 				return error(GL_INVALID_VALUE);
5994 			}
5995 		}
5996 
5997 		programObject->validate();
5998 	}
5999 }
6000 
VertexAttrib1f(GLuint index,GLfloat x)6001 void VertexAttrib1f(GLuint index, GLfloat x)
6002 {
6003 	TRACE("(GLuint index = %d, GLfloat x = %f)", index, x);
6004 
6005 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6006 	{
6007 		return error(GL_INVALID_VALUE);
6008 	}
6009 
6010 	es2::Context *context = es2::getContext();
6011 
6012 	if(context)
6013 	{
6014 		GLfloat vals[4] = { x, 0, 0, 1 };
6015 		context->setVertexAttrib(index, vals);
6016 	}
6017 }
6018 
VertexAttrib1fv(GLuint index,const GLfloat * values)6019 void VertexAttrib1fv(GLuint index, const GLfloat* values)
6020 {
6021 	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6022 
6023 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6024 	{
6025 		return error(GL_INVALID_VALUE);
6026 	}
6027 
6028 	es2::Context *context = es2::getContext();
6029 
6030 	if(context)
6031 	{
6032 		GLfloat vals[4] = { values[0], 0, 0, 1 };
6033 		context->setVertexAttrib(index, vals);
6034 	}
6035 }
6036 
VertexAttrib2f(GLuint index,GLfloat x,GLfloat y)6037 void VertexAttrib2f(GLuint index, GLfloat x, GLfloat y)
6038 {
6039 	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f)", index, x, y);
6040 
6041 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6042 	{
6043 		return error(GL_INVALID_VALUE);
6044 	}
6045 
6046 	es2::Context *context = es2::getContext();
6047 
6048 	if(context)
6049 	{
6050 		GLfloat vals[4] = { x, y, 0, 1 };
6051 		context->setVertexAttrib(index, vals);
6052 	}
6053 }
6054 
VertexAttrib2fv(GLuint index,const GLfloat * values)6055 void VertexAttrib2fv(GLuint index, const GLfloat* values)
6056 {
6057 	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6058 
6059 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6060 	{
6061 		return error(GL_INVALID_VALUE);
6062 	}
6063 
6064 	es2::Context *context = es2::getContext();
6065 
6066 	if(context)
6067 	{
6068 		GLfloat vals[4] = { values[0], values[1], 0, 1 };
6069 		context->setVertexAttrib(index, vals);
6070 	}
6071 }
6072 
VertexAttrib3f(GLuint index,GLfloat x,GLfloat y,GLfloat z)6073 void VertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z)
6074 {
6075 	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", index, x, y, z);
6076 
6077 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6078 	{
6079 		return error(GL_INVALID_VALUE);
6080 	}
6081 
6082 	es2::Context *context = es2::getContext();
6083 
6084 	if(context)
6085 	{
6086 		GLfloat vals[4] = { x, y, z, 1 };
6087 		context->setVertexAttrib(index, vals);
6088 	}
6089 }
6090 
VertexAttrib3fv(GLuint index,const GLfloat * values)6091 void VertexAttrib3fv(GLuint index, const GLfloat* values)
6092 {
6093 	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6094 
6095 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6096 	{
6097 		return error(GL_INVALID_VALUE);
6098 	}
6099 
6100 	es2::Context *context = es2::getContext();
6101 
6102 	if(context)
6103 	{
6104 		GLfloat vals[4] = { values[0], values[1], values[2], 1 };
6105 		context->setVertexAttrib(index, vals);
6106 	}
6107 }
6108 
VertexAttrib4f(GLuint index,GLfloat x,GLfloat y,GLfloat z,GLfloat w)6109 void VertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
6110 {
6111 	TRACE("(GLuint index = %d, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat w = %f)", index, x, y, z, w);
6112 
6113 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6114 	{
6115 		return error(GL_INVALID_VALUE);
6116 	}
6117 
6118 	es2::Context *context = es2::getContext();
6119 
6120 	if(context)
6121 	{
6122 		GLfloat vals[4] = { x, y, z, w };
6123 		context->setVertexAttrib(index, vals);
6124 	}
6125 }
6126 
VertexAttrib4fv(GLuint index,const GLfloat * values)6127 void VertexAttrib4fv(GLuint index, const GLfloat* values)
6128 {
6129 	TRACE("(GLuint index = %d, const GLfloat* values = %p)", index, values);
6130 
6131 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6132 	{
6133 		return error(GL_INVALID_VALUE);
6134 	}
6135 
6136 	es2::Context *context = es2::getContext();
6137 
6138 	if(context)
6139 	{
6140 		context->setVertexAttrib(index, values);
6141 	}
6142 }
6143 
VertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)6144 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
6145 {
6146 	TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
6147 	      "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
6148 	      index, size, type, normalized, stride, ptr);
6149 
6150 	if(index >= es2::MAX_VERTEX_ATTRIBS)
6151 	{
6152 		return error(GL_INVALID_VALUE);
6153 	}
6154 
6155 	if(size < 1 || size > 4)
6156 	{
6157 		return error(GL_INVALID_VALUE);
6158 	}
6159 
6160 	GLint clientVersion = egl::getClientVersion();
6161 
6162 	switch(type)
6163 	{
6164 	case GL_BYTE:
6165 	case GL_UNSIGNED_BYTE:
6166 	case GL_SHORT:
6167 	case GL_UNSIGNED_SHORT:
6168 	case GL_FIXED:
6169 	case GL_FLOAT:
6170 		break;
6171 	case GL_INT_2_10_10_10_REV:
6172 	case GL_UNSIGNED_INT_2_10_10_10_REV:
6173 		if(clientVersion >= 3)
6174 		{
6175 			if(size != 4)
6176 			{
6177 				return error(GL_INVALID_OPERATION);
6178 			}
6179 			break;
6180 		}
6181 		else return error(GL_INVALID_ENUM);
6182 	case GL_INT:
6183 	case GL_UNSIGNED_INT:
6184 	case GL_HALF_FLOAT:
6185 		if(clientVersion >= 3)
6186 		{
6187 			break;
6188 		}
6189 		else return error(GL_INVALID_ENUM);
6190 	default:
6191 		return error(GL_INVALID_ENUM);
6192 	}
6193 
6194 	if(stride < 0)
6195 	{
6196 		return error(GL_INVALID_VALUE);
6197 	}
6198 
6199 	es2::Context *context = es2::getContext();
6200 
6201 	if(context)
6202 	{
6203 		context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
6204 	}
6205 }
6206 
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)6207 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
6208 {
6209 	TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
6210 
6211 	if(width < 0 || height < 0)
6212 	{
6213 		return error(GL_INVALID_VALUE);
6214 	}
6215 
6216 	es2::Context *context = es2::getContext();
6217 
6218 	if(context)
6219 	{
6220 		context->setViewportParams(x, y, width, height);
6221 	}
6222 }
6223 
BlitFramebufferNV(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)6224 void BlitFramebufferNV(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
6225 {
6226 	TRACE("(GLint srcX0 = %d, GLint srcY0 = %d, GLint srcX1 = %d, GLint srcY1 = %d, "
6227 	      "GLint dstX0 = %d, GLint dstY0 = %d, GLint dstX1 = %d, GLint dstY1 = %d, "
6228 	      "GLbitfield mask = 0x%X, GLenum filter = 0x%X)",
6229 	      srcX0, srcY0, srcX1, srcX1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6230 
6231 	switch(filter)
6232 	{
6233 	case GL_NEAREST:
6234 		break;
6235 	default:
6236 		return error(GL_INVALID_ENUM);
6237 	}
6238 
6239 	if((mask & ~(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)) != 0)
6240 	{
6241 		return error(GL_INVALID_VALUE);
6242 	}
6243 
6244 	es2::Context *context = es2::getContext();
6245 
6246 	if(context)
6247 	{
6248 		if(context->getReadFramebufferName() == context->getDrawFramebufferName())
6249 		{
6250 			ERR("Blits with the same source and destination framebuffer are not supported by this implementation.");
6251 			return error(GL_INVALID_OPERATION);
6252 		}
6253 
6254 		context->blitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask);
6255 	}
6256 }
6257 
BlitFramebufferANGLE(GLint srcX0,GLint srcY0,GLint srcX1,GLint srcY1,GLint dstX0,GLint dstY0,GLint dstX1,GLint dstY1,GLbitfield mask,GLenum filter)6258 void BlitFramebufferANGLE(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
6259                           GLbitfield mask, GLenum filter)
6260 {
6261 	if(srcX1 - srcX0 != dstX1 - dstX0 || srcY1 - srcY0 != dstY1 - dstY0)
6262 	{
6263 		ERR("Scaling and flipping in BlitFramebufferANGLE not supported by this implementation");
6264 		return error(GL_INVALID_OPERATION);
6265 	}
6266 
6267 	glBlitFramebufferNV(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
6268 }
6269 
TexImage3DOES(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLenum format,GLenum type,const GLvoid * pixels)6270 void TexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth,
6271                    GLint border, GLenum format, GLenum type, const GLvoid* pixels)
6272 {
6273 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
6274 	      "GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, GLint border = %d, "
6275 	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
6276 	      target, level, internalformat, width, height, depth, border, format, type, pixels);
6277 
6278 	switch(target)
6279 	{
6280 	case GL_TEXTURE_3D_OES:
6281 		switch(format)
6282 		{
6283 		case GL_DEPTH_COMPONENT:
6284 		case GL_DEPTH_STENCIL_OES:
6285 			return error(GL_INVALID_OPERATION);
6286 		default:
6287 			break;
6288 		}
6289 		break;
6290 	default:
6291 		return error(GL_INVALID_ENUM);
6292 	}
6293 
6294 	if(!ValidateTextureFormatType(format, type, internalformat, egl::getClientVersion()))
6295 	{
6296 		return;
6297 	}
6298 
6299 	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6300 	{
6301 		return error(GL_INVALID_VALUE);
6302 	}
6303 
6304 	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6305 	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D))
6306 	{
6307 		return error(GL_INVALID_VALUE);
6308 	}
6309 
6310 	if(border != 0)
6311 	{
6312 		return error(GL_INVALID_VALUE);
6313 	}
6314 
6315 	es2::Context *context = es2::getContext();
6316 
6317 	if(context)
6318 	{
6319 		es2::Texture3D *texture = context->getTexture3D();
6320 
6321 		if(!texture)
6322 		{
6323 			return error(GL_INVALID_OPERATION);
6324 		}
6325 
6326 		texture->setImage(level, width, height, depth, GetSizedInternalFormat(internalformat, type), type, context->getUnpackInfo(), pixels);
6327 	}
6328 }
6329 
TexSubImage3DOES(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLenum type,const void * pixels)6330 void TexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels)
6331 {
6332 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6333 	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6334 	      "GLenum format = 0x%X, GLenum type = 0x%x, const GLvoid* pixels = %p)",
6335 	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
6336 
6337 	switch(target)
6338 	{
6339 	case GL_TEXTURE_3D_OES:
6340 		break;
6341 	default:
6342 		return error(GL_INVALID_ENUM);
6343 	}
6344 
6345 	if(!ValidateTextureFormatType(format, type, format, egl::getClientVersion()))
6346 	{
6347 		return;
6348 	}
6349 
6350 	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6351 	{
6352 		return error(GL_INVALID_VALUE);
6353 	}
6354 
6355 	if((width < 0) || (height < 0) || (depth < 0))
6356 	{
6357 		return error(GL_INVALID_VALUE);
6358 	}
6359 
6360 	es2::Context *context = es2::getContext();
6361 
6362 	if(context)
6363 	{
6364 		es2::Texture3D *texture = context->getTexture3D();
6365 
6366 		GLenum sizedInternalFormat = GetSizedInternalFormat(format, type);
6367 
6368 		GLenum validationError = ValidateSubImageParams(false, width, height, depth, xoffset, yoffset, zoffset, target, level, sizedInternalFormat, texture);
6369 		if(validationError == GL_NONE)
6370 		{
6371 			texture->subImage(level, xoffset, yoffset, zoffset, width, height, depth, sizedInternalFormat, type, context->getUnpackInfo(), pixels);
6372 		}
6373 		else
6374 		{
6375 			return error(validationError);
6376 		}
6377 	}
6378 }
6379 
CopyTexSubImage3DOES(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLint x,GLint y,GLsizei width,GLsizei height)6380 void CopyTexSubImage3DOES(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height)
6381 {
6382 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6383 	      "GLint zoffset = %d, GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
6384 	      target, level, xoffset, yoffset, zoffset, x, y, width, height);
6385 
6386 	switch(target)
6387 	{
6388 	case GL_TEXTURE_3D_OES:
6389 		break;
6390 	default:
6391 		return error(GL_INVALID_ENUM);
6392 	}
6393 
6394 	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6395 	{
6396 		return error(GL_INVALID_VALUE);
6397 	}
6398 
6399 	es2::Context *context = es2::getContext();
6400 
6401 	if(context)
6402 	{
6403 		es2::Framebuffer *framebuffer = context->getReadFramebuffer();
6404 
6405 		if(framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE)
6406 		{
6407 			return error(GL_INVALID_FRAMEBUFFER_OPERATION);
6408 		}
6409 
6410 		es2::Renderbuffer *source = framebuffer->getReadColorbuffer();
6411 
6412 		if(context->getReadFramebufferName() != 0 && (!source || source->getSamples() > 1))
6413 		{
6414 			return error(GL_INVALID_OPERATION);
6415 		}
6416 
6417 		es2::Texture3D *texture = context->getTexture3D();
6418 
6419 		GLenum validationError = ValidateSubImageParams(false, width, height, 1, xoffset, yoffset, zoffset, target, level, GL_NONE, texture);
6420 
6421 		if(validationError != GL_NONE)
6422 		{
6423 			return error(validationError);
6424 		}
6425 
6426 		texture->copySubImage(target, level, xoffset, yoffset, zoffset, x, y, width, height, framebuffer);
6427 	}
6428 }
6429 
CompressedTexImage3DOES(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLsizei depth,GLint border,GLsizei imageSize,const void * data)6430 void CompressedTexImage3DOES(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data)
6431 {
6432 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
6433 	      "GLsizei height = %d, GLsizei depth = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
6434 	      target, level, internalformat, width, height, depth, border, imageSize, data);
6435 
6436 	switch(target)
6437 	{
6438 	case GL_TEXTURE_3D_OES:
6439 		break;
6440 	default:
6441 		return error(GL_INVALID_ENUM);
6442 	}
6443 
6444 	if((level < 0) || (level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
6445 	{
6446 		return error(GL_INVALID_VALUE);
6447 	}
6448 
6449 	const GLsizei maxSize3D = es2::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level;
6450 	if((width < 0) || (height < 0) || (depth < 0) || (width > maxSize3D) || (height > maxSize3D) || (depth > maxSize3D) ||(border != 0) || (imageSize < 0))
6451 	{
6452 		return error(GL_INVALID_VALUE);
6453 	}
6454 
6455 	switch(internalformat)
6456 	{
6457 	case GL_DEPTH_COMPONENT:
6458 	case GL_DEPTH_COMPONENT16:
6459 	case GL_DEPTH_COMPONENT32_OES:
6460 	case GL_DEPTH_STENCIL_OES:
6461 	case GL_DEPTH24_STENCIL8_OES:
6462 		return error(GL_INVALID_OPERATION);
6463 	default:
6464 		{
6465 			GLenum validationError = ValidateCompressedFormat(internalformat, egl::getClientVersion(), true);
6466 			if(validationError != GL_NONE)
6467 			{
6468 				return error(validationError);
6469 			}
6470 		}
6471 	}
6472 
6473 	if(imageSize != egl::ComputeCompressedSize(width, height, internalformat) * depth)
6474 	{
6475 		return error(GL_INVALID_VALUE);
6476 	}
6477 
6478 	es2::Context *context = es2::getContext();
6479 
6480 	if(context)
6481 	{
6482 		es2::Texture3D *texture = context->getTexture3D();
6483 
6484 		if(!texture)
6485 		{
6486 			return error(GL_INVALID_OPERATION);
6487 		}
6488 
6489 		texture->setCompressedImage(level, internalformat, width, height, depth, imageSize, data);
6490 	}
6491 }
6492 
CompressedTexSubImage3DOES(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint zoffset,GLsizei width,GLsizei height,GLsizei depth,GLenum format,GLsizei imageSize,const void * data)6493 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)
6494 {
6495 	TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
6496 	      "GLint zoffset = %d, GLsizei width = %d, GLsizei height = %d, GLsizei depth = %d, "
6497 	      "GLenum format = 0x%X, GLsizei imageSize = %d, const void *data = %p)",
6498 	      target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6499 
6500 	switch(target)
6501 	{
6502 	case GL_TEXTURE_3D_OES:
6503 		break;
6504 	default:
6505 		return error(GL_INVALID_ENUM);
6506 	}
6507 
6508 	if(level < 0 || level >= es2::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
6509 	{
6510 		return error(GL_INVALID_VALUE);
6511 	}
6512 
6513 	if(xoffset < 0 || yoffset < 0 || zoffset < 0 || !validImageSize(level, width, height) || depth < 0 || imageSize < 0)
6514 	{
6515 		return error(GL_INVALID_VALUE);
6516 	}
6517 
6518 	GLenum validationError = ValidateCompressedFormat(format, egl::getClientVersion(), true);
6519 	if(validationError != GL_NONE)
6520 	{
6521 		return error(validationError);
6522 	}
6523 
6524 	if(width == 0 || height == 0 || depth == 0 || !data)
6525 	{
6526 		return;
6527 	}
6528 
6529 	es2::Context *context = es2::getContext();
6530 
6531 	if(context)
6532 	{
6533 		es2::Texture3D *texture = context->getTexture3D();
6534 
6535 		if(!texture)
6536 		{
6537 			return error(GL_INVALID_OPERATION);
6538 		}
6539 
6540 		texture->subImageCompressed(level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
6541 	}
6542 }
6543 
FramebufferTexture3DOES(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level,GLint zoffset)6544 void FramebufferTexture3DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset)
6545 {
6546 	TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
6547 	      "GLuint texture = %d, GLint level = %d, GLint zoffset = %d)", target, attachment, textarget, texture, level, zoffset);
6548 
6549 	if(target != GL_FRAMEBUFFER && target != GL_DRAW_FRAMEBUFFER_ANGLE && target != GL_READ_FRAMEBUFFER_ANGLE)
6550 	{
6551 		return error(GL_INVALID_ENUM);
6552 	}
6553 
6554 	es2::Context *context = es2::getContext();
6555 
6556 	if(context)
6557 	{
6558 		if(texture == 0)
6559 		{
6560 			textarget = GL_NONE;
6561 		}
6562 		else
6563 		{
6564 			es2::Texture *tex = context->getTexture(texture);
6565 
6566 			if(!tex)
6567 			{
6568 				return error(GL_INVALID_OPERATION);
6569 			}
6570 
6571 			if(tex->isCompressed(textarget, level))
6572 			{
6573 				return error(GL_INVALID_OPERATION);
6574 			}
6575 
6576 			switch(textarget)
6577 			{
6578 			case GL_TEXTURE_3D_OES:
6579 				if(tex->getTarget() != GL_TEXTURE_3D_OES)
6580 				{
6581 					return error(GL_INVALID_OPERATION);
6582 				}
6583 				break;
6584 			default:
6585 				return error(GL_INVALID_ENUM);
6586 			}
6587 
6588 			if(level != 0)
6589 			{
6590 				return error(GL_INVALID_VALUE);
6591 			}
6592 		}
6593 
6594 		es2::Framebuffer *framebuffer = nullptr;
6595 		GLuint framebufferName = 0;
6596 		if(target == GL_READ_FRAMEBUFFER_ANGLE)
6597 		{
6598 			framebuffer = context->getReadFramebuffer();
6599 			framebufferName = context->getReadFramebufferName();
6600 		}
6601 		else
6602 		{
6603 			framebuffer = context->getDrawFramebuffer();
6604 			framebufferName = context->getDrawFramebufferName();
6605 		}
6606 
6607 		if(framebufferName == 0 || !framebuffer)
6608 		{
6609 			return error(GL_INVALID_OPERATION);
6610 		}
6611 
6612 		GLint clientVersion = context->getClientVersion();
6613 
6614 		switch(attachment)
6615 		{
6616 		case GL_COLOR_ATTACHMENT1:
6617 		case GL_COLOR_ATTACHMENT2:
6618 		case GL_COLOR_ATTACHMENT3:
6619 		case GL_COLOR_ATTACHMENT4:
6620 		case GL_COLOR_ATTACHMENT5:
6621 		case GL_COLOR_ATTACHMENT6:
6622 		case GL_COLOR_ATTACHMENT7:
6623 		case GL_COLOR_ATTACHMENT8:
6624 		case GL_COLOR_ATTACHMENT9:
6625 		case GL_COLOR_ATTACHMENT10:
6626 		case GL_COLOR_ATTACHMENT11:
6627 		case GL_COLOR_ATTACHMENT12:
6628 		case GL_COLOR_ATTACHMENT13:
6629 		case GL_COLOR_ATTACHMENT14:
6630 		case GL_COLOR_ATTACHMENT15:
6631 		case GL_COLOR_ATTACHMENT16:
6632 		case GL_COLOR_ATTACHMENT17:
6633 		case GL_COLOR_ATTACHMENT18:
6634 		case GL_COLOR_ATTACHMENT19:
6635 		case GL_COLOR_ATTACHMENT20:
6636 		case GL_COLOR_ATTACHMENT21:
6637 		case GL_COLOR_ATTACHMENT22:
6638 		case GL_COLOR_ATTACHMENT23:
6639 		case GL_COLOR_ATTACHMENT24:
6640 		case GL_COLOR_ATTACHMENT25:
6641 		case GL_COLOR_ATTACHMENT26:
6642 		case GL_COLOR_ATTACHMENT27:
6643 		case GL_COLOR_ATTACHMENT28:
6644 		case GL_COLOR_ATTACHMENT29:
6645 		case GL_COLOR_ATTACHMENT30:
6646 		case GL_COLOR_ATTACHMENT31:
6647 			if(clientVersion < 3)
6648 			{
6649 				return error(GL_INVALID_ENUM);
6650 			}
6651 			// fall through
6652 		case GL_COLOR_ATTACHMENT0:
6653 			if((attachment - GL_COLOR_ATTACHMENT0) >= MAX_COLOR_ATTACHMENTS)
6654 			{
6655 				return error(GL_INVALID_ENUM);
6656 			}
6657 			framebuffer->setColorbuffer(textarget, texture, attachment - GL_COLOR_ATTACHMENT0);
6658 			break;
6659 		case GL_DEPTH_ATTACHMENT:   framebuffer->setDepthbuffer(textarget, texture);   break;
6660 		case GL_STENCIL_ATTACHMENT: framebuffer->setStencilbuffer(textarget, texture); break;
6661 		default:
6662 			return error(GL_INVALID_ENUM);
6663 		}
6664 	}
6665 }
6666 
EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)6667 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
6668 {
6669 	if(egl::getClientVersion() == 1)
6670 	{
6671 		return libGLES_CM->glEGLImageTargetTexture2DOES(target, image);
6672 	}
6673 
6674 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6675 
6676 	switch(target)
6677 	{
6678 	case GL_TEXTURE_2D:
6679 	case GL_TEXTURE_EXTERNAL_OES:
6680 		break;
6681 	default:
6682 		return error(GL_INVALID_ENUM);
6683 	}
6684 
6685 	if(!image)
6686 	{
6687 		return error(GL_INVALID_OPERATION);
6688 	}
6689 
6690 	es2::Context *context = es2::getContext();
6691 
6692 	if(context)
6693 	{
6694 		es2::Texture2D *texture = 0;
6695 
6696 		switch(target)
6697 		{
6698 		case GL_TEXTURE_2D:           texture = context->getTexture2D();       break;
6699 		case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
6700 		default:                      UNREACHABLE(target);
6701 		}
6702 
6703 		if(!texture)
6704 		{
6705 			return error(GL_INVALID_OPERATION);
6706 		}
6707 
6708 		egl::Image *glImage = static_cast<egl::Image*>(image);
6709 
6710 		texture->setImage(glImage);
6711 	}
6712 }
6713 
EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)6714 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
6715 {
6716 	TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
6717 
6718 	UNIMPLEMENTED();
6719 }
6720 
IsRenderbufferOES(GLuint renderbuffer)6721 GLboolean IsRenderbufferOES(GLuint renderbuffer)
6722 {
6723 	return IsRenderbuffer(renderbuffer);
6724 }
6725 
BindRenderbufferOES(GLenum target,GLuint renderbuffer)6726 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
6727 {
6728 	BindRenderbuffer(target, renderbuffer);
6729 }
6730 
DeleteRenderbuffersOES(GLsizei n,const GLuint * renderbuffers)6731 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
6732 {
6733 	DeleteRenderbuffers(n, renderbuffers);
6734 }
6735 
GenRenderbuffersOES(GLsizei n,GLuint * renderbuffers)6736 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
6737 {
6738 	GenRenderbuffers(n, renderbuffers);
6739 }
6740 
RenderbufferStorageOES(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)6741 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
6742 {
6743 	RenderbufferStorage(target, internalformat, width, height);
6744 }
6745 
GetRenderbufferParameterivOES(GLenum target,GLenum pname,GLint * params)6746 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
6747 {
6748 	GetRenderbufferParameteriv(target, pname, params);
6749 }
6750 
IsFramebufferOES(GLuint framebuffer)6751 GLboolean IsFramebufferOES(GLuint framebuffer)
6752 {
6753 	return IsFramebuffer(framebuffer);
6754 }
6755 
BindFramebufferOES(GLenum target,GLuint framebuffer)6756 void BindFramebufferOES(GLenum target, GLuint framebuffer)
6757 {
6758 	BindFramebuffer(target, framebuffer);
6759 }
6760 
DeleteFramebuffersOES(GLsizei n,const GLuint * framebuffers)6761 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
6762 {
6763 	DeleteFramebuffers(n, framebuffers);
6764 }
6765 
GenFramebuffersOES(GLsizei n,GLuint * framebuffers)6766 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
6767 {
6768 	GenFramebuffers(n, framebuffers);
6769 }
6770 
CheckFramebufferStatusOES(GLenum target)6771 GLenum CheckFramebufferStatusOES(GLenum target)
6772 {
6773 	return CheckFramebufferStatus(target);
6774 }
6775 
FramebufferRenderbufferOES(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)6776 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
6777 {
6778 	FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
6779 }
6780 
FramebufferTexture2DOES(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)6781 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
6782 {
6783 	FramebufferTexture2D(target, attachment, textarget, texture, level);
6784 }
6785 
GetFramebufferAttachmentParameterivOES(GLenum target,GLenum attachment,GLenum pname,GLint * params)6786 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
6787 {
6788 	GetFramebufferAttachmentParameteriv(target, attachment, pname, params);
6789 }
6790 
GenerateMipmapOES(GLenum target)6791 void GenerateMipmapOES(GLenum target)
6792 {
6793 	GenerateMipmap(target);
6794 }
6795 
DrawBuffersEXT(GLsizei n,const GLenum * bufs)6796 void DrawBuffersEXT(GLsizei n, const GLenum *bufs)
6797 {
6798 	TRACE("(GLsizei n = %d, const GLenum *bufs = %p)", n, bufs);
6799 
6800 	if(n < 0 || n > MAX_DRAW_BUFFERS)
6801 	{
6802 		return error(GL_INVALID_VALUE);
6803 	}
6804 
6805 	es2::Context *context = es2::getContext();
6806 
6807 	if(context)
6808 	{
6809 		GLuint drawFramebufferName = context->getDrawFramebufferName();
6810 
6811 		if((drawFramebufferName == 0) && (n != 1))
6812 		{
6813 			return error(GL_INVALID_OPERATION);
6814 		}
6815 
6816 		for(unsigned int i = 0; i < (unsigned)n; i++)
6817 		{
6818 			switch(bufs[i])
6819 			{
6820 			case GL_BACK:
6821 				if(drawFramebufferName != 0)
6822 				{
6823 					return error(GL_INVALID_OPERATION);
6824 				}
6825 				break;
6826 			case GL_NONE:
6827 				break;
6828 			case GL_COLOR_ATTACHMENT0_EXT:
6829 			case GL_COLOR_ATTACHMENT1_EXT:
6830 			case GL_COLOR_ATTACHMENT2_EXT:
6831 			case GL_COLOR_ATTACHMENT3_EXT:
6832 			case GL_COLOR_ATTACHMENT4_EXT:
6833 			case GL_COLOR_ATTACHMENT5_EXT:
6834 			case GL_COLOR_ATTACHMENT6_EXT:
6835 			case GL_COLOR_ATTACHMENT7_EXT:
6836 			case GL_COLOR_ATTACHMENT8_EXT:
6837 			case GL_COLOR_ATTACHMENT9_EXT:
6838 			case GL_COLOR_ATTACHMENT10_EXT:
6839 			case GL_COLOR_ATTACHMENT11_EXT:
6840 			case GL_COLOR_ATTACHMENT12_EXT:
6841 			case GL_COLOR_ATTACHMENT13_EXT:
6842 			case GL_COLOR_ATTACHMENT14_EXT:
6843 			case GL_COLOR_ATTACHMENT15_EXT:
6844 				{
6845 					GLuint index = (bufs[i] - GL_COLOR_ATTACHMENT0_EXT);
6846 
6847 					if(index >= MAX_COLOR_ATTACHMENTS)
6848 					{
6849 						return error(GL_INVALID_OPERATION);
6850 					}
6851 
6852 					if(index != i)
6853 					{
6854 						return error(GL_INVALID_OPERATION);
6855 					}
6856 
6857 					if(drawFramebufferName == 0)
6858 					{
6859 						return error(GL_INVALID_OPERATION);
6860 					}
6861 				}
6862 				break;
6863 			default:
6864 				return error(GL_INVALID_ENUM);
6865 			}
6866 		}
6867 
6868 		context->setFramebufferDrawBuffers(n, bufs);
6869 	}
6870 }
6871 
6872 }
6873 
es2GetProcAddress(const char * procname)6874 extern "C" __eglMustCastToProperFunctionPointerType es2GetProcAddress(const char *procname)
6875 {
6876 	struct Extension
6877 	{
6878 		const char *name;
6879 		__eglMustCastToProperFunctionPointerType address;
6880 	};
6881 
6882 	static const Extension glExtensions[] =
6883 	{
6884 		#define EXTENSION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
6885 
6886 		EXTENSION(glTexImage3DOES),
6887 		EXTENSION(glBlitFramebufferANGLE),
6888 		EXTENSION(glBlitFramebufferNV),
6889 		EXTENSION(glRenderbufferStorageMultisampleANGLE),
6890 		EXTENSION(glDeleteFencesNV),
6891 		EXTENSION(glGenFencesNV),
6892 		EXTENSION(glIsFenceNV),
6893 		EXTENSION(glTestFenceNV),
6894 		EXTENSION(glGetFenceivNV),
6895 		EXTENSION(glFinishFenceNV),
6896 		EXTENSION(glSetFenceNV),
6897 		EXTENSION(glGetGraphicsResetStatusEXT),
6898 		EXTENSION(glReadnPixelsEXT),
6899 		EXTENSION(glGetnUniformfvEXT),
6900 		EXTENSION(glGetnUniformivEXT),
6901 		EXTENSION(glGenQueriesEXT),
6902 		EXTENSION(glDeleteQueriesEXT),
6903 		EXTENSION(glIsQueryEXT),
6904 		EXTENSION(glBeginQueryEXT),
6905 		EXTENSION(glEndQueryEXT),
6906 		EXTENSION(glGetQueryivEXT),
6907 		EXTENSION(glGetQueryObjectuivEXT),
6908 		EXTENSION(glEGLImageTargetTexture2DOES),
6909 		EXTENSION(glEGLImageTargetRenderbufferStorageOES),
6910 		EXTENSION(glDrawElementsInstancedEXT),
6911 		EXTENSION(glDrawArraysInstancedEXT),
6912 		EXTENSION(glVertexAttribDivisorEXT),
6913 		EXTENSION(glDrawArraysInstancedANGLE),
6914 		EXTENSION(glDrawElementsInstancedANGLE),
6915 		EXTENSION(glVertexAttribDivisorANGLE),
6916 		EXTENSION(glIsRenderbufferOES),
6917 		EXTENSION(glBindRenderbufferOES),
6918 		EXTENSION(glDeleteRenderbuffersOES),
6919 		EXTENSION(glGenRenderbuffersOES),
6920 		EXTENSION(glRenderbufferStorageOES),
6921 		EXTENSION(glGetRenderbufferParameterivOES),
6922 		EXTENSION(glIsFramebufferOES),
6923 		EXTENSION(glBindFramebufferOES),
6924 		EXTENSION(glDeleteFramebuffersOES),
6925 		EXTENSION(glGenFramebuffersOES),
6926 		EXTENSION(glCheckFramebufferStatusOES),
6927 		EXTENSION(glFramebufferRenderbufferOES),
6928 		EXTENSION(glFramebufferTexture2DOES),
6929 		EXTENSION(glGetFramebufferAttachmentParameterivOES),
6930 		EXTENSION(glGenerateMipmapOES),
6931 		EXTENSION(glDrawBuffersEXT),
6932 
6933 		#undef EXTENSION
6934 	};
6935 
6936 	for(unsigned int ext = 0; ext < sizeof(glExtensions) / sizeof(Extension); ext++)
6937 	{
6938 		if(strcmp(procname, glExtensions[ext].name) == 0)
6939 		{
6940 			return (__eglMustCastToProperFunctionPointerType)glExtensions[ext].address;
6941 		}
6942 	}
6943 
6944 	return nullptr;
6945 }
6946