• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libs/opengles/state.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #include <stdlib.h>
19 
20 #include "context.h"
21 #include "fp.h"
22 #include "state.h"
23 #include "array.h"
24 #include "matrix.h"
25 #include "vertex.h"
26 #include "light.h"
27 #include "texture.h"
28 #include "BufferObjectManager.h"
29 #include "TextureObjectManager.h"
30 
31 #ifdef LIBAGL_USE_GRALLOC_COPYBITS
32 #include <hardware/copybit.h>
33 #endif // LIBAGL_USE_GRALLOC_COPYBITS
34 
35 namespace android {
36 
37 // ----------------------------------------------------------------------------
38 
39 static char const * const gVendorString     = "Android";
40 static char const * const gRendererString   = "Android PixelFlinger 1.2";
41 static char const * const gVersionString    = "OpenGL ES-CM 1.0";
42 static char const * const gExtensionsString =
43     "GL_OES_byte_coordinates "              // OK
44     "GL_OES_fixed_point "                   // OK
45     "GL_OES_single_precision "              // OK
46     "GL_OES_read_format "                   // OK
47     "GL_OES_compressed_paletted_texture "   // OK
48     "GL_OES_draw_texture "                  // OK
49     "GL_OES_matrix_get "                    // OK
50     "GL_OES_query_matrix "                  // OK
51     //        "GL_OES_point_size_array "              // TODO
52     //        "GL_OES_point_sprite "                  // TODO
53     "GL_OES_EGL_image "                     // OK
54     "GL_ARB_texture_compression "           // OK
55     "GL_ARB_texture_non_power_of_two "      // OK
56     "GL_ANDROID_user_clip_plane "           // OK
57     "GL_ANDROID_vertex_buffer_object "      // OK
58     "GL_ANDROID_generate_mipmap "           // OK
59     ;
60 
61 // ----------------------------------------------------------------------------
62 #if 0
63 #pragma mark -
64 #endif
65 
ogles_init(size_t extra)66 ogles_context_t *ogles_init(size_t extra)
67 {
68     void* const base = malloc(extra + sizeof(ogles_context_t) + 32);
69     if (!base) return 0;
70 
71     ogles_context_t *c =
72             (ogles_context_t *)((ptrdiff_t(base) + extra + 31) & ~0x1FL);
73     memset(c, 0, sizeof(ogles_context_t));
74     ggl_init_context(&(c->rasterizer));
75 
76     // XXX: this should be passed as an argument
77     sp<EGLSurfaceManager> smgr(new EGLSurfaceManager());
78     c->surfaceManager = smgr.get();
79     c->surfaceManager->incStrong(c);
80 
81     sp<EGLBufferObjectManager> bomgr(new EGLBufferObjectManager());
82     c->bufferObjectManager = bomgr.get();
83     c->bufferObjectManager->incStrong(c);
84 
85     ogles_init_array(c);
86     ogles_init_matrix(c);
87     ogles_init_vertex(c);
88     ogles_init_light(c);
89     ogles_init_texture(c);
90 
91     c->rasterizer.base = base;
92     c->point.size = TRI_ONE;
93     c->line.width = TRI_ONE;
94 
95     // in OpenGL, writing to the depth buffer is enabled by default.
96     c->rasterizer.procs.depthMask(c, 1);
97 
98     // OpenGL enables dithering by default
99     c->rasterizer.procs.enable(c, GL_DITHER);
100 
101     c->copybits.blitEngine = NULL;
102     c->copybits.minScale = 0;
103     c->copybits.maxScale = 0;
104     c->copybits.drawSurfaceBuffer = 0;
105 
106 #ifdef LIBAGL_USE_GRALLOC_COPYBITS
107     hw_module_t const* module;
108     if (hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module) == 0) {
109         struct copybit_device_t* copyBits;
110         if (copybit_open(module, &copyBits) == 0) {
111             c->copybits.blitEngine = copyBits;
112             {
113                 int minLim = copyBits->get(copyBits,
114                         COPYBIT_MINIFICATION_LIMIT);
115                 if (minLim != -EINVAL && minLim > 0) {
116                     c->copybits.minScale = (1 << 16) / minLim;
117                 }
118             }
119             {
120                 int magLim = copyBits->get(copyBits,
121                         COPYBIT_MAGNIFICATION_LIMIT);
122                 if (magLim != -EINVAL && magLim > 0) {
123                     c->copybits.maxScale = min(32*1024-1, magLim) << 16;
124                 }
125             }
126         }
127     }
128 #endif // LIBAGL_USE_GRALLOC_COPYBITS
129 
130     return c;
131 }
132 
ogles_uninit(ogles_context_t * c)133 void ogles_uninit(ogles_context_t* c)
134 {
135     ogles_uninit_array(c);
136     ogles_uninit_matrix(c);
137     ogles_uninit_vertex(c);
138     ogles_uninit_light(c);
139     ogles_uninit_texture(c);
140     c->surfaceManager->decStrong(c);
141     c->bufferObjectManager->decStrong(c);
142     ggl_uninit_context(&(c->rasterizer));
143     free(c->rasterizer.base);
144 #ifdef LIBAGL_USE_GRALLOC_COPYBITS
145     if (c->copybits.blitEngine != NULL) {
146         copybit_close((struct copybit_device_t*) c->copybits.blitEngine);
147     }
148 #endif // LIBAGL_USE_GRALLOC_COPYBITS
149 }
150 
_ogles_error(ogles_context_t * c,GLenum error)151 void _ogles_error(ogles_context_t* c, GLenum error)
152 {
153     if (c->error == GL_NO_ERROR)
154         c->error = error;
155 }
156 
stencilop_valid(GLenum op)157 static bool stencilop_valid(GLenum op) {
158     switch (op) {
159     case GL_KEEP:
160     case GL_ZERO:
161     case GL_REPLACE:
162     case GL_INCR:
163     case GL_DECR:
164     case GL_INVERT:
165         return true;
166     }
167     return false;
168 }
169 
enable_disable(ogles_context_t * c,GLenum cap,int enabled)170 static void enable_disable(ogles_context_t* c, GLenum cap, int enabled)
171 {
172     if ((cap >= GL_LIGHT0) && (cap<GL_LIGHT0+OGLES_MAX_LIGHTS)) {
173         c->lighting.lights[cap-GL_LIGHT0].enable = enabled;
174         c->lighting.enabledLights &= ~(1<<(cap-GL_LIGHT0));
175         c->lighting.enabledLights |= (enabled<<(cap-GL_LIGHT0));
176         return;
177     }
178 
179     switch (cap) {
180     case GL_POINT_SMOOTH:
181         c->point.smooth = enabled;
182         break;
183     case GL_LINE_SMOOTH:
184         c->line.smooth = enabled;
185         break;
186     case GL_POLYGON_OFFSET_FILL:
187         c->polygonOffset.enable = enabled;
188         break;
189     case GL_CULL_FACE:
190         c->cull.enable = enabled;
191         break;
192     case GL_LIGHTING:
193         c->lighting.enable = enabled;
194         break;
195     case GL_COLOR_MATERIAL:
196         c->lighting.colorMaterial.enable = enabled;
197         break;
198     case GL_NORMALIZE:
199     case GL_RESCALE_NORMAL:
200         c->transforms.rescaleNormals = enabled ? cap : 0;
201         // XXX: invalidate mvit
202         break;
203 
204     case GL_CLIP_PLANE0:
205     case GL_CLIP_PLANE1:
206     case GL_CLIP_PLANE2:
207     case GL_CLIP_PLANE3:
208     case GL_CLIP_PLANE4:
209     case GL_CLIP_PLANE5:
210         c->clipPlanes.enable &= ~(1<<(cap-GL_CLIP_PLANE0));
211         c->clipPlanes.enable |= (enabled<<(cap-GL_CLIP_PLANE0));
212         ogles_invalidate_perspective(c);
213         break;
214 
215     case GL_FOG:
216     case GL_DEPTH_TEST:
217         ogles_invalidate_perspective(c);
218         // fall-through...
219     case GL_BLEND:
220     case GL_SCISSOR_TEST:
221     case GL_ALPHA_TEST:
222     case GL_COLOR_LOGIC_OP:
223     case GL_DITHER:
224     case GL_STENCIL_TEST:
225     case GL_TEXTURE_2D:
226         // these need to fall through into the rasterizer
227         c->rasterizer.procs.enableDisable(c, cap, enabled);
228         break;
229 
230     case GL_MULTISAMPLE:
231     case GL_SAMPLE_ALPHA_TO_COVERAGE:
232     case GL_SAMPLE_ALPHA_TO_ONE:
233     case GL_SAMPLE_COVERAGE:
234         // not supported in this implementation
235         break;
236 
237     default:
238         ogles_error(c, GL_INVALID_ENUM);
239         return;
240     }
241 }
242 
243 // ----------------------------------------------------------------------------
244 }; // namespace android
245 // ----------------------------------------------------------------------------
246 using namespace android;
247 
248 #if 0
249 #pragma mark -
250 #endif
251 
252 // These ones are super-easy, we're not supporting those features!
glSampleCoverage(GLclampf value,GLboolean invert)253 void glSampleCoverage(GLclampf value, GLboolean invert) {
254 }
glSampleCoveragex(GLclampx value,GLboolean invert)255 void glSampleCoveragex(GLclampx value, GLboolean invert) {
256 }
glStencilFunc(GLenum func,GLint ref,GLuint mask)257 void glStencilFunc(GLenum func, GLint ref, GLuint mask) {
258     ogles_context_t* c = ogles_context_t::get();
259     if (func < GL_NEVER || func > GL_ALWAYS) {
260         ogles_error(c, GL_INVALID_ENUM);
261         return;
262     }
263     // from OpenGL|ES 1.0 sepcification:
264     // If there is no stencil buffer, no stencil modification can occur
265     // and it is as if the stencil test always passes.
266 }
267 
glStencilOp(GLenum fail,GLenum zfail,GLenum zpass)268 void glStencilOp(GLenum fail, GLenum zfail, GLenum zpass) {
269     ogles_context_t* c = ogles_context_t::get();
270     if ((stencilop_valid(fail) &
271          stencilop_valid(zfail) &
272          stencilop_valid(zpass)) == 0) {
273         ogles_error(c, GL_INVALID_ENUM);
274         return;
275     }
276 }
277 
278 // ----------------------------------------------------------------------------
279 
glAlphaFunc(GLenum func,GLclampf ref)280 void glAlphaFunc(GLenum func, GLclampf ref)
281 {
282     glAlphaFuncx(func, gglFloatToFixed(ref));
283 }
284 
glCullFace(GLenum mode)285 void glCullFace(GLenum mode)
286 {
287     ogles_context_t* c = ogles_context_t::get();
288     switch (mode) {
289     case GL_FRONT:
290     case GL_BACK:
291     case GL_FRONT_AND_BACK:
292         break;
293     default:
294         ogles_error(c, GL_INVALID_ENUM);
295     }
296     c->cull.cullFace = mode;
297 }
298 
glFrontFace(GLenum mode)299 void glFrontFace(GLenum mode)
300 {
301     ogles_context_t* c = ogles_context_t::get();
302     switch (mode) {
303     case GL_CW:
304     case GL_CCW:
305         break;
306     default:
307         ogles_error(c, GL_INVALID_ENUM);
308         return;
309     }
310     c->cull.frontFace = mode;
311 }
312 
glHint(GLenum target,GLenum mode)313 void glHint(GLenum target, GLenum mode)
314 {
315     ogles_context_t* c = ogles_context_t::get();
316     switch (target) {
317     case GL_FOG_HINT:
318     case GL_GENERATE_MIPMAP_HINT:
319     case GL_LINE_SMOOTH_HINT:
320         break;
321     case GL_POINT_SMOOTH_HINT:
322         c->rasterizer.procs.enableDisable(c,
323                 GGL_POINT_SMOOTH_NICE, mode==GL_NICEST);
324         break;
325     case GL_PERSPECTIVE_CORRECTION_HINT:
326         c->perspective = (mode == GL_NICEST) ? 1 : 0;
327         break;
328     default:
329         ogles_error(c, GL_INVALID_ENUM);
330     }
331 }
332 
glEnable(GLenum cap)333 void glEnable(GLenum cap) {
334     ogles_context_t* c = ogles_context_t::get();
335     enable_disable(c, cap, 1);
336 }
glDisable(GLenum cap)337 void glDisable(GLenum cap) {
338     ogles_context_t* c = ogles_context_t::get();
339     enable_disable(c, cap, 0);
340 }
341 
glFinish()342 void glFinish()
343 { // nothing to do for our software implementation
344 }
345 
glFlush()346 void glFlush()
347 { // nothing to do for our software implementation
348 }
349 
glGetError()350 GLenum glGetError()
351 {
352     // From OpenGL|ES 1.0 specification:
353     // If more than one flag has recorded an error, glGetError returns
354     // and clears an arbitrary error flag value. Thus, glGetError should
355     // always be called in a loop, until it returns GL_NO_ERROR,
356     // if all error flags are to be reset.
357 
358     ogles_context_t* c = ogles_context_t::get();
359     if (c->error) {
360         const GLenum ret(c->error);
361         c->error = 0;
362         return ret;
363     }
364 
365     if (c->rasterizer.error) {
366         const GLenum ret(c->rasterizer.error);
367         c->rasterizer.error = 0;
368         return ret;
369     }
370 
371     return GL_NO_ERROR;
372 }
373 
glGetString(GLenum string)374 const GLubyte* glGetString(GLenum string)
375 {
376     switch (string) {
377     case GL_VENDOR:     return (const GLubyte*)gVendorString;
378     case GL_RENDERER:   return (const GLubyte*)gRendererString;
379     case GL_VERSION:    return (const GLubyte*)gVersionString;
380     case GL_EXTENSIONS: return (const GLubyte*)gExtensionsString;
381     }
382     ogles_context_t* c = ogles_context_t::get();
383     ogles_error(c, GL_INVALID_ENUM);
384     return 0;
385 }
386 
glGetIntegerv(GLenum pname,GLint * params)387 void glGetIntegerv(GLenum pname, GLint *params)
388 {
389     ogles_context_t* c = ogles_context_t::get();
390     switch (pname) {
391     case GL_ALIASED_POINT_SIZE_RANGE:
392         params[0] = 0;
393         params[1] = GGL_MAX_ALIASED_POINT_SIZE;
394         break;
395     case GL_ALIASED_LINE_WIDTH_RANGE:
396         params[0] = 0;
397         params[1] = GGL_MAX_ALIASED_POINT_SIZE;
398         break;
399     case GL_ALPHA_BITS: {
400         int index = c->rasterizer.state.buffers.color.format;
401         GGLFormat const * formats = gglGetPixelFormatTable();
402         params[0] = formats[index].ah - formats[index].al;
403         break;
404         }
405     case GL_RED_BITS: {
406         int index = c->rasterizer.state.buffers.color.format;
407         GGLFormat const * formats = gglGetPixelFormatTable();
408         params[0] = formats[index].rh - formats[index].rl;
409         break;
410         }
411     case GL_GREEN_BITS: {
412         int index = c->rasterizer.state.buffers.color.format;
413         GGLFormat const * formats = gglGetPixelFormatTable();
414         params[0] = formats[index].gh - formats[index].gl;
415         break;
416         }
417     case GL_BLUE_BITS: {
418         int index = c->rasterizer.state.buffers.color.format;
419         GGLFormat const * formats = gglGetPixelFormatTable();
420         params[0] = formats[index].bh - formats[index].bl;
421         break;
422         }
423     case GL_COMPRESSED_TEXTURE_FORMATS:
424         params[ 0] = GL_PALETTE4_RGB8_OES;
425         params[ 1] = GL_PALETTE4_RGBA8_OES;
426         params[ 2] = GL_PALETTE4_R5_G6_B5_OES;
427         params[ 3] = GL_PALETTE4_RGBA4_OES;
428         params[ 4] = GL_PALETTE4_RGB5_A1_OES;
429         params[ 5] = GL_PALETTE8_RGB8_OES;
430         params[ 6] = GL_PALETTE8_RGBA8_OES;
431         params[ 7] = GL_PALETTE8_R5_G6_B5_OES;
432         params[ 8] = GL_PALETTE8_RGBA4_OES;
433         params[ 9] = GL_PALETTE8_RGB5_A1_OES;
434         break;
435     case GL_DEPTH_BITS:
436         params[0] = c->rasterizer.state.buffers.depth.format ? 0 : 16;
437         break;
438     case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
439         params[0] = GL_RGB;
440         break;
441     case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
442         params[0] = GL_UNSIGNED_SHORT_5_6_5;
443         break;
444     case GL_MAX_LIGHTS:
445         params[0] = OGLES_MAX_LIGHTS;
446         break;
447     case GL_MAX_CLIP_PLANES:
448         params[0] = OGLES_MAX_CLIP_PLANES;
449         break;
450     case GL_MAX_MODELVIEW_STACK_DEPTH:
451         params[0] = OGLES_MODELVIEW_STACK_DEPTH;
452         break;
453     case GL_MAX_PROJECTION_STACK_DEPTH:
454         params[0] = OGLES_PROJECTION_STACK_DEPTH;
455         break;
456     case GL_MAX_TEXTURE_STACK_DEPTH:
457         params[0] = OGLES_TEXTURE_STACK_DEPTH;
458         break;
459     case GL_MAX_TEXTURE_SIZE:
460         params[0] = GGL_MAX_TEXTURE_SIZE;
461         break;
462     case GL_MAX_TEXTURE_UNITS:
463         params[0] = GGL_TEXTURE_UNIT_COUNT;
464         break;
465     case GL_MAX_VIEWPORT_DIMS:
466         params[0] = GGL_MAX_VIEWPORT_DIMS;
467         params[1] = GGL_MAX_VIEWPORT_DIMS;
468         break;
469     case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
470         params[0] = OGLES_NUM_COMPRESSED_TEXTURE_FORMATS;
471         break;
472     case GL_SMOOTH_LINE_WIDTH_RANGE:
473         params[0] = 0;
474         params[1] = GGL_MAX_SMOOTH_LINE_WIDTH;
475         break;
476     case GL_SMOOTH_POINT_SIZE_RANGE:
477         params[0] = 0;
478         params[1] = GGL_MAX_SMOOTH_POINT_SIZE;
479         break;
480     case GL_STENCIL_BITS:
481         params[0] = 0;
482         break;
483     case GL_SUBPIXEL_BITS:
484         params[0] = GGL_SUBPIXEL_BITS;
485         break;
486 
487     case GL_MODELVIEW_MATRIX_FLOAT_AS_INT_BITS_OES:
488         memcpy( params,
489                 c->transforms.modelview.top().elements(),
490                 16*sizeof(GLint));
491         break;
492     case GL_PROJECTION_MATRIX_FLOAT_AS_INT_BITS_OES:
493         memcpy( params,
494                 c->transforms.projection.top().elements(),
495                 16*sizeof(GLint));
496         break;
497     case GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES:
498         memcpy( params,
499                 c->transforms.texture[c->textures.active].top().elements(),
500                 16*sizeof(GLint));
501         break;
502 
503     default:
504         ogles_error(c, GL_INVALID_ENUM);
505         break;
506     }
507 }
508 
509 // ----------------------------------------------------------------------------
510 
glPointSize(GLfloat size)511 void glPointSize(GLfloat size)
512 {
513     ogles_context_t* c = ogles_context_t::get();
514     if (size <= 0) {
515         ogles_error(c, GL_INVALID_ENUM);
516         return;
517     }
518     c->point.size = TRI_FROM_FIXED(gglFloatToFixed(size));
519 }
520 
glPointSizex(GLfixed size)521 void glPointSizex(GLfixed size)
522 {
523     ogles_context_t* c = ogles_context_t::get();
524     if (size <= 0) {
525         ogles_error(c, GL_INVALID_ENUM);
526         return;
527     }
528     c->point.size = TRI_FROM_FIXED(size);
529 }
530 
531 // ----------------------------------------------------------------------------
532 
glLineWidth(GLfloat width)533 void glLineWidth(GLfloat width)
534 {
535     ogles_context_t* c = ogles_context_t::get();
536     if (width <= 0) {
537         ogles_error(c, GL_INVALID_ENUM);
538         return;
539     }
540     c->line.width = TRI_FROM_FIXED(gglFloatToFixed(width));
541 }
542 
glLineWidthx(GLfixed width)543 void glLineWidthx(GLfixed width)
544 {
545     ogles_context_t* c = ogles_context_t::get();
546     if (width <= 0) {
547         ogles_error(c, GL_INVALID_ENUM);
548         return;
549     }
550     c->line.width = TRI_FROM_FIXED(width);
551 }
552 
553 // ----------------------------------------------------------------------------
554 
glColorMask(GLboolean r,GLboolean g,GLboolean b,GLboolean a)555 void glColorMask(GLboolean r, GLboolean g, GLboolean b, GLboolean a) {
556     ogles_context_t* c = ogles_context_t::get();
557     c->rasterizer.procs.colorMask(c, r, g, b, a);
558 }
559 
glDepthMask(GLboolean flag)560 void glDepthMask(GLboolean flag) {
561     ogles_context_t* c = ogles_context_t::get();
562     c->rasterizer.procs.depthMask(c, flag);
563 }
564 
glStencilMask(GLuint mask)565 void glStencilMask(GLuint mask) {
566     ogles_context_t* c = ogles_context_t::get();
567     c->rasterizer.procs.stencilMask(c, mask);
568 }
569 
glDepthFunc(GLenum func)570 void glDepthFunc(GLenum func) {
571     ogles_context_t* c = ogles_context_t::get();
572     c->rasterizer.procs.depthFunc(c, func);
573 }
574 
glLogicOp(GLenum opcode)575 void glLogicOp(GLenum opcode) {
576     ogles_context_t* c = ogles_context_t::get();
577     c->rasterizer.procs.logicOp(c, opcode);
578 }
579 
glAlphaFuncx(GLenum func,GLclampx ref)580 void glAlphaFuncx(GLenum func, GLclampx ref) {
581     ogles_context_t* c = ogles_context_t::get();
582     c->rasterizer.procs.alphaFuncx(c, func, ref);
583 }
584 
glBlendFunc(GLenum sfactor,GLenum dfactor)585 void glBlendFunc(GLenum sfactor, GLenum dfactor) {
586     ogles_context_t* c = ogles_context_t::get();
587     c->rasterizer.procs.blendFunc(c, sfactor, dfactor);
588 }
589 
glClear(GLbitfield mask)590 void glClear(GLbitfield mask) {
591     ogles_context_t* c = ogles_context_t::get();
592     c->rasterizer.procs.clear(c, mask);
593 }
594 
glClearColorx(GLclampx red,GLclampx green,GLclampx blue,GLclampx alpha)595 void glClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha) {
596     ogles_context_t* c = ogles_context_t::get();
597     c->rasterizer.procs.clearColorx(c, red, green, blue, alpha);
598 }
599 
glClearColor(GLclampf r,GLclampf g,GLclampf b,GLclampf a)600 void glClearColor(GLclampf r, GLclampf g, GLclampf b, GLclampf a)
601 {
602     ogles_context_t* c = ogles_context_t::get();
603     c->rasterizer.procs.clearColorx(c,
604                     gglFloatToFixed(r),
605                     gglFloatToFixed(g),
606                     gglFloatToFixed(b),
607                     gglFloatToFixed(a));
608 }
609 
glClearDepthx(GLclampx depth)610 void glClearDepthx(GLclampx depth) {
611     ogles_context_t* c = ogles_context_t::get();
612     c->rasterizer.procs.clearDepthx(c, depth);
613 }
614 
glClearDepthf(GLclampf depth)615 void glClearDepthf(GLclampf depth)
616 {
617     ogles_context_t* c = ogles_context_t::get();
618     c->rasterizer.procs.clearDepthx(c, gglFloatToFixed(depth));
619 }
620 
glClearStencil(GLint s)621 void glClearStencil(GLint s) {
622     ogles_context_t* c = ogles_context_t::get();
623     c->rasterizer.procs.clearStencil(c, s);
624 }
625