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
15 // libGLES_CM.cpp: Implements the exported OpenGL ES 1.1 functions.
16
17 #include "main.h"
18 #include "mathutil.h"
19 #include "utilities.h"
20 #include "Buffer.h"
21 #include "Context.h"
22 #include "Framebuffer.h"
23 #include "Renderbuffer.h"
24 #include "Texture.h"
25 #include "common/debug.h"
26 #include "Common/SharedLibrary.hpp"
27 #include "Common/Version.h"
28
29 #include <EGL/egl.h>
30 #include <EGL/eglext.h>
31
32 #include <GLES/gl.h>
33 #include <GLES/glext.h>
34
35 #include <algorithm>
36 #include <limits>
37
38 namespace es1
39 {
40
validImageSize(GLint level,GLsizei width,GLsizei height)41 static bool validImageSize(GLint level, GLsizei width, GLsizei height)
42 {
43 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS || width < 0 || height < 0)
44 {
45 return false;
46 }
47
48 return true;
49 }
50
ActiveTexture(GLenum texture)51 void ActiveTexture(GLenum texture)
52 {
53 TRACE("(GLenum texture = 0x%X)", texture);
54
55 es1::Context *context = es1::getContext();
56
57 if(context)
58 {
59 if(texture < GL_TEXTURE0 || texture > GL_TEXTURE0 + es1::MAX_TEXTURE_UNITS - 1)
60 {
61 return error(GL_INVALID_ENUM);
62 }
63
64 context->setActiveSampler(texture - GL_TEXTURE0);
65 }
66 }
67
AlphaFunc(GLenum func,GLclampf ref)68 void AlphaFunc(GLenum func, GLclampf ref)
69 {
70 TRACE("(GLenum func = 0x%X, GLclampf ref = %f)", func, ref);
71
72 switch(func)
73 {
74 case GL_NEVER:
75 case GL_ALWAYS:
76 case GL_LESS:
77 case GL_LEQUAL:
78 case GL_EQUAL:
79 case GL_GEQUAL:
80 case GL_GREATER:
81 case GL_NOTEQUAL:
82 break;
83 default:
84 return error(GL_INVALID_ENUM);
85 }
86
87 es1::Context *context = es1::getContext();
88
89 if(context)
90 {
91 context->setAlphaFunc(func, clamp01(ref));
92 }
93 }
94
AlphaFuncx(GLenum func,GLclampx ref)95 void AlphaFuncx(GLenum func, GLclampx ref)
96 {
97 AlphaFunc(func, (float)ref / 0x10000);
98 }
99
BindBuffer(GLenum target,GLuint buffer)100 void BindBuffer(GLenum target, GLuint buffer)
101 {
102 TRACE("(GLenum target = 0x%X, GLuint buffer = %d)", target, buffer);
103
104 es1::Context *context = es1::getContext();
105
106 if(context)
107 {
108 switch(target)
109 {
110 case GL_ARRAY_BUFFER:
111 context->bindArrayBuffer(buffer);
112 return;
113 case GL_ELEMENT_ARRAY_BUFFER:
114 context->bindElementArrayBuffer(buffer);
115 return;
116 default:
117 return error(GL_INVALID_ENUM);
118 }
119 }
120 }
121
BindFramebuffer(GLenum target,GLuint framebuffer)122 void BindFramebuffer(GLenum target, GLuint framebuffer)
123 {
124 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
125
126 if(target != GL_FRAMEBUFFER_OES)
127 {
128 return error(GL_INVALID_ENUM);
129 }
130
131 es1::Context *context = es1::getContext();
132
133 if(context)
134 {
135 context->bindFramebuffer(framebuffer);
136 }
137 }
138
BindFramebufferOES(GLenum target,GLuint framebuffer)139 void BindFramebufferOES(GLenum target, GLuint framebuffer)
140 {
141 TRACE("(GLenum target = 0x%X, GLuint framebuffer = %d)", target, framebuffer);
142
143 if(target != GL_FRAMEBUFFER_OES)
144 {
145 return error(GL_INVALID_ENUM);
146 }
147
148 es1::Context *context = es1::getContext();
149
150 if(context)
151 {
152 context->bindFramebuffer(framebuffer);
153 }
154 }
155
BindRenderbufferOES(GLenum target,GLuint renderbuffer)156 void BindRenderbufferOES(GLenum target, GLuint renderbuffer)
157 {
158 TRACE("(GLenum target = 0x%X, GLuint renderbuffer = %d)", target, renderbuffer);
159
160 if(target != GL_RENDERBUFFER_OES)
161 {
162 return error(GL_INVALID_ENUM);
163 }
164
165 es1::Context *context = es1::getContext();
166
167 if(context)
168 {
169 // [GL_EXT_framebuffer_object]
170 // If <renderbuffer> is not zero, then the resulting renderbuffer object
171 // is a new state vector, initialized with a zero-sized memory buffer
172 context->bindRenderbuffer(renderbuffer);
173 }
174 }
175
BindTexture(GLenum target,GLuint texture)176 void BindTexture(GLenum target, GLuint texture)
177 {
178 TRACE("(GLenum target = 0x%X, GLuint texture = %d)", target, texture);
179
180 es1::Context *context = es1::getContext();
181
182 if(context)
183 {
184 es1::Texture *textureObject = context->getTexture(texture);
185
186 if(textureObject && textureObject->getTarget() != target && texture != 0)
187 {
188 return error(GL_INVALID_OPERATION);
189 }
190
191 switch(target)
192 {
193 case GL_TEXTURE_2D:
194 context->bindTexture(TEXTURE_2D, texture);
195 break;
196 case GL_TEXTURE_EXTERNAL_OES:
197 context->bindTexture(TEXTURE_EXTERNAL, texture);
198 break;
199 default:
200 return error(GL_INVALID_ENUM);
201 }
202 }
203 }
204
205 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha);
206
BlendEquationOES(GLenum mode)207 void BlendEquationOES(GLenum mode)
208 {
209 BlendEquationSeparateOES(mode, mode);
210 }
211
BlendEquationSeparateOES(GLenum modeRGB,GLenum modeAlpha)212 void BlendEquationSeparateOES(GLenum modeRGB, GLenum modeAlpha)
213 {
214 TRACE("(GLenum modeRGB = 0x%X, GLenum modeAlpha = 0x%X)", modeRGB, modeAlpha);
215
216 switch(modeRGB)
217 {
218 case GL_FUNC_ADD_OES:
219 case GL_FUNC_SUBTRACT_OES:
220 case GL_FUNC_REVERSE_SUBTRACT_OES:
221 case GL_MIN_EXT:
222 case GL_MAX_EXT:
223 break;
224 default:
225 return error(GL_INVALID_ENUM);
226 }
227
228 switch(modeAlpha)
229 {
230 case GL_FUNC_ADD_OES:
231 case GL_FUNC_SUBTRACT_OES:
232 case GL_FUNC_REVERSE_SUBTRACT_OES:
233 case GL_MIN_EXT:
234 case GL_MAX_EXT:
235 break;
236 default:
237 return error(GL_INVALID_ENUM);
238 }
239
240 es1::Context *context = es1::getContext();
241
242 if(context)
243 {
244 context->setBlendEquation(modeRGB, modeAlpha);
245 }
246 }
247
248 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
249
BlendFunc(GLenum sfactor,GLenum dfactor)250 void BlendFunc(GLenum sfactor, GLenum dfactor)
251 {
252 BlendFuncSeparateOES(sfactor, dfactor, sfactor, dfactor);
253 }
254
BlendFuncSeparateOES(GLenum srcRGB,GLenum dstRGB,GLenum srcAlpha,GLenum dstAlpha)255 void BlendFuncSeparateOES(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
256 {
257 TRACE("(GLenum srcRGB = 0x%X, GLenum dstRGB = 0x%X, GLenum srcAlpha = 0x%X, GLenum dstAlpha = 0x%X)",
258 srcRGB, dstRGB, srcAlpha, dstAlpha);
259
260 switch(srcRGB)
261 {
262 case GL_ZERO:
263 case GL_ONE:
264 case GL_SRC_COLOR:
265 case GL_ONE_MINUS_SRC_COLOR:
266 case GL_DST_COLOR:
267 case GL_ONE_MINUS_DST_COLOR:
268 case GL_SRC_ALPHA:
269 case GL_ONE_MINUS_SRC_ALPHA:
270 case GL_DST_ALPHA:
271 case GL_ONE_MINUS_DST_ALPHA:
272 case GL_SRC_ALPHA_SATURATE:
273 break;
274 default:
275 return error(GL_INVALID_ENUM);
276 }
277
278 switch(dstRGB)
279 {
280 case GL_ZERO:
281 case GL_ONE:
282 case GL_SRC_COLOR:
283 case GL_ONE_MINUS_SRC_COLOR:
284 case GL_DST_COLOR:
285 case GL_ONE_MINUS_DST_COLOR:
286 case GL_SRC_ALPHA:
287 case GL_ONE_MINUS_SRC_ALPHA:
288 case GL_DST_ALPHA:
289 case GL_ONE_MINUS_DST_ALPHA:
290 break;
291 default:
292 return error(GL_INVALID_ENUM);
293 }
294
295 switch(srcAlpha)
296 {
297 case GL_ZERO:
298 case GL_ONE:
299 case GL_SRC_COLOR:
300 case GL_ONE_MINUS_SRC_COLOR:
301 case GL_DST_COLOR:
302 case GL_ONE_MINUS_DST_COLOR:
303 case GL_SRC_ALPHA:
304 case GL_ONE_MINUS_SRC_ALPHA:
305 case GL_DST_ALPHA:
306 case GL_ONE_MINUS_DST_ALPHA:
307 case GL_SRC_ALPHA_SATURATE:
308 break;
309 default:
310 return error(GL_INVALID_ENUM);
311 }
312
313 switch(dstAlpha)
314 {
315 case GL_ZERO:
316 case GL_ONE:
317 case GL_SRC_COLOR:
318 case GL_ONE_MINUS_SRC_COLOR:
319 case GL_DST_COLOR:
320 case GL_ONE_MINUS_DST_COLOR:
321 case GL_SRC_ALPHA:
322 case GL_ONE_MINUS_SRC_ALPHA:
323 case GL_DST_ALPHA:
324 case GL_ONE_MINUS_DST_ALPHA:
325 break;
326 default:
327 return error(GL_INVALID_ENUM);
328 }
329
330 es1::Context *context = es1::getContext();
331
332 if(context)
333 {
334 context->setBlendFactors(srcRGB, dstRGB, srcAlpha, dstAlpha);
335 }
336 }
337
BufferData(GLenum target,GLsizeiptr size,const GLvoid * data,GLenum usage)338 void BufferData(GLenum target, GLsizeiptr size, const GLvoid* data, GLenum usage)
339 {
340 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
341
342 TRACE("(GLenum target = 0x%X, GLsizeiptr size = %d, const GLvoid* data = %p, GLenum usage = %d)",
343 target, size, data, usage);
344
345 if(size < 0)
346 {
347 return error(GL_INVALID_VALUE);
348 }
349
350 switch(usage)
351 {
352 case GL_STATIC_DRAW:
353 case GL_DYNAMIC_DRAW:
354 break;
355 default:
356 return error(GL_INVALID_ENUM);
357 }
358
359 es1::Context *context = es1::getContext();
360
361 if(context)
362 {
363 es1::Buffer *buffer;
364
365 switch(target)
366 {
367 case GL_ARRAY_BUFFER:
368 buffer = context->getArrayBuffer();
369 break;
370 case GL_ELEMENT_ARRAY_BUFFER:
371 buffer = context->getElementArrayBuffer();
372 break;
373 default:
374 return error(GL_INVALID_ENUM);
375 }
376
377 if(!buffer)
378 {
379 return error(GL_INVALID_OPERATION);
380 }
381
382 buffer->bufferData(data, size, usage);
383 }
384 }
385
BufferSubData(GLenum target,GLintptr offset,GLsizeiptr size,const GLvoid * data)386 void BufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid* data)
387 {
388 size = static_cast<GLint>(size); // Work around issues with some 64-bit applications
389 offset = static_cast<GLint>(offset);
390
391 TRACE("(GLenum target = 0x%X, GLintptr offset = %d, GLsizeiptr size = %d, const GLvoid* data = %p)",
392 target, offset, size, data);
393
394 if(size < 0 || offset < 0)
395 {
396 return error(GL_INVALID_VALUE);
397 }
398
399 if(!data)
400 {
401 return;
402 }
403
404 es1::Context *context = es1::getContext();
405
406 if(context)
407 {
408 es1::Buffer *buffer;
409
410 switch(target)
411 {
412 case GL_ARRAY_BUFFER:
413 buffer = context->getArrayBuffer();
414 break;
415 case GL_ELEMENT_ARRAY_BUFFER:
416 buffer = context->getElementArrayBuffer();
417 break;
418 default:
419 return error(GL_INVALID_ENUM);
420 }
421
422 if(!buffer)
423 {
424 return error(GL_INVALID_OPERATION);
425 }
426
427 if((size_t)size + offset > buffer->size())
428 {
429 return error(GL_INVALID_VALUE);
430 }
431
432 buffer->bufferSubData(data, size, offset);
433 }
434 }
435
CheckFramebufferStatusOES(GLenum target)436 GLenum CheckFramebufferStatusOES(GLenum target)
437 {
438 TRACE("(GLenum target = 0x%X)", target);
439
440 if(target != GL_FRAMEBUFFER_OES)
441 {
442 return error(GL_INVALID_ENUM, 0);
443 }
444
445 es1::Context *context = es1::getContext();
446
447 if(context)
448 {
449 es1::Framebuffer *framebuffer = context->getFramebuffer();
450
451 if(!framebuffer)
452 {
453 return GL_FRAMEBUFFER_UNDEFINED_OES;
454 }
455
456 return framebuffer->completeness();
457 }
458
459 return 0;
460 }
461
Clear(GLbitfield mask)462 void Clear(GLbitfield mask)
463 {
464 TRACE("(GLbitfield mask = %X)", mask);
465
466 if((mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) != 0)
467 {
468 return error(GL_INVALID_VALUE);
469 }
470
471 es1::Context *context = es1::getContext();
472
473 if(context)
474 {
475 context->clear(mask);
476 }
477 }
478
ClearColor(GLclampf red,GLclampf green,GLclampf blue,GLclampf alpha)479 void ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha)
480 {
481 TRACE("(GLclampf red = %f, GLclampf green = %f, GLclampf blue = %f, GLclampf alpha = %f)",
482 red, green, blue, alpha);
483
484 es1::Context *context = es1::getContext();
485
486 if(context)
487 {
488 context->setClearColor(red, green, blue, alpha);
489 }
490 }
491
ClearColorx(GLclampx red,GLclampx green,GLclampx blue,GLclampx alpha)492 void ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha)
493 {
494 ClearColor((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
495 }
496
ClearDepthf(GLclampf depth)497 void ClearDepthf(GLclampf depth)
498 {
499 TRACE("(GLclampf depth = %f)", depth);
500
501 es1::Context *context = es1::getContext();
502
503 if(context)
504 {
505 context->setClearDepth(depth);
506 }
507 }
508
ClearDepthx(GLclampx depth)509 void ClearDepthx(GLclampx depth)
510 {
511 ClearDepthf((float)depth / 0x10000);
512 }
513
ClearStencil(GLint s)514 void ClearStencil(GLint s)
515 {
516 TRACE("(GLint s = %d)", s);
517
518 es1::Context *context = es1::getContext();
519
520 if(context)
521 {
522 context->setClearStencil(s);
523 }
524 }
525
ClientActiveTexture(GLenum texture)526 void ClientActiveTexture(GLenum texture)
527 {
528 TRACE("(GLenum texture = 0x%X)", texture);
529
530 switch(texture)
531 {
532 case GL_TEXTURE0:
533 case GL_TEXTURE1:
534 break;
535 default:
536 return error(GL_INVALID_ENUM);
537 }
538
539 es1::Context *context = es1::getContext();
540
541 if(context)
542 {
543 context->clientActiveTexture(texture);
544 }
545 }
546
ClipPlanef(GLenum plane,const GLfloat * equation)547 void ClipPlanef(GLenum plane, const GLfloat *equation)
548 {
549 TRACE("(GLenum plane = 0x%X, const GLfloat *equation)", plane);
550
551 int index = plane - GL_CLIP_PLANE0;
552
553 if(index < 0 || index >= MAX_CLIP_PLANES)
554 {
555 return error(GL_INVALID_ENUM);
556 }
557
558 es1::Context *context = es1::getContext();
559
560 if(context)
561 {
562 context->setClipPlane(index, equation);
563 }
564 }
565
ClipPlanex(GLenum plane,const GLfixed * equation)566 void ClipPlanex(GLenum plane, const GLfixed *equation)
567 {
568 GLfloat equationf[4] =
569 {
570 (float)equation[0] / 0x10000,
571 (float)equation[1] / 0x10000,
572 (float)equation[2] / 0x10000,
573 (float)equation[3] / 0x10000,
574 };
575
576 ClipPlanef(plane, equationf);
577 }
578
Color4f(GLfloat red,GLfloat green,GLfloat blue,GLfloat alpha)579 void Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
580 {
581 TRACE("(GLfloat red = %f, GLfloat green = %f, GLfloat blue = %f, GLfloat alpha = %f)", red, green, blue, alpha);
582
583 es1::Context *context = es1::getContext();
584
585 if(context)
586 {
587 context->setVertexAttrib(sw::Color0, red, green, blue, alpha);
588 }
589 }
590
Color4ub(GLubyte red,GLubyte green,GLubyte blue,GLubyte alpha)591 void Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
592 {
593 Color4f((float)red / 0xFF, (float)green / 0xFF, (float)blue / 0xFF, (float)alpha / 0xFF);
594 }
595
Color4x(GLfixed red,GLfixed green,GLfixed blue,GLfixed alpha)596 void Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha)
597 {
598 Color4f((float)red / 0x10000, (float)green / 0x10000, (float)blue / 0x10000, (float)alpha / 0x10000);
599 }
600
ColorMask(GLboolean red,GLboolean green,GLboolean blue,GLboolean alpha)601 void ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
602 {
603 TRACE("(GLboolean red = %d, GLboolean green = %d, GLboolean blue = %d, GLboolean alpha = %d)",
604 red, green, blue, alpha);
605
606 es1::Context *context = es1::getContext();
607
608 if(context)
609 {
610 context->setColorMask(red == GL_TRUE, green == GL_TRUE, blue == GL_TRUE, alpha == GL_TRUE);
611 }
612 }
613
VertexAttribPointer(GLuint index,GLint size,GLenum type,GLboolean normalized,GLsizei stride,const GLvoid * ptr)614 void VertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const GLvoid* ptr)
615 {
616 TRACE("(GLuint index = %d, GLint size = %d, GLenum type = 0x%X, "
617 "GLboolean normalized = %d, GLsizei stride = %d, const GLvoid* ptr = %p)",
618 index, size, type, normalized, stride, ptr);
619
620 if(index >= es1::MAX_VERTEX_ATTRIBS)
621 {
622 return error(GL_INVALID_VALUE);
623 }
624
625 if(size < 1 || size > 4)
626 {
627 return error(GL_INVALID_VALUE);
628 }
629
630 switch(type)
631 {
632 case GL_BYTE:
633 case GL_UNSIGNED_BYTE:
634 case GL_SHORT:
635 case GL_UNSIGNED_SHORT:
636 case GL_FIXED:
637 case GL_FLOAT:
638 break;
639 default:
640 return error(GL_INVALID_ENUM);
641 }
642
643 if(stride < 0)
644 {
645 return error(GL_INVALID_VALUE);
646 }
647
648 es1::Context *context = es1::getContext();
649
650 if(context)
651 {
652 context->setVertexAttribState(index, context->getArrayBuffer(), size, type, (normalized == GL_TRUE), stride, ptr);
653 }
654 }
655
ColorPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)656 void ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
657 {
658 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
659
660 if(size != 4)
661 {
662 return error(GL_INVALID_VALUE);
663 }
664
665 VertexAttribPointer(sw::Color0, size, type, true, stride, pointer);
666 }
667
CompressedTexImage2D(GLenum target,GLint level,GLenum internalformat,GLsizei width,GLsizei height,GLint border,GLsizei imageSize,const GLvoid * data)668 void CompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height,
669 GLint border, GLsizei imageSize, const GLvoid* data)
670 {
671 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, GLsizei width = %d, "
672 "GLsizei height = %d, GLint border = %d, GLsizei imageSize = %d, const GLvoid* data = %p)",
673 target, level, internalformat, width, height, border, imageSize, data);
674
675 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
676 {
677 return error(GL_INVALID_VALUE);
678 }
679
680 if(!validImageSize(level, width, height) || imageSize < 0)
681 {
682 return error(GL_INVALID_VALUE);
683 }
684
685 switch(internalformat)
686 {
687 case GL_ETC1_RGB8_OES:
688 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
689 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
690 break;
691 case GL_DEPTH_COMPONENT16_OES:
692 case GL_DEPTH_STENCIL_OES:
693 case GL_DEPTH24_STENCIL8_OES:
694 return error(GL_INVALID_OPERATION);
695 default:
696 return error(GL_INVALID_ENUM);
697 }
698
699 if(border != 0)
700 {
701 return error(GL_INVALID_VALUE);
702 }
703
704 es1::Context *context = es1::getContext();
705
706 if(context)
707 {
708 switch(target)
709 {
710 case GL_TEXTURE_2D:
711 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
712 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
713 {
714 return error(GL_INVALID_VALUE);
715 }
716 break;
717 default:
718 return error(GL_INVALID_ENUM);
719 }
720
721 if(imageSize != gl::ComputeCompressedSize(width, height, internalformat))
722 {
723 return error(GL_INVALID_VALUE);
724 }
725
726 if(target == GL_TEXTURE_2D)
727 {
728 es1::Texture2D *texture = context->getTexture2D();
729
730 if(!texture)
731 {
732 return error(GL_INVALID_OPERATION);
733 }
734
735 texture->setCompressedImage(level, internalformat, width, height, imageSize, data);
736 }
737 else UNREACHABLE(target);
738 }
739 }
740
CompressedTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLsizei imageSize,const GLvoid * data)741 void CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
742 GLenum format, GLsizei imageSize, const GLvoid* data)
743 {
744 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
745 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, "
746 "GLsizei imageSize = %d, const GLvoid* data = %p)",
747 target, level, xoffset, yoffset, width, height, format, imageSize, data);
748
749 if(!es1::IsTextureTarget(target))
750 {
751 return error(GL_INVALID_ENUM);
752 }
753
754 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
755 {
756 return error(GL_INVALID_VALUE);
757 }
758
759 if(xoffset < 0 || yoffset < 0 || !validImageSize(level, width, height) || imageSize < 0)
760 {
761 return error(GL_INVALID_VALUE);
762 }
763
764 switch(format)
765 {
766 case GL_ETC1_RGB8_OES:
767 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
768 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
769 break;
770 default:
771 return error(GL_INVALID_ENUM);
772 }
773
774 if(width == 0 || height == 0 || !data)
775 {
776 return;
777 }
778
779 es1::Context *context = es1::getContext();
780
781 if(context)
782 {
783 if(imageSize != gl::ComputeCompressedSize(width, height, format))
784 {
785 return error(GL_INVALID_VALUE);
786 }
787
788 if(xoffset % 4 != 0 || yoffset % 4 != 0)
789 {
790 // We wait to check the offsets until this point, because the multiple-of-four restriction does not exist unless DXT1 textures are supported
791 return error(GL_INVALID_OPERATION);
792 }
793
794 if(target == GL_TEXTURE_2D)
795 {
796 es1::Texture2D *texture = context->getTexture2D();
797
798 GLenum validationError = ValidateSubImageParams(true, false, target, level, xoffset, yoffset, width, height, format, GL_NONE_OES, texture);
799 if(validationError != GL_NO_ERROR)
800 {
801 return error(validationError);
802 }
803
804 texture->subImageCompressed(level, xoffset, yoffset, width, height, format, imageSize, data);
805 }
806 else UNREACHABLE(target);
807 }
808 }
809
CopyTexImage2D(GLenum target,GLint level,GLenum internalformat,GLint x,GLint y,GLsizei width,GLsizei height,GLint border)810 void CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
811 {
812 TRACE("(GLenum target = 0x%X, GLint level = %d, GLenum internalformat = 0x%X, "
813 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, GLint border = %d)",
814 target, level, internalformat, x, y, width, height, border);
815
816 if(!validImageSize(level, width, height))
817 {
818 return error(GL_INVALID_VALUE);
819 }
820
821 if(border != 0)
822 {
823 return error(GL_INVALID_VALUE);
824 }
825
826 es1::Context *context = es1::getContext();
827
828 if(context)
829 {
830 switch(target)
831 {
832 case GL_TEXTURE_2D:
833 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
834 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
835 {
836 return error(GL_INVALID_VALUE);
837 }
838 break;
839 default:
840 return error(GL_INVALID_ENUM);
841 }
842
843 es1::Framebuffer *framebuffer = context->getFramebuffer();
844
845 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES))
846 {
847 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
848 }
849
850 es1::Renderbuffer *source = framebuffer->getColorbuffer();
851
852 if(!source || source->getSamples() > 1)
853 {
854 return error(GL_INVALID_OPERATION);
855 }
856
857 GLenum colorbufferFormat = source->getFormat();
858
859 // [OpenGL ES 1.1.12] table 3.9
860 switch(internalformat)
861 {
862 case GL_ALPHA:
863 if(colorbufferFormat != GL_ALPHA &&
864 colorbufferFormat != GL_RGBA &&
865 colorbufferFormat != GL_RGBA4_OES &&
866 colorbufferFormat != GL_RGB5_A1_OES &&
867 colorbufferFormat != GL_RGBA8_OES)
868 {
869 return error(GL_INVALID_OPERATION);
870 }
871 break;
872 case GL_LUMINANCE:
873 case GL_RGB:
874 if(colorbufferFormat != GL_RGB &&
875 colorbufferFormat != GL_RGB565_OES &&
876 colorbufferFormat != GL_RGB8_OES &&
877 colorbufferFormat != GL_RGBA &&
878 colorbufferFormat != GL_RGBA4_OES &&
879 colorbufferFormat != GL_RGB5_A1_OES &&
880 colorbufferFormat != GL_RGBA8_OES)
881 {
882 return error(GL_INVALID_OPERATION);
883 }
884 break;
885 case GL_LUMINANCE_ALPHA:
886 case GL_RGBA:
887 if(colorbufferFormat != GL_RGBA &&
888 colorbufferFormat != GL_RGBA4_OES &&
889 colorbufferFormat != GL_RGB5_A1_OES &&
890 colorbufferFormat != GL_RGBA8_OES &&
891 colorbufferFormat != GL_BGRA_EXT && // GL_EXT_texture_format_BGRA8888
892 colorbufferFormat != GL_BGRA8_EXT) // GL_EXT_texture_format_BGRA8888
893 {
894 return error(GL_INVALID_OPERATION);
895 }
896 break;
897 case GL_ETC1_RGB8_OES:
898 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
899 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
900 return error(GL_INVALID_OPERATION);
901 case GL_BGRA_EXT: // GL_EXT_texture_format_BGRA8888 doesn't mention the format to be accepted by glCopyTexImage2D.
902 default:
903 return error(GL_INVALID_ENUM);
904 }
905
906 // Determine the sized internal format.
907 if(gl::GetBaseInternalFormat(colorbufferFormat) == internalformat)
908 {
909 internalformat = colorbufferFormat;
910 }
911 else if(GetRedSize(colorbufferFormat) <= 8)
912 {
913 internalformat = gl::GetSizedInternalFormat(internalformat, GL_UNSIGNED_BYTE);
914 }
915 else
916 {
917 UNIMPLEMENTED();
918
919 return error(GL_INVALID_OPERATION);
920 }
921
922 if(target == GL_TEXTURE_2D)
923 {
924 es1::Texture2D *texture = context->getTexture2D();
925
926 if(!texture)
927 {
928 return error(GL_INVALID_OPERATION);
929 }
930
931 texture->copyImage(level, internalformat, x, y, width, height, framebuffer);
932 }
933 else UNREACHABLE(target);
934 }
935 }
936
CopyTexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLint x,GLint y,GLsizei width,GLsizei height)937 void CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
938 {
939 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
940 "GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)",
941 target, level, xoffset, yoffset, x, y, width, height);
942
943 if(!es1::IsTextureTarget(target))
944 {
945 return error(GL_INVALID_ENUM);
946 }
947
948 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
949 {
950 return error(GL_INVALID_VALUE);
951 }
952
953 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
954 {
955 return error(GL_INVALID_VALUE);
956 }
957
958 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
959 {
960 return error(GL_INVALID_VALUE);
961 }
962
963 if(width == 0 || height == 0)
964 {
965 return;
966 }
967
968 es1::Context *context = es1::getContext();
969
970 if(context)
971 {
972 es1::Framebuffer *framebuffer = context->getFramebuffer();
973
974 if(!framebuffer || (framebuffer->completeness() != GL_FRAMEBUFFER_COMPLETE_OES))
975 {
976 return error(GL_INVALID_FRAMEBUFFER_OPERATION_OES);
977 }
978
979 es1::Renderbuffer *source = framebuffer->getColorbuffer();
980
981 if(context->getFramebufferName() != 0 && (!source || source->getSamples() > 1))
982 {
983 return error(GL_INVALID_OPERATION);
984 }
985
986 es1::Texture *texture = nullptr;
987
988 if(target == GL_TEXTURE_2D)
989 {
990 texture = context->getTexture2D();
991 }
992 else UNREACHABLE(target);
993
994 GLenum validationError = ValidateSubImageParams(false, true, target, level, xoffset, yoffset, width, height, GL_NONE_OES, GL_NONE_OES, texture);
995 if(validationError != GL_NO_ERROR)
996 {
997 return error(validationError);
998 }
999
1000 texture->copySubImage(target, level, xoffset, yoffset, x, y, width, height, framebuffer);
1001 }
1002 }
1003
CullFace(GLenum mode)1004 void CullFace(GLenum mode)
1005 {
1006 TRACE("(GLenum mode = 0x%X)", mode);
1007
1008 switch(mode)
1009 {
1010 case GL_FRONT:
1011 case GL_BACK:
1012 case GL_FRONT_AND_BACK:
1013 {
1014 es1::Context *context = es1::getContext();
1015
1016 if(context)
1017 {
1018 context->setCullMode(mode);
1019 }
1020 }
1021 break;
1022 default:
1023 return error(GL_INVALID_ENUM);
1024 }
1025 }
1026
DeleteBuffers(GLsizei n,const GLuint * buffers)1027 void DeleteBuffers(GLsizei n, const GLuint* buffers)
1028 {
1029 TRACE("(GLsizei n = %d, const GLuint* buffers = %p)", n, buffers);
1030
1031 if(n < 0)
1032 {
1033 return error(GL_INVALID_VALUE);
1034 }
1035
1036 es1::Context *context = es1::getContext();
1037
1038 if(context)
1039 {
1040 for(int i = 0; i < n; i++)
1041 {
1042 context->deleteBuffer(buffers[i]);
1043 }
1044 }
1045 }
1046
DeleteFramebuffersOES(GLsizei n,const GLuint * framebuffers)1047 void DeleteFramebuffersOES(GLsizei n, const GLuint* framebuffers)
1048 {
1049 TRACE("(GLsizei n = %d, const GLuint* framebuffers = %p)", n, framebuffers);
1050
1051 if(n < 0)
1052 {
1053 return error(GL_INVALID_VALUE);
1054 }
1055
1056 es1::Context *context = es1::getContext();
1057
1058 if(context)
1059 {
1060 for(int i = 0; i < n; i++)
1061 {
1062 if(framebuffers[i] != 0)
1063 {
1064 context->deleteFramebuffer(framebuffers[i]);
1065 }
1066 }
1067 }
1068 }
1069
DeleteRenderbuffersOES(GLsizei n,const GLuint * renderbuffers)1070 void DeleteRenderbuffersOES(GLsizei n, const GLuint* renderbuffers)
1071 {
1072 TRACE("(GLsizei n = %d, const GLuint* renderbuffers = %p)", n, renderbuffers);
1073
1074 if(n < 0)
1075 {
1076 return error(GL_INVALID_VALUE);
1077 }
1078
1079 es1::Context *context = es1::getContext();
1080
1081 if(context)
1082 {
1083 for(int i = 0; i < n; i++)
1084 {
1085 context->deleteRenderbuffer(renderbuffers[i]);
1086 }
1087 }
1088 }
1089
DeleteTextures(GLsizei n,const GLuint * textures)1090 void DeleteTextures(GLsizei n, const GLuint* textures)
1091 {
1092 TRACE("(GLsizei n = %d, const GLuint* textures = %p)", n, textures);
1093
1094 if(n < 0)
1095 {
1096 return error(GL_INVALID_VALUE);
1097 }
1098
1099 es1::Context *context = es1::getContext();
1100
1101 if(context)
1102 {
1103 for(int i = 0; i < n; i++)
1104 {
1105 if(textures[i] != 0)
1106 {
1107 context->deleteTexture(textures[i]);
1108 }
1109 }
1110 }
1111 }
1112
DepthFunc(GLenum func)1113 void DepthFunc(GLenum func)
1114 {
1115 TRACE("(GLenum func = 0x%X)", func);
1116
1117 switch(func)
1118 {
1119 case GL_NEVER:
1120 case GL_ALWAYS:
1121 case GL_LESS:
1122 case GL_LEQUAL:
1123 case GL_EQUAL:
1124 case GL_GREATER:
1125 case GL_GEQUAL:
1126 case GL_NOTEQUAL:
1127 break;
1128 default:
1129 return error(GL_INVALID_ENUM);
1130 }
1131
1132 es1::Context *context = es1::getContext();
1133
1134 if(context)
1135 {
1136 context->setDepthFunc(func);
1137 }
1138 }
1139
DepthMask(GLboolean flag)1140 void DepthMask(GLboolean flag)
1141 {
1142 TRACE("(GLboolean flag = %d)", flag);
1143
1144 es1::Context *context = es1::getContext();
1145
1146 if(context)
1147 {
1148 context->setDepthMask(flag != GL_FALSE);
1149 }
1150 }
1151
DepthRangef(GLclampf zNear,GLclampf zFar)1152 void DepthRangef(GLclampf zNear, GLclampf zFar)
1153 {
1154 TRACE("(GLclampf zNear = %f, GLclampf zFar = %f)", zNear, zFar);
1155
1156 es1::Context *context = es1::getContext();
1157
1158 if(context)
1159 {
1160 context->setDepthRange(zNear, zFar);
1161 }
1162 }
1163
DepthRangex(GLclampx zNear,GLclampx zFar)1164 void DepthRangex(GLclampx zNear, GLclampx zFar)
1165 {
1166 DepthRangef((float)zNear / 0x10000, (float)zFar / 0x10000);
1167 }
1168
Disable(GLenum cap)1169 void Disable(GLenum cap)
1170 {
1171 TRACE("(GLenum cap = 0x%X)", cap);
1172
1173 es1::Context *context = es1::getContext();
1174
1175 if(context)
1176 {
1177 switch(cap)
1178 {
1179 case GL_CULL_FACE: context->setCullFaceEnabled(false); break;
1180 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(false); break;
1181 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(false); break;
1182 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(false); break;
1183 case GL_SCISSOR_TEST: context->setScissorTestEnabled(false); break;
1184 case GL_STENCIL_TEST: context->setStencilTestEnabled(false); break;
1185 case GL_DEPTH_TEST: context->setDepthTestEnabled(false); break;
1186 case GL_BLEND: context->setBlendEnabled(false); break;
1187 case GL_DITHER: context->setDitherEnabled(false); break;
1188 case GL_LIGHTING: context->setLightingEnabled(false); break;
1189 case GL_LIGHT0: context->setLightEnabled(0, false); break;
1190 case GL_LIGHT1: context->setLightEnabled(1, false); break;
1191 case GL_LIGHT2: context->setLightEnabled(2, false); break;
1192 case GL_LIGHT3: context->setLightEnabled(3, false); break;
1193 case GL_LIGHT4: context->setLightEnabled(4, false); break;
1194 case GL_LIGHT5: context->setLightEnabled(5, false); break;
1195 case GL_LIGHT6: context->setLightEnabled(6, false); break;
1196 case GL_LIGHT7: context->setLightEnabled(7, false); break;
1197 case GL_FOG: context->setFogEnabled(false); break;
1198 case GL_TEXTURE_2D: context->setTexture2Denabled(false); break;
1199 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(false); break;
1200 case GL_ALPHA_TEST: context->setAlphaTestEnabled(false); break;
1201 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(false); break;
1202 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(false); break;
1203 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(false); break;
1204 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(false); break;
1205 case GL_NORMALIZE: context->setNormalizeEnabled(false); break;
1206 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(false); break;
1207 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(false); break;
1208 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(false); break;
1209 case GL_COLOR_ARRAY: context->setColorArrayEnabled(false); break;
1210 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(false); break;
1211 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(false); break;
1212 case GL_MULTISAMPLE: context->setMultisampleEnabled(false); break;
1213 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(false); break;
1214 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, false); break;
1215 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, false); break;
1216 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, false); break;
1217 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, false); break;
1218 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, false); break;
1219 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, false); break;
1220 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(false); break;
1221 default:
1222 return error(GL_INVALID_ENUM);
1223 }
1224 }
1225 }
1226
DisableClientState(GLenum array)1227 void DisableClientState(GLenum array)
1228 {
1229 TRACE("(GLenum array = 0x%X)", array);
1230
1231 switch(array)
1232 {
1233 case GL_VERTEX_ARRAY:
1234 case GL_NORMAL_ARRAY:
1235 case GL_COLOR_ARRAY:
1236 case GL_POINT_SIZE_ARRAY_OES:
1237 case GL_TEXTURE_COORD_ARRAY:
1238 break;
1239 default:
1240 return error(GL_INVALID_ENUM);
1241 }
1242
1243 es1::Context *context = es1::getContext();
1244
1245 if(context)
1246 {
1247 GLenum texture = context->getClientActiveTexture();
1248
1249 switch(array)
1250 {
1251 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, false); break;
1252 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, false); break;
1253 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, false); break;
1254 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, false); break;
1255 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), false); break;
1256 default: UNREACHABLE(array);
1257 }
1258 }
1259 }
1260
DrawArrays(GLenum mode,GLint first,GLsizei count)1261 void DrawArrays(GLenum mode, GLint first, GLsizei count)
1262 {
1263 TRACE("(GLenum mode = 0x%X, GLint first = %d, GLsizei count = %d)", mode, first, count);
1264
1265 if(count < 0 || first < 0)
1266 {
1267 return error(GL_INVALID_VALUE);
1268 }
1269
1270 es1::Context *context = es1::getContext();
1271
1272 if(context)
1273 {
1274 context->drawArrays(mode, first, count);
1275 }
1276 }
1277
DrawElements(GLenum mode,GLsizei count,GLenum type,const GLvoid * indices)1278 void DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid* indices)
1279 {
1280 TRACE("(GLenum mode = 0x%X, GLsizei count = %d, GLenum type = 0x%X, const GLvoid* indices = %p)",
1281 mode, count, type, indices);
1282
1283 if(count < 0)
1284 {
1285 return error(GL_INVALID_VALUE);
1286 }
1287
1288 es1::Context *context = es1::getContext();
1289
1290 if(context)
1291 {
1292 switch(type)
1293 {
1294 case GL_UNSIGNED_BYTE:
1295 case GL_UNSIGNED_SHORT:
1296 case GL_UNSIGNED_INT:
1297 break;
1298 default:
1299 return error(GL_INVALID_ENUM);
1300 }
1301
1302 context->drawElements(mode, count, type, indices);
1303 }
1304 }
1305
Enable(GLenum cap)1306 void Enable(GLenum cap)
1307 {
1308 TRACE("(GLenum cap = 0x%X)", cap);
1309
1310 es1::Context *context = es1::getContext();
1311
1312 if(context)
1313 {
1314 switch(cap)
1315 {
1316 case GL_CULL_FACE: context->setCullFaceEnabled(true); break;
1317 case GL_POLYGON_OFFSET_FILL: context->setPolygonOffsetFillEnabled(true); break;
1318 case GL_SAMPLE_ALPHA_TO_COVERAGE: context->setSampleAlphaToCoverageEnabled(true); break;
1319 case GL_SAMPLE_COVERAGE: context->setSampleCoverageEnabled(true); break;
1320 case GL_SCISSOR_TEST: context->setScissorTestEnabled(true); break;
1321 case GL_STENCIL_TEST: context->setStencilTestEnabled(true); break;
1322 case GL_DEPTH_TEST: context->setDepthTestEnabled(true); break;
1323 case GL_BLEND: context->setBlendEnabled(true); break;
1324 case GL_DITHER: context->setDitherEnabled(true); break;
1325 case GL_LIGHTING: context->setLightingEnabled(true); break;
1326 case GL_LIGHT0: context->setLightEnabled(0, true); break;
1327 case GL_LIGHT1: context->setLightEnabled(1, true); break;
1328 case GL_LIGHT2: context->setLightEnabled(2, true); break;
1329 case GL_LIGHT3: context->setLightEnabled(3, true); break;
1330 case GL_LIGHT4: context->setLightEnabled(4, true); break;
1331 case GL_LIGHT5: context->setLightEnabled(5, true); break;
1332 case GL_LIGHT6: context->setLightEnabled(6, true); break;
1333 case GL_LIGHT7: context->setLightEnabled(7, true); break;
1334 case GL_FOG: context->setFogEnabled(true); break;
1335 case GL_TEXTURE_2D: context->setTexture2Denabled(true); break;
1336 case GL_TEXTURE_EXTERNAL_OES: context->setTextureExternalEnabled(true); break;
1337 case GL_ALPHA_TEST: context->setAlphaTestEnabled(true); break;
1338 case GL_COLOR_LOGIC_OP: context->setColorLogicOpEnabled(true); break;
1339 case GL_POINT_SMOOTH: context->setPointSmoothEnabled(true); break;
1340 case GL_LINE_SMOOTH: context->setLineSmoothEnabled(true); break;
1341 case GL_COLOR_MATERIAL: context->setColorMaterialEnabled(true); break;
1342 case GL_NORMALIZE: context->setNormalizeEnabled(true); break;
1343 case GL_RESCALE_NORMAL: context->setRescaleNormalEnabled(true); break;
1344 case GL_VERTEX_ARRAY: context->setVertexArrayEnabled(true); break;
1345 case GL_NORMAL_ARRAY: context->setNormalArrayEnabled(true); break;
1346 case GL_COLOR_ARRAY: context->setColorArrayEnabled(true); break;
1347 case GL_POINT_SIZE_ARRAY_OES: context->setPointSizeArrayEnabled(true); break;
1348 case GL_TEXTURE_COORD_ARRAY: context->setTextureCoordArrayEnabled(true); break;
1349 case GL_MULTISAMPLE: context->setMultisampleEnabled(true); break;
1350 case GL_SAMPLE_ALPHA_TO_ONE: context->setSampleAlphaToOneEnabled(true); break;
1351 case GL_CLIP_PLANE0: context->setClipPlaneEnabled(0, true); break;
1352 case GL_CLIP_PLANE1: context->setClipPlaneEnabled(1, true); break;
1353 case GL_CLIP_PLANE2: context->setClipPlaneEnabled(2, true); break;
1354 case GL_CLIP_PLANE3: context->setClipPlaneEnabled(3, true); break;
1355 case GL_CLIP_PLANE4: context->setClipPlaneEnabled(4, true); break;
1356 case GL_CLIP_PLANE5: context->setClipPlaneEnabled(5, true); break;
1357 case GL_POINT_SPRITE_OES: context->setPointSpriteEnabled(true); break;
1358 default:
1359 return error(GL_INVALID_ENUM);
1360 }
1361 }
1362 }
1363
EnableClientState(GLenum array)1364 void EnableClientState(GLenum array)
1365 {
1366 TRACE("(GLenum array = 0x%X)", array);
1367
1368 switch(array)
1369 {
1370 case GL_VERTEX_ARRAY:
1371 case GL_NORMAL_ARRAY:
1372 case GL_COLOR_ARRAY:
1373 case GL_POINT_SIZE_ARRAY_OES:
1374 case GL_TEXTURE_COORD_ARRAY:
1375 break;
1376 default:
1377 return error(GL_INVALID_ENUM);
1378 }
1379
1380 es1::Context *context = es1::getContext();
1381
1382 if(context)
1383 {
1384 GLenum texture = context->getClientActiveTexture();
1385
1386 switch(array)
1387 {
1388 case GL_VERTEX_ARRAY: context->setVertexAttribArrayEnabled(sw::Position, true); break;
1389 case GL_NORMAL_ARRAY: context->setVertexAttribArrayEnabled(sw::Normal, true); break;
1390 case GL_COLOR_ARRAY: context->setVertexAttribArrayEnabled(sw::Color0, true); break;
1391 case GL_POINT_SIZE_ARRAY_OES: context->setVertexAttribArrayEnabled(sw::PointSize, true); break;
1392 case GL_TEXTURE_COORD_ARRAY: context->setVertexAttribArrayEnabled(sw::TexCoord0 + (texture - GL_TEXTURE0), true); break;
1393 default: UNREACHABLE(array);
1394 }
1395 }
1396 }
1397
Finish(void)1398 void Finish(void)
1399 {
1400 TRACE("()");
1401
1402 es1::Context *context = es1::getContext();
1403
1404 if(context)
1405 {
1406 context->finish();
1407 }
1408 }
1409
Flush(void)1410 void Flush(void)
1411 {
1412 TRACE("()");
1413
1414 es1::Context *context = es1::getContext();
1415
1416 if(context)
1417 {
1418 context->flush();
1419 }
1420 }
1421
FramebufferRenderbufferOES(GLenum target,GLenum attachment,GLenum renderbuffertarget,GLuint renderbuffer)1422 void FramebufferRenderbufferOES(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)
1423 {
1424 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum renderbuffertarget = 0x%X, "
1425 "GLuint renderbuffer = %d)", target, attachment, renderbuffertarget, renderbuffer);
1426
1427 if(target != GL_FRAMEBUFFER_OES || (renderbuffertarget != GL_RENDERBUFFER_OES && renderbuffer != 0))
1428 {
1429 return error(GL_INVALID_ENUM);
1430 }
1431
1432 es1::Context *context = es1::getContext();
1433
1434 if(context)
1435 {
1436 es1::Framebuffer *framebuffer = context->getFramebuffer();
1437 GLuint framebufferName = context->getFramebufferName();
1438
1439 if(!framebuffer || (framebufferName == 0 && renderbuffer != 0))
1440 {
1441 return error(GL_INVALID_OPERATION);
1442 }
1443
1444 switch(attachment)
1445 {
1446 case GL_COLOR_ATTACHMENT0_OES:
1447 framebuffer->setColorbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1448 break;
1449 case GL_DEPTH_ATTACHMENT_OES:
1450 framebuffer->setDepthbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1451 break;
1452 case GL_STENCIL_ATTACHMENT_OES:
1453 framebuffer->setStencilbuffer(GL_RENDERBUFFER_OES, renderbuffer);
1454 break;
1455 default:
1456 return error(GL_INVALID_ENUM);
1457 }
1458 }
1459 }
1460
FramebufferTexture2DOES(GLenum target,GLenum attachment,GLenum textarget,GLuint texture,GLint level)1461 void FramebufferTexture2DOES(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level)
1462 {
1463 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum textarget = 0x%X, "
1464 "GLuint texture = %d, GLint level = %d)", target, attachment, textarget, texture, level);
1465
1466 if(target != GL_FRAMEBUFFER_OES)
1467 {
1468 return error(GL_INVALID_ENUM);
1469 }
1470
1471 switch(attachment)
1472 {
1473 case GL_COLOR_ATTACHMENT0_OES:
1474 case GL_DEPTH_ATTACHMENT_OES:
1475 case GL_STENCIL_ATTACHMENT_OES:
1476 break;
1477 default:
1478 return error(GL_INVALID_ENUM);
1479 }
1480
1481 es1::Context *context = es1::getContext();
1482
1483 if(context)
1484 {
1485 if(texture == 0)
1486 {
1487 textarget = GL_NONE_OES;
1488 }
1489 else
1490 {
1491 es1::Texture *tex = context->getTexture(texture);
1492
1493 if(!tex)
1494 {
1495 return error(GL_INVALID_OPERATION);
1496 }
1497
1498 switch(textarget)
1499 {
1500 case GL_TEXTURE_2D:
1501 if(tex->getTarget() != GL_TEXTURE_2D)
1502 {
1503 return error(GL_INVALID_OPERATION);
1504 }
1505 break;
1506 default:
1507 return error(GL_INVALID_ENUM);
1508 }
1509
1510 if(level != 0)
1511 {
1512 return error(GL_INVALID_VALUE);
1513 }
1514
1515 if(tex->isCompressed(textarget, level))
1516 {
1517 return error(GL_INVALID_OPERATION);
1518 }
1519 }
1520
1521 es1::Framebuffer *framebuffer = context->getFramebuffer();
1522 GLuint framebufferName = context->getFramebufferName();
1523
1524 if(framebufferName == 0 || !framebuffer)
1525 {
1526 return error(GL_INVALID_OPERATION);
1527 }
1528
1529 switch(attachment)
1530 {
1531 case GL_COLOR_ATTACHMENT0_OES: framebuffer->setColorbuffer(textarget, texture); break;
1532 case GL_DEPTH_ATTACHMENT_OES: framebuffer->setDepthbuffer(textarget, texture); break;
1533 case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture); break;
1534 }
1535 }
1536 }
1537
Fogf(GLenum pname,GLfloat param)1538 void Fogf(GLenum pname, GLfloat param)
1539 {
1540 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
1541
1542 es1::Context *context = es1::getContext();
1543
1544 if(context)
1545 {
1546 switch(pname)
1547 {
1548 case GL_FOG_MODE:
1549 switch((GLenum)param)
1550 {
1551 case GL_LINEAR:
1552 case GL_EXP:
1553 case GL_EXP2:
1554 context->setFogMode((GLenum)param);
1555 break;
1556 default:
1557 return error(GL_INVALID_ENUM);
1558 }
1559 break;
1560 case GL_FOG_DENSITY:
1561 if(param < 0)
1562 {
1563 return error(GL_INVALID_VALUE);
1564 }
1565 context->setFogDensity(param);
1566 break;
1567 case GL_FOG_START:
1568 context->setFogStart(param);
1569 break;
1570 case GL_FOG_END:
1571 context->setFogEnd(param);
1572 break;
1573 case GL_FOG_COLOR:
1574 return error(GL_INVALID_ENUM); // Need four values, should call glFogfv() instead
1575 default:
1576 return error(GL_INVALID_ENUM);
1577 }
1578 }
1579 }
1580
Fogfv(GLenum pname,const GLfloat * params)1581 void Fogfv(GLenum pname, const GLfloat *params)
1582 {
1583 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
1584
1585 es1::Context *context = es1::getContext();
1586
1587 if(context)
1588 {
1589 switch(pname)
1590 {
1591 case GL_FOG_MODE:
1592 switch((GLenum)params[0])
1593 {
1594 case GL_LINEAR:
1595 case GL_EXP:
1596 case GL_EXP2:
1597 context->setFogMode((GLenum)params[0]);
1598 break;
1599 default:
1600 return error(GL_INVALID_ENUM);
1601 }
1602 break;
1603 case GL_FOG_DENSITY:
1604 if(params[0] < 0)
1605 {
1606 return error(GL_INVALID_VALUE);
1607 }
1608 context->setFogDensity(params[0]);
1609 break;
1610 case GL_FOG_START:
1611 context->setFogStart(params[0]);
1612 break;
1613 case GL_FOG_END:
1614 context->setFogEnd(params[0]);
1615 break;
1616 case GL_FOG_COLOR:
1617 context->setFogColor(params[0], params[1], params[2], params[3]);
1618 break;
1619 default:
1620 return error(GL_INVALID_ENUM);
1621 }
1622 }
1623 }
1624
Fogx(GLenum pname,GLfixed param)1625 void Fogx(GLenum pname, GLfixed param)
1626 {
1627 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
1628
1629 es1::Context *context = es1::getContext();
1630
1631 if(context)
1632 {
1633 switch(pname)
1634 {
1635 case GL_FOG_MODE:
1636 switch((GLenum)param)
1637 {
1638 case GL_LINEAR:
1639 case GL_EXP:
1640 case GL_EXP2:
1641 context->setFogMode((GLenum)param);
1642 break;
1643 default:
1644 return error(GL_INVALID_ENUM);
1645 }
1646 break;
1647 case GL_FOG_DENSITY:
1648 if(param < 0)
1649 {
1650 return error(GL_INVALID_VALUE);
1651 }
1652 context->setFogDensity((float)param / 0x10000);
1653 break;
1654 case GL_FOG_START:
1655 context->setFogStart((float)param / 0x10000);
1656 break;
1657 case GL_FOG_END:
1658 context->setFogEnd((float)param / 0x10000);
1659 break;
1660 case GL_FOG_COLOR:
1661 return error(GL_INVALID_ENUM); // Need four values, should call glFogxv() instead
1662 default:
1663 return error(GL_INVALID_ENUM);
1664 }
1665 }
1666 }
1667
Fogxv(GLenum pname,const GLfixed * params)1668 void Fogxv(GLenum pname, const GLfixed *params)
1669 {
1670 UNIMPLEMENTED();
1671 }
1672
FrontFace(GLenum mode)1673 void FrontFace(GLenum mode)
1674 {
1675 TRACE("(GLenum mode = 0x%X)", mode);
1676
1677 switch(mode)
1678 {
1679 case GL_CW:
1680 case GL_CCW:
1681 {
1682 es1::Context *context = es1::getContext();
1683
1684 if(context)
1685 {
1686 context->setFrontFace(mode);
1687 }
1688 }
1689 break;
1690 default:
1691 return error(GL_INVALID_ENUM);
1692 }
1693 }
1694
Frustumf(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)1695 void Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
1696 {
1697 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
1698
1699 if(zNear <= 0.0f || zFar <= 0.0f || left == right || bottom == top || zNear == zFar)
1700 {
1701 return error(GL_INVALID_VALUE);
1702 }
1703
1704 es1::Context *context = es1::getContext();
1705
1706 if(context)
1707 {
1708 context->frustum(left, right, bottom, top, zNear, zFar);
1709 }
1710 }
1711
Frustumx(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)1712 void Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
1713 {
1714 Frustumf((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
1715 }
1716
GenerateMipmapOES(GLenum target)1717 void GenerateMipmapOES(GLenum target)
1718 {
1719 TRACE("(GLenum target = 0x%X)", target);
1720
1721 es1::Context *context = es1::getContext();
1722
1723 if(context)
1724 {
1725 es1::Texture *texture;
1726
1727 switch(target)
1728 {
1729 case GL_TEXTURE_2D:
1730 texture = context->getTexture2D();
1731 break;
1732 default:
1733 return error(GL_INVALID_ENUM);
1734 }
1735
1736 if(texture->isCompressed(target, 0) || texture->isDepth(target, 0))
1737 {
1738 return error(GL_INVALID_OPERATION);
1739 }
1740
1741 texture->generateMipmaps();
1742 }
1743 }
1744
GenBuffers(GLsizei n,GLuint * buffers)1745 void GenBuffers(GLsizei n, GLuint* buffers)
1746 {
1747 TRACE("(GLsizei n = %d, GLuint* buffers = %p)", n, buffers);
1748
1749 if(n < 0)
1750 {
1751 return error(GL_INVALID_VALUE);
1752 }
1753
1754 es1::Context *context = es1::getContext();
1755
1756 if(context)
1757 {
1758 for(int i = 0; i < n; i++)
1759 {
1760 buffers[i] = context->createBuffer();
1761 }
1762 }
1763 }
1764
GenFramebuffersOES(GLsizei n,GLuint * framebuffers)1765 void GenFramebuffersOES(GLsizei n, GLuint* framebuffers)
1766 {
1767 TRACE("(GLsizei n = %d, GLuint* framebuffers = %p)", n, framebuffers);
1768
1769 if(n < 0)
1770 {
1771 return error(GL_INVALID_VALUE);
1772 }
1773
1774 es1::Context *context = es1::getContext();
1775
1776 if(context)
1777 {
1778 for(int i = 0; i < n; i++)
1779 {
1780 framebuffers[i] = context->createFramebuffer();
1781 }
1782 }
1783 }
1784
GenRenderbuffersOES(GLsizei n,GLuint * renderbuffers)1785 void GenRenderbuffersOES(GLsizei n, GLuint* renderbuffers)
1786 {
1787 TRACE("(GLsizei n = %d, GLuint* renderbuffers = %p)", n, renderbuffers);
1788
1789 if(n < 0)
1790 {
1791 return error(GL_INVALID_VALUE);
1792 }
1793
1794 es1::Context *context = es1::getContext();
1795
1796 if(context)
1797 {
1798 for(int i = 0; i < n; i++)
1799 {
1800 renderbuffers[i] = context->createRenderbuffer();
1801 }
1802 }
1803 }
1804
GenTextures(GLsizei n,GLuint * textures)1805 void GenTextures(GLsizei n, GLuint* textures)
1806 {
1807 TRACE("(GLsizei n = %d, GLuint* textures = %p)", n, textures);
1808
1809 if(n < 0)
1810 {
1811 return error(GL_INVALID_VALUE);
1812 }
1813
1814 es1::Context *context = es1::getContext();
1815
1816 if(context)
1817 {
1818 for(int i = 0; i < n; i++)
1819 {
1820 textures[i] = context->createTexture();
1821 }
1822 }
1823 }
1824
GetRenderbufferParameterivOES(GLenum target,GLenum pname,GLint * params)1825 void GetRenderbufferParameterivOES(GLenum target, GLenum pname, GLint* params)
1826 {
1827 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
1828
1829 es1::Context *context = es1::getContext();
1830
1831 if(context)
1832 {
1833 if(target != GL_RENDERBUFFER_OES)
1834 {
1835 return error(GL_INVALID_ENUM);
1836 }
1837
1838 if(context->getRenderbufferName() == 0)
1839 {
1840 return error(GL_INVALID_OPERATION);
1841 }
1842
1843 es1::Renderbuffer *renderbuffer = context->getRenderbuffer(context->getRenderbufferName());
1844
1845 switch(pname)
1846 {
1847 case GL_RENDERBUFFER_WIDTH_OES: *params = renderbuffer->getWidth(); break;
1848 case GL_RENDERBUFFER_HEIGHT_OES: *params = renderbuffer->getHeight(); break;
1849 case GL_RENDERBUFFER_INTERNAL_FORMAT_OES:
1850 {
1851 GLint internalformat = renderbuffer->getFormat();
1852 *params = (internalformat == GL_NONE_OES) ? GL_RGBA4_OES : internalformat;
1853 }
1854 break;
1855 case GL_RENDERBUFFER_RED_SIZE_OES: *params = renderbuffer->getRedSize(); break;
1856 case GL_RENDERBUFFER_GREEN_SIZE_OES: *params = renderbuffer->getGreenSize(); break;
1857 case GL_RENDERBUFFER_BLUE_SIZE_OES: *params = renderbuffer->getBlueSize(); break;
1858 case GL_RENDERBUFFER_ALPHA_SIZE_OES: *params = renderbuffer->getAlphaSize(); break;
1859 case GL_RENDERBUFFER_DEPTH_SIZE_OES: *params = renderbuffer->getDepthSize(); break;
1860 case GL_RENDERBUFFER_STENCIL_SIZE_OES: *params = renderbuffer->getStencilSize(); break;
1861 default:
1862 return error(GL_INVALID_ENUM);
1863 }
1864 }
1865 }
1866
GetBooleanv(GLenum pname,GLboolean * params)1867 void GetBooleanv(GLenum pname, GLboolean* params)
1868 {
1869 TRACE("(GLenum pname = 0x%X, GLboolean* params = %p)", pname, params);
1870
1871 es1::Context *context = es1::getContext();
1872
1873 if(context)
1874 {
1875 if(!(context->getBooleanv(pname, params)))
1876 {
1877 int numParams = context->getQueryParameterNum(pname);
1878
1879 if(numParams < 0)
1880 {
1881 return error(GL_INVALID_ENUM);
1882 }
1883
1884 if(numParams == 0)
1885 {
1886 return;
1887 }
1888
1889 if(context->isQueryParameterFloat(pname))
1890 {
1891 GLfloat *floatParams = nullptr;
1892 floatParams = new GLfloat[numParams];
1893
1894 context->getFloatv(pname, floatParams);
1895
1896 for(int i = 0; i < numParams; ++i)
1897 {
1898 if(floatParams[i] == 0.0f)
1899 params[i] = GL_FALSE;
1900 else
1901 params[i] = GL_TRUE;
1902 }
1903
1904 delete [] floatParams;
1905 }
1906 else if(context->isQueryParameterInt(pname))
1907 {
1908 GLint *intParams = nullptr;
1909 intParams = new GLint[numParams];
1910
1911 context->getIntegerv(pname, intParams);
1912
1913 for(int i = 0; i < numParams; ++i)
1914 {
1915 if(intParams[i] == 0)
1916 params[i] = GL_FALSE;
1917 else
1918 params[i] = GL_TRUE;
1919 }
1920
1921 delete [] intParams;
1922 }
1923 else UNREACHABLE(pname);
1924 }
1925 }
1926 }
1927
GetBufferParameteriv(GLenum target,GLenum pname,GLint * params)1928 void GetBufferParameteriv(GLenum target, GLenum pname, GLint* params)
1929 {
1930 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
1931
1932 es1::Context *context = es1::getContext();
1933
1934 if(context)
1935 {
1936 es1::Buffer *buffer;
1937
1938 switch(target)
1939 {
1940 case GL_ARRAY_BUFFER:
1941 buffer = context->getArrayBuffer();
1942 break;
1943 case GL_ELEMENT_ARRAY_BUFFER:
1944 buffer = context->getElementArrayBuffer();
1945 break;
1946 default:
1947 return error(GL_INVALID_ENUM);
1948 }
1949
1950 if(!buffer)
1951 {
1952 // A null buffer means that "0" is bound to the requested buffer target
1953 return error(GL_INVALID_OPERATION);
1954 }
1955
1956 switch(pname)
1957 {
1958 case GL_BUFFER_USAGE:
1959 *params = buffer->usage();
1960 break;
1961 case GL_BUFFER_SIZE:
1962 *params = (GLint)buffer->size();
1963 break;
1964 default:
1965 return error(GL_INVALID_ENUM);
1966 }
1967 }
1968 }
1969
GetClipPlanef(GLenum pname,GLfloat eqn[4])1970 void GetClipPlanef(GLenum pname, GLfloat eqn[4])
1971 {
1972 UNIMPLEMENTED();
1973 }
1974
GetClipPlanex(GLenum pname,GLfixed eqn[4])1975 void GetClipPlanex(GLenum pname, GLfixed eqn[4])
1976 {
1977 UNIMPLEMENTED();
1978 }
1979
GetError(void)1980 GLenum GetError(void)
1981 {
1982 TRACE("()");
1983
1984 es1::Context *context = es1::getContext();
1985
1986 if(context)
1987 {
1988 return context->getError();
1989 }
1990
1991 return GL_NO_ERROR;
1992 }
1993
GetFixedv(GLenum pname,GLfixed * params)1994 void GetFixedv(GLenum pname, GLfixed *params)
1995 {
1996 UNIMPLEMENTED();
1997 }
1998
GetFloatv(GLenum pname,GLfloat * params)1999 void GetFloatv(GLenum pname, GLfloat* params)
2000 {
2001 TRACE("(GLenum pname = 0x%X, GLfloat* params = %p)", pname, params);
2002
2003 es1::Context *context = es1::getContext();
2004
2005 if(context)
2006 {
2007 if(!(context->getFloatv(pname, params)))
2008 {
2009 int numParams = context->getQueryParameterNum(pname);
2010
2011 if(numParams < 0)
2012 {
2013 return error(GL_INVALID_ENUM);
2014 }
2015
2016 if(numParams == 0)
2017 {
2018 return;
2019 }
2020
2021 if(context->isQueryParameterBool(pname))
2022 {
2023 GLboolean *boolParams = nullptr;
2024 boolParams = new GLboolean[numParams];
2025
2026 context->getBooleanv(pname, boolParams);
2027
2028 for(int i = 0; i < numParams; ++i)
2029 {
2030 if(boolParams[i] == GL_FALSE)
2031 params[i] = 0.0f;
2032 else
2033 params[i] = 1.0f;
2034 }
2035
2036 delete [] boolParams;
2037 }
2038 else if(context->isQueryParameterInt(pname))
2039 {
2040 GLint *intParams = nullptr;
2041 intParams = new GLint[numParams];
2042
2043 context->getIntegerv(pname, intParams);
2044
2045 for(int i = 0; i < numParams; ++i)
2046 {
2047 params[i] = (GLfloat)intParams[i];
2048 }
2049
2050 delete [] intParams;
2051 }
2052 else UNREACHABLE(pname);
2053 }
2054 }
2055 }
2056
GetFramebufferAttachmentParameterivOES(GLenum target,GLenum attachment,GLenum pname,GLint * params)2057 void GetFramebufferAttachmentParameterivOES(GLenum target, GLenum attachment, GLenum pname, GLint* params)
2058 {
2059 TRACE("(GLenum target = 0x%X, GLenum attachment = 0x%X, GLenum pname = 0x%X, GLint* params = %p)",
2060 target, attachment, pname, params);
2061
2062 es1::Context *context = es1::getContext();
2063
2064 if(context)
2065 {
2066 if(target != GL_FRAMEBUFFER_OES)
2067 {
2068 return error(GL_INVALID_ENUM);
2069 }
2070
2071 if(context->getFramebufferName() == 0)
2072 {
2073 return error(GL_INVALID_OPERATION);
2074 }
2075
2076 es1::Framebuffer *framebuffer = context->getFramebuffer();
2077
2078 if(!framebuffer)
2079 {
2080 return error(GL_INVALID_OPERATION);
2081 }
2082
2083 GLenum attachmentType;
2084 GLuint attachmentHandle;
2085 switch(attachment)
2086 {
2087 case GL_COLOR_ATTACHMENT0_OES:
2088 attachmentType = framebuffer->getColorbufferType();
2089 attachmentHandle = framebuffer->getColorbufferName();
2090 break;
2091 case GL_DEPTH_ATTACHMENT_OES:
2092 attachmentType = framebuffer->getDepthbufferType();
2093 attachmentHandle = framebuffer->getDepthbufferName();
2094 break;
2095 case GL_STENCIL_ATTACHMENT_OES:
2096 attachmentType = framebuffer->getStencilbufferType();
2097 attachmentHandle = framebuffer->getStencilbufferName();
2098 break;
2099 default:
2100 return error(GL_INVALID_ENUM);
2101 }
2102
2103 GLenum attachmentObjectType; // Type category
2104 if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
2105 {
2106 attachmentObjectType = attachmentType;
2107 }
2108 else if(es1::IsTextureTarget(attachmentType))
2109 {
2110 attachmentObjectType = GL_TEXTURE;
2111 }
2112 else UNREACHABLE(attachmentType);
2113
2114 switch(pname)
2115 {
2116 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
2117 *params = attachmentObjectType;
2118 break;
2119 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
2120 if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
2121 {
2122 *params = attachmentHandle;
2123 }
2124 else
2125 {
2126 return error(GL_INVALID_ENUM);
2127 }
2128 break;
2129 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
2130 if(attachmentObjectType == GL_TEXTURE)
2131 {
2132 *params = 0; // FramebufferTexture2D will not allow level to be set to anything else in GL ES 2.0
2133 }
2134 else
2135 {
2136 return error(GL_INVALID_ENUM);
2137 }
2138 break;
2139 default:
2140 return error(GL_INVALID_ENUM);
2141 }
2142 }
2143 }
2144
GetIntegerv(GLenum pname,GLint * params)2145 void GetIntegerv(GLenum pname, GLint* params)
2146 {
2147 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
2148
2149 es1::Context *context = es1::getContext();
2150
2151 if(context)
2152 {
2153 if(!(context->getIntegerv(pname, params)))
2154 {
2155 int numParams = context->getQueryParameterNum(pname);
2156
2157 if(numParams < 0)
2158 {
2159 return error(GL_INVALID_ENUM);
2160 }
2161
2162 if(numParams == 0)
2163 {
2164 return;
2165 }
2166
2167 if(context->isQueryParameterBool(pname))
2168 {
2169 GLboolean *boolParams = nullptr;
2170 boolParams = new GLboolean[numParams];
2171
2172 context->getBooleanv(pname, boolParams);
2173
2174 for(int i = 0; i < numParams; ++i)
2175 {
2176 if(boolParams[i] == GL_FALSE)
2177 params[i] = 0;
2178 else
2179 params[i] = 1;
2180 }
2181
2182 delete [] boolParams;
2183 }
2184 else if(context->isQueryParameterFloat(pname))
2185 {
2186 GLfloat *floatParams = nullptr;
2187 floatParams = new GLfloat[numParams];
2188
2189 context->getFloatv(pname, floatParams);
2190
2191 for(int i = 0; i < numParams; ++i)
2192 {
2193 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
2194 {
2195 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2196 }
2197 else
2198 {
2199 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2200 }
2201 }
2202
2203 delete [] floatParams;
2204 }
2205 else UNREACHABLE(pname);
2206 }
2207 }
2208 }
2209
GetLightfv(GLenum light,GLenum pname,GLfloat * params)2210 void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
2211 {
2212 UNIMPLEMENTED();
2213 }
2214
GetLightxv(GLenum light,GLenum pname,GLfixed * params)2215 void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
2216 {
2217 UNIMPLEMENTED();
2218 }
2219
GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)2220 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
2221 {
2222 UNIMPLEMENTED();
2223 }
2224
GetMaterialxv(GLenum face,GLenum pname,GLfixed * params)2225 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
2226 {
2227 UNIMPLEMENTED();
2228 }
2229
GetPointerv(GLenum pname,GLvoid ** params)2230 void GetPointerv(GLenum pname, GLvoid **params)
2231 {
2232 TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
2233
2234 es1::Context *context = es1::getContext();
2235
2236 if(context)
2237 {
2238 if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
2239 {
2240 return error(GL_INVALID_ENUM);
2241 }
2242 }
2243 }
2244
GetString(GLenum name)2245 const GLubyte* GetString(GLenum name)
2246 {
2247 TRACE("(GLenum name = 0x%X)", name);
2248
2249 switch(name)
2250 {
2251 case GL_VENDOR:
2252 return (GLubyte*)"Google Inc.";
2253 case GL_RENDERER:
2254 return (GLubyte*)"Google SwiftShader " VERSION_STRING;
2255 case GL_VERSION:
2256 return (GLubyte*)"OpenGL ES-CM 1.1";
2257 case GL_EXTENSIONS:
2258 // Keep list sorted in following order:
2259 // OES extensions
2260 // EXT extensions
2261 // Vendor extensions
2262 return (GLubyte*)
2263 "GL_OES_blend_equation_separate "
2264 "GL_OES_blend_func_separate "
2265 "GL_OES_blend_subtract "
2266 "GL_OES_compressed_ETC1_RGB8_texture "
2267 "GL_OES_EGL_image "
2268 "GL_OES_EGL_image_external "
2269 "GL_OES_EGL_sync "
2270 "GL_OES_element_index_uint "
2271 "GL_OES_framebuffer_object "
2272 "GL_OES_packed_depth_stencil "
2273 "GL_OES_read_format "
2274 "GL_OES_rgb8_rgba8 "
2275 "GL_OES_stencil8 "
2276 "GL_OES_stencil_wrap "
2277 "GL_OES_surfaceless_context "
2278 "GL_OES_texture_mirrored_repeat "
2279 "GL_OES_texture_npot "
2280 "GL_EXT_blend_minmax "
2281 "GL_EXT_read_format_bgra "
2282 "GL_EXT_texture_compression_dxt1 "
2283 "GL_ANGLE_texture_compression_dxt3 "
2284 "GL_ANGLE_texture_compression_dxt5 "
2285 "GL_EXT_texture_filter_anisotropic "
2286 "GL_EXT_texture_format_BGRA8888";
2287 default:
2288 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
2289 }
2290 }
2291
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2292 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2293 {
2294 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
2295
2296 es1::Context *context = es1::getContext();
2297
2298 if(context)
2299 {
2300 es1::Texture *texture;
2301
2302 switch(target)
2303 {
2304 case GL_TEXTURE_2D:
2305 texture = context->getTexture2D();
2306 break;
2307 case GL_TEXTURE_EXTERNAL_OES:
2308 texture = context->getTextureExternal();
2309 break;
2310 default:
2311 return error(GL_INVALID_ENUM);
2312 }
2313
2314 switch(pname)
2315 {
2316 case GL_TEXTURE_MAG_FILTER:
2317 *params = (GLfloat)texture->getMagFilter();
2318 break;
2319 case GL_TEXTURE_MIN_FILTER:
2320 *params = (GLfloat)texture->getMinFilter();
2321 break;
2322 case GL_TEXTURE_WRAP_S:
2323 *params = (GLfloat)texture->getWrapS();
2324 break;
2325 case GL_TEXTURE_WRAP_T:
2326 *params = (GLfloat)texture->getWrapT();
2327 break;
2328 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2329 *params = texture->getMaxAnisotropy();
2330 break;
2331 case GL_GENERATE_MIPMAP:
2332 *params = (GLfloat)texture->getGenerateMipmap();
2333 break;
2334 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2335 *params = (GLfloat)1;
2336 break;
2337 default:
2338 return error(GL_INVALID_ENUM);
2339 }
2340 }
2341 }
2342
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)2343 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2344 {
2345 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2346
2347 es1::Context *context = es1::getContext();
2348
2349 if(context)
2350 {
2351 es1::Texture *texture;
2352
2353 switch(target)
2354 {
2355 case GL_TEXTURE_2D:
2356 texture = context->getTexture2D();
2357 break;
2358 case GL_TEXTURE_EXTERNAL_OES:
2359 texture = context->getTextureExternal();
2360 break;
2361 default:
2362 return error(GL_INVALID_ENUM);
2363 }
2364
2365 switch(pname)
2366 {
2367 case GL_TEXTURE_MAG_FILTER:
2368 *params = texture->getMagFilter();
2369 break;
2370 case GL_TEXTURE_MIN_FILTER:
2371 *params = texture->getMinFilter();
2372 break;
2373 case GL_TEXTURE_WRAP_S:
2374 *params = texture->getWrapS();
2375 break;
2376 case GL_TEXTURE_WRAP_T:
2377 *params = texture->getWrapT();
2378 break;
2379 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2380 *params = (GLint)texture->getMaxAnisotropy();
2381 break;
2382 case GL_GENERATE_MIPMAP:
2383 *params = (GLint)texture->getGenerateMipmap();
2384 break;
2385 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2386 *params = 1;
2387 break;
2388 default:
2389 return error(GL_INVALID_ENUM);
2390 }
2391 }
2392 }
2393
GetTexEnvfv(GLenum env,GLenum pname,GLfloat * params)2394 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
2395 {
2396 UNIMPLEMENTED();
2397 }
2398
GetTexEnviv(GLenum env,GLenum pname,GLint * params)2399 void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
2400 {
2401 UNIMPLEMENTED();
2402 }
2403
GetTexEnvxv(GLenum env,GLenum pname,GLfixed * params)2404 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
2405 {
2406 UNIMPLEMENTED();
2407 }
2408
GetTexParameterxv(GLenum target,GLenum pname,GLfixed * params)2409 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
2410 {
2411 UNIMPLEMENTED();
2412 }
2413
Hint(GLenum target,GLenum mode)2414 void Hint(GLenum target, GLenum mode)
2415 {
2416 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
2417
2418 switch(mode)
2419 {
2420 case GL_FASTEST:
2421 case GL_NICEST:
2422 case GL_DONT_CARE:
2423 break;
2424 default:
2425 return error(GL_INVALID_ENUM);
2426 }
2427
2428 es1::Context *context = es1::getContext();
2429
2430 if(context)
2431 {
2432 switch(target)
2433 {
2434 case GL_GENERATE_MIPMAP_HINT:
2435 context->setGenerateMipmapHint(mode);
2436 break;
2437 case GL_PERSPECTIVE_CORRECTION_HINT:
2438 context->setPerspectiveCorrectionHint(mode);
2439 break;
2440 case GL_FOG_HINT:
2441 context->setFogHint(mode);
2442 break;
2443 default:
2444 return error(GL_INVALID_ENUM);
2445 }
2446 }
2447 }
2448
IsBuffer(GLuint buffer)2449 GLboolean IsBuffer(GLuint buffer)
2450 {
2451 TRACE("(GLuint buffer = %d)", buffer);
2452
2453 es1::Context *context = es1::getContext();
2454
2455 if(context && buffer)
2456 {
2457 es1::Buffer *bufferObject = context->getBuffer(buffer);
2458
2459 if(bufferObject)
2460 {
2461 return GL_TRUE;
2462 }
2463 }
2464
2465 return GL_FALSE;
2466 }
2467
IsEnabled(GLenum cap)2468 GLboolean IsEnabled(GLenum cap)
2469 {
2470 TRACE("(GLenum cap = 0x%X)", cap);
2471
2472 es1::Context *context = es1::getContext();
2473
2474 if(context)
2475 {
2476 switch(cap)
2477 {
2478 case GL_CULL_FACE: return context->isCullFaceEnabled(); break;
2479 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); break;
2480 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
2481 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); break;
2482 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); break;
2483 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); break;
2484 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); break;
2485 case GL_BLEND: return context->isBlendEnabled(); break;
2486 case GL_DITHER: return context->isDitherEnabled(); break;
2487 case GL_LIGHTING: return context->isLightingEnabled(); break;
2488 case GL_LIGHT0: return context->isLightEnabled(0); break;
2489 case GL_LIGHT1: return context->isLightEnabled(1); break;
2490 case GL_LIGHT2: return context->isLightEnabled(2); break;
2491 case GL_LIGHT3: return context->isLightEnabled(3); break;
2492 case GL_LIGHT4: return context->isLightEnabled(4); break;
2493 case GL_LIGHT5: return context->isLightEnabled(5); break;
2494 case GL_LIGHT6: return context->isLightEnabled(6); break;
2495 case GL_LIGHT7: return context->isLightEnabled(7); break;
2496 case GL_FOG: return context->isFogEnabled(); break;
2497 case GL_TEXTURE_2D: return context->isTexture2Denabled(); break;
2498 case GL_TEXTURE_EXTERNAL_OES: return context->isTextureExternalEnabled(); break;
2499 case GL_ALPHA_TEST: return context->isAlphaTestEnabled(); break;
2500 case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled(); break;
2501 case GL_POINT_SMOOTH: return context->isPointSmoothEnabled(); break;
2502 case GL_LINE_SMOOTH: return context->isLineSmoothEnabled(); break;
2503 case GL_COLOR_MATERIAL: return context->isColorMaterialEnabled(); break;
2504 case GL_NORMALIZE: return context->isNormalizeEnabled(); break;
2505 case GL_RESCALE_NORMAL: return context->isRescaleNormalEnabled(); break;
2506 case GL_VERTEX_ARRAY: return context->isVertexArrayEnabled(); break;
2507 case GL_NORMAL_ARRAY: return context->isNormalArrayEnabled(); break;
2508 case GL_COLOR_ARRAY: return context->isColorArrayEnabled(); break;
2509 case GL_POINT_SIZE_ARRAY_OES: return context->isPointSizeArrayEnabled(); break;
2510 case GL_TEXTURE_COORD_ARRAY: return context->isTextureCoordArrayEnabled(); break;
2511 case GL_MULTISAMPLE: return context->isMultisampleEnabled(); break;
2512 case GL_SAMPLE_ALPHA_TO_ONE: return context->isSampleAlphaToOneEnabled(); break;
2513 case GL_CLIP_PLANE0: return context->isClipPlaneEnabled(0); break;
2514 case GL_CLIP_PLANE1: return context->isClipPlaneEnabled(1); break;
2515 case GL_CLIP_PLANE2: return context->isClipPlaneEnabled(2); break;
2516 case GL_CLIP_PLANE3: return context->isClipPlaneEnabled(3); break;
2517 case GL_CLIP_PLANE4: return context->isClipPlaneEnabled(4); break;
2518 case GL_CLIP_PLANE5: return context->isClipPlaneEnabled(5); break;
2519 case GL_POINT_SPRITE_OES: return context->isPointSpriteEnabled(); break;
2520 default:
2521 return error(GL_INVALID_ENUM, GL_FALSE);
2522 }
2523 }
2524
2525 return GL_FALSE;
2526 }
2527
IsFramebufferOES(GLuint framebuffer)2528 GLboolean IsFramebufferOES(GLuint framebuffer)
2529 {
2530 TRACE("(GLuint framebuffer = %d)", framebuffer);
2531
2532 es1::Context *context = es1::getContext();
2533
2534 if(context && framebuffer)
2535 {
2536 es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2537
2538 if(framebufferObject)
2539 {
2540 return GL_TRUE;
2541 }
2542 }
2543
2544 return GL_FALSE;
2545 }
2546
IsTexture(GLuint texture)2547 GLboolean IsTexture(GLuint texture)
2548 {
2549 TRACE("(GLuint texture = %d)", texture);
2550
2551 es1::Context *context = es1::getContext();
2552
2553 if(context && texture)
2554 {
2555 es1::Texture *textureObject = context->getTexture(texture);
2556
2557 if(textureObject)
2558 {
2559 return GL_TRUE;
2560 }
2561 }
2562
2563 return GL_FALSE;
2564 }
2565
IsRenderbufferOES(GLuint renderbuffer)2566 GLboolean IsRenderbufferOES(GLuint renderbuffer)
2567 {
2568 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
2569
2570 es1::Context *context = es1::getContext();
2571
2572 if(context && renderbuffer)
2573 {
2574 es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2575
2576 if(renderbufferObject)
2577 {
2578 return GL_TRUE;
2579 }
2580 }
2581
2582 return GL_FALSE;
2583 }
2584
LightModelf(GLenum pname,GLfloat param)2585 void LightModelf(GLenum pname, GLfloat param)
2586 {
2587 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
2588
2589 es1::Context *context = es1::getContext();
2590
2591 if(context)
2592 {
2593 switch(pname)
2594 {
2595 case GL_LIGHT_MODEL_TWO_SIDE:
2596 context->setLightModelTwoSide(param != 0.0f);
2597 break;
2598 case GL_LIGHT_MODEL_AMBIENT:
2599 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelfv() instead
2600 default:
2601 return error(GL_INVALID_ENUM);
2602 }
2603 }
2604 }
2605
LightModelfv(GLenum pname,const GLfloat * params)2606 void LightModelfv(GLenum pname, const GLfloat *params)
2607 {
2608 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
2609
2610 es1::Context *context = es1::getContext();
2611
2612 if(context)
2613 {
2614 switch(pname)
2615 {
2616 case GL_LIGHT_MODEL_AMBIENT:
2617 context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
2618 break;
2619 case GL_LIGHT_MODEL_TWO_SIDE:
2620 context->setLightModelTwoSide(params[0] != 0.0f);
2621 break;
2622 default:
2623 return error(GL_INVALID_ENUM);
2624 }
2625 }
2626 }
2627
LightModelx(GLenum pname,GLfixed param)2628 void LightModelx(GLenum pname, GLfixed param)
2629 {
2630 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
2631
2632 es1::Context *context = es1::getContext();
2633
2634 if(context)
2635 {
2636 switch(pname)
2637 {
2638 case GL_LIGHT_MODEL_TWO_SIDE:
2639 context->setLightModelTwoSide(param != 0);
2640 break;
2641 case GL_LIGHT_MODEL_AMBIENT:
2642 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelxv() instead
2643 default:
2644 return error(GL_INVALID_ENUM);
2645 }
2646 }
2647 }
2648
LightModelxv(GLenum pname,const GLfixed * params)2649 void LightModelxv(GLenum pname, const GLfixed *params)
2650 {
2651 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
2652
2653 es1::Context *context = es1::getContext();
2654
2655 if(context)
2656 {
2657 switch(pname)
2658 {
2659 case GL_LIGHT_MODEL_AMBIENT:
2660 context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
2661 break;
2662 case GL_LIGHT_MODEL_TWO_SIDE:
2663 context->setLightModelTwoSide(params[0] != 0);
2664 break;
2665 default:
2666 return error(GL_INVALID_ENUM);
2667 }
2668 }
2669 }
2670
Lightf(GLenum light,GLenum pname,GLfloat param)2671 void Lightf(GLenum light, GLenum pname, GLfloat param)
2672 {
2673 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
2674
2675 int index = light - GL_LIGHT0;
2676
2677 if(index < 0 || index >= es1::MAX_LIGHTS)
2678 {
2679 return error(GL_INVALID_ENUM);
2680 }
2681
2682 es1::Context *context = es1::getContext();
2683
2684 if(context)
2685 {
2686 switch(pname)
2687 {
2688 case GL_SPOT_EXPONENT:
2689 if(param < 0.0f || param > 128.0f)
2690 {
2691 return error(GL_INVALID_VALUE);
2692 }
2693 context->setSpotLightExponent(index, param);
2694 break;
2695 case GL_SPOT_CUTOFF:
2696 if((param < 0.0f || param > 90.0f) && param != 180.0f)
2697 {
2698 return error(GL_INVALID_VALUE);
2699 }
2700 context->setSpotLightCutoff(index, param);
2701 break;
2702 case GL_CONSTANT_ATTENUATION:
2703 if(param < 0.0f)
2704 {
2705 return error(GL_INVALID_VALUE);
2706 }
2707 context->setLightAttenuationConstant(index, param);
2708 break;
2709 case GL_LINEAR_ATTENUATION:
2710 if(param < 0.0f)
2711 {
2712 return error(GL_INVALID_VALUE);
2713 }
2714 context->setLightAttenuationLinear(index, param);
2715 break;
2716 case GL_QUADRATIC_ATTENUATION:
2717 if(param < 0.0f)
2718 {
2719 return error(GL_INVALID_VALUE);
2720 }
2721 context->setLightAttenuationQuadratic(index, param);
2722 break;
2723 case GL_AMBIENT:
2724 case GL_DIFFUSE:
2725 case GL_SPECULAR:
2726 case GL_POSITION:
2727 case GL_SPOT_DIRECTION:
2728 return error(GL_INVALID_ENUM); // Need four values, should call glLightfv() instead
2729 default:
2730 return error(GL_INVALID_ENUM);
2731 }
2732 }
2733 }
2734
Lightfv(GLenum light,GLenum pname,const GLfloat * params)2735 void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2736 {
2737 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
2738
2739 es1::Context *context = es1::getContext();
2740
2741 if(context)
2742 {
2743 int index = light - GL_LIGHT0;
2744
2745 if(index < 0 || index > es1::MAX_LIGHTS)
2746 {
2747 return error(GL_INVALID_ENUM);
2748 }
2749
2750 switch(pname)
2751 {
2752 case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break;
2753 case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break;
2754 case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
2755 case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
2756 case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break;
2757 case GL_SPOT_EXPONENT:
2758 if(params[0] < 0.0f || params[0] > 128.0f)
2759 {
2760 return error(GL_INVALID_VALUE);
2761 }
2762 context->setSpotLightExponent(index, params[0]);
2763 break;
2764 case GL_SPOT_CUTOFF:
2765 if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
2766 {
2767 return error(GL_INVALID_VALUE);
2768 }
2769 context->setSpotLightCutoff(index, params[0]);
2770 break;
2771 case GL_CONSTANT_ATTENUATION:
2772 if(params[0] < 0.0f)
2773 {
2774 return error(GL_INVALID_VALUE);
2775 }
2776 context->setLightAttenuationConstant(index, params[0]);
2777 break;
2778 case GL_LINEAR_ATTENUATION:
2779 if(params[0] < 0.0f)
2780 {
2781 return error(GL_INVALID_VALUE);
2782 }
2783 context->setLightAttenuationLinear(index, params[0]);
2784 break;
2785 case GL_QUADRATIC_ATTENUATION:
2786 if(params[0] < 0.0f)
2787 {
2788 return error(GL_INVALID_VALUE);
2789 }
2790 context->setLightAttenuationQuadratic(index, params[0]);
2791 break;
2792 default:
2793 return error(GL_INVALID_ENUM);
2794 }
2795 }
2796 }
2797
Lightx(GLenum light,GLenum pname,GLfixed param)2798 void Lightx(GLenum light, GLenum pname, GLfixed param)
2799 {
2800 UNIMPLEMENTED();
2801 }
2802
Lightxv(GLenum light,GLenum pname,const GLfixed * params)2803 void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
2804 {
2805 UNIMPLEMENTED();
2806 }
2807
LineWidth(GLfloat width)2808 void LineWidth(GLfloat width)
2809 {
2810 TRACE("(GLfloat width = %f)", width);
2811
2812 if(width <= 0.0f)
2813 {
2814 return error(GL_INVALID_VALUE);
2815 }
2816
2817 es1::Context *context = es1::getContext();
2818
2819 if(context)
2820 {
2821 context->setLineWidth(width);
2822 }
2823 }
2824
LineWidthx(GLfixed width)2825 void LineWidthx(GLfixed width)
2826 {
2827 LineWidth((float)width / 0x10000);
2828 }
2829
LoadIdentity(void)2830 void LoadIdentity(void)
2831 {
2832 TRACE("()");
2833
2834 es1::Context *context = es1::getContext();
2835
2836 if(context)
2837 {
2838 context->loadIdentity();
2839 }
2840 }
2841
LoadMatrixf(const GLfloat * m)2842 void LoadMatrixf(const GLfloat *m)
2843 {
2844 TRACE("(const GLfloat *m)");
2845
2846 es1::Context *context = es1::getContext();
2847
2848 if(context)
2849 {
2850 context->load(m);
2851 }
2852 }
2853
LoadMatrixx(const GLfixed * m)2854 void LoadMatrixx(const GLfixed *m)
2855 {
2856 GLfloat matrix[16] =
2857 {
2858 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
2859 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
2860 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
2861 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
2862 };
2863
2864 LoadMatrixf(matrix);
2865 }
2866
LogicOp(GLenum opcode)2867 void LogicOp(GLenum opcode)
2868 {
2869 TRACE("(GLenum opcode = 0x%X)", opcode);
2870
2871 switch(opcode)
2872 {
2873 case GL_CLEAR:
2874 case GL_SET:
2875 case GL_COPY:
2876 case GL_COPY_INVERTED:
2877 case GL_NOOP:
2878 case GL_INVERT:
2879 case GL_AND:
2880 case GL_NAND:
2881 case GL_OR:
2882 case GL_NOR:
2883 case GL_XOR:
2884 case GL_EQUIV:
2885 case GL_AND_REVERSE:
2886 case GL_AND_INVERTED:
2887 case GL_OR_REVERSE:
2888 case GL_OR_INVERTED:
2889 break;
2890 default:
2891 return error(GL_INVALID_ENUM);
2892 }
2893
2894 es1::Context *context = es1::getContext();
2895
2896 if(context)
2897 {
2898 context->setLogicalOperation(opcode);
2899 }
2900 }
2901
Materialf(GLenum face,GLenum pname,GLfloat param)2902 void Materialf(GLenum face, GLenum pname, GLfloat param)
2903 {
2904 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
2905
2906 if(face != GL_FRONT_AND_BACK)
2907 {
2908 return error(GL_INVALID_ENUM);
2909 }
2910
2911 es1::Context *context = es1::getContext();
2912
2913 if(context)
2914 {
2915 switch(pname)
2916 {
2917 case GL_SHININESS:
2918 if(param < 0.0f || param > 128.0f)
2919 {
2920 return error(GL_INVALID_VALUE);
2921 }
2922 context->setMaterialShininess(param);
2923 break;
2924 case GL_AMBIENT:
2925 case GL_DIFFUSE:
2926 case GL_AMBIENT_AND_DIFFUSE:
2927 case GL_SPECULAR:
2928 case GL_EMISSION:
2929 return error(GL_INVALID_ENUM); // Need four values, should call glMaterialfv() instead
2930 default:
2931 return error(GL_INVALID_ENUM);
2932 }
2933 }
2934 }
2935
Materialfv(GLenum face,GLenum pname,const GLfloat * params)2936 void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
2937 {
2938 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
2939
2940 if(face != GL_FRONT_AND_BACK)
2941 {
2942 return error(GL_INVALID_ENUM);
2943 }
2944
2945 es1::Context *context = es1::getContext();
2946
2947 if(context)
2948 {
2949 switch(pname)
2950 {
2951 case GL_AMBIENT:
2952 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2953 break;
2954 case GL_DIFFUSE:
2955 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2956 break;
2957 case GL_AMBIENT_AND_DIFFUSE:
2958 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2959 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2960 break;
2961 case GL_SPECULAR:
2962 context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
2963 break;
2964 case GL_EMISSION:
2965 context->setMaterialEmission(params[0], params[1], params[2], params[3]);
2966 break;
2967 case GL_SHININESS:
2968 context->setMaterialShininess(params[0]);
2969 break;
2970 default:
2971 return error(GL_INVALID_ENUM);
2972 }
2973 }
2974 }
2975
Materialx(GLenum face,GLenum pname,GLfixed param)2976 void Materialx(GLenum face, GLenum pname, GLfixed param)
2977 {
2978 UNIMPLEMENTED();
2979 }
2980
Materialxv(GLenum face,GLenum pname,const GLfixed * params)2981 void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
2982 {
2983 UNIMPLEMENTED();
2984 }
2985
MatrixMode(GLenum mode)2986 void MatrixMode(GLenum mode)
2987 {
2988 TRACE("(GLenum mode = 0x%X)", mode);
2989
2990 es1::Context *context = es1::getContext();
2991
2992 if(context)
2993 {
2994 context->setMatrixMode(mode);
2995 }
2996 }
2997
MultMatrixf(const GLfloat * m)2998 void MultMatrixf(const GLfloat *m)
2999 {
3000 TRACE("(const GLfloat *m)");
3001
3002 es1::Context *context = es1::getContext();
3003
3004 if(context)
3005 {
3006 context->multiply(m);
3007 }
3008 }
3009
MultMatrixx(const GLfixed * m)3010 void MultMatrixx(const GLfixed *m)
3011 {
3012 GLfloat matrix[16] =
3013 {
3014 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
3015 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
3016 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
3017 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
3018 };
3019
3020 MultMatrixf(matrix);
3021 }
3022
MultiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)3023 void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3024 {
3025 TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
3026
3027 switch(target)
3028 {
3029 case GL_TEXTURE0:
3030 case GL_TEXTURE1:
3031 break;
3032 default:
3033 return error(GL_INVALID_ENUM);
3034 }
3035
3036 es1::Context *context = es1::getContext();
3037
3038 if(context)
3039 {
3040 context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
3041 }
3042 }
3043
MultiTexCoord4x(GLenum target,GLfixed s,GLfixed t,GLfixed r,GLfixed q)3044 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3045 {
3046 UNIMPLEMENTED();
3047 }
3048
Normal3f(GLfloat nx,GLfloat ny,GLfloat nz)3049 void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
3050 {
3051 TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
3052
3053 es1::Context *context = es1::getContext();
3054
3055 if(context)
3056 {
3057 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
3058 }
3059 }
3060
Normal3x(GLfixed nx,GLfixed ny,GLfixed nz)3061 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
3062 {
3063 UNIMPLEMENTED();
3064 }
3065
NormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)3066 void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
3067 {
3068 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3069
3070 VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
3071 }
3072
Orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3073 void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3074 {
3075 TRACE("(GLfloat left = %f, GLfloat right = %f, GLfloat bottom = %f, GLfloat top = %f, GLfloat zNear = %f, GLfloat zFar = %f)", left, right, bottom, top, zNear, zFar);
3076
3077 if(left == right || bottom == top || zNear == zFar)
3078 {
3079 return error(GL_INVALID_VALUE);
3080 }
3081
3082 es1::Context *context = es1::getContext();
3083
3084 if(context)
3085 {
3086 context->ortho(left, right, bottom, top, zNear, zFar);
3087 }
3088 }
3089
Orthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)3090 void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3091 {
3092 Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
3093 }
3094
PixelStorei(GLenum pname,GLint param)3095 void PixelStorei(GLenum pname, GLint param)
3096 {
3097 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3098
3099 es1::Context *context = es1::getContext();
3100
3101 if(context)
3102 {
3103 switch(pname)
3104 {
3105 case GL_UNPACK_ALIGNMENT:
3106 if(param != 1 && param != 2 && param != 4 && param != 8)
3107 {
3108 return error(GL_INVALID_VALUE);
3109 }
3110
3111 context->setUnpackAlignment(param);
3112 break;
3113 case GL_PACK_ALIGNMENT:
3114 if(param != 1 && param != 2 && param != 4 && param != 8)
3115 {
3116 return error(GL_INVALID_VALUE);
3117 }
3118
3119 context->setPackAlignment(param);
3120 break;
3121 default:
3122 return error(GL_INVALID_ENUM);
3123 }
3124 }
3125 }
3126
PointParameterf(GLenum pname,GLfloat param)3127 void PointParameterf(GLenum pname, GLfloat param)
3128 {
3129 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
3130
3131 es1::Context *context = es1::getContext();
3132
3133 if(context)
3134 {
3135 switch(pname)
3136 {
3137 case GL_POINT_SIZE_MIN:
3138 if(param < 0.0f)
3139 {
3140 return error(GL_INVALID_VALUE);
3141 }
3142 context->setPointSizeMin(param);
3143 break;
3144 case GL_POINT_SIZE_MAX:
3145 if(param < 0.0f)
3146 {
3147 return error(GL_INVALID_VALUE);
3148 }
3149 context->setPointSizeMax(param);
3150 break;
3151 case GL_POINT_FADE_THRESHOLD_SIZE:
3152 if(param < 0.0f)
3153 {
3154 return error(GL_INVALID_VALUE);
3155 }
3156 context->setPointFadeThresholdSize(param);
3157 break;
3158 case GL_POINT_DISTANCE_ATTENUATION:
3159 return error(GL_INVALID_ENUM); // Needs three values, should call glPointParameterfv() instead
3160 default:
3161 return error(GL_INVALID_ENUM);
3162 }
3163 }
3164 }
3165
PointParameterfv(GLenum pname,const GLfloat * params)3166 void PointParameterfv(GLenum pname, const GLfloat *params)
3167 {
3168 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
3169
3170 es1::Context *context = es1::getContext();
3171
3172 if(context)
3173 {
3174 switch(pname)
3175 {
3176 case GL_POINT_SIZE_MIN:
3177 if(params[0] < 0.0f)
3178 {
3179 return error(GL_INVALID_VALUE);
3180 }
3181 context->setPointSizeMin(params[0]);
3182 break;
3183 case GL_POINT_SIZE_MAX:
3184 if(params[0] < 0.0f)
3185 {
3186 return error(GL_INVALID_VALUE);
3187 }
3188 context->setPointSizeMax(params[0]);
3189 break;
3190 case GL_POINT_DISTANCE_ATTENUATION:
3191 context->setPointDistanceAttenuation(params[0], params[1], params[2]);
3192 break;
3193 case GL_POINT_FADE_THRESHOLD_SIZE:
3194 if(params[0] < 0.0f)
3195 {
3196 return error(GL_INVALID_VALUE);
3197 }
3198 context->setPointFadeThresholdSize(params[0]);
3199 break;
3200 default:
3201 return error(GL_INVALID_ENUM);
3202 }
3203 }
3204 }
3205
PointParameterx(GLenum pname,GLfixed param)3206 void PointParameterx(GLenum pname, GLfixed param)
3207 {
3208 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
3209
3210 es1::Context *context = es1::getContext();
3211
3212 if(context)
3213 {
3214 switch(pname)
3215 {
3216 case GL_POINT_SIZE_MIN:
3217 if(param < 0)
3218 {
3219 return error(GL_INVALID_VALUE);
3220 }
3221 context->setPointSizeMin((float)param / 0x10000);
3222 break;
3223 case GL_POINT_SIZE_MAX:
3224 if(param < 0)
3225 {
3226 return error(GL_INVALID_VALUE);
3227 }
3228 context->setPointSizeMax((float)param / 0x10000);
3229 break;
3230 case GL_POINT_FADE_THRESHOLD_SIZE:
3231 if(param < 0)
3232 {
3233 return error(GL_INVALID_VALUE);
3234 }
3235 context->setPointFadeThresholdSize((float)param / 0x10000);
3236 break;
3237 case GL_POINT_DISTANCE_ATTENUATION:
3238 return error(GL_INVALID_ENUM); // Needs three parameters, should call glPointParameterxv() instead
3239 default:
3240 return error(GL_INVALID_ENUM);
3241 }
3242 }
3243 }
3244
PointParameterxv(GLenum pname,const GLfixed * params)3245 void PointParameterxv(GLenum pname, const GLfixed *params)
3246 {
3247 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
3248
3249 es1::Context *context = es1::getContext();
3250
3251 if(context)
3252 {
3253 switch(pname)
3254 {
3255 case GL_POINT_SIZE_MIN:
3256 if(params[0] < 0)
3257 {
3258 return error(GL_INVALID_VALUE);
3259 }
3260 context->setPointSizeMin((float)params[0] / 0x10000);
3261 break;
3262 case GL_POINT_SIZE_MAX:
3263 if(params[0] < 0)
3264 {
3265 return error(GL_INVALID_VALUE);
3266 }
3267 context->setPointSizeMax((float)params[0] / 0x10000);
3268 break;
3269 case GL_POINT_DISTANCE_ATTENUATION:
3270 context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
3271 break;
3272 case GL_POINT_FADE_THRESHOLD_SIZE:
3273 if(params[0] < 0)
3274 {
3275 return error(GL_INVALID_VALUE);
3276 }
3277 context->setPointFadeThresholdSize((float)params[0] / 0x10000);
3278 break;
3279 default:
3280 return error(GL_INVALID_ENUM);
3281 }
3282 }
3283 }
3284
PointSize(GLfloat size)3285 void PointSize(GLfloat size)
3286 {
3287 TRACE("(GLfloat size = %f)", size);
3288
3289 if(size <= 0)
3290 {
3291 return error(GL_INVALID_VALUE);
3292 }
3293
3294 es1::Context *context = es1::getContext();
3295
3296 if(context)
3297 {
3298 context->setVertexAttrib(sw::PointSize, size, size, size, size);
3299 }
3300 }
3301
PointSizePointerOES(GLenum type,GLsizei stride,const GLvoid * pointer)3302 void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
3303 {
3304 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3305
3306 switch(type)
3307 {
3308 case GL_FIXED:
3309 case GL_FLOAT:
3310 break;
3311 default:
3312 return error(GL_INVALID_ENUM);
3313 }
3314
3315 VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
3316 }
3317
PointSizex(GLfixed size)3318 void PointSizex(GLfixed size)
3319 {
3320 PointSize((float)size / 0x10000);
3321 }
3322
PolygonOffset(GLfloat factor,GLfloat units)3323 void PolygonOffset(GLfloat factor, GLfloat units)
3324 {
3325 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3326
3327 es1::Context *context = es1::getContext();
3328
3329 if(context)
3330 {
3331 context->setPolygonOffsetParams(factor, units);
3332 }
3333 }
3334
PolygonOffsetx(GLfixed factor,GLfixed units)3335 void PolygonOffsetx(GLfixed factor, GLfixed units)
3336 {
3337 PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
3338 }
3339
PopMatrix(void)3340 void PopMatrix(void)
3341 {
3342 TRACE("()");
3343
3344 es1::Context *context = es1::getContext();
3345
3346 if(context)
3347 {
3348 context->popMatrix();
3349 }
3350 }
3351
PushMatrix(void)3352 void PushMatrix(void)
3353 {
3354 TRACE("()");
3355
3356 es1::Context *context = es1::getContext();
3357
3358 if(context)
3359 {
3360 context->pushMatrix();
3361 }
3362 }
3363
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3364 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
3365 {
3366 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3367 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
3368 x, y, width, height, format, type, pixels);
3369
3370 if(width < 0 || height < 0)
3371 {
3372 return error(GL_INVALID_VALUE);
3373 }
3374
3375 es1::Context *context = es1::getContext();
3376
3377 if(context)
3378 {
3379 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
3380 }
3381 }
3382
RenderbufferStorageOES(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3383 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3384 {
3385 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3386 target, internalformat, width, height);
3387
3388 switch(target)
3389 {
3390 case GL_RENDERBUFFER_OES:
3391 break;
3392 default:
3393 return error(GL_INVALID_ENUM);
3394 }
3395
3396 if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
3397 {
3398 return error(GL_INVALID_ENUM);
3399 }
3400
3401 if(width < 0 || height < 0)
3402 {
3403 return error(GL_INVALID_VALUE);
3404 }
3405
3406 es1::Context *context = es1::getContext();
3407
3408 if(context)
3409 {
3410 if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3411 height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
3412 {
3413 return error(GL_INVALID_VALUE);
3414 }
3415
3416 GLuint handle = context->getRenderbufferName();
3417 if(handle == 0)
3418 {
3419 return error(GL_INVALID_OPERATION);
3420 }
3421
3422 switch(internalformat)
3423 {
3424 case GL_RGBA4_OES:
3425 case GL_RGB5_A1_OES:
3426 case GL_RGB565_OES:
3427 case GL_RGB8_OES:
3428 case GL_RGBA8_OES:
3429 context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
3430 break;
3431 case GL_DEPTH_COMPONENT16_OES:
3432 context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat, 0));
3433 break;
3434 case GL_STENCIL_INDEX8_OES:
3435 context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
3436 break;
3437 case GL_DEPTH24_STENCIL8_OES:
3438 context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0));
3439 break;
3440 default:
3441 return error(GL_INVALID_ENUM);
3442 }
3443 }
3444 }
3445
Rotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3446 void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3447 {
3448 TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
3449
3450 es1::Context *context = es1::getContext();
3451
3452 if(context)
3453 {
3454 context->rotate(angle, x, y, z);
3455 }
3456 }
3457
Rotatex(GLfixed angle,GLfixed x,GLfixed y,GLfixed z)3458 void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3459 {
3460 Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3461 }
3462
SampleCoverage(GLclampf value,GLboolean invert)3463 void SampleCoverage(GLclampf value, GLboolean invert)
3464 {
3465 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3466
3467 es1::Context* context = es1::getContext();
3468
3469 if(context)
3470 {
3471 context->setSampleCoverageParams(es1::clamp01(value), invert == GL_TRUE);
3472 }
3473 }
3474
SampleCoveragex(GLclampx value,GLboolean invert)3475 void SampleCoveragex(GLclampx value, GLboolean invert)
3476 {
3477 SampleCoverage((float)value / 0x10000, invert);
3478 }
3479
Scalef(GLfloat x,GLfloat y,GLfloat z)3480 void Scalef(GLfloat x, GLfloat y, GLfloat z)
3481 {
3482 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
3483
3484 es1::Context *context = es1::getContext();
3485
3486 if(context)
3487 {
3488 context->scale(x, y, z);
3489 }
3490 }
3491
Scalex(GLfixed x,GLfixed y,GLfixed z)3492 void Scalex(GLfixed x, GLfixed y, GLfixed z)
3493 {
3494 Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3495 }
3496
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)3497 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3498 {
3499 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
3500
3501 if(width < 0 || height < 0)
3502 {
3503 return error(GL_INVALID_VALUE);
3504 }
3505
3506 es1::Context* context = es1::getContext();
3507
3508 if(context)
3509 {
3510 context->setScissorParams(x, y, width, height);
3511 }
3512 }
3513
ShadeModel(GLenum mode)3514 void ShadeModel(GLenum mode)
3515 {
3516 switch(mode)
3517 {
3518 case GL_FLAT:
3519 case GL_SMOOTH:
3520 break;
3521 default:
3522 return error(GL_INVALID_ENUM);
3523 }
3524
3525 es1::Context *context = es1::getContext();
3526
3527 if(context)
3528 {
3529 context->setShadeModel(mode);
3530 }
3531 }
3532
StencilFunc(GLenum func,GLint ref,GLuint mask)3533 void StencilFunc(GLenum func, GLint ref, GLuint mask)
3534 {
3535 TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", func, ref, mask);
3536
3537 switch(func)
3538 {
3539 case GL_NEVER:
3540 case GL_ALWAYS:
3541 case GL_LESS:
3542 case GL_LEQUAL:
3543 case GL_EQUAL:
3544 case GL_GEQUAL:
3545 case GL_GREATER:
3546 case GL_NOTEQUAL:
3547 break;
3548 default:
3549 return error(GL_INVALID_ENUM);
3550 }
3551
3552 es1::Context *context = es1::getContext();
3553
3554 if(context)
3555 {
3556 context->setStencilParams(func, ref, mask);
3557 }
3558 }
3559
StencilMask(GLuint mask)3560 void StencilMask(GLuint mask)
3561 {
3562 TRACE("(GLuint mask = %d)", mask);
3563
3564 es1::Context *context = es1::getContext();
3565
3566 if(context)
3567 {
3568 context->setStencilWritemask(mask);
3569 }
3570 }
3571
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)3572 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3573 {
3574 TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
3575
3576 switch(fail)
3577 {
3578 case GL_ZERO:
3579 case GL_KEEP:
3580 case GL_REPLACE:
3581 case GL_INCR:
3582 case GL_DECR:
3583 case GL_INVERT:
3584 case GL_INCR_WRAP_OES:
3585 case GL_DECR_WRAP_OES:
3586 break;
3587 default:
3588 return error(GL_INVALID_ENUM);
3589 }
3590
3591 switch(zfail)
3592 {
3593 case GL_ZERO:
3594 case GL_KEEP:
3595 case GL_REPLACE:
3596 case GL_INCR:
3597 case GL_DECR:
3598 case GL_INVERT:
3599 case GL_INCR_WRAP_OES:
3600 case GL_DECR_WRAP_OES:
3601 break;
3602 default:
3603 return error(GL_INVALID_ENUM);
3604 }
3605
3606 switch(zpass)
3607 {
3608 case GL_ZERO:
3609 case GL_KEEP:
3610 case GL_REPLACE:
3611 case GL_INCR:
3612 case GL_DECR:
3613 case GL_INVERT:
3614 case GL_INCR_WRAP_OES:
3615 case GL_DECR_WRAP_OES:
3616 break;
3617 default:
3618 return error(GL_INVALID_ENUM);
3619 }
3620
3621 es1::Context *context = es1::getContext();
3622
3623 if(context)
3624 {
3625 context->setStencilOperations(fail, zfail, zpass);
3626 }
3627 }
3628
TexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3629 void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3630 {
3631 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
3632
3633 if(size < 2 || size > 4)
3634 {
3635 return error(GL_INVALID_VALUE);
3636 }
3637
3638 es1::Context *context = es1::getContext();
3639
3640 if(context)
3641 {
3642 GLenum texture = context->getClientActiveTexture();
3643 VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
3644 }
3645 }
3646
3647 void TexEnvi(GLenum target, GLenum pname, GLint param);
3648
TexEnvf(GLenum target,GLenum pname,GLfloat param)3649 void TexEnvf(GLenum target, GLenum pname, GLfloat param)
3650 {
3651 TexEnvi(target, pname, (GLint)param);
3652 }
3653
TexEnvfv(GLenum target,GLenum pname,const GLfloat * params)3654 void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
3655 {
3656 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
3657
3658 es1::Context *context = es1::getContext();
3659
3660 if(context)
3661 {
3662 GLint iParam = (GLint)roundf(params[0]);
3663
3664 switch(target)
3665 {
3666 case GL_POINT_SPRITE_OES:
3667 UNIMPLEMENTED();
3668 break;
3669 case GL_TEXTURE_ENV:
3670 switch(pname)
3671 {
3672 case GL_TEXTURE_ENV_MODE:
3673 switch(iParam)
3674 {
3675 case GL_REPLACE:
3676 case GL_MODULATE:
3677 case GL_DECAL:
3678 case GL_BLEND:
3679 case GL_ADD:
3680 case GL_COMBINE:
3681 break;
3682 default:
3683 error(GL_INVALID_ENUM);
3684 }
3685
3686 context->setTextureEnvMode(iParam);
3687 break;
3688 case GL_TEXTURE_ENV_COLOR:
3689 context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
3690 break;
3691 case GL_COMBINE_RGB:
3692 switch(iParam)
3693 {
3694 case GL_REPLACE:
3695 case GL_MODULATE:
3696 case GL_ADD:
3697 case GL_ADD_SIGNED:
3698 case GL_INTERPOLATE:
3699 case GL_SUBTRACT:
3700 case GL_DOT3_RGB:
3701 case GL_DOT3_RGBA:
3702 break;
3703 default:
3704 error(GL_INVALID_ENUM);
3705 }
3706
3707 context->setCombineRGB(iParam);
3708 break;
3709 case GL_COMBINE_ALPHA:
3710 switch(iParam)
3711 {
3712 case GL_REPLACE:
3713 case GL_MODULATE:
3714 case GL_ADD:
3715 case GL_ADD_SIGNED:
3716 case GL_INTERPOLATE:
3717 case GL_SUBTRACT:
3718 break;
3719 default:
3720 error(GL_INVALID_ENUM);
3721 }
3722
3723 context->setCombineAlpha(iParam);
3724 break;
3725 case GL_RGB_SCALE:
3726 if(iParam != 1 && iParam != 2 && iParam != 4)
3727 {
3728 return error(GL_INVALID_VALUE);
3729 }
3730 if(iParam != 1) UNIMPLEMENTED();
3731 break;
3732 case GL_ALPHA_SCALE:
3733 if(iParam != 1 && iParam != 2 && iParam != 4)
3734 {
3735 return error(GL_INVALID_VALUE);
3736 }
3737 if(iParam != 1) UNIMPLEMENTED();
3738 break;
3739 case GL_OPERAND0_RGB:
3740 switch(iParam)
3741 {
3742 case GL_SRC_COLOR:
3743 case GL_ONE_MINUS_SRC_COLOR:
3744 case GL_SRC_ALPHA:
3745 case GL_ONE_MINUS_SRC_ALPHA:
3746 break;
3747 default:
3748 error(GL_INVALID_ENUM);
3749 }
3750
3751 context->setOperand0RGB(iParam);
3752 break;
3753 case GL_OPERAND1_RGB:
3754 switch(iParam)
3755 {
3756 case GL_SRC_COLOR:
3757 case GL_ONE_MINUS_SRC_COLOR:
3758 case GL_SRC_ALPHA:
3759 case GL_ONE_MINUS_SRC_ALPHA:
3760 break;
3761 default:
3762 error(GL_INVALID_ENUM);
3763 }
3764
3765 context->setOperand1RGB(iParam);
3766 break;
3767 case GL_OPERAND2_RGB:
3768 switch(iParam)
3769 {
3770 case GL_SRC_COLOR:
3771 case GL_ONE_MINUS_SRC_COLOR:
3772 case GL_SRC_ALPHA:
3773 case GL_ONE_MINUS_SRC_ALPHA:
3774 break;
3775 default:
3776 error(GL_INVALID_ENUM);
3777 }
3778
3779 context->setOperand2RGB(iParam);
3780 break;
3781 case GL_OPERAND0_ALPHA:
3782 switch(iParam)
3783 {
3784 case GL_SRC_ALPHA:
3785 case GL_ONE_MINUS_SRC_ALPHA:
3786 break;
3787 default:
3788 error(GL_INVALID_ENUM);
3789 }
3790
3791 context->setOperand0Alpha(iParam);
3792 break;
3793 case GL_OPERAND1_ALPHA:
3794 switch(iParam)
3795 {
3796 case GL_SRC_ALPHA:
3797 case GL_ONE_MINUS_SRC_ALPHA:
3798 break;
3799 default:
3800 error(GL_INVALID_ENUM);
3801 }
3802
3803 context->setOperand1Alpha(iParam);
3804 break;
3805 case GL_OPERAND2_ALPHA:
3806 switch(iParam)
3807 {
3808 case GL_SRC_ALPHA:
3809 case GL_ONE_MINUS_SRC_ALPHA:
3810 break;
3811 default:
3812 error(GL_INVALID_ENUM);
3813 }
3814
3815 context->setOperand2Alpha(iParam);
3816 break;
3817 case GL_SRC0_RGB:
3818 switch(iParam)
3819 {
3820 case GL_TEXTURE:
3821 case GL_CONSTANT:
3822 case GL_PRIMARY_COLOR:
3823 case GL_PREVIOUS:
3824 break;
3825 default:
3826 error(GL_INVALID_ENUM);
3827 }
3828
3829 context->setSrc0RGB(iParam);
3830 break;
3831 case GL_SRC1_RGB:
3832 switch(iParam)
3833 {
3834 case GL_TEXTURE:
3835 case GL_CONSTANT:
3836 case GL_PRIMARY_COLOR:
3837 case GL_PREVIOUS:
3838 break;
3839 default:
3840 error(GL_INVALID_ENUM);
3841 }
3842
3843 context->setSrc1RGB(iParam);
3844 break;
3845 case GL_SRC2_RGB:
3846 switch(iParam)
3847 {
3848 case GL_TEXTURE:
3849 case GL_CONSTANT:
3850 case GL_PRIMARY_COLOR:
3851 case GL_PREVIOUS:
3852 break;
3853 default:
3854 error(GL_INVALID_ENUM);
3855 }
3856
3857 context->setSrc2RGB(iParam);
3858 break;
3859 case GL_SRC0_ALPHA:
3860 switch(iParam)
3861 {
3862 case GL_TEXTURE:
3863 case GL_CONSTANT:
3864 case GL_PRIMARY_COLOR:
3865 case GL_PREVIOUS:
3866 break;
3867 default:
3868 error(GL_INVALID_ENUM);
3869 }
3870
3871 context->setSrc0Alpha(iParam);
3872 break;
3873 case GL_SRC1_ALPHA:
3874 switch(iParam)
3875 {
3876 case GL_TEXTURE:
3877 case GL_CONSTANT:
3878 case GL_PRIMARY_COLOR:
3879 case GL_PREVIOUS:
3880 break;
3881 default:
3882 error(GL_INVALID_ENUM);
3883 }
3884
3885 context->setSrc1Alpha(iParam);
3886 break;
3887 case GL_SRC2_ALPHA:
3888 switch(iParam)
3889 {
3890 case GL_TEXTURE:
3891 case GL_CONSTANT:
3892 case GL_PRIMARY_COLOR:
3893 case GL_PREVIOUS:
3894 break;
3895 default:
3896 error(GL_INVALID_ENUM);
3897 }
3898
3899 context->setSrc2Alpha(iParam);
3900 break;
3901 default:
3902 return error(GL_INVALID_ENUM);
3903 }
3904 break;
3905 default:
3906 return error(GL_INVALID_ENUM);
3907 }
3908 }
3909 }
3910
TexEnvi(GLenum target,GLenum pname,GLint param)3911 void TexEnvi(GLenum target, GLenum pname, GLint param)
3912 {
3913 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
3914
3915 es1::Context *context = es1::getContext();
3916
3917 if(context)
3918 {
3919 switch(target)
3920 {
3921 case GL_POINT_SPRITE_OES:
3922 UNIMPLEMENTED();
3923 break;
3924 case GL_TEXTURE_ENV:
3925 switch(pname)
3926 {
3927 case GL_TEXTURE_ENV_MODE:
3928 switch((GLenum)param)
3929 {
3930 case GL_REPLACE:
3931 case GL_MODULATE:
3932 case GL_DECAL:
3933 case GL_BLEND:
3934 case GL_ADD:
3935 case GL_COMBINE:
3936 break;
3937 default:
3938 error(GL_INVALID_ENUM);
3939 }
3940
3941 context->setTextureEnvMode((GLenum)param);
3942 break;
3943 case GL_TEXTURE_ENV_COLOR:
3944 return error(GL_INVALID_ENUM); // Needs four values, should call glTexEnviv() instead
3945 break;
3946 case GL_COMBINE_RGB:
3947 switch((GLenum)param)
3948 {
3949 case GL_REPLACE:
3950 case GL_MODULATE:
3951 case GL_ADD:
3952 case GL_ADD_SIGNED:
3953 case GL_INTERPOLATE:
3954 case GL_SUBTRACT:
3955 case GL_DOT3_RGB:
3956 case GL_DOT3_RGBA:
3957 break;
3958 default:
3959 error(GL_INVALID_ENUM);
3960 }
3961
3962 context->setCombineRGB((GLenum)param);
3963 break;
3964 case GL_COMBINE_ALPHA:
3965 switch((GLenum)param)
3966 {
3967 case GL_REPLACE:
3968 case GL_MODULATE:
3969 case GL_ADD:
3970 case GL_ADD_SIGNED:
3971 case GL_INTERPOLATE:
3972 case GL_SUBTRACT:
3973 break;
3974 default:
3975 error(GL_INVALID_ENUM);
3976 }
3977
3978 context->setCombineAlpha((GLenum)param);
3979 break;
3980 case GL_RGB_SCALE:
3981 if(param != 1 && param != 2 && param != 4)
3982 {
3983 return error(GL_INVALID_VALUE);
3984 }
3985 if(param != 1) UNIMPLEMENTED();
3986 break;
3987 case GL_ALPHA_SCALE:
3988 if(param != 1 && param != 2 && param != 4)
3989 {
3990 return error(GL_INVALID_VALUE);
3991 }
3992 if(param != 1) UNIMPLEMENTED();
3993 break;
3994 case GL_OPERAND0_RGB:
3995 switch((GLenum)param)
3996 {
3997 case GL_SRC_COLOR:
3998 case GL_ONE_MINUS_SRC_COLOR:
3999 case GL_SRC_ALPHA:
4000 case GL_ONE_MINUS_SRC_ALPHA:
4001 break;
4002 default:
4003 error(GL_INVALID_ENUM);
4004 }
4005
4006 context->setOperand0RGB((GLenum)param);
4007 break;
4008 case GL_OPERAND1_RGB:
4009 switch((GLenum)param)
4010 {
4011 case GL_SRC_COLOR:
4012 case GL_ONE_MINUS_SRC_COLOR:
4013 case GL_SRC_ALPHA:
4014 case GL_ONE_MINUS_SRC_ALPHA:
4015 break;
4016 default:
4017 error(GL_INVALID_ENUM);
4018 }
4019
4020 context->setOperand1RGB((GLenum)param);
4021 break;
4022 case GL_OPERAND2_RGB:
4023 switch((GLenum)param)
4024 {
4025 case GL_SRC_COLOR:
4026 case GL_ONE_MINUS_SRC_COLOR:
4027 case GL_SRC_ALPHA:
4028 case GL_ONE_MINUS_SRC_ALPHA:
4029 break;
4030 default:
4031 error(GL_INVALID_ENUM);
4032 }
4033
4034 context->setOperand2RGB((GLenum)param);
4035 break;
4036 case GL_OPERAND0_ALPHA:
4037 switch((GLenum)param)
4038 {
4039 case GL_SRC_ALPHA:
4040 case GL_ONE_MINUS_SRC_ALPHA:
4041 break;
4042 default:
4043 error(GL_INVALID_ENUM);
4044 }
4045
4046 context->setOperand0Alpha((GLenum)param);
4047 break;
4048 case GL_OPERAND1_ALPHA:
4049 switch((GLenum)param)
4050 {
4051 case GL_SRC_ALPHA:
4052 case GL_ONE_MINUS_SRC_ALPHA:
4053 break;
4054 default:
4055 error(GL_INVALID_ENUM);
4056 }
4057
4058 context->setOperand1Alpha((GLenum)param);
4059 break;
4060 case GL_OPERAND2_ALPHA:
4061 switch((GLenum)param)
4062 {
4063 case GL_SRC_ALPHA:
4064 case GL_ONE_MINUS_SRC_ALPHA:
4065 break;
4066 default:
4067 error(GL_INVALID_ENUM);
4068 }
4069
4070 context->setOperand2Alpha((GLenum)param);
4071 break;
4072 case GL_SRC0_RGB:
4073 switch((GLenum)param)
4074 {
4075 case GL_TEXTURE:
4076 case GL_CONSTANT:
4077 case GL_PRIMARY_COLOR:
4078 case GL_PREVIOUS:
4079 break;
4080 default:
4081 error(GL_INVALID_ENUM);
4082 }
4083
4084 context->setSrc0RGB((GLenum)param);
4085 break;
4086 case GL_SRC1_RGB:
4087 switch((GLenum)param)
4088 {
4089 case GL_TEXTURE:
4090 case GL_CONSTANT:
4091 case GL_PRIMARY_COLOR:
4092 case GL_PREVIOUS:
4093 break;
4094 default:
4095 error(GL_INVALID_ENUM);
4096 }
4097
4098 context->setSrc1RGB((GLenum)param);
4099 break;
4100 case GL_SRC2_RGB:
4101 switch((GLenum)param)
4102 {
4103 case GL_TEXTURE:
4104 case GL_CONSTANT:
4105 case GL_PRIMARY_COLOR:
4106 case GL_PREVIOUS:
4107 break;
4108 default:
4109 error(GL_INVALID_ENUM);
4110 }
4111
4112 context->setSrc2RGB((GLenum)param);
4113 break;
4114 case GL_SRC0_ALPHA:
4115 switch((GLenum)param)
4116 {
4117 case GL_TEXTURE:
4118 case GL_CONSTANT:
4119 case GL_PRIMARY_COLOR:
4120 case GL_PREVIOUS:
4121 break;
4122 default:
4123 error(GL_INVALID_ENUM);
4124 }
4125
4126 context->setSrc0Alpha((GLenum)param);
4127 break;
4128 case GL_SRC1_ALPHA:
4129 switch((GLenum)param)
4130 {
4131 case GL_TEXTURE:
4132 case GL_CONSTANT:
4133 case GL_PRIMARY_COLOR:
4134 case GL_PREVIOUS:
4135 break;
4136 default:
4137 error(GL_INVALID_ENUM);
4138 }
4139
4140 context->setSrc1Alpha((GLenum)param);
4141 break;
4142 case GL_SRC2_ALPHA:
4143 switch((GLenum)param)
4144 {
4145 case GL_TEXTURE:
4146 case GL_CONSTANT:
4147 case GL_PRIMARY_COLOR:
4148 case GL_PREVIOUS:
4149 break;
4150 default:
4151 error(GL_INVALID_ENUM);
4152 }
4153
4154 context->setSrc2Alpha((GLenum)param);
4155 break;
4156 default:
4157 return error(GL_INVALID_ENUM);
4158 }
4159 break;
4160 default:
4161 return error(GL_INVALID_ENUM);
4162 }
4163 }
4164 }
4165
TexEnvx(GLenum target,GLenum pname,GLfixed param)4166 void TexEnvx(GLenum target, GLenum pname, GLfixed param)
4167 {
4168 TexEnvi(target, pname, (GLint)param);
4169 }
4170
TexEnviv(GLenum target,GLenum pname,const GLint * params)4171 void TexEnviv(GLenum target, GLenum pname, const GLint *params)
4172 {
4173 UNIMPLEMENTED();
4174 }
4175
TexEnvxv(GLenum target,GLenum pname,const GLfixed * params)4176 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
4177 {
4178 UNIMPLEMENTED();
4179 }
4180
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4181 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4182 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4183 {
4184 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4185 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
4186 target, level, internalformat, width, height, border, format, type, pixels);
4187
4188 if(!validImageSize(level, width, height))
4189 {
4190 return error(GL_INVALID_VALUE);
4191 }
4192
4193 if(internalformat != (GLint)format)
4194 {
4195 return error(GL_INVALID_OPERATION);
4196 }
4197
4198 switch(format)
4199 {
4200 case GL_ALPHA:
4201 case GL_LUMINANCE:
4202 case GL_LUMINANCE_ALPHA:
4203 switch(type)
4204 {
4205 case GL_UNSIGNED_BYTE:
4206 break;
4207 default:
4208 return error(GL_INVALID_ENUM);
4209 }
4210 break;
4211 case GL_RGB:
4212 switch(type)
4213 {
4214 case GL_UNSIGNED_BYTE:
4215 case GL_UNSIGNED_SHORT_5_6_5:
4216 break;
4217 default:
4218 return error(GL_INVALID_ENUM);
4219 }
4220 break;
4221 case GL_RGBA:
4222 switch(type)
4223 {
4224 case GL_UNSIGNED_BYTE:
4225 case GL_UNSIGNED_SHORT_4_4_4_4:
4226 case GL_UNSIGNED_SHORT_5_5_5_1:
4227 break;
4228 default:
4229 return error(GL_INVALID_ENUM);
4230 }
4231 break;
4232 case GL_BGRA_EXT:
4233 switch(type)
4234 {
4235 case GL_UNSIGNED_BYTE:
4236 break;
4237 default:
4238 return error(GL_INVALID_ENUM);
4239 }
4240 break;
4241 case GL_ETC1_RGB8_OES:
4242 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4243 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4244 return error(GL_INVALID_OPERATION);
4245 case GL_DEPTH_STENCIL_OES:
4246 switch(type)
4247 {
4248 case GL_UNSIGNED_INT_24_8_OES:
4249 break;
4250 default:
4251 return error(GL_INVALID_ENUM);
4252 }
4253 break;
4254 default:
4255 return error(GL_INVALID_VALUE);
4256 }
4257
4258 if(border != 0)
4259 {
4260 return error(GL_INVALID_VALUE);
4261 }
4262
4263 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
4264
4265 es1::Context *context = es1::getContext();
4266
4267 if(context)
4268 {
4269 switch(target)
4270 {
4271 case GL_TEXTURE_2D:
4272 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4273 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4274 {
4275 return error(GL_INVALID_VALUE);
4276 }
4277 break;
4278 default:
4279 return error(GL_INVALID_ENUM);
4280 }
4281
4282 if(target == GL_TEXTURE_2D)
4283 {
4284 es1::Texture2D *texture = context->getTexture2D();
4285
4286 if(!texture)
4287 {
4288 return error(GL_INVALID_OPERATION);
4289 }
4290
4291 texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels);
4292 }
4293 else UNREACHABLE(target);
4294 }
4295 }
4296
TexParameterf(GLenum target,GLenum pname,GLfloat param)4297 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
4298 {
4299 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4300
4301 es1::Context *context = es1::getContext();
4302
4303 if(context)
4304 {
4305 es1::Texture *texture;
4306
4307 switch(target)
4308 {
4309 case GL_TEXTURE_2D:
4310 texture = context->getTexture2D();
4311 break;
4312 case GL_TEXTURE_EXTERNAL_OES:
4313 texture = context->getTextureExternal();
4314 break;
4315 default:
4316 return error(GL_INVALID_ENUM);
4317 }
4318
4319 switch(pname)
4320 {
4321 case GL_TEXTURE_WRAP_S:
4322 if(!texture->setWrapS((GLenum)param))
4323 {
4324 return error(GL_INVALID_ENUM);
4325 }
4326 break;
4327 case GL_TEXTURE_WRAP_T:
4328 if(!texture->setWrapT((GLenum)param))
4329 {
4330 return error(GL_INVALID_ENUM);
4331 }
4332 break;
4333 case GL_TEXTURE_MIN_FILTER:
4334 if(!texture->setMinFilter((GLenum)param))
4335 {
4336 return error(GL_INVALID_ENUM);
4337 }
4338 break;
4339 case GL_TEXTURE_MAG_FILTER:
4340 if(!texture->setMagFilter((GLenum)param))
4341 {
4342 return error(GL_INVALID_ENUM);
4343 }
4344 break;
4345 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4346 if(!texture->setMaxAnisotropy(param))
4347 {
4348 return error(GL_INVALID_VALUE);
4349 }
4350 break;
4351 case GL_GENERATE_MIPMAP:
4352 texture->setGenerateMipmap((GLboolean)param);
4353 break;
4354 case GL_TEXTURE_CROP_RECT_OES:
4355 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameterfv() instead
4356 default:
4357 return error(GL_INVALID_ENUM);
4358 }
4359 }
4360 }
4361
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4362 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4363 {
4364 TexParameterf(target, pname, *params);
4365 }
4366
TexParameteri(GLenum target,GLenum pname,GLint param)4367 void TexParameteri(GLenum target, GLenum pname, GLint param)
4368 {
4369 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4370
4371 es1::Context *context = es1::getContext();
4372
4373 if(context)
4374 {
4375 es1::Texture *texture;
4376
4377 switch(target)
4378 {
4379 case GL_TEXTURE_2D:
4380 texture = context->getTexture2D();
4381 break;
4382 case GL_TEXTURE_EXTERNAL_OES:
4383 texture = context->getTextureExternal();
4384 break;
4385 default:
4386 return error(GL_INVALID_ENUM);
4387 }
4388
4389 switch(pname)
4390 {
4391 case GL_TEXTURE_WRAP_S:
4392 if(!texture->setWrapS((GLenum)param))
4393 {
4394 return error(GL_INVALID_ENUM);
4395 }
4396 break;
4397 case GL_TEXTURE_WRAP_T:
4398 if(!texture->setWrapT((GLenum)param))
4399 {
4400 return error(GL_INVALID_ENUM);
4401 }
4402 break;
4403 case GL_TEXTURE_MIN_FILTER:
4404 if(!texture->setMinFilter((GLenum)param))
4405 {
4406 return error(GL_INVALID_ENUM);
4407 }
4408 break;
4409 case GL_TEXTURE_MAG_FILTER:
4410 if(!texture->setMagFilter((GLenum)param))
4411 {
4412 return error(GL_INVALID_ENUM);
4413 }
4414 break;
4415 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4416 if(!texture->setMaxAnisotropy((GLfloat)param))
4417 {
4418 return error(GL_INVALID_VALUE);
4419 }
4420 break;
4421 case GL_GENERATE_MIPMAP:
4422 texture->setGenerateMipmap((GLboolean)param);
4423 break;
4424 case GL_TEXTURE_CROP_RECT_OES:
4425 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameteriv() instead
4426 default:
4427 return error(GL_INVALID_ENUM);
4428 }
4429 }
4430 }
4431
TexParameteriv(GLenum target,GLenum pname,const GLint * params)4432 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
4433 {
4434 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
4435
4436 switch(pname)
4437 {
4438 case GL_TEXTURE_CROP_RECT_OES:
4439 break;
4440 default:
4441 return TexParameteri(target, pname, params[0]);
4442 }
4443
4444 es1::Context *context = es1::getContext();
4445
4446 if(context)
4447 {
4448 es1::Texture *texture;
4449
4450 switch(target)
4451 {
4452 case GL_TEXTURE_2D:
4453 texture = context->getTexture2D();
4454 break;
4455 default:
4456 return error(GL_INVALID_ENUM);
4457 }
4458
4459 switch(pname)
4460 {
4461 case GL_TEXTURE_CROP_RECT_OES:
4462 texture->setCropRect(params[0], params[1], params[2], params[3]);
4463 break;
4464 default:
4465 return error(GL_INVALID_ENUM);
4466 }
4467 }
4468 }
4469
TexParameterx(GLenum target,GLenum pname,GLfixed param)4470 void TexParameterx(GLenum target, GLenum pname, GLfixed param)
4471 {
4472 TexParameteri(target, pname, (GLint)param);
4473 }
4474
TexParameterxv(GLenum target,GLenum pname,const GLfixed * params)4475 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
4476 {
4477 UNIMPLEMENTED();
4478 }
4479
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4480 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4481 GLenum format, GLenum type, const GLvoid* pixels)
4482 {
4483 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4484 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4485 "const GLvoid* pixels = %p)",
4486 target, level, xoffset, yoffset, width, height, format, type, pixels);
4487
4488 if(!es1::IsTextureTarget(target))
4489 {
4490 return error(GL_INVALID_ENUM);
4491 }
4492
4493 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4494 {
4495 return error(GL_INVALID_VALUE);
4496 }
4497
4498 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4499 {
4500 return error(GL_INVALID_VALUE);
4501 }
4502
4503 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4504 {
4505 return error(GL_INVALID_VALUE);
4506 }
4507
4508 if(width == 0 || height == 0 || !pixels)
4509 {
4510 return;
4511 }
4512
4513 es1::Context *context = es1::getContext();
4514
4515 if(context)
4516 {
4517 if(target == GL_TEXTURE_2D)
4518 {
4519 es1::Texture2D *texture = context->getTexture2D();
4520
4521 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
4522 if(validationError != GL_NO_ERROR)
4523 {
4524 return error(validationError);
4525 }
4526
4527 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4528 }
4529 else UNREACHABLE(target);
4530 }
4531 }
4532
Translatef(GLfloat x,GLfloat y,GLfloat z)4533 void Translatef(GLfloat x, GLfloat y, GLfloat z)
4534 {
4535 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
4536
4537 es1::Context *context = es1::getContext();
4538
4539 if(context)
4540 {
4541 context->translate(x, y, z);
4542 }
4543 }
4544
Translatex(GLfixed x,GLfixed y,GLfixed z)4545 void Translatex(GLfixed x, GLfixed y, GLfixed z)
4546 {
4547 Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
4548 }
4549
VertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4550 void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4551 {
4552 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
4553
4554 if(size < 2 || size > 4)
4555 {
4556 return error(GL_INVALID_VALUE);
4557 }
4558
4559 VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
4560 }
4561
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)4562 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
4563 {
4564 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4565
4566 if(width < 0 || height < 0)
4567 {
4568 return error(GL_INVALID_VALUE);
4569 }
4570
4571 es1::Context *context = es1::getContext();
4572
4573 if(context)
4574 {
4575 context->setViewportParams(x, y, width, height);
4576 }
4577 }
4578
EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)4579 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
4580 {
4581 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4582
4583 switch(target)
4584 {
4585 case GL_TEXTURE_2D:
4586 case GL_TEXTURE_EXTERNAL_OES:
4587 break;
4588 default:
4589 return error(GL_INVALID_ENUM);
4590 }
4591
4592 es1::Context *context = es1::getContext();
4593
4594 if(context)
4595 {
4596 es1::Texture2D *texture = nullptr;
4597
4598 switch(target)
4599 {
4600 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
4601 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
4602 default: UNREACHABLE(target);
4603 }
4604
4605 if(!texture)
4606 {
4607 return error(GL_INVALID_OPERATION);
4608 }
4609
4610 egl::Image *eglImage = context->getSharedImage(image);
4611
4612 if(!eglImage)
4613 {
4614 return error(GL_INVALID_OPERATION);
4615 }
4616
4617 texture->setSharedImage(eglImage);
4618 }
4619 }
4620
EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)4621 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
4622 {
4623 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4624
4625 UNIMPLEMENTED();
4626 }
4627
DrawTexsOES(GLshort x,GLshort y,GLshort z,GLshort width,GLshort height)4628 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
4629 {
4630 UNIMPLEMENTED();
4631 }
4632
DrawTexiOES(GLint x,GLint y,GLint z,GLint width,GLint height)4633 void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
4634 {
4635 TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
4636
4637 if(width <= 0 || height <= 0)
4638 {
4639 return error(GL_INVALID_VALUE);
4640 }
4641
4642 es1::Context *context = es1::getContext();
4643
4644 if(context)
4645 {
4646 context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
4647 }
4648 }
4649
DrawTexxOES(GLfixed x,GLfixed y,GLfixed z,GLfixed width,GLfixed height)4650 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
4651 {
4652 UNIMPLEMENTED();
4653 }
4654
DrawTexsvOES(const GLshort * coords)4655 void DrawTexsvOES(const GLshort *coords)
4656 {
4657 UNIMPLEMENTED();
4658 }
4659
DrawTexivOES(const GLint * coords)4660 void DrawTexivOES(const GLint *coords)
4661 {
4662 UNIMPLEMENTED();
4663 }
4664
DrawTexxvOES(const GLfixed * coords)4665 void DrawTexxvOES(const GLfixed *coords)
4666 {
4667 UNIMPLEMENTED();
4668 }
4669
DrawTexfOES(GLfloat x,GLfloat y,GLfloat z,GLfloat width,GLfloat height)4670 void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
4671 {
4672 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
4673
4674 if(width <= 0 || height <= 0)
4675 {
4676 return error(GL_INVALID_VALUE);
4677 }
4678
4679 es1::Context *context = es1::getContext();
4680
4681 if(context)
4682 {
4683 context->drawTexture(x, y, z, width, height);
4684 }
4685 }
4686
DrawTexfvOES(const GLfloat * coords)4687 void DrawTexfvOES(const GLfloat *coords)
4688 {
4689 UNIMPLEMENTED();
4690 }
4691
4692 }
4693
es1GetProcAddress(const char * procname)4694 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
4695 {
4696 struct Function
4697 {
4698 const char *name;
4699 __eglMustCastToProperFunctionPointerType address;
4700 };
4701
4702 struct CompareFunctor
4703 {
4704 bool operator()(const Function &a, const Function &b) const
4705 {
4706 return strcmp(a.name, b.name) < 0;
4707 }
4708 };
4709
4710 // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
4711 // The Unix command "LC_COLLATE=C sort" will generate the correct order.
4712 static const Function glFunctions[] =
4713 {
4714 #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
4715
4716 FUNCTION(glActiveTexture),
4717 FUNCTION(glAlphaFunc),
4718 FUNCTION(glAlphaFuncx),
4719 FUNCTION(glBindBuffer),
4720 FUNCTION(glBindFramebufferOES),
4721 FUNCTION(glBindRenderbufferOES),
4722 FUNCTION(glBindTexture),
4723 FUNCTION(glBlendEquationOES),
4724 FUNCTION(glBlendEquationSeparateOES),
4725 FUNCTION(glBlendFunc),
4726 FUNCTION(glBlendFuncSeparateOES),
4727 FUNCTION(glBufferData),
4728 FUNCTION(glBufferSubData),
4729 FUNCTION(glCheckFramebufferStatusOES),
4730 FUNCTION(glClear),
4731 FUNCTION(glClearColor),
4732 FUNCTION(glClearColorx),
4733 FUNCTION(glClearDepthf),
4734 FUNCTION(glClearDepthx),
4735 FUNCTION(glClearStencil),
4736 FUNCTION(glClientActiveTexture),
4737 FUNCTION(glClipPlanef),
4738 FUNCTION(glClipPlanex),
4739 FUNCTION(glColor4f),
4740 FUNCTION(glColor4ub),
4741 FUNCTION(glColor4x),
4742 FUNCTION(glColorMask),
4743 FUNCTION(glColorPointer),
4744 FUNCTION(glCompressedTexImage2D),
4745 FUNCTION(glCompressedTexSubImage2D),
4746 FUNCTION(glCopyTexImage2D),
4747 FUNCTION(glCopyTexSubImage2D),
4748 FUNCTION(glCullFace),
4749 FUNCTION(glDeleteBuffers),
4750 FUNCTION(glDeleteFramebuffersOES),
4751 FUNCTION(glDeleteRenderbuffersOES),
4752 FUNCTION(glDeleteTextures),
4753 FUNCTION(glDepthFunc),
4754 FUNCTION(glDepthMask),
4755 FUNCTION(glDepthRangef),
4756 FUNCTION(glDepthRangex),
4757 FUNCTION(glDisable),
4758 FUNCTION(glDisableClientState),
4759 FUNCTION(glDrawArrays),
4760 FUNCTION(glDrawElements),
4761 FUNCTION(glDrawTexfOES),
4762 FUNCTION(glDrawTexfvOES),
4763 FUNCTION(glDrawTexiOES),
4764 FUNCTION(glDrawTexivOES),
4765 FUNCTION(glDrawTexsOES),
4766 FUNCTION(glDrawTexsvOES),
4767 FUNCTION(glDrawTexxOES),
4768 FUNCTION(glDrawTexxvOES),
4769 FUNCTION(glEGLImageTargetRenderbufferStorageOES),
4770 FUNCTION(glEGLImageTargetTexture2DOES),
4771 FUNCTION(glEnable),
4772 FUNCTION(glEnableClientState),
4773 FUNCTION(glFinish),
4774 FUNCTION(glFlush),
4775 FUNCTION(glFogf),
4776 FUNCTION(glFogfv),
4777 FUNCTION(glFogx),
4778 FUNCTION(glFogxv),
4779 FUNCTION(glFramebufferRenderbufferOES),
4780 FUNCTION(glFramebufferTexture2DOES),
4781 FUNCTION(glFrontFace),
4782 FUNCTION(glFrustumf),
4783 FUNCTION(glFrustumx),
4784 FUNCTION(glGenBuffers),
4785 FUNCTION(glGenFramebuffersOES),
4786 FUNCTION(glGenRenderbuffersOES),
4787 FUNCTION(glGenTextures),
4788 FUNCTION(glGenerateMipmapOES),
4789 FUNCTION(glGetBooleanv),
4790 FUNCTION(glGetBufferParameteriv),
4791 FUNCTION(glGetClipPlanef),
4792 FUNCTION(glGetClipPlanex),
4793 FUNCTION(glGetError),
4794 FUNCTION(glGetFixedv),
4795 FUNCTION(glGetFloatv),
4796 FUNCTION(glGetFramebufferAttachmentParameterivOES),
4797 FUNCTION(glGetIntegerv),
4798 FUNCTION(glGetLightfv),
4799 FUNCTION(glGetLightxv),
4800 FUNCTION(glGetMaterialfv),
4801 FUNCTION(glGetMaterialxv),
4802 FUNCTION(glGetPointerv),
4803 FUNCTION(glGetRenderbufferParameterivOES),
4804 FUNCTION(glGetString),
4805 FUNCTION(glGetTexEnvfv),
4806 FUNCTION(glGetTexEnviv),
4807 FUNCTION(glGetTexEnvxv),
4808 FUNCTION(glGetTexParameterfv),
4809 FUNCTION(glGetTexParameteriv),
4810 FUNCTION(glGetTexParameterxv),
4811 FUNCTION(glHint),
4812 FUNCTION(glIsBuffer),
4813 FUNCTION(glIsEnabled),
4814 FUNCTION(glIsFramebufferOES),
4815 FUNCTION(glIsRenderbufferOES),
4816 FUNCTION(glIsTexture),
4817 FUNCTION(glLightModelf),
4818 FUNCTION(glLightModelfv),
4819 FUNCTION(glLightModelx),
4820 FUNCTION(glLightModelxv),
4821 FUNCTION(glLightf),
4822 FUNCTION(glLightfv),
4823 FUNCTION(glLightx),
4824 FUNCTION(glLightxv),
4825 FUNCTION(glLineWidth),
4826 FUNCTION(glLineWidthx),
4827 FUNCTION(glLoadIdentity),
4828 FUNCTION(glLoadMatrixf),
4829 FUNCTION(glLoadMatrixx),
4830 FUNCTION(glLogicOp),
4831 FUNCTION(glMaterialf),
4832 FUNCTION(glMaterialfv),
4833 FUNCTION(glMaterialx),
4834 FUNCTION(glMaterialxv),
4835 FUNCTION(glMatrixMode),
4836 FUNCTION(glMultMatrixf),
4837 FUNCTION(glMultMatrixx),
4838 FUNCTION(glMultiTexCoord4f),
4839 FUNCTION(glMultiTexCoord4x),
4840 FUNCTION(glNormal3f),
4841 FUNCTION(glNormal3x),
4842 FUNCTION(glNormalPointer),
4843 FUNCTION(glOrthof),
4844 FUNCTION(glOrthox),
4845 FUNCTION(glPixelStorei),
4846 FUNCTION(glPointParameterf),
4847 FUNCTION(glPointParameterfv),
4848 FUNCTION(glPointParameterx),
4849 FUNCTION(glPointParameterxv),
4850 FUNCTION(glPointSize),
4851 FUNCTION(glPointSizePointerOES),
4852 FUNCTION(glPointSizex),
4853 FUNCTION(glPolygonOffset),
4854 FUNCTION(glPolygonOffsetx),
4855 FUNCTION(glPopMatrix),
4856 FUNCTION(glPushMatrix),
4857 FUNCTION(glReadPixels),
4858 FUNCTION(glRenderbufferStorageOES),
4859 FUNCTION(glRotatef),
4860 FUNCTION(glRotatex),
4861 FUNCTION(glSampleCoverage),
4862 FUNCTION(glSampleCoveragex),
4863 FUNCTION(glScalef),
4864 FUNCTION(glScalex),
4865 FUNCTION(glScissor),
4866 FUNCTION(glShadeModel),
4867 FUNCTION(glStencilFunc),
4868 FUNCTION(glStencilMask),
4869 FUNCTION(glStencilOp),
4870 FUNCTION(glTexCoordPointer),
4871 FUNCTION(glTexEnvf),
4872 FUNCTION(glTexEnvfv),
4873 FUNCTION(glTexEnvi),
4874 FUNCTION(glTexEnviv),
4875 FUNCTION(glTexEnvx),
4876 FUNCTION(glTexEnvxv),
4877 FUNCTION(glTexImage2D),
4878 FUNCTION(glTexParameterf),
4879 FUNCTION(glTexParameterfv),
4880 FUNCTION(glTexParameteri),
4881 FUNCTION(glTexParameteriv),
4882 FUNCTION(glTexParameterx),
4883 FUNCTION(glTexParameterxv),
4884 FUNCTION(glTexSubImage2D),
4885 FUNCTION(glTranslatef),
4886 FUNCTION(glTranslatex),
4887 FUNCTION(glVertexPointer),
4888 FUNCTION(glViewport),
4889
4890 #undef FUNCTION
4891 };
4892
4893 static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
4894 static const Function *const glFunctionsEnd = glFunctions + numFunctions;
4895
4896 Function needle;
4897 needle.name = procname;
4898
4899 if(procname && strncmp("gl", procname, 2) == 0)
4900 {
4901 const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
4902 if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
4903 {
4904 return (__eglMustCastToProperFunctionPointerType)result->address;
4905 }
4906 }
4907
4908 return nullptr;
4909 }
4910