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