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_FALSE, green != GL_FALSE, blue != GL_FALSE, alpha != GL_FALSE);
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_FALSE), 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) || (level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS))
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, level); break;
1532 case GL_DEPTH_ATTACHMENT_OES: framebuffer->setDepthbuffer(textarget, texture, level); break;
1533 case GL_STENCIL_ATTACHMENT_OES: framebuffer->setStencilbuffer(textarget, texture, level); 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 Renderbuffer *renderbuffer = nullptr;
2086 switch(attachment)
2087 {
2088 case GL_COLOR_ATTACHMENT0_OES:
2089 attachmentType = framebuffer->getColorbufferType();
2090 attachmentHandle = framebuffer->getColorbufferName();
2091 renderbuffer = framebuffer->getColorbuffer();
2092 break;
2093 case GL_DEPTH_ATTACHMENT_OES:
2094 attachmentType = framebuffer->getDepthbufferType();
2095 attachmentHandle = framebuffer->getDepthbufferName();
2096 renderbuffer = framebuffer->getDepthbuffer();
2097 break;
2098 case GL_STENCIL_ATTACHMENT_OES:
2099 attachmentType = framebuffer->getStencilbufferType();
2100 attachmentHandle = framebuffer->getStencilbufferName();
2101 renderbuffer = framebuffer->getStencilbuffer();
2102 break;
2103 default:
2104 return error(GL_INVALID_ENUM);
2105 }
2106
2107 GLenum attachmentObjectType; // Type category
2108 if(attachmentType == GL_NONE_OES || attachmentType == GL_RENDERBUFFER_OES)
2109 {
2110 attachmentObjectType = attachmentType;
2111 }
2112 else if(es1::IsTextureTarget(attachmentType))
2113 {
2114 attachmentObjectType = GL_TEXTURE;
2115 }
2116 else UNREACHABLE(attachmentType);
2117
2118 switch(pname)
2119 {
2120 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_OES:
2121 *params = attachmentObjectType;
2122 break;
2123 case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_OES:
2124 if(attachmentObjectType == GL_RENDERBUFFER_OES || attachmentObjectType == GL_TEXTURE)
2125 {
2126 *params = attachmentHandle;
2127 }
2128 else
2129 {
2130 return error(GL_INVALID_ENUM);
2131 }
2132 break;
2133 case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_OES:
2134 if(attachmentObjectType == GL_TEXTURE)
2135 {
2136 *params = renderbuffer->getLevel();
2137 }
2138 else
2139 {
2140 return error(GL_INVALID_ENUM);
2141 }
2142 break;
2143 default:
2144 return error(GL_INVALID_ENUM);
2145 }
2146 }
2147 }
2148
GetIntegerv(GLenum pname,GLint * params)2149 void GetIntegerv(GLenum pname, GLint* params)
2150 {
2151 TRACE("(GLenum pname = 0x%X, GLint* params = %p)", pname, params);
2152
2153 es1::Context *context = es1::getContext();
2154
2155 if(context)
2156 {
2157 if(!(context->getIntegerv(pname, params)))
2158 {
2159 int numParams = context->getQueryParameterNum(pname);
2160
2161 if(numParams < 0)
2162 {
2163 return error(GL_INVALID_ENUM);
2164 }
2165
2166 if(numParams == 0)
2167 {
2168 return;
2169 }
2170
2171 if(context->isQueryParameterBool(pname))
2172 {
2173 GLboolean *boolParams = nullptr;
2174 boolParams = new GLboolean[numParams];
2175
2176 context->getBooleanv(pname, boolParams);
2177
2178 for(int i = 0; i < numParams; ++i)
2179 {
2180 if(boolParams[i] == GL_FALSE)
2181 params[i] = 0;
2182 else
2183 params[i] = 1;
2184 }
2185
2186 delete [] boolParams;
2187 }
2188 else if(context->isQueryParameterFloat(pname))
2189 {
2190 GLfloat *floatParams = nullptr;
2191 floatParams = new GLfloat[numParams];
2192
2193 context->getFloatv(pname, floatParams);
2194
2195 for(int i = 0; i < numParams; ++i)
2196 {
2197 if(pname == GL_DEPTH_RANGE || pname == GL_COLOR_CLEAR_VALUE || pname == GL_DEPTH_CLEAR_VALUE)
2198 {
2199 params[i] = (GLint)(((GLfloat)(0xFFFFFFFF) * floatParams[i] - 1.0f) / 2.0f);
2200 }
2201 else
2202 {
2203 params[i] = (GLint)(floatParams[i] > 0.0f ? floor(floatParams[i] + 0.5) : ceil(floatParams[i] - 0.5));
2204 }
2205 }
2206
2207 delete [] floatParams;
2208 }
2209 else UNREACHABLE(pname);
2210 }
2211 }
2212 }
2213
GetLightfv(GLenum light,GLenum pname,GLfloat * params)2214 void GetLightfv(GLenum light, GLenum pname, GLfloat *params)
2215 {
2216 UNIMPLEMENTED();
2217 }
2218
GetLightxv(GLenum light,GLenum pname,GLfixed * params)2219 void GetLightxv(GLenum light, GLenum pname, GLfixed *params)
2220 {
2221 UNIMPLEMENTED();
2222 }
2223
GetMaterialfv(GLenum face,GLenum pname,GLfloat * params)2224 void GetMaterialfv(GLenum face, GLenum pname, GLfloat *params)
2225 {
2226 UNIMPLEMENTED();
2227 }
2228
GetMaterialxv(GLenum face,GLenum pname,GLfixed * params)2229 void GetMaterialxv(GLenum face, GLenum pname, GLfixed *params)
2230 {
2231 UNIMPLEMENTED();
2232 }
2233
GetPointerv(GLenum pname,GLvoid ** params)2234 void GetPointerv(GLenum pname, GLvoid **params)
2235 {
2236 TRACE("(GLenum pname = 0x%X, GLvoid **params = %p)", pname, params);
2237
2238 es1::Context *context = es1::getContext();
2239
2240 if(context)
2241 {
2242 if(!(context->getPointerv(pname, const_cast<const GLvoid**>(params))))
2243 {
2244 return error(GL_INVALID_ENUM);
2245 }
2246 }
2247 }
2248
GetString(GLenum name)2249 const GLubyte* GetString(GLenum name)
2250 {
2251 TRACE("(GLenum name = 0x%X)", name);
2252
2253 switch(name)
2254 {
2255 case GL_VENDOR:
2256 return (GLubyte*)"Google Inc.";
2257 case GL_RENDERER:
2258 return (GLubyte*)"Google SwiftShader " VERSION_STRING;
2259 case GL_VERSION:
2260 return (GLubyte*)"OpenGL ES-CM 1.1";
2261 case GL_EXTENSIONS:
2262 // Keep list sorted in following order:
2263 // OES extensions
2264 // EXT extensions
2265 // Vendor extensions
2266 return (GLubyte*)
2267 "GL_OES_blend_equation_separate "
2268 "GL_OES_blend_func_separate "
2269 "GL_OES_blend_subtract "
2270 "GL_OES_compressed_ETC1_RGB8_texture "
2271 "GL_OES_EGL_image "
2272 "GL_OES_EGL_image_external "
2273 "GL_OES_EGL_sync "
2274 "GL_OES_element_index_uint "
2275 "GL_OES_fbo_render_mipmap "
2276 "GL_OES_framebuffer_object "
2277 "GL_OES_packed_depth_stencil "
2278 "GL_OES_read_format "
2279 "GL_OES_rgb8_rgba8 "
2280 "GL_OES_stencil8 "
2281 "GL_OES_stencil_wrap "
2282 "GL_OES_surfaceless_context "
2283 "GL_OES_texture_mirrored_repeat "
2284 "GL_OES_texture_npot "
2285 "GL_EXT_blend_minmax "
2286 "GL_EXT_read_format_bgra "
2287 "GL_EXT_texture_compression_dxt1 "
2288 "GL_ANGLE_texture_compression_dxt3 "
2289 "GL_ANGLE_texture_compression_dxt5 "
2290 "GL_EXT_texture_filter_anisotropic "
2291 "GL_EXT_texture_format_BGRA8888";
2292 default:
2293 return error(GL_INVALID_ENUM, (GLubyte*)nullptr);
2294 }
2295 }
2296
GetTexParameterfv(GLenum target,GLenum pname,GLfloat * params)2297 void GetTexParameterfv(GLenum target, GLenum pname, GLfloat* params)
2298 {
2299 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat* params = %p)", target, pname, params);
2300
2301 es1::Context *context = es1::getContext();
2302
2303 if(context)
2304 {
2305 es1::Texture *texture;
2306
2307 switch(target)
2308 {
2309 case GL_TEXTURE_2D:
2310 texture = context->getTexture2D();
2311 break;
2312 case GL_TEXTURE_EXTERNAL_OES:
2313 texture = context->getTextureExternal();
2314 break;
2315 default:
2316 return error(GL_INVALID_ENUM);
2317 }
2318
2319 switch(pname)
2320 {
2321 case GL_TEXTURE_MAG_FILTER:
2322 *params = (GLfloat)texture->getMagFilter();
2323 break;
2324 case GL_TEXTURE_MIN_FILTER:
2325 *params = (GLfloat)texture->getMinFilter();
2326 break;
2327 case GL_TEXTURE_WRAP_S:
2328 *params = (GLfloat)texture->getWrapS();
2329 break;
2330 case GL_TEXTURE_WRAP_T:
2331 *params = (GLfloat)texture->getWrapT();
2332 break;
2333 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2334 *params = texture->getMaxAnisotropy();
2335 break;
2336 case GL_GENERATE_MIPMAP:
2337 *params = (GLfloat)texture->getGenerateMipmap();
2338 break;
2339 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2340 *params = (GLfloat)1;
2341 break;
2342 default:
2343 return error(GL_INVALID_ENUM);
2344 }
2345 }
2346 }
2347
GetTexParameteriv(GLenum target,GLenum pname,GLint * params)2348 void GetTexParameteriv(GLenum target, GLenum pname, GLint* params)
2349 {
2350 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint* params = %p)", target, pname, params);
2351
2352 es1::Context *context = es1::getContext();
2353
2354 if(context)
2355 {
2356 es1::Texture *texture;
2357
2358 switch(target)
2359 {
2360 case GL_TEXTURE_2D:
2361 texture = context->getTexture2D();
2362 break;
2363 case GL_TEXTURE_EXTERNAL_OES:
2364 texture = context->getTextureExternal();
2365 break;
2366 default:
2367 return error(GL_INVALID_ENUM);
2368 }
2369
2370 switch(pname)
2371 {
2372 case GL_TEXTURE_MAG_FILTER:
2373 *params = texture->getMagFilter();
2374 break;
2375 case GL_TEXTURE_MIN_FILTER:
2376 *params = texture->getMinFilter();
2377 break;
2378 case GL_TEXTURE_WRAP_S:
2379 *params = texture->getWrapS();
2380 break;
2381 case GL_TEXTURE_WRAP_T:
2382 *params = texture->getWrapT();
2383 break;
2384 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2385 *params = (GLint)texture->getMaxAnisotropy();
2386 break;
2387 case GL_GENERATE_MIPMAP:
2388 *params = (GLint)texture->getGenerateMipmap();
2389 break;
2390 case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
2391 *params = 1;
2392 break;
2393 default:
2394 return error(GL_INVALID_ENUM);
2395 }
2396 }
2397 }
2398
GetTexEnvfv(GLenum env,GLenum pname,GLfloat * params)2399 void GetTexEnvfv(GLenum env, GLenum pname, GLfloat *params)
2400 {
2401 UNIMPLEMENTED();
2402 }
2403
GetTexEnviv(GLenum env,GLenum pname,GLint * params)2404 void GetTexEnviv(GLenum env, GLenum pname, GLint *params)
2405 {
2406 UNIMPLEMENTED();
2407 }
2408
GetTexEnvxv(GLenum env,GLenum pname,GLfixed * params)2409 void GetTexEnvxv(GLenum env, GLenum pname, GLfixed *params)
2410 {
2411 UNIMPLEMENTED();
2412 }
2413
GetTexParameterxv(GLenum target,GLenum pname,GLfixed * params)2414 void GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params)
2415 {
2416 UNIMPLEMENTED();
2417 }
2418
Hint(GLenum target,GLenum mode)2419 void Hint(GLenum target, GLenum mode)
2420 {
2421 TRACE("(GLenum target = 0x%X, GLenum mode = 0x%X)", target, mode);
2422
2423 switch(mode)
2424 {
2425 case GL_FASTEST:
2426 case GL_NICEST:
2427 case GL_DONT_CARE:
2428 break;
2429 default:
2430 return error(GL_INVALID_ENUM);
2431 }
2432
2433 es1::Context *context = es1::getContext();
2434
2435 if(context)
2436 {
2437 switch(target)
2438 {
2439 case GL_GENERATE_MIPMAP_HINT:
2440 context->setGenerateMipmapHint(mode);
2441 break;
2442 case GL_PERSPECTIVE_CORRECTION_HINT:
2443 context->setPerspectiveCorrectionHint(mode);
2444 break;
2445 case GL_FOG_HINT:
2446 context->setFogHint(mode);
2447 break;
2448 default:
2449 return error(GL_INVALID_ENUM);
2450 }
2451 }
2452 }
2453
IsBuffer(GLuint buffer)2454 GLboolean IsBuffer(GLuint buffer)
2455 {
2456 TRACE("(GLuint buffer = %d)", buffer);
2457
2458 es1::Context *context = es1::getContext();
2459
2460 if(context && buffer)
2461 {
2462 es1::Buffer *bufferObject = context->getBuffer(buffer);
2463
2464 if(bufferObject)
2465 {
2466 return GL_TRUE;
2467 }
2468 }
2469
2470 return GL_FALSE;
2471 }
2472
IsEnabled(GLenum cap)2473 GLboolean IsEnabled(GLenum cap)
2474 {
2475 TRACE("(GLenum cap = 0x%X)", cap);
2476
2477 es1::Context *context = es1::getContext();
2478
2479 if(context)
2480 {
2481 switch(cap)
2482 {
2483 case GL_CULL_FACE: return context->isCullFaceEnabled(); break;
2484 case GL_POLYGON_OFFSET_FILL: return context->isPolygonOffsetFillEnabled(); break;
2485 case GL_SAMPLE_ALPHA_TO_COVERAGE: return context->isSampleAlphaToCoverageEnabled(); break;
2486 case GL_SAMPLE_COVERAGE: return context->isSampleCoverageEnabled(); break;
2487 case GL_SCISSOR_TEST: return context->isScissorTestEnabled(); break;
2488 case GL_STENCIL_TEST: return context->isStencilTestEnabled(); break;
2489 case GL_DEPTH_TEST: return context->isDepthTestEnabled(); break;
2490 case GL_BLEND: return context->isBlendEnabled(); break;
2491 case GL_DITHER: return context->isDitherEnabled(); break;
2492 case GL_LIGHTING: return context->isLightingEnabled(); break;
2493 case GL_LIGHT0: return context->isLightEnabled(0); break;
2494 case GL_LIGHT1: return context->isLightEnabled(1); break;
2495 case GL_LIGHT2: return context->isLightEnabled(2); break;
2496 case GL_LIGHT3: return context->isLightEnabled(3); break;
2497 case GL_LIGHT4: return context->isLightEnabled(4); break;
2498 case GL_LIGHT5: return context->isLightEnabled(5); break;
2499 case GL_LIGHT6: return context->isLightEnabled(6); break;
2500 case GL_LIGHT7: return context->isLightEnabled(7); break;
2501 case GL_FOG: return context->isFogEnabled(); break;
2502 case GL_TEXTURE_2D: return context->isTexture2Denabled(); break;
2503 case GL_TEXTURE_EXTERNAL_OES: return context->isTextureExternalEnabled(); break;
2504 case GL_ALPHA_TEST: return context->isAlphaTestEnabled(); break;
2505 case GL_COLOR_LOGIC_OP: return context->isColorLogicOpEnabled(); break;
2506 case GL_POINT_SMOOTH: return context->isPointSmoothEnabled(); break;
2507 case GL_LINE_SMOOTH: return context->isLineSmoothEnabled(); break;
2508 case GL_COLOR_MATERIAL: return context->isColorMaterialEnabled(); break;
2509 case GL_NORMALIZE: return context->isNormalizeEnabled(); break;
2510 case GL_RESCALE_NORMAL: return context->isRescaleNormalEnabled(); break;
2511 case GL_VERTEX_ARRAY: return context->isVertexArrayEnabled(); break;
2512 case GL_NORMAL_ARRAY: return context->isNormalArrayEnabled(); break;
2513 case GL_COLOR_ARRAY: return context->isColorArrayEnabled(); break;
2514 case GL_POINT_SIZE_ARRAY_OES: return context->isPointSizeArrayEnabled(); break;
2515 case GL_TEXTURE_COORD_ARRAY: return context->isTextureCoordArrayEnabled(); break;
2516 case GL_MULTISAMPLE: return context->isMultisampleEnabled(); break;
2517 case GL_SAMPLE_ALPHA_TO_ONE: return context->isSampleAlphaToOneEnabled(); break;
2518 case GL_CLIP_PLANE0: return context->isClipPlaneEnabled(0); break;
2519 case GL_CLIP_PLANE1: return context->isClipPlaneEnabled(1); break;
2520 case GL_CLIP_PLANE2: return context->isClipPlaneEnabled(2); break;
2521 case GL_CLIP_PLANE3: return context->isClipPlaneEnabled(3); break;
2522 case GL_CLIP_PLANE4: return context->isClipPlaneEnabled(4); break;
2523 case GL_CLIP_PLANE5: return context->isClipPlaneEnabled(5); break;
2524 case GL_POINT_SPRITE_OES: return context->isPointSpriteEnabled(); break;
2525 default:
2526 return error(GL_INVALID_ENUM, GL_FALSE);
2527 }
2528 }
2529
2530 return GL_FALSE;
2531 }
2532
IsFramebufferOES(GLuint framebuffer)2533 GLboolean IsFramebufferOES(GLuint framebuffer)
2534 {
2535 TRACE("(GLuint framebuffer = %d)", framebuffer);
2536
2537 es1::Context *context = es1::getContext();
2538
2539 if(context && framebuffer)
2540 {
2541 es1::Framebuffer *framebufferObject = context->getFramebuffer(framebuffer);
2542
2543 if(framebufferObject)
2544 {
2545 return GL_TRUE;
2546 }
2547 }
2548
2549 return GL_FALSE;
2550 }
2551
IsTexture(GLuint texture)2552 GLboolean IsTexture(GLuint texture)
2553 {
2554 TRACE("(GLuint texture = %d)", texture);
2555
2556 es1::Context *context = es1::getContext();
2557
2558 if(context && texture)
2559 {
2560 es1::Texture *textureObject = context->getTexture(texture);
2561
2562 if(textureObject)
2563 {
2564 return GL_TRUE;
2565 }
2566 }
2567
2568 return GL_FALSE;
2569 }
2570
IsRenderbufferOES(GLuint renderbuffer)2571 GLboolean IsRenderbufferOES(GLuint renderbuffer)
2572 {
2573 TRACE("(GLuint renderbuffer = %d)", renderbuffer);
2574
2575 es1::Context *context = es1::getContext();
2576
2577 if(context && renderbuffer)
2578 {
2579 es1::Renderbuffer *renderbufferObject = context->getRenderbuffer(renderbuffer);
2580
2581 if(renderbufferObject)
2582 {
2583 return GL_TRUE;
2584 }
2585 }
2586
2587 return GL_FALSE;
2588 }
2589
LightModelf(GLenum pname,GLfloat param)2590 void LightModelf(GLenum pname, GLfloat param)
2591 {
2592 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
2593
2594 es1::Context *context = es1::getContext();
2595
2596 if(context)
2597 {
2598 switch(pname)
2599 {
2600 case GL_LIGHT_MODEL_TWO_SIDE:
2601 context->setLightModelTwoSide(param != 0.0f);
2602 break;
2603 case GL_LIGHT_MODEL_AMBIENT:
2604 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelfv() instead
2605 default:
2606 return error(GL_INVALID_ENUM);
2607 }
2608 }
2609 }
2610
LightModelfv(GLenum pname,const GLfloat * params)2611 void LightModelfv(GLenum pname, const GLfloat *params)
2612 {
2613 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
2614
2615 es1::Context *context = es1::getContext();
2616
2617 if(context)
2618 {
2619 switch(pname)
2620 {
2621 case GL_LIGHT_MODEL_AMBIENT:
2622 context->setGlobalAmbient(params[0], params[1], params[2], params[3]);
2623 break;
2624 case GL_LIGHT_MODEL_TWO_SIDE:
2625 context->setLightModelTwoSide(params[0] != 0.0f);
2626 break;
2627 default:
2628 return error(GL_INVALID_ENUM);
2629 }
2630 }
2631 }
2632
LightModelx(GLenum pname,GLfixed param)2633 void LightModelx(GLenum pname, GLfixed param)
2634 {
2635 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
2636
2637 es1::Context *context = es1::getContext();
2638
2639 if(context)
2640 {
2641 switch(pname)
2642 {
2643 case GL_LIGHT_MODEL_TWO_SIDE:
2644 context->setLightModelTwoSide(param != 0);
2645 break;
2646 case GL_LIGHT_MODEL_AMBIENT:
2647 return error(GL_INVALID_ENUM); // Need four values, should call glLightModelxv() instead
2648 default:
2649 return error(GL_INVALID_ENUM);
2650 }
2651 }
2652 }
2653
LightModelxv(GLenum pname,const GLfixed * params)2654 void LightModelxv(GLenum pname, const GLfixed *params)
2655 {
2656 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
2657
2658 es1::Context *context = es1::getContext();
2659
2660 if(context)
2661 {
2662 switch(pname)
2663 {
2664 case GL_LIGHT_MODEL_AMBIENT:
2665 context->setGlobalAmbient((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000, (float)params[3] / 0x10000);
2666 break;
2667 case GL_LIGHT_MODEL_TWO_SIDE:
2668 context->setLightModelTwoSide(params[0] != 0);
2669 break;
2670 default:
2671 return error(GL_INVALID_ENUM);
2672 }
2673 }
2674 }
2675
Lightf(GLenum light,GLenum pname,GLfloat param)2676 void Lightf(GLenum light, GLenum pname, GLfloat param)
2677 {
2678 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", light, pname, param);
2679
2680 int index = light - GL_LIGHT0;
2681
2682 if(index < 0 || index >= es1::MAX_LIGHTS)
2683 {
2684 return error(GL_INVALID_ENUM);
2685 }
2686
2687 es1::Context *context = es1::getContext();
2688
2689 if(context)
2690 {
2691 switch(pname)
2692 {
2693 case GL_SPOT_EXPONENT:
2694 if(param < 0.0f || param > 128.0f)
2695 {
2696 return error(GL_INVALID_VALUE);
2697 }
2698 context->setSpotLightExponent(index, param);
2699 break;
2700 case GL_SPOT_CUTOFF:
2701 if((param < 0.0f || param > 90.0f) && param != 180.0f)
2702 {
2703 return error(GL_INVALID_VALUE);
2704 }
2705 context->setSpotLightCutoff(index, param);
2706 break;
2707 case GL_CONSTANT_ATTENUATION:
2708 if(param < 0.0f)
2709 {
2710 return error(GL_INVALID_VALUE);
2711 }
2712 context->setLightAttenuationConstant(index, param);
2713 break;
2714 case GL_LINEAR_ATTENUATION:
2715 if(param < 0.0f)
2716 {
2717 return error(GL_INVALID_VALUE);
2718 }
2719 context->setLightAttenuationLinear(index, param);
2720 break;
2721 case GL_QUADRATIC_ATTENUATION:
2722 if(param < 0.0f)
2723 {
2724 return error(GL_INVALID_VALUE);
2725 }
2726 context->setLightAttenuationQuadratic(index, param);
2727 break;
2728 case GL_AMBIENT:
2729 case GL_DIFFUSE:
2730 case GL_SPECULAR:
2731 case GL_POSITION:
2732 case GL_SPOT_DIRECTION:
2733 return error(GL_INVALID_ENUM); // Need four values, should call glLightfv() instead
2734 default:
2735 return error(GL_INVALID_ENUM);
2736 }
2737 }
2738 }
2739
Lightfv(GLenum light,GLenum pname,const GLfloat * params)2740 void Lightfv(GLenum light, GLenum pname, const GLfloat *params)
2741 {
2742 TRACE("(GLenum light = 0x%X, GLenum pname = 0x%X, const GLint *params)", light, pname);
2743
2744 es1::Context *context = es1::getContext();
2745
2746 if(context)
2747 {
2748 int index = light - GL_LIGHT0;
2749
2750 if(index < 0 || index > es1::MAX_LIGHTS)
2751 {
2752 return error(GL_INVALID_ENUM);
2753 }
2754
2755 switch(pname)
2756 {
2757 case GL_AMBIENT: context->setLightAmbient(index, params[0], params[1], params[2], params[3]); break;
2758 case GL_DIFFUSE: context->setLightDiffuse(index, params[0], params[1], params[2], params[3]); break;
2759 case GL_SPECULAR: context->setLightSpecular(index, params[0], params[1], params[2], params[3]); break;
2760 case GL_POSITION: context->setLightPosition(index, params[0], params[1], params[2], params[3]); break;
2761 case GL_SPOT_DIRECTION: context->setLightDirection(index, params[0], params[1], params[2]); break;
2762 case GL_SPOT_EXPONENT:
2763 if(params[0] < 0.0f || params[0] > 128.0f)
2764 {
2765 return error(GL_INVALID_VALUE);
2766 }
2767 context->setSpotLightExponent(index, params[0]);
2768 break;
2769 case GL_SPOT_CUTOFF:
2770 if((params[0] < 0.0f || params[0] > 90.0f) && params[0] != 180.0f)
2771 {
2772 return error(GL_INVALID_VALUE);
2773 }
2774 context->setSpotLightCutoff(index, params[0]);
2775 break;
2776 case GL_CONSTANT_ATTENUATION:
2777 if(params[0] < 0.0f)
2778 {
2779 return error(GL_INVALID_VALUE);
2780 }
2781 context->setLightAttenuationConstant(index, params[0]);
2782 break;
2783 case GL_LINEAR_ATTENUATION:
2784 if(params[0] < 0.0f)
2785 {
2786 return error(GL_INVALID_VALUE);
2787 }
2788 context->setLightAttenuationLinear(index, params[0]);
2789 break;
2790 case GL_QUADRATIC_ATTENUATION:
2791 if(params[0] < 0.0f)
2792 {
2793 return error(GL_INVALID_VALUE);
2794 }
2795 context->setLightAttenuationQuadratic(index, params[0]);
2796 break;
2797 default:
2798 return error(GL_INVALID_ENUM);
2799 }
2800 }
2801 }
2802
Lightx(GLenum light,GLenum pname,GLfixed param)2803 void Lightx(GLenum light, GLenum pname, GLfixed param)
2804 {
2805 UNIMPLEMENTED();
2806 }
2807
Lightxv(GLenum light,GLenum pname,const GLfixed * params)2808 void Lightxv(GLenum light, GLenum pname, const GLfixed *params)
2809 {
2810 UNIMPLEMENTED();
2811 }
2812
LineWidth(GLfloat width)2813 void LineWidth(GLfloat width)
2814 {
2815 TRACE("(GLfloat width = %f)", width);
2816
2817 if(width <= 0.0f)
2818 {
2819 return error(GL_INVALID_VALUE);
2820 }
2821
2822 es1::Context *context = es1::getContext();
2823
2824 if(context)
2825 {
2826 context->setLineWidth(width);
2827 }
2828 }
2829
LineWidthx(GLfixed width)2830 void LineWidthx(GLfixed width)
2831 {
2832 LineWidth((float)width / 0x10000);
2833 }
2834
LoadIdentity(void)2835 void LoadIdentity(void)
2836 {
2837 TRACE("()");
2838
2839 es1::Context *context = es1::getContext();
2840
2841 if(context)
2842 {
2843 context->loadIdentity();
2844 }
2845 }
2846
LoadMatrixf(const GLfloat * m)2847 void LoadMatrixf(const GLfloat *m)
2848 {
2849 TRACE("(const GLfloat *m)");
2850
2851 es1::Context *context = es1::getContext();
2852
2853 if(context)
2854 {
2855 context->load(m);
2856 }
2857 }
2858
LoadMatrixx(const GLfixed * m)2859 void LoadMatrixx(const GLfixed *m)
2860 {
2861 GLfloat matrix[16] =
2862 {
2863 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
2864 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
2865 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
2866 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
2867 };
2868
2869 LoadMatrixf(matrix);
2870 }
2871
LogicOp(GLenum opcode)2872 void LogicOp(GLenum opcode)
2873 {
2874 TRACE("(GLenum opcode = 0x%X)", opcode);
2875
2876 switch(opcode)
2877 {
2878 case GL_CLEAR:
2879 case GL_SET:
2880 case GL_COPY:
2881 case GL_COPY_INVERTED:
2882 case GL_NOOP:
2883 case GL_INVERT:
2884 case GL_AND:
2885 case GL_NAND:
2886 case GL_OR:
2887 case GL_NOR:
2888 case GL_XOR:
2889 case GL_EQUIV:
2890 case GL_AND_REVERSE:
2891 case GL_AND_INVERTED:
2892 case GL_OR_REVERSE:
2893 case GL_OR_INVERTED:
2894 break;
2895 default:
2896 return error(GL_INVALID_ENUM);
2897 }
2898
2899 es1::Context *context = es1::getContext();
2900
2901 if(context)
2902 {
2903 context->setLogicalOperation(opcode);
2904 }
2905 }
2906
Materialf(GLenum face,GLenum pname,GLfloat param)2907 void Materialf(GLenum face, GLenum pname, GLfloat param)
2908 {
2909 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", face, pname, param);
2910
2911 if(face != GL_FRONT_AND_BACK)
2912 {
2913 return error(GL_INVALID_ENUM);
2914 }
2915
2916 es1::Context *context = es1::getContext();
2917
2918 if(context)
2919 {
2920 switch(pname)
2921 {
2922 case GL_SHININESS:
2923 if(param < 0.0f || param > 128.0f)
2924 {
2925 return error(GL_INVALID_VALUE);
2926 }
2927 context->setMaterialShininess(param);
2928 break;
2929 case GL_AMBIENT:
2930 case GL_DIFFUSE:
2931 case GL_AMBIENT_AND_DIFFUSE:
2932 case GL_SPECULAR:
2933 case GL_EMISSION:
2934 return error(GL_INVALID_ENUM); // Need four values, should call glMaterialfv() instead
2935 default:
2936 return error(GL_INVALID_ENUM);
2937 }
2938 }
2939 }
2940
Materialfv(GLenum face,GLenum pname,const GLfloat * params)2941 void Materialfv(GLenum face, GLenum pname, const GLfloat *params)
2942 {
2943 TRACE("(GLenum face = 0x%X, GLenum pname = 0x%X, GLfloat params)", face, pname);
2944
2945 if(face != GL_FRONT_AND_BACK)
2946 {
2947 return error(GL_INVALID_ENUM);
2948 }
2949
2950 es1::Context *context = es1::getContext();
2951
2952 if(context)
2953 {
2954 switch(pname)
2955 {
2956 case GL_AMBIENT:
2957 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2958 break;
2959 case GL_DIFFUSE:
2960 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2961 break;
2962 case GL_AMBIENT_AND_DIFFUSE:
2963 context->setMaterialAmbient(params[0], params[1], params[2], params[3]);
2964 context->setMaterialDiffuse(params[0], params[1], params[2], params[3]);
2965 break;
2966 case GL_SPECULAR:
2967 context->setMaterialSpecular(params[0], params[1], params[2], params[3]);
2968 break;
2969 case GL_EMISSION:
2970 context->setMaterialEmission(params[0], params[1], params[2], params[3]);
2971 break;
2972 case GL_SHININESS:
2973 context->setMaterialShininess(params[0]);
2974 break;
2975 default:
2976 return error(GL_INVALID_ENUM);
2977 }
2978 }
2979 }
2980
Materialx(GLenum face,GLenum pname,GLfixed param)2981 void Materialx(GLenum face, GLenum pname, GLfixed param)
2982 {
2983 UNIMPLEMENTED();
2984 }
2985
Materialxv(GLenum face,GLenum pname,const GLfixed * params)2986 void Materialxv(GLenum face, GLenum pname, const GLfixed *params)
2987 {
2988 UNIMPLEMENTED();
2989 }
2990
MatrixMode(GLenum mode)2991 void MatrixMode(GLenum mode)
2992 {
2993 TRACE("(GLenum mode = 0x%X)", mode);
2994
2995 es1::Context *context = es1::getContext();
2996
2997 if(context)
2998 {
2999 context->setMatrixMode(mode);
3000 }
3001 }
3002
MultMatrixf(const GLfloat * m)3003 void MultMatrixf(const GLfloat *m)
3004 {
3005 TRACE("(const GLfloat *m)");
3006
3007 es1::Context *context = es1::getContext();
3008
3009 if(context)
3010 {
3011 context->multiply(m);
3012 }
3013 }
3014
MultMatrixx(const GLfixed * m)3015 void MultMatrixx(const GLfixed *m)
3016 {
3017 GLfloat matrix[16] =
3018 {
3019 (float)m[0] / 0x10000, (float)m[1] / 0x10000, (float)m[2] / 0x10000, (float)m[3] / 0x10000,
3020 (float)m[4] / 0x10000, (float)m[5] / 0x10000, (float)m[6] / 0x10000, (float)m[7] / 0x10000,
3021 (float)m[8] / 0x10000, (float)m[9] / 0x10000, (float)m[10] / 0x10000, (float)m[11] / 0x10000,
3022 (float)m[12] / 0x10000, (float)m[13] / 0x10000, (float)m[14] / 0x10000, (float)m[15] / 0x10000
3023 };
3024
3025 MultMatrixf(matrix);
3026 }
3027
MultiTexCoord4f(GLenum target,GLfloat s,GLfloat t,GLfloat r,GLfloat q)3028 void MultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q)
3029 {
3030 TRACE("(GLenum target = 0x%X, GLfloat s = %f, GLfloat t = %f, GLfloat r = %f, GLfloat q = %f)", target, s, t, r, q);
3031
3032 switch(target)
3033 {
3034 case GL_TEXTURE0:
3035 case GL_TEXTURE1:
3036 break;
3037 default:
3038 return error(GL_INVALID_ENUM);
3039 }
3040
3041 es1::Context *context = es1::getContext();
3042
3043 if(context)
3044 {
3045 context->setVertexAttrib(sw::TexCoord0 + (target - GL_TEXTURE0), s, t, r, q);
3046 }
3047 }
3048
MultiTexCoord4x(GLenum target,GLfixed s,GLfixed t,GLfixed r,GLfixed q)3049 void MultiTexCoord4x(GLenum target, GLfixed s, GLfixed t, GLfixed r, GLfixed q)
3050 {
3051 UNIMPLEMENTED();
3052 }
3053
Normal3f(GLfloat nx,GLfloat ny,GLfloat nz)3054 void Normal3f(GLfloat nx, GLfloat ny, GLfloat nz)
3055 {
3056 TRACE("(GLfloat nx, GLfloat ny, GLfloat nz)", nx, ny, nz);
3057
3058 es1::Context *context = es1::getContext();
3059
3060 if(context)
3061 {
3062 context->setVertexAttrib(sw::Normal, nx, ny, nz, 0);
3063 }
3064 }
3065
Normal3x(GLfixed nx,GLfixed ny,GLfixed nz)3066 void Normal3x(GLfixed nx, GLfixed ny, GLfixed nz)
3067 {
3068 UNIMPLEMENTED();
3069 }
3070
NormalPointer(GLenum type,GLsizei stride,const GLvoid * pointer)3071 void NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer)
3072 {
3073 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3074
3075 VertexAttribPointer(sw::Normal, 3, type, true, stride, pointer);
3076 }
3077
Orthof(GLfloat left,GLfloat right,GLfloat bottom,GLfloat top,GLfloat zNear,GLfloat zFar)3078 void Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat zNear, GLfloat zFar)
3079 {
3080 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);
3081
3082 if(left == right || bottom == top || zNear == zFar)
3083 {
3084 return error(GL_INVALID_VALUE);
3085 }
3086
3087 es1::Context *context = es1::getContext();
3088
3089 if(context)
3090 {
3091 context->ortho(left, right, bottom, top, zNear, zFar);
3092 }
3093 }
3094
Orthox(GLfixed left,GLfixed right,GLfixed bottom,GLfixed top,GLfixed zNear,GLfixed zFar)3095 void Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, GLfixed zNear, GLfixed zFar)
3096 {
3097 Orthof((float)left / 0x10000, (float)right / 0x10000, (float)bottom / 0x10000, (float)top / 0x10000, (float)zNear / 0x10000, (float)zFar / 0x10000);
3098 }
3099
PixelStorei(GLenum pname,GLint param)3100 void PixelStorei(GLenum pname, GLint param)
3101 {
3102 TRACE("(GLenum pname = 0x%X, GLint param = %d)", pname, param);
3103
3104 es1::Context *context = es1::getContext();
3105
3106 if(context)
3107 {
3108 switch(pname)
3109 {
3110 case GL_UNPACK_ALIGNMENT:
3111 if(param != 1 && param != 2 && param != 4 && param != 8)
3112 {
3113 return error(GL_INVALID_VALUE);
3114 }
3115
3116 context->setUnpackAlignment(param);
3117 break;
3118 case GL_PACK_ALIGNMENT:
3119 if(param != 1 && param != 2 && param != 4 && param != 8)
3120 {
3121 return error(GL_INVALID_VALUE);
3122 }
3123
3124 context->setPackAlignment(param);
3125 break;
3126 default:
3127 return error(GL_INVALID_ENUM);
3128 }
3129 }
3130 }
3131
PointParameterf(GLenum pname,GLfloat param)3132 void PointParameterf(GLenum pname, GLfloat param)
3133 {
3134 TRACE("(GLenum pname = 0x%X, GLfloat param = %f)", pname, param);
3135
3136 es1::Context *context = es1::getContext();
3137
3138 if(context)
3139 {
3140 switch(pname)
3141 {
3142 case GL_POINT_SIZE_MIN:
3143 if(param < 0.0f)
3144 {
3145 return error(GL_INVALID_VALUE);
3146 }
3147 context->setPointSizeMin(param);
3148 break;
3149 case GL_POINT_SIZE_MAX:
3150 if(param < 0.0f)
3151 {
3152 return error(GL_INVALID_VALUE);
3153 }
3154 context->setPointSizeMax(param);
3155 break;
3156 case GL_POINT_FADE_THRESHOLD_SIZE:
3157 if(param < 0.0f)
3158 {
3159 return error(GL_INVALID_VALUE);
3160 }
3161 context->setPointFadeThresholdSize(param);
3162 break;
3163 case GL_POINT_DISTANCE_ATTENUATION:
3164 return error(GL_INVALID_ENUM); // Needs three values, should call glPointParameterfv() instead
3165 default:
3166 return error(GL_INVALID_ENUM);
3167 }
3168 }
3169 }
3170
PointParameterfv(GLenum pname,const GLfloat * params)3171 void PointParameterfv(GLenum pname, const GLfloat *params)
3172 {
3173 TRACE("(GLenum pname = 0x%X, const GLfloat *params)", pname);
3174
3175 es1::Context *context = es1::getContext();
3176
3177 if(context)
3178 {
3179 switch(pname)
3180 {
3181 case GL_POINT_SIZE_MIN:
3182 if(params[0] < 0.0f)
3183 {
3184 return error(GL_INVALID_VALUE);
3185 }
3186 context->setPointSizeMin(params[0]);
3187 break;
3188 case GL_POINT_SIZE_MAX:
3189 if(params[0] < 0.0f)
3190 {
3191 return error(GL_INVALID_VALUE);
3192 }
3193 context->setPointSizeMax(params[0]);
3194 break;
3195 case GL_POINT_DISTANCE_ATTENUATION:
3196 context->setPointDistanceAttenuation(params[0], params[1], params[2]);
3197 break;
3198 case GL_POINT_FADE_THRESHOLD_SIZE:
3199 if(params[0] < 0.0f)
3200 {
3201 return error(GL_INVALID_VALUE);
3202 }
3203 context->setPointFadeThresholdSize(params[0]);
3204 break;
3205 default:
3206 return error(GL_INVALID_ENUM);
3207 }
3208 }
3209 }
3210
PointParameterx(GLenum pname,GLfixed param)3211 void PointParameterx(GLenum pname, GLfixed param)
3212 {
3213 TRACE("(GLenum pname = 0x%X, GLfixed param = %d)", pname, param);
3214
3215 es1::Context *context = es1::getContext();
3216
3217 if(context)
3218 {
3219 switch(pname)
3220 {
3221 case GL_POINT_SIZE_MIN:
3222 if(param < 0)
3223 {
3224 return error(GL_INVALID_VALUE);
3225 }
3226 context->setPointSizeMin((float)param / 0x10000);
3227 break;
3228 case GL_POINT_SIZE_MAX:
3229 if(param < 0)
3230 {
3231 return error(GL_INVALID_VALUE);
3232 }
3233 context->setPointSizeMax((float)param / 0x10000);
3234 break;
3235 case GL_POINT_FADE_THRESHOLD_SIZE:
3236 if(param < 0)
3237 {
3238 return error(GL_INVALID_VALUE);
3239 }
3240 context->setPointFadeThresholdSize((float)param / 0x10000);
3241 break;
3242 case GL_POINT_DISTANCE_ATTENUATION:
3243 return error(GL_INVALID_ENUM); // Needs three parameters, should call glPointParameterxv() instead
3244 default:
3245 return error(GL_INVALID_ENUM);
3246 }
3247 }
3248 }
3249
PointParameterxv(GLenum pname,const GLfixed * params)3250 void PointParameterxv(GLenum pname, const GLfixed *params)
3251 {
3252 TRACE("(GLenum pname = 0x%X, const GLfixed *params)", pname);
3253
3254 es1::Context *context = es1::getContext();
3255
3256 if(context)
3257 {
3258 switch(pname)
3259 {
3260 case GL_POINT_SIZE_MIN:
3261 if(params[0] < 0)
3262 {
3263 return error(GL_INVALID_VALUE);
3264 }
3265 context->setPointSizeMin((float)params[0] / 0x10000);
3266 break;
3267 case GL_POINT_SIZE_MAX:
3268 if(params[0] < 0)
3269 {
3270 return error(GL_INVALID_VALUE);
3271 }
3272 context->setPointSizeMax((float)params[0] / 0x10000);
3273 break;
3274 case GL_POINT_DISTANCE_ATTENUATION:
3275 context->setPointDistanceAttenuation((float)params[0] / 0x10000, (float)params[1] / 0x10000, (float)params[2] / 0x10000);
3276 break;
3277 case GL_POINT_FADE_THRESHOLD_SIZE:
3278 if(params[0] < 0)
3279 {
3280 return error(GL_INVALID_VALUE);
3281 }
3282 context->setPointFadeThresholdSize((float)params[0] / 0x10000);
3283 break;
3284 default:
3285 return error(GL_INVALID_ENUM);
3286 }
3287 }
3288 }
3289
PointSize(GLfloat size)3290 void PointSize(GLfloat size)
3291 {
3292 TRACE("(GLfloat size = %f)", size);
3293
3294 if(size <= 0)
3295 {
3296 return error(GL_INVALID_VALUE);
3297 }
3298
3299 es1::Context *context = es1::getContext();
3300
3301 if(context)
3302 {
3303 context->setVertexAttrib(sw::PointSize, size, size, size, size);
3304 }
3305 }
3306
PointSizePointerOES(GLenum type,GLsizei stride,const GLvoid * pointer)3307 void PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *pointer)
3308 {
3309 TRACE("(GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", type, stride, pointer);
3310
3311 switch(type)
3312 {
3313 case GL_FIXED:
3314 case GL_FLOAT:
3315 break;
3316 default:
3317 return error(GL_INVALID_ENUM);
3318 }
3319
3320 VertexAttribPointer(sw::PointSize, 1, type, true, stride, pointer);
3321 }
3322
PointSizex(GLfixed size)3323 void PointSizex(GLfixed size)
3324 {
3325 PointSize((float)size / 0x10000);
3326 }
3327
PolygonOffset(GLfloat factor,GLfloat units)3328 void PolygonOffset(GLfloat factor, GLfloat units)
3329 {
3330 TRACE("(GLfloat factor = %f, GLfloat units = %f)", factor, units);
3331
3332 es1::Context *context = es1::getContext();
3333
3334 if(context)
3335 {
3336 context->setPolygonOffsetParams(factor, units);
3337 }
3338 }
3339
PolygonOffsetx(GLfixed factor,GLfixed units)3340 void PolygonOffsetx(GLfixed factor, GLfixed units)
3341 {
3342 PolygonOffset((float)factor / 0x10000, (float)units / 0x10000);
3343 }
3344
PopMatrix(void)3345 void PopMatrix(void)
3346 {
3347 TRACE("()");
3348
3349 es1::Context *context = es1::getContext();
3350
3351 if(context)
3352 {
3353 context->popMatrix();
3354 }
3355 }
3356
PushMatrix(void)3357 void PushMatrix(void)
3358 {
3359 TRACE("()");
3360
3361 es1::Context *context = es1::getContext();
3362
3363 if(context)
3364 {
3365 context->pushMatrix();
3366 }
3367 }
3368
ReadPixels(GLint x,GLint y,GLsizei width,GLsizei height,GLenum format,GLenum type,GLvoid * pixels)3369 void ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid* pixels)
3370 {
3371 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d, "
3372 "GLenum format = 0x%X, GLenum type = 0x%X, GLvoid* pixels = %p)",
3373 x, y, width, height, format, type, pixels);
3374
3375 if(width < 0 || height < 0)
3376 {
3377 return error(GL_INVALID_VALUE);
3378 }
3379
3380 es1::Context *context = es1::getContext();
3381
3382 if(context)
3383 {
3384 context->readPixels(x, y, width, height, format, type, nullptr, pixels);
3385 }
3386 }
3387
RenderbufferStorageOES(GLenum target,GLenum internalformat,GLsizei width,GLsizei height)3388 void RenderbufferStorageOES(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
3389 {
3390 TRACE("(GLenum target = 0x%X, GLenum internalformat = 0x%X, GLsizei width = %d, GLsizei height = %d)",
3391 target, internalformat, width, height);
3392
3393 switch(target)
3394 {
3395 case GL_RENDERBUFFER_OES:
3396 break;
3397 default:
3398 return error(GL_INVALID_ENUM);
3399 }
3400
3401 if(!es1::IsColorRenderable(internalformat) && !es1::IsDepthRenderable(internalformat) && !es1::IsStencilRenderable(internalformat))
3402 {
3403 return error(GL_INVALID_ENUM);
3404 }
3405
3406 if(width < 0 || height < 0)
3407 {
3408 return error(GL_INVALID_VALUE);
3409 }
3410
3411 es1::Context *context = es1::getContext();
3412
3413 if(context)
3414 {
3415 if(width > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE ||
3416 height > es1::IMPLEMENTATION_MAX_RENDERBUFFER_SIZE)
3417 {
3418 return error(GL_INVALID_VALUE);
3419 }
3420
3421 GLuint handle = context->getRenderbufferName();
3422 if(handle == 0)
3423 {
3424 return error(GL_INVALID_OPERATION);
3425 }
3426
3427 switch(internalformat)
3428 {
3429 case GL_RGBA4_OES:
3430 case GL_RGB5_A1_OES:
3431 case GL_RGB565_OES:
3432 case GL_RGB8_OES:
3433 case GL_RGBA8_OES:
3434 context->setRenderbufferStorage(new es1::Colorbuffer(width, height, internalformat, 0));
3435 break;
3436 case GL_DEPTH_COMPONENT16_OES:
3437 context->setRenderbufferStorage(new es1::Depthbuffer(width, height, internalformat, 0));
3438 break;
3439 case GL_STENCIL_INDEX8_OES:
3440 context->setRenderbufferStorage(new es1::Stencilbuffer(width, height, 0));
3441 break;
3442 case GL_DEPTH24_STENCIL8_OES:
3443 context->setRenderbufferStorage(new es1::DepthStencilbuffer(width, height, internalformat, 0));
3444 break;
3445 default:
3446 return error(GL_INVALID_ENUM);
3447 }
3448 }
3449 }
3450
Rotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)3451 void Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z)
3452 {
3453 TRACE("(GLfloat angle = %f, GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", angle, x, y, z);
3454
3455 es1::Context *context = es1::getContext();
3456
3457 if(context)
3458 {
3459 context->rotate(angle, x, y, z);
3460 }
3461 }
3462
Rotatex(GLfixed angle,GLfixed x,GLfixed y,GLfixed z)3463 void Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z)
3464 {
3465 Rotatef((float)angle / 0x10000, (float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3466 }
3467
SampleCoverage(GLclampf value,GLboolean invert)3468 void SampleCoverage(GLclampf value, GLboolean invert)
3469 {
3470 TRACE("(GLclampf value = %f, GLboolean invert = %d)", value, invert);
3471
3472 es1::Context* context = es1::getContext();
3473
3474 if(context)
3475 {
3476 context->setSampleCoverageParams(es1::clamp01(value), invert != GL_FALSE);
3477 }
3478 }
3479
SampleCoveragex(GLclampx value,GLboolean invert)3480 void SampleCoveragex(GLclampx value, GLboolean invert)
3481 {
3482 SampleCoverage((float)value / 0x10000, invert);
3483 }
3484
Scalef(GLfloat x,GLfloat y,GLfloat z)3485 void Scalef(GLfloat x, GLfloat y, GLfloat z)
3486 {
3487 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
3488
3489 es1::Context *context = es1::getContext();
3490
3491 if(context)
3492 {
3493 context->scale(x, y, z);
3494 }
3495 }
3496
Scalex(GLfixed x,GLfixed y,GLfixed z)3497 void Scalex(GLfixed x, GLfixed y, GLfixed z)
3498 {
3499 Scalef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
3500 }
3501
Scissor(GLint x,GLint y,GLsizei width,GLsizei height)3502 void Scissor(GLint x, GLint y, GLsizei width, GLsizei height)
3503 {
3504 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
3505
3506 if(width < 0 || height < 0)
3507 {
3508 return error(GL_INVALID_VALUE);
3509 }
3510
3511 es1::Context* context = es1::getContext();
3512
3513 if(context)
3514 {
3515 context->setScissorParams(x, y, width, height);
3516 }
3517 }
3518
ShadeModel(GLenum mode)3519 void ShadeModel(GLenum mode)
3520 {
3521 switch(mode)
3522 {
3523 case GL_FLAT:
3524 case GL_SMOOTH:
3525 break;
3526 default:
3527 return error(GL_INVALID_ENUM);
3528 }
3529
3530 es1::Context *context = es1::getContext();
3531
3532 if(context)
3533 {
3534 context->setShadeModel(mode);
3535 }
3536 }
3537
StencilFunc(GLenum func,GLint ref,GLuint mask)3538 void StencilFunc(GLenum func, GLint ref, GLuint mask)
3539 {
3540 TRACE("(GLenum func = 0x%X, GLint ref = %d, GLuint mask = %d)", func, ref, mask);
3541
3542 switch(func)
3543 {
3544 case GL_NEVER:
3545 case GL_ALWAYS:
3546 case GL_LESS:
3547 case GL_LEQUAL:
3548 case GL_EQUAL:
3549 case GL_GEQUAL:
3550 case GL_GREATER:
3551 case GL_NOTEQUAL:
3552 break;
3553 default:
3554 return error(GL_INVALID_ENUM);
3555 }
3556
3557 es1::Context *context = es1::getContext();
3558
3559 if(context)
3560 {
3561 context->setStencilParams(func, ref, mask);
3562 }
3563 }
3564
StencilMask(GLuint mask)3565 void StencilMask(GLuint mask)
3566 {
3567 TRACE("(GLuint mask = %d)", mask);
3568
3569 es1::Context *context = es1::getContext();
3570
3571 if(context)
3572 {
3573 context->setStencilWritemask(mask);
3574 }
3575 }
3576
StencilOp(GLenum fail,GLenum zfail,GLenum zpass)3577 void StencilOp(GLenum fail, GLenum zfail, GLenum zpass)
3578 {
3579 TRACE("(GLenum fail = 0x%X, GLenum zfail = 0x%X, GLenum zpas = 0x%Xs)", fail, zfail, zpass);
3580
3581 switch(fail)
3582 {
3583 case GL_ZERO:
3584 case GL_KEEP:
3585 case GL_REPLACE:
3586 case GL_INCR:
3587 case GL_DECR:
3588 case GL_INVERT:
3589 case GL_INCR_WRAP_OES:
3590 case GL_DECR_WRAP_OES:
3591 break;
3592 default:
3593 return error(GL_INVALID_ENUM);
3594 }
3595
3596 switch(zfail)
3597 {
3598 case GL_ZERO:
3599 case GL_KEEP:
3600 case GL_REPLACE:
3601 case GL_INCR:
3602 case GL_DECR:
3603 case GL_INVERT:
3604 case GL_INCR_WRAP_OES:
3605 case GL_DECR_WRAP_OES:
3606 break;
3607 default:
3608 return error(GL_INVALID_ENUM);
3609 }
3610
3611 switch(zpass)
3612 {
3613 case GL_ZERO:
3614 case GL_KEEP:
3615 case GL_REPLACE:
3616 case GL_INCR:
3617 case GL_DECR:
3618 case GL_INVERT:
3619 case GL_INCR_WRAP_OES:
3620 case GL_DECR_WRAP_OES:
3621 break;
3622 default:
3623 return error(GL_INVALID_ENUM);
3624 }
3625
3626 es1::Context *context = es1::getContext();
3627
3628 if(context)
3629 {
3630 context->setStencilOperations(fail, zfail, zpass);
3631 }
3632 }
3633
TexCoordPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)3634 void TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
3635 {
3636 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
3637
3638 if(size < 2 || size > 4)
3639 {
3640 return error(GL_INVALID_VALUE);
3641 }
3642
3643 es1::Context *context = es1::getContext();
3644
3645 if(context)
3646 {
3647 GLenum texture = context->getClientActiveTexture();
3648 VertexAttribPointer(sw::TexCoord0 + (texture - GL_TEXTURE0), size, type, false, stride, pointer);
3649 }
3650 }
3651
3652 void TexEnvi(GLenum target, GLenum pname, GLint param);
3653
TexEnvf(GLenum target,GLenum pname,GLfloat param)3654 void TexEnvf(GLenum target, GLenum pname, GLfloat param)
3655 {
3656 TexEnvi(target, pname, (GLint)param);
3657 }
3658
TexEnvfv(GLenum target,GLenum pname,const GLfloat * params)3659 void TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
3660 {
3661 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, const GLfloat *params)", target, pname);
3662
3663 es1::Context *context = es1::getContext();
3664
3665 if(context)
3666 {
3667 GLint iParam = (GLint)roundf(params[0]);
3668
3669 switch(target)
3670 {
3671 case GL_POINT_SPRITE_OES:
3672 UNIMPLEMENTED();
3673 break;
3674 case GL_TEXTURE_ENV:
3675 switch(pname)
3676 {
3677 case GL_TEXTURE_ENV_MODE:
3678 switch(iParam)
3679 {
3680 case GL_REPLACE:
3681 case GL_MODULATE:
3682 case GL_DECAL:
3683 case GL_BLEND:
3684 case GL_ADD:
3685 case GL_COMBINE:
3686 break;
3687 default:
3688 error(GL_INVALID_ENUM);
3689 }
3690
3691 context->setTextureEnvMode(iParam);
3692 break;
3693 case GL_TEXTURE_ENV_COLOR:
3694 context->setTextureEnvColor(clamp01(params[0]), clamp01(params[1]), clamp01(params[2]), clamp01(params[3]));
3695 break;
3696 case GL_COMBINE_RGB:
3697 switch(iParam)
3698 {
3699 case GL_REPLACE:
3700 case GL_MODULATE:
3701 case GL_ADD:
3702 case GL_ADD_SIGNED:
3703 case GL_INTERPOLATE:
3704 case GL_SUBTRACT:
3705 case GL_DOT3_RGB:
3706 case GL_DOT3_RGBA:
3707 break;
3708 default:
3709 error(GL_INVALID_ENUM);
3710 }
3711
3712 context->setCombineRGB(iParam);
3713 break;
3714 case GL_COMBINE_ALPHA:
3715 switch(iParam)
3716 {
3717 case GL_REPLACE:
3718 case GL_MODULATE:
3719 case GL_ADD:
3720 case GL_ADD_SIGNED:
3721 case GL_INTERPOLATE:
3722 case GL_SUBTRACT:
3723 break;
3724 default:
3725 error(GL_INVALID_ENUM);
3726 }
3727
3728 context->setCombineAlpha(iParam);
3729 break;
3730 case GL_RGB_SCALE:
3731 if(iParam != 1 && iParam != 2 && iParam != 4)
3732 {
3733 return error(GL_INVALID_VALUE);
3734 }
3735 if(iParam != 1) UNIMPLEMENTED();
3736 break;
3737 case GL_ALPHA_SCALE:
3738 if(iParam != 1 && iParam != 2 && iParam != 4)
3739 {
3740 return error(GL_INVALID_VALUE);
3741 }
3742 if(iParam != 1) UNIMPLEMENTED();
3743 break;
3744 case GL_OPERAND0_RGB:
3745 switch(iParam)
3746 {
3747 case GL_SRC_COLOR:
3748 case GL_ONE_MINUS_SRC_COLOR:
3749 case GL_SRC_ALPHA:
3750 case GL_ONE_MINUS_SRC_ALPHA:
3751 break;
3752 default:
3753 error(GL_INVALID_ENUM);
3754 }
3755
3756 context->setOperand0RGB(iParam);
3757 break;
3758 case GL_OPERAND1_RGB:
3759 switch(iParam)
3760 {
3761 case GL_SRC_COLOR:
3762 case GL_ONE_MINUS_SRC_COLOR:
3763 case GL_SRC_ALPHA:
3764 case GL_ONE_MINUS_SRC_ALPHA:
3765 break;
3766 default:
3767 error(GL_INVALID_ENUM);
3768 }
3769
3770 context->setOperand1RGB(iParam);
3771 break;
3772 case GL_OPERAND2_RGB:
3773 switch(iParam)
3774 {
3775 case GL_SRC_COLOR:
3776 case GL_ONE_MINUS_SRC_COLOR:
3777 case GL_SRC_ALPHA:
3778 case GL_ONE_MINUS_SRC_ALPHA:
3779 break;
3780 default:
3781 error(GL_INVALID_ENUM);
3782 }
3783
3784 context->setOperand2RGB(iParam);
3785 break;
3786 case GL_OPERAND0_ALPHA:
3787 switch(iParam)
3788 {
3789 case GL_SRC_ALPHA:
3790 case GL_ONE_MINUS_SRC_ALPHA:
3791 break;
3792 default:
3793 error(GL_INVALID_ENUM);
3794 }
3795
3796 context->setOperand0Alpha(iParam);
3797 break;
3798 case GL_OPERAND1_ALPHA:
3799 switch(iParam)
3800 {
3801 case GL_SRC_ALPHA:
3802 case GL_ONE_MINUS_SRC_ALPHA:
3803 break;
3804 default:
3805 error(GL_INVALID_ENUM);
3806 }
3807
3808 context->setOperand1Alpha(iParam);
3809 break;
3810 case GL_OPERAND2_ALPHA:
3811 switch(iParam)
3812 {
3813 case GL_SRC_ALPHA:
3814 case GL_ONE_MINUS_SRC_ALPHA:
3815 break;
3816 default:
3817 error(GL_INVALID_ENUM);
3818 }
3819
3820 context->setOperand2Alpha(iParam);
3821 break;
3822 case GL_SRC0_RGB:
3823 switch(iParam)
3824 {
3825 case GL_TEXTURE:
3826 case GL_CONSTANT:
3827 case GL_PRIMARY_COLOR:
3828 case GL_PREVIOUS:
3829 break;
3830 default:
3831 error(GL_INVALID_ENUM);
3832 }
3833
3834 context->setSrc0RGB(iParam);
3835 break;
3836 case GL_SRC1_RGB:
3837 switch(iParam)
3838 {
3839 case GL_TEXTURE:
3840 case GL_CONSTANT:
3841 case GL_PRIMARY_COLOR:
3842 case GL_PREVIOUS:
3843 break;
3844 default:
3845 error(GL_INVALID_ENUM);
3846 }
3847
3848 context->setSrc1RGB(iParam);
3849 break;
3850 case GL_SRC2_RGB:
3851 switch(iParam)
3852 {
3853 case GL_TEXTURE:
3854 case GL_CONSTANT:
3855 case GL_PRIMARY_COLOR:
3856 case GL_PREVIOUS:
3857 break;
3858 default:
3859 error(GL_INVALID_ENUM);
3860 }
3861
3862 context->setSrc2RGB(iParam);
3863 break;
3864 case GL_SRC0_ALPHA:
3865 switch(iParam)
3866 {
3867 case GL_TEXTURE:
3868 case GL_CONSTANT:
3869 case GL_PRIMARY_COLOR:
3870 case GL_PREVIOUS:
3871 break;
3872 default:
3873 error(GL_INVALID_ENUM);
3874 }
3875
3876 context->setSrc0Alpha(iParam);
3877 break;
3878 case GL_SRC1_ALPHA:
3879 switch(iParam)
3880 {
3881 case GL_TEXTURE:
3882 case GL_CONSTANT:
3883 case GL_PRIMARY_COLOR:
3884 case GL_PREVIOUS:
3885 break;
3886 default:
3887 error(GL_INVALID_ENUM);
3888 }
3889
3890 context->setSrc1Alpha(iParam);
3891 break;
3892 case GL_SRC2_ALPHA:
3893 switch(iParam)
3894 {
3895 case GL_TEXTURE:
3896 case GL_CONSTANT:
3897 case GL_PRIMARY_COLOR:
3898 case GL_PREVIOUS:
3899 break;
3900 default:
3901 error(GL_INVALID_ENUM);
3902 }
3903
3904 context->setSrc2Alpha(iParam);
3905 break;
3906 default:
3907 return error(GL_INVALID_ENUM);
3908 }
3909 break;
3910 default:
3911 return error(GL_INVALID_ENUM);
3912 }
3913 }
3914 }
3915
TexEnvi(GLenum target,GLenum pname,GLint param)3916 void TexEnvi(GLenum target, GLenum pname, GLint param)
3917 {
3918 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
3919
3920 es1::Context *context = es1::getContext();
3921
3922 if(context)
3923 {
3924 switch(target)
3925 {
3926 case GL_POINT_SPRITE_OES:
3927 UNIMPLEMENTED();
3928 break;
3929 case GL_TEXTURE_ENV:
3930 switch(pname)
3931 {
3932 case GL_TEXTURE_ENV_MODE:
3933 switch((GLenum)param)
3934 {
3935 case GL_REPLACE:
3936 case GL_MODULATE:
3937 case GL_DECAL:
3938 case GL_BLEND:
3939 case GL_ADD:
3940 case GL_COMBINE:
3941 break;
3942 default:
3943 error(GL_INVALID_ENUM);
3944 }
3945
3946 context->setTextureEnvMode((GLenum)param);
3947 break;
3948 case GL_TEXTURE_ENV_COLOR:
3949 return error(GL_INVALID_ENUM); // Needs four values, should call glTexEnviv() instead
3950 break;
3951 case GL_COMBINE_RGB:
3952 switch((GLenum)param)
3953 {
3954 case GL_REPLACE:
3955 case GL_MODULATE:
3956 case GL_ADD:
3957 case GL_ADD_SIGNED:
3958 case GL_INTERPOLATE:
3959 case GL_SUBTRACT:
3960 case GL_DOT3_RGB:
3961 case GL_DOT3_RGBA:
3962 break;
3963 default:
3964 error(GL_INVALID_ENUM);
3965 }
3966
3967 context->setCombineRGB((GLenum)param);
3968 break;
3969 case GL_COMBINE_ALPHA:
3970 switch((GLenum)param)
3971 {
3972 case GL_REPLACE:
3973 case GL_MODULATE:
3974 case GL_ADD:
3975 case GL_ADD_SIGNED:
3976 case GL_INTERPOLATE:
3977 case GL_SUBTRACT:
3978 break;
3979 default:
3980 error(GL_INVALID_ENUM);
3981 }
3982
3983 context->setCombineAlpha((GLenum)param);
3984 break;
3985 case GL_RGB_SCALE:
3986 if(param != 1 && param != 2 && param != 4)
3987 {
3988 return error(GL_INVALID_VALUE);
3989 }
3990 if(param != 1) UNIMPLEMENTED();
3991 break;
3992 case GL_ALPHA_SCALE:
3993 if(param != 1 && param != 2 && param != 4)
3994 {
3995 return error(GL_INVALID_VALUE);
3996 }
3997 if(param != 1) UNIMPLEMENTED();
3998 break;
3999 case GL_OPERAND0_RGB:
4000 switch((GLenum)param)
4001 {
4002 case GL_SRC_COLOR:
4003 case GL_ONE_MINUS_SRC_COLOR:
4004 case GL_SRC_ALPHA:
4005 case GL_ONE_MINUS_SRC_ALPHA:
4006 break;
4007 default:
4008 error(GL_INVALID_ENUM);
4009 }
4010
4011 context->setOperand0RGB((GLenum)param);
4012 break;
4013 case GL_OPERAND1_RGB:
4014 switch((GLenum)param)
4015 {
4016 case GL_SRC_COLOR:
4017 case GL_ONE_MINUS_SRC_COLOR:
4018 case GL_SRC_ALPHA:
4019 case GL_ONE_MINUS_SRC_ALPHA:
4020 break;
4021 default:
4022 error(GL_INVALID_ENUM);
4023 }
4024
4025 context->setOperand1RGB((GLenum)param);
4026 break;
4027 case GL_OPERAND2_RGB:
4028 switch((GLenum)param)
4029 {
4030 case GL_SRC_COLOR:
4031 case GL_ONE_MINUS_SRC_COLOR:
4032 case GL_SRC_ALPHA:
4033 case GL_ONE_MINUS_SRC_ALPHA:
4034 break;
4035 default:
4036 error(GL_INVALID_ENUM);
4037 }
4038
4039 context->setOperand2RGB((GLenum)param);
4040 break;
4041 case GL_OPERAND0_ALPHA:
4042 switch((GLenum)param)
4043 {
4044 case GL_SRC_ALPHA:
4045 case GL_ONE_MINUS_SRC_ALPHA:
4046 break;
4047 default:
4048 error(GL_INVALID_ENUM);
4049 }
4050
4051 context->setOperand0Alpha((GLenum)param);
4052 break;
4053 case GL_OPERAND1_ALPHA:
4054 switch((GLenum)param)
4055 {
4056 case GL_SRC_ALPHA:
4057 case GL_ONE_MINUS_SRC_ALPHA:
4058 break;
4059 default:
4060 error(GL_INVALID_ENUM);
4061 }
4062
4063 context->setOperand1Alpha((GLenum)param);
4064 break;
4065 case GL_OPERAND2_ALPHA:
4066 switch((GLenum)param)
4067 {
4068 case GL_SRC_ALPHA:
4069 case GL_ONE_MINUS_SRC_ALPHA:
4070 break;
4071 default:
4072 error(GL_INVALID_ENUM);
4073 }
4074
4075 context->setOperand2Alpha((GLenum)param);
4076 break;
4077 case GL_SRC0_RGB:
4078 switch((GLenum)param)
4079 {
4080 case GL_TEXTURE:
4081 case GL_CONSTANT:
4082 case GL_PRIMARY_COLOR:
4083 case GL_PREVIOUS:
4084 break;
4085 default:
4086 error(GL_INVALID_ENUM);
4087 }
4088
4089 context->setSrc0RGB((GLenum)param);
4090 break;
4091 case GL_SRC1_RGB:
4092 switch((GLenum)param)
4093 {
4094 case GL_TEXTURE:
4095 case GL_CONSTANT:
4096 case GL_PRIMARY_COLOR:
4097 case GL_PREVIOUS:
4098 break;
4099 default:
4100 error(GL_INVALID_ENUM);
4101 }
4102
4103 context->setSrc1RGB((GLenum)param);
4104 break;
4105 case GL_SRC2_RGB:
4106 switch((GLenum)param)
4107 {
4108 case GL_TEXTURE:
4109 case GL_CONSTANT:
4110 case GL_PRIMARY_COLOR:
4111 case GL_PREVIOUS:
4112 break;
4113 default:
4114 error(GL_INVALID_ENUM);
4115 }
4116
4117 context->setSrc2RGB((GLenum)param);
4118 break;
4119 case GL_SRC0_ALPHA:
4120 switch((GLenum)param)
4121 {
4122 case GL_TEXTURE:
4123 case GL_CONSTANT:
4124 case GL_PRIMARY_COLOR:
4125 case GL_PREVIOUS:
4126 break;
4127 default:
4128 error(GL_INVALID_ENUM);
4129 }
4130
4131 context->setSrc0Alpha((GLenum)param);
4132 break;
4133 case GL_SRC1_ALPHA:
4134 switch((GLenum)param)
4135 {
4136 case GL_TEXTURE:
4137 case GL_CONSTANT:
4138 case GL_PRIMARY_COLOR:
4139 case GL_PREVIOUS:
4140 break;
4141 default:
4142 error(GL_INVALID_ENUM);
4143 }
4144
4145 context->setSrc1Alpha((GLenum)param);
4146 break;
4147 case GL_SRC2_ALPHA:
4148 switch((GLenum)param)
4149 {
4150 case GL_TEXTURE:
4151 case GL_CONSTANT:
4152 case GL_PRIMARY_COLOR:
4153 case GL_PREVIOUS:
4154 break;
4155 default:
4156 error(GL_INVALID_ENUM);
4157 }
4158
4159 context->setSrc2Alpha((GLenum)param);
4160 break;
4161 default:
4162 return error(GL_INVALID_ENUM);
4163 }
4164 break;
4165 default:
4166 return error(GL_INVALID_ENUM);
4167 }
4168 }
4169 }
4170
TexEnvx(GLenum target,GLenum pname,GLfixed param)4171 void TexEnvx(GLenum target, GLenum pname, GLfixed param)
4172 {
4173 TexEnvi(target, pname, (GLint)param);
4174 }
4175
TexEnviv(GLenum target,GLenum pname,const GLint * params)4176 void TexEnviv(GLenum target, GLenum pname, const GLint *params)
4177 {
4178 UNIMPLEMENTED();
4179 }
4180
TexEnvxv(GLenum target,GLenum pname,const GLfixed * params)4181 void TexEnvxv(GLenum target, GLenum pname, const GLfixed *params)
4182 {
4183 UNIMPLEMENTED();
4184 }
4185
TexImage2D(GLenum target,GLint level,GLint internalformat,GLsizei width,GLsizei height,GLint border,GLenum format,GLenum type,const GLvoid * pixels)4186 void TexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height,
4187 GLint border, GLenum format, GLenum type, const GLvoid* pixels)
4188 {
4189 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint internalformat = %d, GLsizei width = %d, GLsizei height = %d, "
4190 "GLint border = %d, GLenum format = 0x%X, GLenum type = 0x%X, const GLvoid* pixels = %p)",
4191 target, level, internalformat, width, height, border, format, type, pixels);
4192
4193 if(!validImageSize(level, width, height))
4194 {
4195 return error(GL_INVALID_VALUE);
4196 }
4197
4198 if(internalformat != (GLint)format)
4199 {
4200 return error(GL_INVALID_OPERATION);
4201 }
4202
4203 switch(format)
4204 {
4205 case GL_ALPHA:
4206 case GL_LUMINANCE:
4207 case GL_LUMINANCE_ALPHA:
4208 switch(type)
4209 {
4210 case GL_UNSIGNED_BYTE:
4211 break;
4212 default:
4213 return error(GL_INVALID_ENUM);
4214 }
4215 break;
4216 case GL_RGB:
4217 switch(type)
4218 {
4219 case GL_UNSIGNED_BYTE:
4220 case GL_UNSIGNED_SHORT_5_6_5:
4221 break;
4222 default:
4223 return error(GL_INVALID_ENUM);
4224 }
4225 break;
4226 case GL_RGBA:
4227 switch(type)
4228 {
4229 case GL_UNSIGNED_BYTE:
4230 case GL_UNSIGNED_SHORT_4_4_4_4:
4231 case GL_UNSIGNED_SHORT_5_5_5_1:
4232 break;
4233 default:
4234 return error(GL_INVALID_ENUM);
4235 }
4236 break;
4237 case GL_BGRA_EXT:
4238 switch(type)
4239 {
4240 case GL_UNSIGNED_BYTE:
4241 break;
4242 default:
4243 return error(GL_INVALID_ENUM);
4244 }
4245 break;
4246 case GL_ETC1_RGB8_OES:
4247 case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
4248 case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
4249 return error(GL_INVALID_OPERATION);
4250 case GL_DEPTH_STENCIL_OES:
4251 switch(type)
4252 {
4253 case GL_UNSIGNED_INT_24_8_OES:
4254 break;
4255 default:
4256 return error(GL_INVALID_ENUM);
4257 }
4258 break;
4259 default:
4260 return error(GL_INVALID_VALUE);
4261 }
4262
4263 if(border != 0)
4264 {
4265 return error(GL_INVALID_VALUE);
4266 }
4267
4268 GLint sizedInternalFormat = gl::GetSizedInternalFormat(internalformat, type);
4269
4270 es1::Context *context = es1::getContext();
4271
4272 if(context)
4273 {
4274 switch(target)
4275 {
4276 case GL_TEXTURE_2D:
4277 if(width > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level) ||
4278 height > (es1::IMPLEMENTATION_MAX_TEXTURE_SIZE >> level))
4279 {
4280 return error(GL_INVALID_VALUE);
4281 }
4282 break;
4283 default:
4284 return error(GL_INVALID_ENUM);
4285 }
4286
4287 if(target == GL_TEXTURE_2D)
4288 {
4289 es1::Texture2D *texture = context->getTexture2D();
4290
4291 if(!texture)
4292 {
4293 return error(GL_INVALID_OPERATION);
4294 }
4295
4296 texture->setImage(level, width, height, sizedInternalFormat, format, type, context->getUnpackAlignment(), pixels);
4297 }
4298 else UNREACHABLE(target);
4299 }
4300 }
4301
TexParameterf(GLenum target,GLenum pname,GLfloat param)4302 void TexParameterf(GLenum target, GLenum pname, GLfloat param)
4303 {
4304 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLfloat param = %f)", target, pname, param);
4305
4306 es1::Context *context = es1::getContext();
4307
4308 if(context)
4309 {
4310 es1::Texture *texture;
4311
4312 switch(target)
4313 {
4314 case GL_TEXTURE_2D:
4315 texture = context->getTexture2D();
4316 break;
4317 case GL_TEXTURE_EXTERNAL_OES:
4318 texture = context->getTextureExternal();
4319 break;
4320 default:
4321 return error(GL_INVALID_ENUM);
4322 }
4323
4324 switch(pname)
4325 {
4326 case GL_TEXTURE_WRAP_S:
4327 if(!texture->setWrapS((GLenum)param))
4328 {
4329 return error(GL_INVALID_ENUM);
4330 }
4331 break;
4332 case GL_TEXTURE_WRAP_T:
4333 if(!texture->setWrapT((GLenum)param))
4334 {
4335 return error(GL_INVALID_ENUM);
4336 }
4337 break;
4338 case GL_TEXTURE_MIN_FILTER:
4339 if(!texture->setMinFilter((GLenum)param))
4340 {
4341 return error(GL_INVALID_ENUM);
4342 }
4343 break;
4344 case GL_TEXTURE_MAG_FILTER:
4345 if(!texture->setMagFilter((GLenum)param))
4346 {
4347 return error(GL_INVALID_ENUM);
4348 }
4349 break;
4350 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4351 if(!texture->setMaxAnisotropy(param))
4352 {
4353 return error(GL_INVALID_VALUE);
4354 }
4355 break;
4356 case GL_GENERATE_MIPMAP:
4357 texture->setGenerateMipmap((GLboolean)param);
4358 break;
4359 case GL_TEXTURE_CROP_RECT_OES:
4360 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameterfv() instead
4361 default:
4362 return error(GL_INVALID_ENUM);
4363 }
4364 }
4365 }
4366
TexParameterfv(GLenum target,GLenum pname,const GLfloat * params)4367 void TexParameterfv(GLenum target, GLenum pname, const GLfloat* params)
4368 {
4369 TexParameterf(target, pname, *params);
4370 }
4371
TexParameteri(GLenum target,GLenum pname,GLint param)4372 void TexParameteri(GLenum target, GLenum pname, GLint param)
4373 {
4374 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %d)", target, pname, param);
4375
4376 es1::Context *context = es1::getContext();
4377
4378 if(context)
4379 {
4380 es1::Texture *texture;
4381
4382 switch(target)
4383 {
4384 case GL_TEXTURE_2D:
4385 texture = context->getTexture2D();
4386 break;
4387 case GL_TEXTURE_EXTERNAL_OES:
4388 texture = context->getTextureExternal();
4389 break;
4390 default:
4391 return error(GL_INVALID_ENUM);
4392 }
4393
4394 switch(pname)
4395 {
4396 case GL_TEXTURE_WRAP_S:
4397 if(!texture->setWrapS((GLenum)param))
4398 {
4399 return error(GL_INVALID_ENUM);
4400 }
4401 break;
4402 case GL_TEXTURE_WRAP_T:
4403 if(!texture->setWrapT((GLenum)param))
4404 {
4405 return error(GL_INVALID_ENUM);
4406 }
4407 break;
4408 case GL_TEXTURE_MIN_FILTER:
4409 if(!texture->setMinFilter((GLenum)param))
4410 {
4411 return error(GL_INVALID_ENUM);
4412 }
4413 break;
4414 case GL_TEXTURE_MAG_FILTER:
4415 if(!texture->setMagFilter((GLenum)param))
4416 {
4417 return error(GL_INVALID_ENUM);
4418 }
4419 break;
4420 case GL_TEXTURE_MAX_ANISOTROPY_EXT:
4421 if(!texture->setMaxAnisotropy((GLfloat)param))
4422 {
4423 return error(GL_INVALID_VALUE);
4424 }
4425 break;
4426 case GL_GENERATE_MIPMAP:
4427 texture->setGenerateMipmap((GLboolean)param);
4428 break;
4429 case GL_TEXTURE_CROP_RECT_OES:
4430 return error(GL_INVALID_ENUM); // Needs four values, should call glTexParameteriv() instead
4431 default:
4432 return error(GL_INVALID_ENUM);
4433 }
4434 }
4435 }
4436
TexParameteriv(GLenum target,GLenum pname,const GLint * params)4437 void TexParameteriv(GLenum target, GLenum pname, const GLint* params)
4438 {
4439 TRACE("(GLenum target = 0x%X, GLenum pname = 0x%X, GLint param = %p)", target, pname, params);
4440
4441 switch(pname)
4442 {
4443 case GL_TEXTURE_CROP_RECT_OES:
4444 break;
4445 default:
4446 return TexParameteri(target, pname, params[0]);
4447 }
4448
4449 es1::Context *context = es1::getContext();
4450
4451 if(context)
4452 {
4453 es1::Texture *texture;
4454
4455 switch(target)
4456 {
4457 case GL_TEXTURE_2D:
4458 texture = context->getTexture2D();
4459 break;
4460 default:
4461 return error(GL_INVALID_ENUM);
4462 }
4463
4464 switch(pname)
4465 {
4466 case GL_TEXTURE_CROP_RECT_OES:
4467 texture->setCropRect(params[0], params[1], params[2], params[3]);
4468 break;
4469 default:
4470 return error(GL_INVALID_ENUM);
4471 }
4472 }
4473 }
4474
TexParameterx(GLenum target,GLenum pname,GLfixed param)4475 void TexParameterx(GLenum target, GLenum pname, GLfixed param)
4476 {
4477 TexParameteri(target, pname, (GLint)param);
4478 }
4479
TexParameterxv(GLenum target,GLenum pname,const GLfixed * params)4480 void TexParameterxv(GLenum target, GLenum pname, const GLfixed *params)
4481 {
4482 UNIMPLEMENTED();
4483 }
4484
TexSubImage2D(GLenum target,GLint level,GLint xoffset,GLint yoffset,GLsizei width,GLsizei height,GLenum format,GLenum type,const GLvoid * pixels)4485 void TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
4486 GLenum format, GLenum type, const GLvoid* pixels)
4487 {
4488 TRACE("(GLenum target = 0x%X, GLint level = %d, GLint xoffset = %d, GLint yoffset = %d, "
4489 "GLsizei width = %d, GLsizei height = %d, GLenum format = 0x%X, GLenum type = 0x%X, "
4490 "const GLvoid* pixels = %p)",
4491 target, level, xoffset, yoffset, width, height, format, type, pixels);
4492
4493 if(!es1::IsTextureTarget(target))
4494 {
4495 return error(GL_INVALID_ENUM);
4496 }
4497
4498 if(level < 0 || level >= es1::IMPLEMENTATION_MAX_TEXTURE_LEVELS)
4499 {
4500 return error(GL_INVALID_VALUE);
4501 }
4502
4503 if(xoffset < 0 || yoffset < 0 || width < 0 || height < 0)
4504 {
4505 return error(GL_INVALID_VALUE);
4506 }
4507
4508 if(std::numeric_limits<GLsizei>::max() - xoffset < width || std::numeric_limits<GLsizei>::max() - yoffset < height)
4509 {
4510 return error(GL_INVALID_VALUE);
4511 }
4512
4513 if(width == 0 || height == 0 || !pixels)
4514 {
4515 return;
4516 }
4517
4518 es1::Context *context = es1::getContext();
4519
4520 if(context)
4521 {
4522 if(target == GL_TEXTURE_2D)
4523 {
4524 es1::Texture2D *texture = context->getTexture2D();
4525
4526 GLenum validationError = ValidateSubImageParams(false, false, target, level, xoffset, yoffset, width, height, format, type, texture);
4527 if(validationError != GL_NO_ERROR)
4528 {
4529 return error(validationError);
4530 }
4531
4532 texture->subImage(level, xoffset, yoffset, width, height, format, type, context->getUnpackAlignment(), pixels);
4533 }
4534 else UNREACHABLE(target);
4535 }
4536 }
4537
Translatef(GLfloat x,GLfloat y,GLfloat z)4538 void Translatef(GLfloat x, GLfloat y, GLfloat z)
4539 {
4540 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f)", x, y, z);
4541
4542 es1::Context *context = es1::getContext();
4543
4544 if(context)
4545 {
4546 context->translate(x, y, z);
4547 }
4548 }
4549
Translatex(GLfixed x,GLfixed y,GLfixed z)4550 void Translatex(GLfixed x, GLfixed y, GLfixed z)
4551 {
4552 Translatef((float)x / 0x10000, (float)y / 0x10000, (float)z / 0x10000);
4553 }
4554
VertexPointer(GLint size,GLenum type,GLsizei stride,const GLvoid * pointer)4555 void VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer)
4556 {
4557 TRACE("(GLint size = %d, GLenum type = 0x%X, GLsizei stride = %d, const GLvoid *pointer = %p)", size, type, stride, pointer);
4558
4559 if(size < 2 || size > 4)
4560 {
4561 return error(GL_INVALID_VALUE);
4562 }
4563
4564 VertexAttribPointer(sw::Position, size, type, false, stride, pointer);
4565 }
4566
Viewport(GLint x,GLint y,GLsizei width,GLsizei height)4567 void Viewport(GLint x, GLint y, GLsizei width, GLsizei height)
4568 {
4569 TRACE("(GLint x = %d, GLint y = %d, GLsizei width = %d, GLsizei height = %d)", x, y, width, height);
4570
4571 if(width < 0 || height < 0)
4572 {
4573 return error(GL_INVALID_VALUE);
4574 }
4575
4576 es1::Context *context = es1::getContext();
4577
4578 if(context)
4579 {
4580 context->setViewportParams(x, y, width, height);
4581 }
4582 }
4583
EGLImageTargetTexture2DOES(GLenum target,GLeglImageOES image)4584 void EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image)
4585 {
4586 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4587
4588 switch(target)
4589 {
4590 case GL_TEXTURE_2D:
4591 case GL_TEXTURE_EXTERNAL_OES:
4592 break;
4593 default:
4594 return error(GL_INVALID_ENUM);
4595 }
4596
4597 es1::Context *context = es1::getContext();
4598
4599 if(context)
4600 {
4601 es1::Texture2D *texture = nullptr;
4602
4603 switch(target)
4604 {
4605 case GL_TEXTURE_2D: texture = context->getTexture2D(); break;
4606 case GL_TEXTURE_EXTERNAL_OES: texture = context->getTextureExternal(); break;
4607 default: UNREACHABLE(target);
4608 }
4609
4610 if(!texture)
4611 {
4612 return error(GL_INVALID_OPERATION);
4613 }
4614
4615 egl::Image *eglImage = context->getSharedImage(image);
4616
4617 if(!eglImage)
4618 {
4619 return error(GL_INVALID_OPERATION);
4620 }
4621
4622 texture->setSharedImage(eglImage);
4623 }
4624 }
4625
EGLImageTargetRenderbufferStorageOES(GLenum target,GLeglImageOES image)4626 void EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image)
4627 {
4628 TRACE("(GLenum target = 0x%X, GLeglImageOES image = %p)", target, image);
4629
4630 UNIMPLEMENTED();
4631 }
4632
DrawTexsOES(GLshort x,GLshort y,GLshort z,GLshort width,GLshort height)4633 void DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height)
4634 {
4635 UNIMPLEMENTED();
4636 }
4637
DrawTexiOES(GLint x,GLint y,GLint z,GLint width,GLint height)4638 void DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
4639 {
4640 TRACE("(GLint x = %d, GLint y = %d, GLint z = %d, GLint width = %d, GLint height = %d)", x, y, z, width, height);
4641
4642 if(width <= 0 || height <= 0)
4643 {
4644 return error(GL_INVALID_VALUE);
4645 }
4646
4647 es1::Context *context = es1::getContext();
4648
4649 if(context)
4650 {
4651 context->drawTexture((GLfloat)x, (GLfloat)y, (GLfloat)z, (GLfloat)width, (GLfloat)height);
4652 }
4653 }
4654
DrawTexxOES(GLfixed x,GLfixed y,GLfixed z,GLfixed width,GLfixed height)4655 void DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height)
4656 {
4657 UNIMPLEMENTED();
4658 }
4659
DrawTexsvOES(const GLshort * coords)4660 void DrawTexsvOES(const GLshort *coords)
4661 {
4662 UNIMPLEMENTED();
4663 }
4664
DrawTexivOES(const GLint * coords)4665 void DrawTexivOES(const GLint *coords)
4666 {
4667 UNIMPLEMENTED();
4668 }
4669
DrawTexxvOES(const GLfixed * coords)4670 void DrawTexxvOES(const GLfixed *coords)
4671 {
4672 UNIMPLEMENTED();
4673 }
4674
DrawTexfOES(GLfloat x,GLfloat y,GLfloat z,GLfloat width,GLfloat height)4675 void DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height)
4676 {
4677 TRACE("(GLfloat x = %f, GLfloat y = %f, GLfloat z = %f, GLfloat width = %f, GLfloat height = %f)", x, y, z, width, height);
4678
4679 if(width <= 0 || height <= 0)
4680 {
4681 return error(GL_INVALID_VALUE);
4682 }
4683
4684 es1::Context *context = es1::getContext();
4685
4686 if(context)
4687 {
4688 context->drawTexture(x, y, z, width, height);
4689 }
4690 }
4691
DrawTexfvOES(const GLfloat * coords)4692 void DrawTexfvOES(const GLfloat *coords)
4693 {
4694 UNIMPLEMENTED();
4695 }
4696
4697 }
4698
es1GetProcAddress(const char * procname)4699 extern "C" __eglMustCastToProperFunctionPointerType es1GetProcAddress(const char *procname)
4700 {
4701 struct Function
4702 {
4703 const char *name;
4704 __eglMustCastToProperFunctionPointerType address;
4705 };
4706
4707 struct CompareFunctor
4708 {
4709 bool operator()(const Function &a, const Function &b) const
4710 {
4711 return strcmp(a.name, b.name) < 0;
4712 }
4713 };
4714
4715 // This array must be kept sorted with respect to strcmp(), so that binary search works correctly.
4716 // The Unix command "LC_COLLATE=C sort" will generate the correct order.
4717 static const Function glFunctions[] =
4718 {
4719 #define FUNCTION(name) {#name, (__eglMustCastToProperFunctionPointerType)name}
4720
4721 FUNCTION(glActiveTexture),
4722 FUNCTION(glAlphaFunc),
4723 FUNCTION(glAlphaFuncx),
4724 FUNCTION(glBindBuffer),
4725 FUNCTION(glBindFramebufferOES),
4726 FUNCTION(glBindRenderbufferOES),
4727 FUNCTION(glBindTexture),
4728 FUNCTION(glBlendEquationOES),
4729 FUNCTION(glBlendEquationSeparateOES),
4730 FUNCTION(glBlendFunc),
4731 FUNCTION(glBlendFuncSeparateOES),
4732 FUNCTION(glBufferData),
4733 FUNCTION(glBufferSubData),
4734 FUNCTION(glCheckFramebufferStatusOES),
4735 FUNCTION(glClear),
4736 FUNCTION(glClearColor),
4737 FUNCTION(glClearColorx),
4738 FUNCTION(glClearDepthf),
4739 FUNCTION(glClearDepthx),
4740 FUNCTION(glClearStencil),
4741 FUNCTION(glClientActiveTexture),
4742 FUNCTION(glClipPlanef),
4743 FUNCTION(glClipPlanex),
4744 FUNCTION(glColor4f),
4745 FUNCTION(glColor4ub),
4746 FUNCTION(glColor4x),
4747 FUNCTION(glColorMask),
4748 FUNCTION(glColorPointer),
4749 FUNCTION(glCompressedTexImage2D),
4750 FUNCTION(glCompressedTexSubImage2D),
4751 FUNCTION(glCopyTexImage2D),
4752 FUNCTION(glCopyTexSubImage2D),
4753 FUNCTION(glCullFace),
4754 FUNCTION(glDeleteBuffers),
4755 FUNCTION(glDeleteFramebuffersOES),
4756 FUNCTION(glDeleteRenderbuffersOES),
4757 FUNCTION(glDeleteTextures),
4758 FUNCTION(glDepthFunc),
4759 FUNCTION(glDepthMask),
4760 FUNCTION(glDepthRangef),
4761 FUNCTION(glDepthRangex),
4762 FUNCTION(glDisable),
4763 FUNCTION(glDisableClientState),
4764 FUNCTION(glDrawArrays),
4765 FUNCTION(glDrawElements),
4766 FUNCTION(glDrawTexfOES),
4767 FUNCTION(glDrawTexfvOES),
4768 FUNCTION(glDrawTexiOES),
4769 FUNCTION(glDrawTexivOES),
4770 FUNCTION(glDrawTexsOES),
4771 FUNCTION(glDrawTexsvOES),
4772 FUNCTION(glDrawTexxOES),
4773 FUNCTION(glDrawTexxvOES),
4774 FUNCTION(glEGLImageTargetRenderbufferStorageOES),
4775 FUNCTION(glEGLImageTargetTexture2DOES),
4776 FUNCTION(glEnable),
4777 FUNCTION(glEnableClientState),
4778 FUNCTION(glFinish),
4779 FUNCTION(glFlush),
4780 FUNCTION(glFogf),
4781 FUNCTION(glFogfv),
4782 FUNCTION(glFogx),
4783 FUNCTION(glFogxv),
4784 FUNCTION(glFramebufferRenderbufferOES),
4785 FUNCTION(glFramebufferTexture2DOES),
4786 FUNCTION(glFrontFace),
4787 FUNCTION(glFrustumf),
4788 FUNCTION(glFrustumx),
4789 FUNCTION(glGenBuffers),
4790 FUNCTION(glGenFramebuffersOES),
4791 FUNCTION(glGenRenderbuffersOES),
4792 FUNCTION(glGenTextures),
4793 FUNCTION(glGenerateMipmapOES),
4794 FUNCTION(glGetBooleanv),
4795 FUNCTION(glGetBufferParameteriv),
4796 FUNCTION(glGetClipPlanef),
4797 FUNCTION(glGetClipPlanex),
4798 FUNCTION(glGetError),
4799 FUNCTION(glGetFixedv),
4800 FUNCTION(glGetFloatv),
4801 FUNCTION(glGetFramebufferAttachmentParameterivOES),
4802 FUNCTION(glGetIntegerv),
4803 FUNCTION(glGetLightfv),
4804 FUNCTION(glGetLightxv),
4805 FUNCTION(glGetMaterialfv),
4806 FUNCTION(glGetMaterialxv),
4807 FUNCTION(glGetPointerv),
4808 FUNCTION(glGetRenderbufferParameterivOES),
4809 FUNCTION(glGetString),
4810 FUNCTION(glGetTexEnvfv),
4811 FUNCTION(glGetTexEnviv),
4812 FUNCTION(glGetTexEnvxv),
4813 FUNCTION(glGetTexParameterfv),
4814 FUNCTION(glGetTexParameteriv),
4815 FUNCTION(glGetTexParameterxv),
4816 FUNCTION(glHint),
4817 FUNCTION(glIsBuffer),
4818 FUNCTION(glIsEnabled),
4819 FUNCTION(glIsFramebufferOES),
4820 FUNCTION(glIsRenderbufferOES),
4821 FUNCTION(glIsTexture),
4822 FUNCTION(glLightModelf),
4823 FUNCTION(glLightModelfv),
4824 FUNCTION(glLightModelx),
4825 FUNCTION(glLightModelxv),
4826 FUNCTION(glLightf),
4827 FUNCTION(glLightfv),
4828 FUNCTION(glLightx),
4829 FUNCTION(glLightxv),
4830 FUNCTION(glLineWidth),
4831 FUNCTION(glLineWidthx),
4832 FUNCTION(glLoadIdentity),
4833 FUNCTION(glLoadMatrixf),
4834 FUNCTION(glLoadMatrixx),
4835 FUNCTION(glLogicOp),
4836 FUNCTION(glMaterialf),
4837 FUNCTION(glMaterialfv),
4838 FUNCTION(glMaterialx),
4839 FUNCTION(glMaterialxv),
4840 FUNCTION(glMatrixMode),
4841 FUNCTION(glMultMatrixf),
4842 FUNCTION(glMultMatrixx),
4843 FUNCTION(glMultiTexCoord4f),
4844 FUNCTION(glMultiTexCoord4x),
4845 FUNCTION(glNormal3f),
4846 FUNCTION(glNormal3x),
4847 FUNCTION(glNormalPointer),
4848 FUNCTION(glOrthof),
4849 FUNCTION(glOrthox),
4850 FUNCTION(glPixelStorei),
4851 FUNCTION(glPointParameterf),
4852 FUNCTION(glPointParameterfv),
4853 FUNCTION(glPointParameterx),
4854 FUNCTION(glPointParameterxv),
4855 FUNCTION(glPointSize),
4856 FUNCTION(glPointSizePointerOES),
4857 FUNCTION(glPointSizex),
4858 FUNCTION(glPolygonOffset),
4859 FUNCTION(glPolygonOffsetx),
4860 FUNCTION(glPopMatrix),
4861 FUNCTION(glPushMatrix),
4862 FUNCTION(glReadPixels),
4863 FUNCTION(glRenderbufferStorageOES),
4864 FUNCTION(glRotatef),
4865 FUNCTION(glRotatex),
4866 FUNCTION(glSampleCoverage),
4867 FUNCTION(glSampleCoveragex),
4868 FUNCTION(glScalef),
4869 FUNCTION(glScalex),
4870 FUNCTION(glScissor),
4871 FUNCTION(glShadeModel),
4872 FUNCTION(glStencilFunc),
4873 FUNCTION(glStencilMask),
4874 FUNCTION(glStencilOp),
4875 FUNCTION(glTexCoordPointer),
4876 FUNCTION(glTexEnvf),
4877 FUNCTION(glTexEnvfv),
4878 FUNCTION(glTexEnvi),
4879 FUNCTION(glTexEnviv),
4880 FUNCTION(glTexEnvx),
4881 FUNCTION(glTexEnvxv),
4882 FUNCTION(glTexImage2D),
4883 FUNCTION(glTexParameterf),
4884 FUNCTION(glTexParameterfv),
4885 FUNCTION(glTexParameteri),
4886 FUNCTION(glTexParameteriv),
4887 FUNCTION(glTexParameterx),
4888 FUNCTION(glTexParameterxv),
4889 FUNCTION(glTexSubImage2D),
4890 FUNCTION(glTranslatef),
4891 FUNCTION(glTranslatex),
4892 FUNCTION(glVertexPointer),
4893 FUNCTION(glViewport),
4894
4895 #undef FUNCTION
4896 };
4897
4898 static const size_t numFunctions = sizeof glFunctions / sizeof(Function);
4899 static const Function *const glFunctionsEnd = glFunctions + numFunctions;
4900
4901 Function needle;
4902 needle.name = procname;
4903
4904 if(procname && strncmp("gl", procname, 2) == 0)
4905 {
4906 const Function *result = std::lower_bound(glFunctions, glFunctionsEnd, needle, CompareFunctor());
4907 if(result != glFunctionsEnd && strcmp(procname, result->name) == 0)
4908 {
4909 return (__eglMustCastToProperFunctionPointerType)result->address;
4910 }
4911 }
4912
4913 return nullptr;
4914 }
4915