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