diff --git a/project/jni/glshim/Android.mk b/project/jni/glshim/Android.mk index fde2529be..a69303515 100644 --- a/project/jni/glshim/Android.mk +++ b/project/jni/glshim/Android.mk @@ -30,6 +30,7 @@ LOCAL_SRC_FILES := \ src/gl/list.c \ src/gl/loader.c \ src/gl/pixel.c \ + src/gl/queries.c \ src/gl/raster.c \ src/gl/render.c \ src/gl/stack.c \ diff --git a/project/jni/glshim/README.md b/project/jni/glshim/README.md index 36722a404..e80823e62 100755 --- a/project/jni/glshim/README.md +++ b/project/jni/glshim/README.md @@ -183,3 +183,18 @@ Debug: Hide or Show the Sub / Not found message * 0 : Default, the messages are shown * 1 : Silent, don't print the STUB or glXGetProcAddress glXXXXX not found message +##### LIBGL_NOBANNER +Show/Hide initial text + * 0 : Default, print starting message + * 1 : Silent: no LIBGL message at start (combile with LIBGL_SILENTSTUB for more silence) + +##### LIBGL_NPOT +Expose NPOT (Non Power of Two) Support + * 0 : Default, don't expose the extension (but npot are still supported) + * 1 : Expose limited NPOT extension + * 2 : Expose GL_ARB_texture_non_power_of_two extension + +##### LIBGL_QUERIES +Expose glQueries functions + * 0 : Default, don't expose the function (fake one will be used if called) + * 1 : Expose fake functions (always answer 0) diff --git a/project/jni/glshim/src/gl/array.c b/project/jni/glshim/src/gl/array.c index 06ce7bd63..f1447a144 100755 --- a/project/jni/glshim/src/gl/array.c +++ b/project/jni/glshim/src/gl/array.c @@ -238,35 +238,30 @@ GLvoid *copy_gl_array_convert(const GLvoid *src, return dst; } -GLvoid *copy_gl_pointer(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff) { +GLvoid *copy_gl_pointer(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 0.0f; - uintptr_t buffer = (buff)?(uintptr_t)buff->data:0; - return copy_gl_array_convert(ptr->pointer+buffer, ptr->type, ptr->size, ptr->stride, + return copy_gl_array_convert(ptr->pointer, ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler); } -GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff) { +GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 1.0f; - uintptr_t buffer = (buff)?(uintptr_t)buff->data:0; - return copy_gl_array_convert(ptr->pointer+buffer, ptr->type, ptr->size, ptr->stride, + return copy_gl_array_convert(ptr->pointer, ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler); } -GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff) { +GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { GLubyte filler = 255; - uintptr_t buffer = (buff)?(uintptr_t)buff->data:0; - return copy_gl_array_convert(ptr->pointer+buffer, ptr->type, ptr->size, ptr->stride, + return copy_gl_array_convert(ptr->pointer, ptr->type, ptr->size, ptr->stride, GL_UNSIGNED_BYTE, width, skip, count, &filler); } -GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff) { - uintptr_t buffer = (buff)?(uintptr_t)buff->data:0; - return copy_gl_array(ptr->pointer+buffer, ptr->type, ptr->size, ptr->stride, +GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { + return copy_gl_array(ptr->pointer, ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count); } -GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff) { +GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count) { float filler = 1.0f; - uintptr_t buffer = (buff)?(uintptr_t)buff->data:0; - return copy_gl_array_texcoord(ptr->pointer+buffer, ptr->type, ptr->size, ptr->stride, + return copy_gl_array_texcoord(ptr->pointer, ptr->type, ptr->size, ptr->stride, GL_FLOAT, width, skip, count, &filler); } @@ -274,8 +269,7 @@ GLfloat *gl_pointer_index(pointer_state_t *p, GLint index) { static GLfloat buf[4]; GLsizei size = gl_sizeof(p->type); GLsizei stride = p->stride ? p->stride : (size * p->size); - uintptr_t ptr = (uintptr_t)(p->pointer) + (stride * index) - + (uintptr_t)((glstate.vao->vertex)?glstate.vao->vertex->data:0); + uintptr_t ptr = (uintptr_t)(p->pointer) + (stride * index); GL_TYPE_SWITCH(src, ptr, p->type, for (int i = 0; i < p->size; i++) { diff --git a/project/jni/glshim/src/gl/array.h b/project/jni/glshim/src/gl/array.h index 672bdbd86..b0c685502 100755 --- a/project/jni/glshim/src/gl/array.h +++ b/project/jni/glshim/src/gl/array.h @@ -13,11 +13,11 @@ GLvoid *copy_gl_array_convert(const GLvoid *src, GLenum from, GLsizei width, GLsizei stride, GLenum to, GLsizei to_width, GLsizei skip, GLsizei count, GLvoid* filler); -GLvoid *copy_gl_pointer(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff); -GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff); -GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff); -GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff); -GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count, glbuffer_t *buff); +GLvoid *copy_gl_pointer(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); +GLvoid *copy_gl_pointer_color(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); +GLvoid *copy_gl_pointer_bytecolor(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); +GLvoid *copy_gl_pointer_raw(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); +GLvoid *copy_gl_pointer_tex(pointer_state_t *ptr, GLsizei width, GLsizei skip, GLsizei count); GLfloat *gl_pointer_index(pointer_state_t *ptr, GLint index); GLfloat *copy_eval_double(GLenum target, GLint ustride, GLint uorder, GLint vstride, GLint vorder, const GLdouble *points); void normalize_indices(GLushort *indices, GLsizei *max, GLsizei *min, GLsizei count); diff --git a/project/jni/glshim/src/gl/buffers.c b/project/jni/glshim/src/gl/buffers.c index 3956dca67..c467df44f 100755 --- a/project/jni/glshim/src/gl/buffers.c +++ b/project/jni/glshim/src/gl/buffers.c @@ -8,16 +8,16 @@ static GLuint lastbuffer = 1; glbuffer_t** BUFF(GLenum target) { switch(target) { case GL_ARRAY_BUFFER: - return &glstate.vao->vertex; + return &glstate->vao->vertex; break; case GL_ELEMENT_ARRAY_BUFFER: - return &glstate.vao->elements; + return &glstate->vao->elements; break; case GL_PIXEL_PACK_BUFFER: - return &glstate.vao->pack; + return &glstate->vao->pack; break; case GL_PIXEL_UNPACK_BUFFER: - return &glstate.vao->unpack; + return &glstate->vao->unpack; break; default: printf("LIBGL: Warning, unknown buffer target 0x%04X\n", target); @@ -68,15 +68,15 @@ void glshim_glGenBuffers(GLsizei n, GLuint * buffers) { void glshim_glBindBuffer(GLenum target, GLuint buffer) { //printf("glBindBuffer(%s, %u)\n", PrintEnum(target), buffer); - if (glstate.gl_batch) { + if (glstate->gl_batch) { flush(); } khint_t k; int ret; - khash_t(buff) *list = glstate.buffers; + khash_t(buff) *list = glstate->buffers; if (! list) { - list = glstate.buffers = kh_init(buff); + list = glstate->buffers = kh_init(buff); // segfaults if we don't do a single put kh_put(buff, list, 1, &ret); kh_del(buff, list, 1); @@ -153,11 +153,11 @@ void glshim_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, con void glshim_glDeleteBuffers(GLsizei n, const GLuint * buffers) { //printf("glDeleteBuffers(%i, %p)\n", n, buffers); - if (glstate.gl_batch) { + if (glstate->gl_batch) { flush(); } - khash_t(buff) *list = glstate.buffers; + khash_t(buff) *list = glstate->buffers; if (list) { khint_t k; glbuffer_t *buff; @@ -167,14 +167,14 @@ void glshim_glDeleteBuffers(GLsizei n, const GLuint * buffers) { k = kh_get(buff, list, t); if (k != kh_end(list)) { buff = kh_value(list, k); - if (glstate.vao->vertex == buff) - glstate.vao->vertex = NULL; - if (glstate.vao->elements == buff) - glstate.vao->elements = NULL; - if (glstate.vao->pack == buff) - glstate.vao->pack = NULL; - if (glstate.vao->unpack == buff) - glstate.vao->unpack = NULL; + if (glstate->vao->vertex == buff) + glstate->vao->vertex = NULL; + if (glstate->vao->elements == buff) + glstate->vao->elements = NULL; + if (glstate->vao->pack == buff) + glstate->vao->pack = NULL; + if (glstate->vao->unpack == buff) + glstate->vao->unpack = NULL; if (buff->data) free(buff->data); kh_del(buff, list, k); free(buff); @@ -187,7 +187,7 @@ void glshim_glDeleteBuffers(GLsizei n, const GLuint * buffers) { GLboolean glshim_glIsBuffer(GLuint buffer) { //printf("glIsBuffer(%u)\n", buffer); - khash_t(buff) *list = glstate.buffers; + khash_t(buff) *list = glstate->buffers; khint_t k; noerrorShim(); if (list) { @@ -349,15 +349,15 @@ void glshim_glGenVertexArrays(GLsizei n, GLuint *arrays) { } void glshim_glBindVertexArray(GLuint array) { //printf("glBindVertexArray(%u)\n", array); - if (glstate.gl_batch) { + if (glstate->gl_batch) { flush(); } khint_t k; int ret; - khash_t(glvao) *list = glstate.vaos; + khash_t(glvao) *list = glstate->vaos; if (! list) { - list = glstate.vaos = kh_init(glvao); + list = glstate->vaos = kh_init(glvao); // segfaults if we don't do a single put kh_put(glvao, list, 1, &ret); kh_del(glvao, list, 1); @@ -365,7 +365,7 @@ void glshim_glBindVertexArray(GLuint array) { // if array = 0 => unbind buffer! if (array == 0) { // unbind buffer - glstate.vao = glstate.defaultvao; + glstate->vao = glstate->defaultvao; } else { // search for an existing buffer k = kh_get(glvao, list, array); @@ -376,10 +376,10 @@ void glshim_glBindVertexArray(GLuint array) { // new vao is binded to nothing memset(glvao, 0, sizeof(glvao_t)); /* - glstate.vao->vertex = glstate.defaultvbo; - glstate.vao->elements = glstate.defaultvbo; - glstate.vao->pack = glstate.defaultvbo; - glstate.vao->unpack = glstate.defaultvbo; + glstate->vao->vertex = glstate->defaultvbo; + glstate->vao->elements = glstate->defaultvbo; + glstate->vao->pack = glstate->defaultvbo; + glstate->vao->unpack = glstate->defaultvbo; */ // just put is number @@ -387,16 +387,16 @@ void glshim_glBindVertexArray(GLuint array) { } else { glvao = kh_value(list, k); } - glstate.vao = glvao; + glstate->vao = glvao; } noerrorShim(); } void glshim_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { //printf("glDeleteVertexArrays(%i, %p)\n", n, arrays); - if (glstate.gl_batch) { + if (glstate->gl_batch) { flush(); } - khash_t(glvao) *list = glstate.vaos; + khash_t(glvao) *list = glstate->vaos; if (list) { khint_t k; glvao_t *glvao; @@ -416,7 +416,7 @@ void glshim_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { } GLboolean glshim_glIsVertexArray(GLuint array) { //printf("glIsVertexArray(%u)\n", array); - khash_t(glvao) *list = glstate.vaos; + khash_t(glvao) *list = glstate->vaos; khint_t k; noerrorShim(); if (list) { diff --git a/project/jni/glshim/src/gl/buffers.h b/project/jni/glshim/src/gl/buffers.h index 98e664753..c70429359 100755 --- a/project/jni/glshim/src/gl/buffers.h +++ b/project/jni/glshim/src/gl/buffers.h @@ -58,7 +58,6 @@ typedef struct { GLint size; GLenum type; GLsizei stride; - glbuffer_t *buffer; const GLvoid *pointer; } pointer_state_t; diff --git a/project/jni/glshim/src/gl/debug.c b/project/jni/glshim/src/gl/debug.c index baa1c3c15..f64fbd4d0 100755 --- a/project/jni/glshim/src/gl/debug.c +++ b/project/jni/glshim/src/gl/debug.c @@ -111,6 +111,16 @@ const char* PrintEnum(GLenum what) { p(GL_QUADS); p(GL_QUAD_STRIP); p(GL_POLYGON); + // texgen + p(GL_S); + p(GL_T); + p(GL_Q); + p(GL_TEXTURE_GEN_MODE); + p(GL_OBJECT_LINEAR); + p(GL_EYE_LINEAR); + p(GL_SPHERE_MAP); + p(GL_NORMAL_MAP); + p(GL_REFLECTION_MAP); default: sprintf(fallback, "0x%04X", what); } diff --git a/project/jni/glshim/src/gl/directstate.c b/project/jni/glshim/src/gl/directstate.c index 4919a499f..765e2e7f8 100755 --- a/project/jni/glshim/src/gl/directstate.c +++ b/project/jni/glshim/src/gl/directstate.c @@ -19,7 +19,7 @@ void glshim_glClientAttribDefault(GLbitfield mask) { else glshim_glDisableClientState(pname) if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { - int client = glstate.texture.client; + int client = glstate->texture.client; enable_disable(GL_VERTEX_ARRAY, false); enable_disable(GL_NORMAL_ARRAY, false); @@ -30,7 +30,7 @@ void glshim_glClientAttribDefault(GLbitfield mask) { enable_disable(GL_TEXTURE_COORD_ARRAY, false); } #undef enable_disable - if (glstate.texture.client != client) glshim_glClientActiveTexture(GL_TEXTURE0+client); + if (glstate->texture.client != client) glshim_glClientActiveTexture(GL_TEXTURE0+client); } } void glshim_glPushClientAttribDefault(GLbitfield mask) { @@ -197,12 +197,12 @@ void glshim_glGetCompressedTextureImage(GLuint texture, GLenum target, GLint lev #undef text #define text(f) \ - GLenum old_tex = glstate.texture.active; \ + GLenum old_tex = glstate->texture.active; \ if(texunit != old_tex) glshim_glActiveTexture(texunit); \ glshim_##f; \ if(texunit != old_tex) glshim_glActiveTexture(old_tex) #define texc(f) \ - GLenum old_tex = glstate.texture.client; \ + GLenum old_tex = glstate->texture.client; \ if(texunit != old_tex) glshim_glClientActiveTexture(texunit); \ glshim_##f; \ if(texunit != old_tex) glshim_glClientActiveTexture(old_tex) diff --git a/project/jni/glshim/src/gl/eval.c b/project/jni/glshim/src/gl/eval.c index 4026317f2..347cc0d40 100755 --- a/project/jni/glshim/src/gl/eval.c +++ b/project/jni/glshim/src/gl/eval.c @@ -6,22 +6,22 @@ static inline map_state_t **get_map_pointer(GLenum target) { switch (target) { - case GL_MAP1_COLOR_4: return &glstate.map1.color4; - case GL_MAP1_INDEX: return &glstate.map1.index; - case GL_MAP1_TEXTURE_COORD_1: return &glstate.map1.texture1; - case GL_MAP1_TEXTURE_COORD_2: return &glstate.map1.texture2; - case GL_MAP1_TEXTURE_COORD_3: return &glstate.map1.texture3; - case GL_MAP1_TEXTURE_COORD_4: return &glstate.map1.texture4; - case GL_MAP1_VERTEX_3: return &glstate.map1.vertex3; - case GL_MAP1_VERTEX_4: return &glstate.map1.vertex4; - case GL_MAP2_COLOR_4: return &glstate.map2.color4; - case GL_MAP2_INDEX: return &glstate.map2.index; - case GL_MAP2_TEXTURE_COORD_1: return &glstate.map2.texture1; - case GL_MAP2_TEXTURE_COORD_2: return &glstate.map2.texture2; - case GL_MAP2_TEXTURE_COORD_3: return &glstate.map2.texture3; - case GL_MAP2_TEXTURE_COORD_4: return &glstate.map2.texture4; - case GL_MAP2_VERTEX_3: return &glstate.map2.vertex3; - case GL_MAP2_VERTEX_4: return &glstate.map2.vertex4; + case GL_MAP1_COLOR_4: return &glstate->map1.color4; + case GL_MAP1_INDEX: return &glstate->map1.index; + case GL_MAP1_TEXTURE_COORD_1: return &glstate->map1.texture1; + case GL_MAP1_TEXTURE_COORD_2: return &glstate->map1.texture2; + case GL_MAP1_TEXTURE_COORD_3: return &glstate->map1.texture3; + case GL_MAP1_TEXTURE_COORD_4: return &glstate->map1.texture4; + case GL_MAP1_VERTEX_3: return &glstate->map1.vertex3; + case GL_MAP1_VERTEX_4: return &glstate->map1.vertex4; + case GL_MAP2_COLOR_4: return &glstate->map2.color4; + case GL_MAP2_INDEX: return &glstate->map2.index; + case GL_MAP2_TEXTURE_COORD_1: return &glstate->map2.texture1; + case GL_MAP2_TEXTURE_COORD_2: return &glstate->map2.texture2; + case GL_MAP2_TEXTURE_COORD_3: return &glstate->map2.texture3; + case GL_MAP2_TEXTURE_COORD_4: return &glstate->map2.texture4; + case GL_MAP2_VERTEX_3: return &glstate->map2.vertex3; + case GL_MAP2_VERTEX_4: return &glstate->map2.vertex4; default: printf("libGL: unknown glMap target 0x%x\n", target); } @@ -38,13 +38,13 @@ static inline map_state_t **get_map_pointer(GLenum target) { #define case_state(dims, magic, name) \ case magic: { \ map->width = get_map_width(magic); \ - map_statef_t *m = (map_statef_t *)glstate.map##dims.name; \ + map_statef_t *m = (map_statef_t *)glstate->map##dims.name; \ if (m) { \ if (m->free) \ free((void *)m->points); \ free(m); \ } \ - glstate.map##dims.name = (map_state_t *)map; \ + glstate->map##dims.name = (map_state_t *)map; \ break; \ } @@ -110,7 +110,7 @@ void glshim_glMap2f(GLenum target, GLfloat u1, GLfloat u2, #undef map_switch #define p_map(d, name, func, code) { \ - map_state_t *_map = glstate.map##d.name; \ + map_state_t *_map = glstate->map##d.name; \ if (_map) { \ if (_map->type == GL_DOUBLE) { \ map_stated_t *map = (map_stated_t *)_map; \ @@ -161,10 +161,10 @@ void glshim_glMapGrid1f(GLint un, GLfloat u1, GLfloat u2) { noerrorShim(); // TODO: double support? map_statef_t *map; - if (! glstate.map_grid) - glstate.map_grid = malloc(sizeof(map_statef_t)); + if (! glstate->map_grid) + glstate->map_grid = malloc(sizeof(map_statef_t)); - map = (map_statef_t *)glstate.map_grid; + map = (map_statef_t *)glstate->map_grid; map->dims = 1; map->u.n = un; map->u._1 = u1; @@ -176,10 +176,10 @@ void glshim_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, noerrorShim(); // TODO: double support? map_statef_t *map; - if (! glstate.map_grid) - glstate.map_grid = malloc(sizeof(map_statef_t)); + if (! glstate->map_grid) + glstate->map_grid = malloc(sizeof(map_statef_t)); - map = (map_statef_t *)glstate.map_grid; + map = (map_statef_t *)glstate->map_grid; map->dims = 2; map->u.n = un; map->u._1 = u1; @@ -190,10 +190,10 @@ void glshim_glMapGrid2f(GLint un, GLfloat u1, GLfloat u2, } static inline GLenum eval_mesh_prep(map_statef_t **map, GLenum mode) { - if (glstate.map2.vertex4) { - *map = (map_statef_t *)glstate.map2.vertex4; - } else if (glstate.map2.vertex3) { - *map = (map_statef_t *)glstate.map2.vertex3; + if (glstate->map2.vertex4) { + *map = (map_statef_t *)glstate->map2.vertex4; + } else if (glstate->map2.vertex3) { + *map = (map_statef_t *)glstate->map2.vertex3; } else { return 0; } diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index 4028673bd..70d1aa601 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -70,7 +70,7 @@ void glshim_glGenFramebuffers(GLsizei n, GLuint *ids) { void glshim_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { //printf("glDeleteFramebuffers(%i, %p), framebuffers[0]=%u\n", n, framebuffers, framebuffers[0]); - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); if (g_recyclefbo) { //printf("Recycling %i FBOs\n", n); noerrorShim(); @@ -93,7 +93,7 @@ void glshim_glDeleteFramebuffers(GLsizei n, GLuint *framebuffers) { GLboolean glshim_glIsFramebuffer(GLuint framebuffer) { //printf("glIsFramebuffer(%u)\n", framebuffer); - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glIsFramebuffer); errorGL(); @@ -103,7 +103,7 @@ GLboolean glshim_glIsFramebuffer(GLuint framebuffer) { GLenum fb_status; GLenum glshim_glCheckFramebufferStatus(GLenum target) { - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); //#define BEFORE 1 #ifdef BEFORE GLenum result = fb_status; @@ -120,9 +120,9 @@ GLenum glshim_glCheckFramebufferStatus(GLenum target) { } void glshim_glBindFramebuffer(GLenum target, GLuint framebuffer) { - //printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, glstate.list.active?"active":"none"); + //printf("glBindFramebuffer(%s, %u), list=%s\n", PrintEnum(target), framebuffer, glstate->list.active?"active":"none"); //PUSH_IF_COMPILING(glBindFramebuffer); - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glBindFramebuffer); LOAD_GLES_OES(glCheckFramebufferStatus); LOAD_GLES(glGetError); @@ -169,7 +169,7 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text static int scrap_width = 0; static int scrap_height = 0; - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glFramebufferTexture2D); LOAD_GLES(glTexImage2D); LOAD_GLES(glBindTexture); @@ -187,9 +187,9 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text gltexture_t *tex = NULL; int ret; khint_t k; - khash_t(tex) *list = glstate.texture.list; + khash_t(tex) *list = glstate->texture.list; if (! list) { - list = glstate.texture.list = kh_init(tex); + list = glstate->texture.list = kh_init(tex); // segfaults if we don't do a single put kh_put(tex, list, 1, &ret); kh_del(tex, list, 1); @@ -209,7 +209,7 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text tex->nwidth = npot(tex->width); tex->nheight = npot(tex->height); tex->shrink = 0; - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); @@ -222,7 +222,7 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text tex->nwidth = (tex->nwidth<32)?32:tex->nwidth; tex->nheight = (tex->nheight<32)?32:tex->nheight; tex->shrink = 0; - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); @@ -257,7 +257,7 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text if ((scrap_width!=twidth) || (scrap_height!=theight)) { scrap_width = twidth; scrap_height = theight; - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=scrap_tex) gles_glBindTexture(GL_TEXTURE_2D, scrap_tex); gles_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, scrap_width, scrap_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); @@ -321,7 +321,7 @@ void glshim_glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum r } void glshim_glDeleteRenderbuffers(GLsizei n, GLuint *renderbuffers) { - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glDeleteRenderbuffers); // check if we delete a depthstencil @@ -398,7 +398,7 @@ void glshim_glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLe } void glshim_glBindRenderbuffer(GLenum target, GLuint renderbuffer) { - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glBindRenderbuffer); //printf("glBindRenderbuffer(%s, %u), binded Fbo=%u\n", PrintEnum(target), renderbuffer, current_fb); @@ -410,7 +410,7 @@ void glshim_glBindRenderbuffer(GLenum target, GLuint renderbuffer) { GLboolean glshim_glIsRenderbuffer(GLuint renderbuffer) { //printf("glIsRenderbuffer(%u)\n", renderbuffer); - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES_OES(glIsRenderbuffer); errorGL(); @@ -474,9 +474,9 @@ void createMainFBO(int width, int height) { deleteMainFBO(); } // switch to texture unit 0 if needed - if (glstate.texture.active != 0) + if (glstate->texture.active != 0) gles_glActiveTexture(GL_TEXTURE0); - if (glstate.texture.client != 0) + if (glstate->texture.client != 0) gles_glClientActiveTexture(GL_TEXTURE0); mainfbo_width = width; @@ -536,12 +536,12 @@ void createMainFBO(int width, int height) { gles_glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } // Put everything back, and active the MainFBO - if (glstate.texture.bound[0]) - gles_glBindTexture(GL_TEXTURE_2D, glstate.texture.bound[0]->glname); - if (glstate.texture.active != 0) - gles_glActiveTexture(GL_TEXTURE0 + glstate.texture.active); - if (glstate.texture.client != 0) - gles_glClientActiveTexture(GL_TEXTURE0 + glstate.texture.client); + if (glstate->texture.bound[0]) + gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0]->glname); + if (glstate->texture.active != 0) + gles_glActiveTexture(GL_TEXTURE0 + glstate->texture.active); + if (glstate->texture.client != 0) + gles_glClientActiveTexture(GL_TEXTURE0 + glstate->texture.client); } @@ -561,11 +561,11 @@ void blitMainFBO() { return; // switch to texture unit 0 if needed - int old_tex = glstate.texture.active; - int old_client = glstate.texture.client; - if (glstate.texture.active != 0) + int old_tex = glstate->texture.active; + int old_client = glstate->texture.client; + if (glstate->texture.active != 0) glshim_glActiveTexture(GL_TEXTURE0); - if (glstate.texture.client != 0) + if (glstate->texture.client != 0) glshim_glClientActiveTexture(GL_TEXTURE0); // bind the FBO texture gles_glEnable(GL_TEXTURE_2D); @@ -625,29 +625,29 @@ void blitMainFBO() { // glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - if(!glstate.clientstate.vertex_array) { + if(!glstate->clientstate.vertex_array) { gles_glEnableClientState(GL_VERTEX_ARRAY); - glstate.clientstate.vertex_array = 1; + glstate->clientstate.vertex_array = 1; } gles_glVertexPointer(2, GL_FLOAT, 0, vert); - if(!glstate.clientstate.tex_coord_array[0]) { + if(!glstate->clientstate.tex_coord_array[0]) { gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[0] = 1; + glstate->clientstate.tex_coord_array[0] = 1; } gles_glTexCoordPointer(2, GL_FLOAT, 0, tex); for (int a=1; a clientstate.tex_coord_array[a]) { glshim_glClientActiveTexture(GL_TEXTURE0 + a); gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[a] = 0; + glstate->clientstate.tex_coord_array[a] = 0; } - if(glstate.clientstate.color_array) { + if(glstate->clientstate.color_array) { gles_glDisableClientState(GL_COLOR_ARRAY); - glstate.clientstate.color_array = 0; + glstate->clientstate.color_array = 0; } - if(glstate.clientstate.normal_array) { + if(glstate->clientstate.normal_array) { gles_glDisableClientState(GL_NORMAL_ARRAY); - glstate.clientstate.normal_array = 0; + glstate->clientstate.normal_array = 0; } @@ -668,11 +668,11 @@ void blitMainFBO() { // put back viewport gles_glViewport(old_vp[0], old_vp[1], old_vp[2], old_vp[3]); // Put everything back - if (glstate.texture.bound[0]) - gles_glBindTexture(GL_TEXTURE_2D, glstate.texture.bound[0]->glname); + if (glstate->texture.bound[0]) + gles_glBindTexture(GL_TEXTURE_2D, glstate->texture.bound[0]->glname); else gles_glBindTexture(GL_TEXTURE_2D, 0); - if (!glstate.enable.texture_2d[0]) + if (!glstate->enable.texture_2d[0]) gles_glDisable(GL_TEXTURE_2D); if (old_tex != 0) glshim_glActiveTexture(GL_TEXTURE0 + old_tex); diff --git a/project/jni/glshim/src/gl/gl.c b/project/jni/glshim/src/gl/gl.c index ba66222e2..56f69c1c9 100755 --- a/project/jni/glshim/src/gl/gl.c +++ b/project/jni/glshim/src/gl/gl.c @@ -20,7 +20,9 @@ glstate_t state = {.color = {1.0f, 1.0f, 1.0f, 1.0f}, .gl_batch = 0 }; */ -glstate_t glstate; +glstate_t *glstate = NULL; + +glstate_t *default_glstate = NULL; GLuint readhack = 0; GLint readhack_x = 0; @@ -34,25 +36,27 @@ int export_blendcolor = 0; char glshim_version[50]; int initialized = 0; int glshim_noerror = 0; +int glshim_nobanner = 0; +int glshim_npot = 0; -__attribute__((constructor)) -void initialize_glshim() { - printf("LIBGL: Initialising glshim\n"); - +void* NewGLState(void* shared_glstate) { + if(shared_glstate) { + glstate_t* glstate = (glstate_t*)shared_glstate; + glstate->shared_cnt++; + return (void*)glstate; + } + glstate_t *glstate = (glstate_t*)malloc(sizeof(glstate_t)); GLfloat white[] = {1.0f, 1.0f, 1.0f, 1.0f}; - memset(&glstate, 0, sizeof(glstate)); - memcpy(glstate.color, white, sizeof(GLfloat)*4); - glstate.last_error = GL_NO_ERROR; - glstate.normal[3] = 1.0f; // default normal is 0/0/1 + memset(glstate, 0, sizeof(glstate_t)); + memcpy(glstate->color, white, sizeof(GLfloat)*4); + glstate->last_error = GL_NO_ERROR; + glstate->normal[3] = 1.0f; // default normal is 0/0/1 // add default VBO { khint_t k; int ret; - khash_t(buff) *list = glstate.buffers; - if (! list) { - list = glstate.buffers = kh_init(buff); - } + khash_t(buff) *list = glstate->buffers = kh_init(buff); k = kh_put(buff, list, 0, &ret); glbuffer_t *buff = kh_value(list, k) = malloc(sizeof(glbuffer_t)); buff->buffer = 0; @@ -62,27 +66,114 @@ void initialize_glshim() { buff->size = 0; buff->access = GL_READ_WRITE; buff->mapped = 0; - glstate.defaultvbo = buff; + glstate->defaultvbo = buff; } // add default VAO { khint_t k; int ret; - khash_t(glvao) *list = glstate.vaos; - if (! list) { - list = glstate.vaos = kh_init(glvao); - } + khash_t(glvao) *list = glstate->vaos = kh_init(glvao); k = kh_put(glvao, list, 0, &ret); glvao_t *glvao = kh_value(list, k) = malloc(sizeof(glvao_t)); // new vao is binded to default vbo memset(glvao, 0, sizeof(glvao_t)); // just put is number glvao->array = 0; - glstate.defaultvao = glvao; + glstate->defaultvao = glvao; } // Bind defaults... - glstate.vao = glstate.defaultvao; - + glstate->vao = glstate->defaultvao; + + glstate->shared_cnt = 0; + + glstate->gl_batch = gl_batch; + + return (void*)glstate; +} + + +void DeleteGLState(void* oldstate) { + glstate_t* state = (glstate_t*)state; + if(!state) return; + + if(state->shared_cnt) { + --state->shared_cnt; + return; + } + + if(glstate == state) + glstate = NULL; + + + #define free_hashmap(T, N, K) \ + { \ + T *m; \ + kh_foreach_value(state->N, m, \ + free(m); \ + ) \ + kh_destroy(K, state->N); \ + } + free_hashmap(glvao_t, vaos, glvao); + free_hashmap(glbuffer_t, buffers, buff); + free_hashmap(glquery_t, queries, queries); + free_hashmap(gltexture_t, texture.list, tex); + #undef free_hashmap + // free eval maps + #define freemap(dims, name) \ + { map_statef_t *m = (map_statef_t *)state->map##dims.name; \ + if (m) { \ + if (m->free) \ + free((void *)m->points); \ + free(m); \ + } } + freemap(1, vertex3); freemap(1, vertex4); freemap(1, index); freemap(1, color4); freemap(1, normal); + freemap(1, texture1); freemap(1, texture2); freemap(1, texture3); freemap(1, texture4); + freemap(2, vertex3); freemap(2, vertex4); freemap(2, index); freemap(2, color4); freemap(2, normal); + freemap(2, texture1); freemap(2, texture2); freemap(2, texture3); freemap(2, texture4); + #undef freemap + // free lists + if(state->lists) { + for (int i=0; ilist.count; i++) + free_renderlist(state->lists[i]); + free(state->lists); + } + if(state->list.active) free_renderlist(state->list.active); + + // free matrix stack + #define free_matrix(A) \ + if (state->A) { \ + free(state->A->stack); \ + free(state->A); \ + } + free_matrix(projection_matrix); + free_matrix(modelview_matrix); + for (int i=0; itexture_matrix); + #undef free_matrix + // probably missing some things to free here! + + // all done + free(state); + return; +} + +void ActivateGLState(void* new_glstate) { + if(glstate == (glstate_t*)new_glstate) return; // same state, nothing to do + if (glstate && glstate->gl_batch) flush(); + glstate = (glstate_t*)new_glstate; + if (gl_batch && glstate->init_batch==0) init_batch(); + +} + +__attribute__((constructor)) +void initialize_glshim() { + char *env_nobanner = getenv("LIBGL_NOBANNER"); + if (env_nobanner && strcmp(env_nobanner, "1") == 0) + glshim_nobanner = 1; + + if(!glshim_nobanner) printf("LIBGL: Initialising glshim\n"); + // init read hack char *env_readhack = getenv("LIBGL_READHACK"); if (env_readhack && strcmp(env_readhack, "1") == 0) { @@ -108,8 +199,9 @@ void initialize_glshim() { printf("LIBGL: Batch mode disabled, merging of list disabled too\n"); } - if (gl_batch) init_batch(); - glstate.gl_batch = gl_batch; + default_glstate = (glstate_t*)NewGLState(NULL); + ActivateGLState(default_glstate); + initialized = 1; } @@ -118,14 +210,11 @@ const GLubyte *glshim_glGetString(GLenum name) { // LOAD_GLES(glGetString); const GLubyte *str; errorShim(GL_NO_ERROR); -/* if ((str=gles_glGetString(name))==NULL) - printf("**warning** glGetString(%i) called with bad init\n", name);*/ - switch (name) { - case GL_VERSION: - return (GLubyte *)glshim_version; - case GL_EXTENSIONS: - return (const GLubyte *)(char *){ - "GL_EXT_abgr " + static GLubyte *extensions = NULL; + if(!extensions) { + extensions = (GLubyte*)malloc(5000); // arbitrary size... + strcpy(extensions, + "GL_EXT_abgr " "GL_EXT_packed_pixels " "GL_ARB_vertex_buffer_object " "GL_ARB_vertex_array_object " @@ -172,7 +261,17 @@ const GLubyte *glshim_glGetString(GLenum name) { // "GL_EXT_blend_logic_op " // "GL_EXT_blend_color " // "GL_ARB_texture_cube_map " - }; + ); + if(glshim_npot>=1) + strcat(extensions, "GL_APPLE_texture_2D_limited_npot "); + if(glshim_npot>=2) + strcat(extensions, "GL_ARB_texture_non_power_of_two "); + } + switch (name) { + case GL_VERSION: + return (GLubyte *)glshim_version; + case GL_EXTENSIONS: + return extensions; case GL_VENDOR: return (GLubyte *)"ptitSeb"; case GL_RENDERER: @@ -207,6 +306,7 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) { } GLint dummy; LOAD_GLES(glGetIntegerv); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); noerrorShim(); switch (pname) { case GL_MAX_ELEMENTS_INDICES: @@ -222,34 +322,34 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) { *params = 1; break; case GL_UNPACK_ROW_LENGTH: - *params = glstate.texture.unpack_row_length; + *params = glstate->texture.unpack_row_length; break; case GL_UNPACK_SKIP_PIXELS: - *params = glstate.texture.unpack_skip_pixels; + *params = glstate->texture.unpack_skip_pixels; break; case GL_UNPACK_SKIP_ROWS: - *params = glstate.texture.unpack_skip_rows; + *params = glstate->texture.unpack_skip_rows; break; case GL_UNPACK_LSB_FIRST: - *params = glstate.texture.unpack_lsb_first; + *params = glstate->texture.unpack_lsb_first; break; case GL_UNPACK_IMAGE_HEIGHT: - *params = glstate.texture.unpack_image_height; + *params = glstate->texture.unpack_image_height; break; case GL_PACK_ROW_LENGTH: - *params = glstate.texture.pack_row_length; + *params = glstate->texture.pack_row_length; break; case GL_PACK_SKIP_PIXELS: - *params = glstate.texture.pack_skip_pixels; + *params = glstate->texture.pack_skip_pixels; break; case GL_PACK_SKIP_ROWS: - *params = glstate.texture.pack_skip_rows; + *params = glstate->texture.pack_skip_rows; break; case GL_PACK_LSB_FIRST: - *params = glstate.texture.pack_lsb_first; + *params = glstate->texture.pack_lsb_first; break; case GL_PACK_IMAGE_HEIGHT: - *params = glstate.texture.pack_image_height; + *params = glstate->texture.pack_image_height; break; case GL_UNPACK_SWAP_BYTES: case GL_PACK_SWAP_BYTES: @@ -261,10 +361,10 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) { gles_glGetIntegerv(GL_POINT_SIZE_MAX, params+1); break; case GL_RENDER_MODE: - *params = (glstate.render_mode)?glstate.render_mode:GL_RENDER; + *params = (glstate->render_mode)?glstate->render_mode:GL_RENDER; break; case GL_NAME_STACK_DEPTH: - *params = glstate.namestack.top; + *params = glstate->namestack.top; break; case GL_MAX_NAME_STACK_DEPTH: *params = 1024; @@ -297,28 +397,28 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) { *params=MAX_STACK_TEXTURE; break; case GL_MODELVIEW_STACK_DEPTH: - *params=(glstate.modelview_matrix)?(glstate.modelview_matrix->top+1):1; + *params=(glstate->modelview_matrix)?(glstate->modelview_matrix->top+1):1; break; case GL_PROJECTION_STACK_DEPTH: - *params=(glstate.projection_matrix)?(glstate.projection_matrix->top+1):1; + *params=(glstate->projection_matrix)?(glstate->projection_matrix->top+1):1; break; case GL_TEXTURE_STACK_DEPTH: - *params=(glstate.texture_matrix)?(glstate.texture_matrix[glstate.texture.active]->top+1):1; + *params=(glstate->texture_matrix)?(glstate->texture_matrix[glstate->texture.active]->top+1):1; break; case GL_MAX_LIST_NESTING: *params=64; // fake, no limit in fact break; case GL_ARRAY_BUFFER_BINDING: - *params=(glstate.vao->vertex)?glstate.vao->vertex->buffer:0; + *params=(glstate->vao->vertex)?glstate->vao->vertex->buffer:0; break; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - *params=(glstate.vao->elements)?glstate.vao->elements->buffer:0; + *params=(glstate->vao->elements)?glstate->vao->elements->buffer:0; break; case GL_PIXEL_PACK_BUFFER_BINDING: - *params=(glstate.vao->pack)?glstate.vao->pack->buffer:0; + *params=(glstate->vao->pack)?glstate->vao->pack->buffer:0; break; case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params=(glstate.vao->unpack)?glstate.vao->unpack->buffer:0; + *params=(glstate->vao->unpack)?glstate->vao->unpack->buffer:0; break; default: errorGL(); @@ -329,6 +429,7 @@ void glGetIntegerv(GLenum pname, GLint *params) AliasExport("glshim_glGetInteger void glshim_glGetFloatv(GLenum pname, GLfloat *params) { LOAD_GLES(glGetFloatv); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); noerrorShim(); switch (pname) { case GL_MAX_ELEMENTS_INDICES: @@ -341,28 +442,28 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) { *params = 0; break; case GL_UNPACK_ROW_LENGTH: - *params = glstate.texture.unpack_row_length; + *params = glstate->texture.unpack_row_length; break; case GL_UNPACK_SKIP_PIXELS: - *params = glstate.texture.unpack_skip_pixels; + *params = glstate->texture.unpack_skip_pixels; break; case GL_UNPACK_SKIP_ROWS: - *params = glstate.texture.unpack_skip_rows; + *params = glstate->texture.unpack_skip_rows; break; case GL_UNPACK_LSB_FIRST: - *params = glstate.texture.unpack_lsb_first; + *params = glstate->texture.unpack_lsb_first; break; case GL_PACK_ROW_LENGTH: - *params = glstate.texture.pack_row_length; + *params = glstate->texture.pack_row_length; break; case GL_PACK_SKIP_PIXELS: - *params = glstate.texture.pack_skip_pixels; + *params = glstate->texture.pack_skip_pixels; break; case GL_PACK_SKIP_ROWS: - *params = glstate.texture.pack_skip_rows; + *params = glstate->texture.pack_skip_rows; break; case GL_PACK_LSB_FIRST: - *params = glstate.texture.pack_lsb_first; + *params = glstate->texture.pack_lsb_first; break; case GL_ZOOM_X: *params = raster_zoomx; @@ -391,10 +492,10 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) { gles_glGetFloatv(GL_POINT_SIZE_MAX, params+1); break; case GL_RENDER_MODE: - *params = (glstate.render_mode)?glstate.render_mode:GL_RENDER; + *params = (glstate->render_mode)?glstate->render_mode:GL_RENDER; break; case GL_NAME_STACK_DEPTH: - *params = glstate.namestack.top; + *params = glstate->namestack.top; break; case GL_MAX_NAME_STACK_DEPTH: *params = 1024; @@ -409,28 +510,28 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) { *params=MAX_STACK_TEXTURE; break; case GL_MODELVIEW_STACK_DEPTH: - *params=(glstate.modelview_matrix)?(glstate.modelview_matrix->top+1):1; + *params=(glstate->modelview_matrix)?(glstate->modelview_matrix->top+1):1; break; case GL_PROJECTION_STACK_DEPTH: - *params=(glstate.projection_matrix)?(glstate.projection_matrix->top+1):1; + *params=(glstate->projection_matrix)?(glstate->projection_matrix->top+1):1; break; case GL_TEXTURE_STACK_DEPTH: - *params=(glstate.texture_matrix)?(glstate.texture_matrix[glstate.texture.active]->top+1):1; + *params=(glstate->texture_matrix)?(glstate->texture_matrix[glstate->texture.active]->top+1):1; break; case GL_MAX_LIST_NESTING: *params=64; // fake, no limit in fact break; case GL_ARRAY_BUFFER_BINDING: - *params=(glstate.vao->vertex)?glstate.vao->vertex->buffer:0; + *params=(glstate->vao->vertex)?glstate->vao->vertex->buffer:0; break; case GL_ELEMENT_ARRAY_BUFFER_BINDING: - *params=(glstate.vao->elements)?glstate.vao->elements->buffer:0; + *params=(glstate->vao->elements)?glstate->vao->elements->buffer:0; break; case GL_PIXEL_PACK_BUFFER_BINDING: - *params=(glstate.vao->pack)?glstate.vao->pack->buffer:0; + *params=(glstate->vao->pack)?glstate->vao->pack->buffer:0; break; case GL_PIXEL_UNPACK_BUFFER_BINDING: - *params=(glstate.vao->unpack)?glstate.vao->unpack->buffer:0; + *params=(glstate->vao->unpack)?glstate->vao->unpack->buffer:0; break; case GL_TRANSPOSE_PROJECTION_MATRIX: gles_glGetFloatv(GL_PROJECTION_MATRIX, params); @@ -460,13 +561,13 @@ extern int texstream; static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { #define proxy_enable(constant, name) \ - case constant: glstate.enable.name = enable; next(cap); break + case constant: glstate->enable.name = enable; next(cap); break #define enable(constant, name) \ - case constant: glstate.enable.name = enable; break; + case constant: glstate->enable.name = enable; break; #define proxy_clientenable(constant, name) \ - case constant: glstate.vao->name = enable; next(cap); break + case constant: glstate->vao->name = enable; next(cap); break #define clientenable(constant, name) \ - case constant: glstate.vao->name = enable; break; + case constant: glstate->vao->name = enable; break; // TODO: maybe could be weird behavior if someone tried to: // 1. enable GL_TEXTURE_1D @@ -476,22 +577,23 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { // cap = map_tex_target(cap); // Alpha Hack - if (alphahack && (cap==GL_ALPHA_TEST) && enable) - if (glstate.texture.bound[glstate.texture.active]) - if (!glstate.texture.bound[glstate.texture.active]->alpha) - enable = false; + if (alphahack && (cap==GL_ALPHA_TEST) && enable) { + if (glstate->texture.bound[glstate->texture.active]) + if (!glstate->texture.bound[glstate->texture.active]->alpha) + enable = false; + } noerrorShim(); #ifdef TEXSTREAM if (cap==GL_TEXTURE_STREAM_IMG) - glstate.enable.texture_2d[glstate.texture.active] = enable; + glstate->enable.texture_2d[glstate->texture.active] = enable; #endif switch (cap) { enable(GL_AUTO_NORMAL, auto_normal); proxy_enable(GL_BLEND, blend); - proxy_enable(GL_TEXTURE_2D, texture_2d[glstate.texture.active]); - enable(GL_TEXTURE_GEN_S, texgen_s[glstate.texture.active]); - enable(GL_TEXTURE_GEN_T, texgen_t[glstate.texture.active]); - enable(GL_TEXTURE_GEN_R, texgen_r[glstate.texture.active]); + proxy_enable(GL_TEXTURE_2D, texture_2d[glstate->texture.active]); + enable(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]); + enable(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]); + enable(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]); enable(GL_LINE_STIPPLE, line_stipple); // Secondary color @@ -502,11 +604,11 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { clientenable(GL_VERTEX_ARRAY, vertex_array); clientenable(GL_NORMAL_ARRAY, normal_array); clientenable(GL_COLOR_ARRAY, color_array); - clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate.texture.client]); + clientenable(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]); // Texture 1D and 3D - enable(GL_TEXTURE_1D, texture_1d[glstate.texture.active]); - enable(GL_TEXTURE_3D, texture_3d[glstate.texture.active]); + enable(GL_TEXTURE_1D, texture_1d[glstate->texture.active]); + enable(GL_TEXTURE_3D, texture_3d[glstate->texture.active]); default: errorGL(); next(cap); break; } @@ -516,24 +618,26 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { #undef clientenable } -void glshim_glEnable(GLenum cap) { - if (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling)) { - int which_cap; +int Cap2BatchState(GLenum cap) { switch (cap) { - case GL_ALPHA_TEST: which_cap = ENABLED_ALPHA; break; - case GL_BLEND: which_cap = ENABLED_BLEND; break; - case GL_CULL_FACE: which_cap = ENABLED_CULL; break; - case GL_DEPTH_TEST: which_cap = ENABLED_DEPTH; break; - case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D_TEX0 - +(glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active); - break; - default: which_cap = ENABLED_LAST; break; + case GL_ALPHA_TEST: return ENABLED_ALPHA; + case GL_BLEND: return ENABLED_BLEND; + case GL_CULL_FACE: return ENABLED_CULL; + case GL_DEPTH_TEST: return ENABLED_DEPTH; + case GL_TEXTURE_2D: return ENABLED_TEX2D_TEX0 + +(glstate->statebatch.active_tex_changed?glstate->statebatch.active_tex-GL_TEXTURE0:glstate->texture.active); } + return ENABLED_LAST; +} + +void glshim_glEnable(GLenum cap) { + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { + int which_cap = Cap2BatchState(cap); if (which_cap!=ENABLED_LAST) { - if ((glstate.statebatch.enabled[which_cap] == 1)) + if ((glstate->statebatch.enabled[which_cap] == 1)) return; // nothing to do... - if (!glstate.statebatch.enabled[which_cap]) { - glstate.statebatch.enabled[which_cap] = 1; + if (!glstate->statebatch.enabled[which_cap]) { + glstate->statebatch.enabled[which_cap] = 1; } else { flush(); } @@ -542,8 +646,8 @@ void glshim_glEnable(GLenum cap) { PUSH_IF_COMPILING(glEnable) if (texstream && (cap==GL_TEXTURE_2D)) { - if (glstate.texture.bound[glstate.texture.active]) - if (glstate.texture.bound[glstate.texture.active]->streamed) + if (glstate->texture.bound[glstate->texture.active]) + if (glstate->texture.bound[glstate->texture.active]->streamed) cap = GL_TEXTURE_STREAM_IMG; } @@ -553,23 +657,13 @@ void glshim_glEnable(GLenum cap) { void glEnable(GLenum cap) AliasExport("glshim_glEnable"); void glshim_glDisable(GLenum cap) { - if (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling)) { - int which_cap; - switch (cap) { - case GL_ALPHA_TEST: which_cap = ENABLED_ALPHA; break; - case GL_BLEND: which_cap = ENABLED_BLEND; break; - case GL_CULL_FACE: which_cap = ENABLED_CULL; break; - case GL_DEPTH_TEST: which_cap = ENABLED_DEPTH; break; - case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D_TEX0 - +(glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active); - break; - default: which_cap = ENABLED_LAST; break; - } + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { + int which_cap = Cap2BatchState(cap); if (which_cap!=ENABLED_LAST) { - if ((glstate.statebatch.enabled[which_cap] == 2)) + if ((glstate->statebatch.enabled[which_cap] == 2)) return; // nothing to do... - if (!glstate.statebatch.enabled[which_cap]) { - glstate.statebatch.enabled[which_cap] = 2; + if (!glstate->statebatch.enabled[which_cap]) { + glstate->statebatch.enabled[which_cap] = 2; } else { flush(); } @@ -578,8 +672,8 @@ void glshim_glDisable(GLenum cap) { PUSH_IF_COMPILING(glDisable) if (texstream && (cap==GL_TEXTURE_2D)) { - if (glstate.texture.bound[glstate.texture.active]) - if (glstate.texture.bound[glstate.texture.active]->streamed) + if (glstate->texture.bound[glstate->texture.active]) + if (glstate->texture.bound[glstate->texture.active]->streamed) cap = GL_TEXTURE_STREAM_IMG; } @@ -602,29 +696,29 @@ void glDisableClientState(GLenum cap) AliasExport("glshim_glDisableClientState") #define isenabled(what, where) \ - case what: return glstate.enable.where + case what: return glstate->enable.where #define clientisenabled(what, where) \ - case what: return glstate.vao->where + case what: return glstate->vao->where GLboolean glshim_glIsEnabled(GLenum cap) { // should flush for now... to be optimized later! - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES(glIsEnabled); noerrorShim(); switch (cap) { isenabled(GL_AUTO_NORMAL, auto_normal); isenabled(GL_LINE_STIPPLE, line_stipple); - isenabled(GL_TEXTURE_GEN_S, texgen_s[glstate.texture.active]); - isenabled(GL_TEXTURE_GEN_T, texgen_t[glstate.texture.active]); - isenabled(GL_TEXTURE_GEN_R, texgen_r[glstate.texture.active]); + isenabled(GL_TEXTURE_GEN_S, texgen_s[glstate->texture.active]); + isenabled(GL_TEXTURE_GEN_T, texgen_t[glstate->texture.active]); + isenabled(GL_TEXTURE_GEN_R, texgen_r[glstate->texture.active]); isenabled(GL_COLOR_SUM, color_sum); clientisenabled(GL_SECONDARY_COLOR_ARRAY, secondary_array); - isenabled(GL_TEXTURE_1D, texture_1d[glstate.texture.active]); - isenabled(GL_TEXTURE_3D, texture_3d[glstate.texture.active]); + isenabled(GL_TEXTURE_1D, texture_1d[glstate->texture.active]); + isenabled(GL_TEXTURE_3D, texture_3d[glstate->texture.active]); clientisenabled(GL_VERTEX_ARRAY, vertex_array); clientisenabled(GL_NORMAL_ARRAY, normal_array); clientisenabled(GL_COLOR_ARRAY, color_array); - clientisenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate.texture.client]); + clientisenabled(GL_TEXTURE_COORD_ARRAY, tex_coord_array[glstate->texture.client]); default: errorGL(); return gles_glIsEnabled(cap); @@ -638,46 +732,57 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, GLsizei skip, GLsizei count) { if (! list) list = alloc_renderlist(); -//if (glstate.list.compiling) printf("arrary_to_renderlist while compiling list, skip=%d, count=%d\n", skip, count); +//if (glstate->list.compiling) printf("arrary_to_renderlist while compiling list, skip=%d, count=%d\n", skip, count); list->mode = mode; list->mode_init = mode; list->len = count-skip; list->cap = count-skip; - if (glstate.vao->vertex_array) { - list->vert = copy_gl_pointer_tex(&glstate.vao->pointers.vertex, 4, skip, count, glstate.vao->pointers.vertex.buffer); + if (glstate->vao->vertex_array) { + list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count); } - if (glstate.vao->color_array) { - list->color = copy_gl_pointer_color(&glstate.vao->pointers.color, 4, skip, count, glstate.vao->pointers.color.buffer); + if (glstate->vao->color_array) { + list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count); } - if (glstate.vao->secondary_array/* && glstate.enable.color_array*/) { - list->secondary = copy_gl_pointer(&glstate.vao->pointers.secondary, 4, skip, count, glstate.vao->pointers.secondary.buffer); // alpha chanel is always 0 for secondary... + if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) { + list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary... } - if (glstate.vao->normal_array) { - list->normal = copy_gl_pointer_raw(&glstate.vao->pointers.normal, 3, skip, count, glstate.vao->pointers.normal.buffer); + if (glstate->vao->normal_array) { + list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count); } for (int i=0; itex_coord_array[i]) { - list->tex[i] = copy_gl_pointer_tex(&glstate.vao->pointers.tex_coord[i], 4, skip, count, glstate.vao->pointers.tex_coord[i].buffer); + if (glstate->vao->tex_coord_array[i]) { + list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count); } } return list; } static inline bool should_intercept_render(GLenum mode) { + // check bounded tex that will be used if one need some transformations + for (int aa=0; aaenable.texture_2d[aa] || glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa]) { + if(glstate->texture.rect_arb[aa]) + return true; + gltexture_t *bound = glstate->texture.bound[aa]; + if (bound && (bound->width!=bound->nwidth || bound->height!=bound->height)) + return true; + } + } + return ( - (glstate.vao->vertex_array && ! valid_vertex_type(glstate.vao->pointers.vertex.type)) || - (/*glstate.enable.texture_2d[0] && */(glstate.enable.texgen_s[0] || glstate.enable.texgen_t[0] || glstate.enable.texgen_r[0])) || - (/*glstate.enable.texture_2d[1] && */(glstate.enable.texgen_s[1] || glstate.enable.texgen_t[1] || glstate.enable.texgen_r[1])) || - (/*glstate.enable.texture_2d[2] && */(glstate.enable.texgen_s[2] || glstate.enable.texgen_t[2] || glstate.enable.texgen_r[2])) || - (/*glstate.enable.texture_2d[3] && */(glstate.enable.texgen_s[3] || glstate.enable.texgen_t[3] || glstate.enable.texgen_r[3])) || - (mode == GL_LINES && glstate.enable.line_stipple) || - (mode == GL_QUADS) || (glstate.list.active && (glstate.list.compiling || glstate.gl_batch)) + (glstate->vao->vertex_array && ! valid_vertex_type(glstate->vao->pointers.vertex.type)) || + (/*glstate->enable.texture_2d[0] && */(glstate->enable.texgen_s[0] || glstate->enable.texgen_t[0] || glstate->enable.texgen_r[0])) || + (/*glstate->enable.texture_2d[1] && */(glstate->enable.texgen_s[1] || glstate->enable.texgen_t[1] || glstate->enable.texgen_r[1])) || + (/*glstate->enable.texture_2d[2] && */(glstate->enable.texgen_s[2] || glstate->enable.texgen_t[2] || glstate->enable.texgen_r[2])) || + (/*glstate->enable.texture_2d[3] && */(glstate->enable.texgen_s[3] || glstate->enable.texgen_t[3] || glstate->enable.texgen_r[3])) || + (mode == GL_LINES && glstate->enable.line_stipple) || + (mode == GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) ); } void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { - //printf("glDrawElements(0x%04X, %d, 0x%04X, %p), map=%p\n", mode, count, type, indices, (glstate.vao->elements)?glstate.vao->elements->data:NULL); + //printf("glDrawElements(%s, %d, %s, %p), vtx=%p map=%p\n", PrintEnum(mode), count, PrintEnum(type), indices, (glstate->vao->vertex)?glstate->vao->vertex->data:NULL, (glstate->vao->elements)?glstate->vao->elements->data:NULL); // TODO: split for count > 65535? // special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex... if (mode == GL_QUADS) while(count%4) count--; @@ -696,18 +801,18 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid GLushort *sindices; bool need_free = (type!=GL_UNSIGNED_SHORT); if(need_free) - sindices = copy_gl_array((glstate.vao->elements)?glstate.vao->elements->data + (uintptr_t)indices:indices, + sindices = copy_gl_array((glstate->vao->elements)?glstate->vao->elements->data + (uintptr_t)indices:indices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); else - sindices = (glstate.vao->elements)?(glstate.vao->elements->data + (uintptr_t)indices):(GLvoid*)indices; - bool compiling = (glstate.list.active && (glstate.list.compiling || glstate.gl_batch)); + sindices = (glstate->vao->elements)?(glstate->vao->elements->data + (uintptr_t)indices):(GLvoid*)indices; + bool compiling = (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)); if (compiling) { renderlist_t *list = NULL; GLsizei min, max; - NewStage(glstate.list.active, STAGE_DRAW); - list = glstate.list.active; + NewStage(glstate->list.active, STAGE_DRAW); + list = glstate->list.active; normalize_indices(sindices, &max, &min, count); list = arrays_to_renderlist(list, mode, min, max + 1); @@ -716,7 +821,7 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid list->indice_cap = count; //end_renderlist(list); - glstate.list.active = extend_renderlist(list); + glstate->list.active = extend_renderlist(list); return; } @@ -729,7 +834,7 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid list->indices = (need_free)?sindices:copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); list->ilen = count; list->indice_cap = count; - end_renderlist(list); + list = end_renderlist(list); draw_renderlist(list); free_renderlist(list); @@ -748,21 +853,10 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid for (int i=0; ib && glstate.vao->pointers.a.buffer) glstate.vao->pointers.a.pointer += (uintptr_t)glstate.vao->pointers.a.buffer->data; - - shift_pointer(color, color_array); - shift_pointer(secondary, secondary_array); - shift_pointer(vertex, vertex_array); - for (int aa=0; aaA != glstate.clientstate.A) { \ + if(glstate->vao->A != glstate->clientstate.A) { \ C \ - if((glstate.clientstate.A = glstate.vao->A)==true) \ + if((glstate->clientstate.A = glstate->vao->A)==true) \ gles_glEnableClientState(B); \ else \ gles_glDisableClientState(B); \ @@ -770,62 +864,65 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid GLenum mode_init = mode; - if (glstate.polygon_mode == GL_LINE && mode>=GL_TRIANGLES) + if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) mode = GL_LINE_LOOP; - if (glstate.polygon_mode == GL_POINT && mode>=GL_TRIANGLES) + if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES) mode = GL_POINTS; if (mode == GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP; if (mode == GL_POLYGON) mode = GL_TRIANGLE_FAN; - if (glstate.render_mode == GL_SELECT) { - select_glDrawElements(&glstate.vao->pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices); + if (glstate->render_mode == GL_SELECT) { + select_glDrawElements(&glstate->vao->pointers.vertex, mode, count, GL_UNSIGNED_SHORT, sindices); } else { // secondary color... GLfloat *final_colors = NULL; pointer_state_t old_color; client_state(color_array, GL_COLOR_ARRAY, ); - if (/*glstate.enable.color_sum && */(glstate.vao->secondary_array) && (glstate.vao->color_array)) { - final_colors=copy_gl_pointer_color(&glstate.vao->pointers.color, 4, 0, len, 0); - GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate.vao->pointers.secondary, 4, 0, len, 0); + if (/*glstate->enable.color_sum && */(glstate->vao->secondary_array) && (glstate->vao->color_array)) { + final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, len); + GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, len); for (int i=0; icolor_array && (glstate.vao->pointers.color.size != 4)) { + } else if (glstate->vao->color_array && (glstate->vao->pointers.color.size != 4)) { // Pandora doesn't like Color Pointer with size != 4 - if(glstate.vao->pointers.color.type == GL_UNSIGNED_BYTE) { - final_colors=copy_gl_pointer_bytecolor(&glstate.vao->pointers.color, 4, 0, len, 0); + if(glstate->vao->pointers.color.type == GL_UNSIGNED_BYTE) { + final_colors=copy_gl_pointer_bytecolor(&glstate->vao->pointers.color, 4, 0, len); gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); } else { - final_colors=copy_gl_pointer_color(&glstate.vao->pointers.color, 4, 0, len, 0); + final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, len); gles_glColorPointer(4, GL_FLOAT, 0, final_colors); } - } else if (glstate.vao->color_array) - gles_glColorPointer(glstate.vao->pointers.color.size, glstate.vao->pointers.color.type, glstate.vao->pointers.color.stride, glstate.vao->pointers.color.pointer); + } else if (glstate->vao->color_array) + gles_glColorPointer(glstate->vao->pointers.color.size, glstate->vao->pointers.color.type, glstate->vao->pointers.color.stride, glstate->vao->pointers.color.pointer); client_state(normal_array, GL_NORMAL_ARRAY, ); - if (glstate.vao->normal_array) - gles_glNormalPointer(glstate.vao->pointers.normal.type, glstate.vao->pointers.normal.stride, glstate.vao->pointers.normal.pointer); + if (glstate->vao->normal_array) + gles_glNormalPointer(glstate->vao->pointers.normal.type, glstate->vao->pointers.normal.stride, glstate->vao->pointers.normal.pointer); client_state(vertex_array, GL_VERTEX_ARRAY, ); - if (glstate.vao->vertex_array) - gles_glVertexPointer(glstate.vao->pointers.vertex.size, glstate.vao->pointers.vertex.type, glstate.vao->pointers.vertex.stride, glstate.vao->pointers.vertex.pointer); - GLuint old_tex = glstate.texture.client; - for (int aa=0; aavao->vertex_array) + gles_glVertexPointer(glstate->vao->pointers.vertex.size, glstate->vao->pointers.vertex.type, glstate->vao->pointers.vertex.stride, glstate->vao->pointers.vertex.pointer); + GLuint old_tex = glstate->texture.client; + GLuint cur_tex = old_tex; + #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { + TEXTURE(aa); gles_glEnable(GL_TEXTURE_2D); } - if (glstate.vao->tex_coord_array[aa]) { - tex_setup_texcoord(aa, len); + if (glstate->vao->tex_coord_array[aa]) { + TEXTURE(aa); + tex_setup_texcoord(len); } } - if (glstate.texture.client!=old_tex) - glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); + if (glstate->texture.client!=old_tex) + TEXTURE(old_tex); + #undef TEXTURE - if (glstate.polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { + if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { int n, s; switch (mode_init) { case GL_TRIANGLES: @@ -861,27 +958,18 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid // secondary color if (final_colors) { free(final_colors); -// glColorPointer(old_color.size, old_color.type, old_color.stride, old_color.pointer); } + #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { + TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); } } - if (glstate.texture.client!=old_tex) - glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); + if (glstate->texture.client!=old_tex) + TEXTURE(old_tex); + #undef TEXTURE } -#define shift_pointer(a, b) \ - if (glstate.vao->b && glstate.vao->pointers.a.buffer) glstate.vao->pointers.a.pointer -= (uintptr_t)glstate.vao->pointers.a.buffer->data; - - shift_pointer(color, color_array); - shift_pointer(secondary, secondary_array); - shift_pointer(vertex, vertex_array); - for (int aa=0; aalist.active && (glstate->list.compiling || glstate->gl_batch)) { + NewStage(glstate->list.active, STAGE_DRAW); + glstate->list.active = arrays_to_renderlist(glstate->list.active, mode, first, count+first); + glstate->list.active = extend_renderlist(glstate->list.active); return; } - if (glstate.polygon_mode == GL_LINE && mode>=GL_TRIANGLES) + if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) mode = GL_LINE_LOOP; - if (glstate.polygon_mode == GL_POINT && mode>=GL_TRIANGLES) + if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES) mode = GL_POINTS; if (should_intercept_render(mode)) { + renderlist_t *list; list = arrays_to_renderlist(NULL, mode, first, count+first); - end_renderlist(list); + list = end_renderlist(list); draw_renderlist(list); free_renderlist(list); } else { @@ -944,74 +1032,65 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { // like texgen, stipple, npot LOAD_GLES(glDrawArrays); -#define shift_pointer(a, b) \ - if (glstate.vao->b && glstate.vao->pointers.a.buffer) glstate.vao->pointers.a.pointer = glstate.vao->pointers.a.buffer->data + (uintptr_t)glstate.vao->pointers.a.pointer; - - shift_pointer(color, color_array); - shift_pointer(secondary, secondary_array); - shift_pointer(vertex, vertex_array); - for (int aa=0; aapointers.vertex, mode, first, count); + if (glstate->render_mode == GL_SELECT) { + select_glDrawArrays(&glstate->vao->pointers.vertex, mode, first, count); } else { // setup the Array Pointers // secondary color... GLfloat *final_colors = NULL; client_state(color_array, GL_COLOR_ARRAY, ); - if (/*glstate.enable.color_sum && */(glstate.vao->secondary_array) && (glstate.vao->color_array)) { - final_colors=copy_gl_pointer_color(&glstate.vao->pointers.color, 4, 0, count+first, 0); - GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate.vao->pointers.secondary, 4, first, count+first, 0); + if (/*glstate->enable.color_sum && */(glstate->vao->secondary_array) && (glstate->vao->color_array)) { + final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count+first); + GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate->vao->pointers.secondary, 4, first, count+first); for (int i=0; i<(count+first)*4; i++) final_colors[i]+=seconds_colors[i]; gles_glColorPointer(4, GL_FLOAT, 0, final_colors); free(seconds_colors); - } else if ((glstate.vao->color_array && (glstate.vao->pointers.color.size != 4)) - || (glstate.vao->color_array && (glstate.vao->pointers.color.stride!=0) && (glstate.vao->pointers.color.type != GL_FLOAT))) { + } else if ((glstate->vao->color_array && (glstate->vao->pointers.color.size != 4)) + || (glstate->vao->color_array && (glstate->vao->pointers.color.stride!=0) && (glstate->vao->pointers.color.type != GL_FLOAT))) { // Pandora doesn't like Color Pointer with size != 4 - if(glstate.vao->pointers.color.type == GL_UNSIGNED_BYTE) { - final_colors=copy_gl_pointer_bytecolor(&glstate.vao->pointers.color, 4, 0, count+first, 0); + if(glstate->vao->pointers.color.type == GL_UNSIGNED_BYTE) { + final_colors=copy_gl_pointer_bytecolor(&glstate->vao->pointers.color, 4, 0, count+first); gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); } else { - final_colors=copy_gl_pointer_color(&glstate.vao->pointers.color, 4, 0, count+first, 0); + final_colors=copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count+first); gles_glColorPointer(4, GL_FLOAT, 0, final_colors); } - } else if (glstate.vao->color_array) - gles_glColorPointer(glstate.vao->pointers.color.size, glstate.vao->pointers.color.type, glstate.vao->pointers.color.stride, glstate.vao->pointers.color.pointer); + } else if (glstate->vao->color_array) + gles_glColorPointer(glstate->vao->pointers.color.size, glstate->vao->pointers.color.type, glstate->vao->pointers.color.stride, glstate->vao->pointers.color.pointer); client_state(normal_array, GL_NORMAL_ARRAY, ); - if (glstate.vao->normal_array) - gles_glNormalPointer(glstate.vao->pointers.normal.type, glstate.vao->pointers.normal.stride, glstate.vao->pointers.normal.pointer); + if (glstate->vao->normal_array) + gles_glNormalPointer(glstate->vao->pointers.normal.type, glstate->vao->pointers.normal.stride, glstate->vao->pointers.normal.pointer); client_state(vertex_array, GL_VERTEX_ARRAY, ); - if (glstate.vao->vertex_array) - gles_glVertexPointer(glstate.vao->pointers.vertex.size, glstate.vao->pointers.vertex.type, glstate.vao->pointers.vertex.stride, glstate.vao->pointers.vertex.pointer); - GLuint old_tex = glstate.texture.client; - for (int aa=0; aavao->vertex_array) + gles_glVertexPointer(glstate->vao->pointers.vertex.size, glstate->vao->pointers.vertex.type, glstate->vao->pointers.vertex.stride, glstate->vao->pointers.vertex.pointer); + GLuint old_tex = glstate->texture.client; + GLuint cur_tex = old_tex; + #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { + TEXTURE(aa); gles_glEnable(GL_TEXTURE_2D); } - if (glstate.vao->tex_coord_array[aa]) { - tex_setup_texcoord(aa, count+first); + if (glstate->vao->tex_coord_array[aa]) { + TEXTURE(aa); + tex_setup_texcoord(count+first); /*glClientActiveTexture(aa+GL_TEXTURE0); - gles_glTexCoordPointer(glstate.pointers.tex_coord[aa].size, glstate.pointers.tex_coord[aa].type, glstate.pointers.tex_coord[aa].stride, glstate.pointers.tex_coord[aa].pointer);*/ + gles_glTexCoordPointer(glstate->pointers.tex_coord[aa].size, glstate->pointers.tex_coord[aa].type, glstate->pointers.tex_coord[aa].stride, glstate->pointers.tex_coord[aa].pointer);*/ } } - if (glstate.texture.client!=old_tex) - glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); + if (glstate->texture.client!=old_tex) + TEXTURE(old_tex); + #undef TEXTURE - if (glstate.polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { + if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { int n, s; switch (mode_init) { case GL_TRIANGLES: @@ -1049,23 +1128,13 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { free(final_colors); } for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { glshim_glClientActiveTexture(aa+GL_TEXTURE0); gles_glDisable(GL_TEXTURE_2D); } } - if (glstate.texture.client!=old_tex) + if (glstate->texture.client!=old_tex) glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); -#define shift_pointer(a, b) \ - if (glstate.vao->b && glstate.vao->pointers.a.buffer) glstate.vao->pointers.a.pointer = glstate.vao->pointers.a.pointer - (uintptr_t)glstate.vao->pointers.a.buffer->data; - - shift_pointer(color, color_array); - shift_pointer(secondary, secondary_array); - shift_pointer(vertex, vertex_array); - for (int aa=0; aavertex + t.size = s; t.type = type; t.stride = stride; t.pointer = pointer + (uintptr_t)((glstate->vao->vertex)?glstate->vao->vertex->data:0) void glshim_glVertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(glstate.vao->pointers.vertex, size); + clone_gl_pointer(glstate->vao->pointers.vertex, size); } void glshim_glColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(glstate.vao->pointers.color, size); + clone_gl_pointer(glstate->vao->pointers.color, size); } void glshim_glNormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(glstate.vao->pointers.normal, 3); + clone_gl_pointer(glstate->vao->pointers.normal, 3); } void glshim_glTexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { noerrorShim(); - clone_gl_pointer(glstate.vao->pointers.tex_coord[glstate.texture.client], size); + clone_gl_pointer(glstate->vao->pointers.tex_coord[glstate->texture.client], size); } void glshim_glSecondaryColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { if (size!=3) return; // Size must be 3... - clone_gl_pointer(glstate.vao->pointers.secondary, size); + clone_gl_pointer(glstate->vao->pointers.secondary, size); noerrorShim(); } @@ -1210,47 +1279,47 @@ void glInterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer) A // immediate mode functions void glshim_glBegin(GLenum mode) { - if (!glstate.list.active) - glstate.list.active = alloc_renderlist(); - NewStage(glstate.list.active, STAGE_DRAW); - glstate.list.active->mode = mode; - glstate.list.active->mode_init = mode; + if (!glstate->list.active) + glstate->list.active = alloc_renderlist(); + NewStage(glstate->list.active, STAGE_DRAW); + glstate->list.active->mode = mode; + glstate->list.active->mode_init = mode; noerrorShim(); // TODO, check Enum validity } void glBegin(GLenum mode) AliasExport("glshim_glBegin"); void glshim_glEnd() { - if (!glstate.list.active) return; - // check if TEXTUREx is activate and no TexCoord (or texgen), in that case, create a dummy one base on glstate... + if (!glstate->list.active) return; + // check if TEXTUREx is activate and no TexCoord (or texgen), in that case, create a dummy one base on glstate->.. for (int a=0; atex[a]==0) && (!glstate.enable.texgen_s[a]))) - rlMultiTexCoord4f(glstate.list.active, GL_TEXTURE0+a, glstate.texcoord[a][0], glstate.texcoord[a][1], glstate.texcoord[a][2], glstate.texcoord[a][3]); + if (glstate->enable.texture_2d[a] && ((glstate->list.active->tex[a]==0) && (!glstate->enable.texgen_s[a]))) + rlMultiTexCoord4f(glstate->list.active, GL_TEXTURE0+a, glstate->texcoord[a][0], glstate->texcoord[a][1], glstate->texcoord[a][2], glstate->texcoord[a][3]); // render if we're not in a display list - if (!(glstate.list.compiling || glstate.gl_batch)) { - renderlist_t *mylist = glstate.list.active; - glstate.list.active = NULL; - end_renderlist(mylist); + if (!(glstate->list.compiling || glstate->gl_batch)) { + renderlist_t *mylist = glstate->list.active; + glstate->list.active = NULL; + mylist = end_renderlist(mylist); draw_renderlist(mylist); free_renderlist(mylist); } else { - glstate.list.active = extend_renderlist(glstate.list.active); + glstate->list.active = extend_renderlist(glstate->list.active); } noerrorShim(); } void glEnd() AliasExport("glshim_glEnd"); void glshim_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { - if (glstate.list.active) { - if (glstate.list.active->stage != STAGE_DRAW) { - if (glstate.list.active->stage != STAGE_DRAW) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - glstate.list.active->lastNormal[0] = nx; glstate.list.active->lastNormal[1] = ny; glstate.list.active->lastNormal[2] = nz; + if (glstate->list.active) { + if (glstate->list.active->stage != STAGE_DRAW) { + if (glstate->list.active->stage != STAGE_DRAW) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + glstate->list.active->lastNormal[0] = nx; glstate->list.active->lastNormal[1] = ny; glstate->list.active->lastNormal[2] = nz; } PUSH_IF_COMPILING(glNormal3f); } } else { - rlNormal3f(glstate.list.active, nx, ny, nz); - glstate.list.active->lastNormal[0] = nx; glstate.list.active->lastNormal[1] = ny; glstate.list.active->lastNormal[2] = nz; + rlNormal3f(glstate->list.active, nx, ny, nz); + glstate->list.active->lastNormal[0] = nx; glstate->list.active->lastNormal[1] = ny; glstate->list.active->lastNormal[2] = nz; noerrorShim(); } } @@ -1261,30 +1330,27 @@ void glshim_glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) { errorGL(); } #endif - glstate.normal[0] = nx; glstate.normal[1] = ny; glstate.normal[2] = nz; + glstate->normal[0] = nx; glstate->normal[1] = ny; glstate->normal[2] = nz; } void glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz) AliasExport("glshim_glNormal3f"); void glshim_glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { - if (glstate.list.active) { - rlVertex4f(glstate.list.active, x, y, z, w); + if (glstate->list.active) { + rlVertex4f(glstate->list.active, x, y, z, w); noerrorShim(); } } void glVertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) AliasExport("glshim_glVertex4f"); void glshim_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { - if (glstate.list.active) { - if (glstate.list.active->stage != STAGE_DRAW) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - glstate.list.active->lastColors[0] = red; glstate.list.active->lastColors[1] = green; - glstate.list.active->lastColors[2] = blue; glstate.list.active->lastColors[3] = alpha; - } + if (glstate->list.active) { + if (glstate->list.active->stage != STAGE_DRAW) { + glstate->list.active->lastColors[0] = red; glstate->list.active->lastColors[1] = green; + glstate->list.active->lastColors[2] = blue; glstate->list.active->lastColors[3] = alpha; + glstate->list.active->lastColorsSet = 1; PUSH_IF_COMPILING(glColor4f); } - rlColor4f(glstate.list.active, red, green, blue, alpha); - glstate.list.active->lastColors[0] = red; glstate.list.active->lastColors[1] = green; - glstate.list.active->lastColors[2] = blue; glstate.list.active->lastColors[3] = alpha; + rlColor4f(glstate->list.active, red, green, blue, alpha); noerrorShim(); } #ifndef USE_ES2 @@ -1295,33 +1361,33 @@ void glshim_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { } #endif // change the state last thing - glstate.color[0] = red; glstate.color[1] = green; - glstate.color[2] = blue; glstate.color[3] = alpha; + glstate->color[0] = red; glstate->color[1] = green; + glstate->color[2] = blue; glstate->color[3] = alpha; } void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) AliasExport("glshim_glColor4f"); void glshim_glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) { - if (glstate.list.active) { - rlSecondary3f(glstate.list.active, r, g, b); - glstate.list.active->lastSecondaryColors[0] = r; glstate.list.active->lastSecondaryColors[1] = g; - glstate.list.active->lastSecondaryColors[2] = b; + if (glstate->list.active) { + rlSecondary3f(glstate->list.active, r, g, b); + glstate->list.active->lastSecondaryColors[0] = r; glstate->list.active->lastSecondaryColors[1] = g; + glstate->list.active->lastSecondaryColors[2] = b; noerrorShim(); } else { noerrorShim(); } // change the state last thing - glstate.secondary[0] = r; glstate.secondary[1] = g; - glstate.secondary[2] = b; + glstate->secondary[0] = r; glstate->secondary[1] = g; + glstate->secondary[2] = b; } void glSecondaryColor3f(GLfloat r, GLfloat g, GLfloat b) AliasExport("glshim_glSecondaryColor3f"); #ifndef USE_ES2 void glshim_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { LOAD_GLES(glMaterialfv); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { //TODO: Materialfv can be done per vertex, how to handle that ?! - //NewStage(glstate.list.active, STAGE_MATERIAL); - rlMaterialfv(glstate.list.active, face, pname, params); + //NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); noerrorShim(); } else { if (face!=GL_FRONT_AND_BACK) { @@ -1334,12 +1400,12 @@ void glshim_glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) { void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params) AliasExport("glshim_glMaterialfv"); void glshim_glMaterialf(GLenum face, GLenum pname, const GLfloat param) { LOAD_GLES(glMaterialf); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { GLfloat params[4]; memset(params, 0, 4*sizeof(GLfloat)); params[0] = param; - NewStage(glstate.list.active, STAGE_MATERIAL); - rlMaterialfv(glstate.list.active, face, pname, params); + NewStage(glstate->list.active, STAGE_MATERIAL); + rlMaterialfv(glstate->list.active, face, pname, params); noerrorShim(); } else { if (face!=GL_FRONT_AND_BACK) { @@ -1353,27 +1419,23 @@ void glMaterialf(GLenum face, GLenum pname, const GLfloat param) AliasExport("gl #endif void glshim_glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { - if (glstate.list.active) { - rlTexCoord4f(glstate.list.active, s, t, r, q); - noerrorShim(); - } else { - noerrorShim(); + if (glstate->list.active) { + rlTexCoord4f(glstate->list.active, s, t, r, q); } - glstate.texcoord[0][0] = s; glstate.texcoord[0][1] = t; - glstate.texcoord[0][2] = r; glstate.texcoord[0][3] = q; + noerrorShim(); + glstate->texcoord[0][0] = s; glstate->texcoord[0][1] = t; + glstate->texcoord[0][2] = r; glstate->texcoord[0][3] = q; } void glTexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) AliasExport("glshim_glTexCoord4f"); void glshim_glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) { // TODO, error if target is unsuported texture.... - if (glstate.list.active) { - rlMultiTexCoord4f(glstate.list.active, target, s, t, r, q); - noerrorShim(); - } else { - noerrorShim(); + if (glstate->list.active) { + rlMultiTexCoord4f(glstate->list.active, target, s, t, r, q); } - glstate.texcoord[target-GL_TEXTURE0][0] = s; glstate.texcoord[target-GL_TEXTURE0][1] = t; - glstate.texcoord[target-GL_TEXTURE0][2] = r; glstate.texcoord[target-GL_TEXTURE0][3] = q; + noerrorShim(); + glstate->texcoord[target-GL_TEXTURE0][0] = s; glstate->texcoord[target-GL_TEXTURE0][1] = t; + glstate->texcoord[target-GL_TEXTURE0][2] = r; glstate->texcoord[target-GL_TEXTURE0][3] = q; } void glMultiTexCoord4f(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) AliasExport("glshim_glMultiTexCoord4f"); void glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q) AliasExport("glshim_glMultiTexCoord4f"); @@ -1381,8 +1443,8 @@ void glMultiTexCoord4fARB(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloa void glshim_glArrayElement(GLint i) { GLfloat *v; pointer_state_t *p; - p = &glstate.vao->pointers.color; - if (glstate.vao->color_array) { + p = &glstate->vao->pointers.color; + if (glstate->vao->color_array) { v = gl_pointer_index(p, i); GLfloat scale = 1.0f/gl_max_value(p->type); // color[3] defaults to 1.0f @@ -1395,8 +1457,8 @@ void glshim_glArrayElement(GLint i) { } glshim_glColor4fv(v); } - p = &glstate.vao->pointers.secondary; - if (glstate.vao->secondary_array) { + p = &glstate->vao->pointers.secondary; + if (glstate->vao->secondary_array) { v = gl_pointer_index(p, i); GLfloat scale = 1.0f/gl_max_value(p->type); @@ -1406,13 +1468,13 @@ void glshim_glArrayElement(GLint i) { } glshim_glSecondaryColor3fv(v); } - p = &glstate.vao->pointers.normal; - if (glstate.vao->normal_array) { + p = &glstate->vao->pointers.normal; + if (glstate->vao->normal_array) { v = gl_pointer_index(p, i); glshim_glNormal3fv(v); } - p = &glstate.vao->pointers.tex_coord[0]; - if (glstate.vao->tex_coord_array[0]) { + p = &glstate->vao->pointers.tex_coord[0]; + if (glstate->vao->tex_coord_array[0]) { v = gl_pointer_index(p, i); if (p->size<4) glshim_glTexCoord2fv(v); @@ -1421,8 +1483,8 @@ void glshim_glArrayElement(GLint i) { } int a; for (a=1; apointers.tex_coord[a]; - if (glstate.vao->tex_coord_array[a]) { + p = &glstate->vao->pointers.tex_coord[a]; + if (glstate->vao->tex_coord_array[a]) { v = gl_pointer_index(p, i); if (p->size<4) glshim_glMultiTexCoord2fv(GL_TEXTURE0+a, v); @@ -1430,8 +1492,8 @@ void glshim_glArrayElement(GLint i) { glshim_glMultiTexCoord4fv(GL_TEXTURE0+a, v); } } - p = &glstate.vao->pointers.vertex; - if (glstate.vao->vertex_array) { + p = &glstate->vao->pointers.vertex; + if (glstate->vao->vertex_array) { v = gl_pointer_index(p, i); if (p->size == 4) { glshim_glVertex4fv(v); @@ -1448,12 +1510,12 @@ void glArrayElement(GLint i) AliasExport("glshim_glArrayElement"); // so I can build a renderlist_t on the first call and hold onto it // maybe I need a way to call a renderlist_t with (first, count) void glshim_glLockArrays(GLint first, GLsizei count) { - glstate.list.locked = true; + glstate->list.locked = true; noerrorShim(); } void glLockArraysEXT(GLint first, GLsizei count) AliasExport("glshim_glLockArrays"); void glshim_glUnlockArrays() { - glstate.list.locked = false; + glstate->list.locked = false; noerrorShim(); } void glUnlockArraysEXT() AliasExport("glshim_glUnlockArrays"); @@ -1461,7 +1523,7 @@ void glUnlockArraysEXT() AliasExport("glshim_glUnlockArrays"); static renderlist_t *glshim_glGetList(GLuint list) { if (glIsList(list)) - return glstate.lists[list - 1]; + return glstate->lists[list - 1]; return NULL; } @@ -1472,18 +1534,18 @@ GLuint glshim_glGenLists(GLsizei range) { return 0; } noerrorShim(); - int start = glstate.list.count; - if (glstate.lists == NULL) { - glstate.list.cap += range + 100; - glstate.lists = malloc(glstate.list.cap * sizeof(uintptr_t)); - } else if (glstate.list.count + range > glstate.list.cap) { - glstate.list.cap += range + 100; - glstate.lists = realloc(glstate.lists, glstate.list.cap * sizeof(uintptr_t)); + int start = glstate->list.count; + if (glstate->lists == NULL) { + glstate->list.cap += range + 100; + glstate->lists = malloc(glstate->list.cap * sizeof(uintptr_t)); + } else if (glstate->list.count + range > glstate->list.cap) { + glstate->list.cap += range + 100; + glstate->lists = realloc(glstate->lists, glstate->list.cap * sizeof(uintptr_t)); } - glstate.list.count += range; + glstate->list.count += range; for (int i = 0; i < range; i++) { - glstate.lists[start+i] = NULL; + glstate->lists[start+i] = NULL; } return start + 1; } @@ -1497,43 +1559,43 @@ void glshim_glNewList(GLuint list, GLenum mode) { if (! glIsList(list)) return; noerrorShim(); - if (glstate.gl_batch) { - glstate.gl_batch = 0; + if (glstate->gl_batch) { + glstate->gl_batch = 0; flush(); } - glstate.list.name = list; - glstate.list.mode = mode; - // TODO: if glstate.list.active is already defined, we probably need to clean up here - glstate.list.active = alloc_renderlist(); - glstate.list.compiling = true; + glstate->list.name = list; + glstate->list.mode = mode; + // TODO: if glstate->list.active is already defined, we probably need to clean up here + glstate->list.active = alloc_renderlist(); + glstate->list.compiling = true; } void glNewList(GLuint list, GLenum mode) AliasExport("glshim_glNewList"); void glshim_glEndList() { noerrorShim(); - GLuint list = glstate.list.name; - if (glstate.list.compiling) { + GLuint list = glstate->list.name; + if (glstate->list.compiling) { // Free the previous list if it exist... - free_renderlist(glstate.lists[list - 1]); - glstate.lists[list - 1] = GetFirst(glstate.list.active); - glstate.list.compiling = false; - end_renderlist(glstate.list.active); - glstate.list.active = NULL; + free_renderlist(glstate->lists[list - 1]); + glstate->lists[list - 1] = GetFirst(glstate->list.active); + glstate->list.compiling = false; + end_renderlist(glstate->list.active); + glstate->list.active = NULL; if (gl_batch==1) { init_batch(); } - if (glstate.list.mode == GL_COMPILE_AND_EXECUTE) { + if (glstate->list.mode == GL_COMPILE_AND_EXECUTE) { glCallList(list); } } } void glEndList() AliasExport("glshim_glEndList"); +renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a); void glshim_glCallList(GLuint list) { noerrorShim(); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_CALLLIST); - glstate.list.active->glcall_list = list; + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + glstate->list.active = append_calllist(glstate->list.active, glshim_glGetList(list)); return; } // TODO: the output of this call can be compiled into another display list @@ -1544,15 +1606,15 @@ void glshim_glCallList(GLuint list) { void glCallList(GLuint list) AliasExport("glshim_glCallList"); void glPushCall(void *call) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_GLCALL); - rlPushCall(glstate.list.active, call); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_GLCALL); + rlPushCall(glstate->list.active, call); } } void glshim_glCallLists(GLsizei n, GLenum type, const GLvoid *lists) { #define call(name, type) \ - case name: glCallList(((type *)lists)[i] + glstate.list.base); break + case name: glCallList(((type *)lists)[i] + glstate->list.base); break // seriously wtf #define call_bytes(name, stride) \ @@ -1562,7 +1624,7 @@ void glshim_glCallLists(GLsizei n, GLenum type, const GLvoid *lists) { for (j = 0; j < stride; j++) { \ list += *(l + (i * stride + j)) << (stride - j); \ } \ - glshim_glCallList(list + glstate.list.base); \ + glshim_glCallList(list + glstate->list.base); \ break unsigned int i, j; @@ -1588,13 +1650,13 @@ void glshim_glCallLists(GLsizei n, GLenum type, const GLvoid *lists) { void glCallLists(GLsizei n, GLenum type, const GLvoid *lists) AliasExport("glshim_glCallLists"); void glshim_glDeleteList(GLuint list) { - if(glstate.gl_batch) { + if(glstate->gl_batch) { flush(); } renderlist_t *l = glshim_glGetList(list); if (l) { free_renderlist(l); - glstate.lists[list-1] = NULL; + glstate->lists[list-1] = NULL; } // lists just grow upwards, maybe use a better storage mechanism? @@ -1610,13 +1672,13 @@ void glDeleteLists(GLuint list, GLsizei range) AliasExport("glshim_glDeleteLists void glshim_glListBase(GLuint base) { noerrorShim(); - glstate.list.base = base; + glstate->list.base = base; } void glListBase(GLuint base) AliasExport("glshim_glListBase"); GLboolean glshim_glIsList(GLuint list) { noerrorShim(); - if (list - 1 < glstate.list.count) { + if (list - 1 < glstate->list.count) { return true; } return false; @@ -1629,23 +1691,21 @@ void glshim_glPolygonMode(GLenum face, GLenum mode) { errorShim(GL_INVALID_ENUM); if (face == GL_BACK) return; //TODO, handle face enum for polygon mode != GL_FILL - if ((glstate.list.compiling || glstate.gl_batch) && (glstate.list.active)) { - NewStage(glstate.list.active, STAGE_POLYGON); -/* if (glstate.list.active->polygon_mode) - glstate.list.active = extend_renderlist(glstate.list.active);*/ - glstate.list.active->polygon_mode = mode; + if ((glstate->list.compiling || glstate->gl_batch) && (glstate->list.active)) { + NewStage(glstate->list.active, STAGE_POLYGON); + glstate->list.active->polygon_mode = mode; return; } switch(mode) { case GL_LINE: case GL_POINT: - glstate.polygon_mode = mode; + glstate->polygon_mode = mode; break; case GL_FILL: - glstate.polygon_mode = 0; + glstate->polygon_mode = 0; break; default: - glstate.polygon_mode = 0; + glstate->polygon_mode = 0; } } void glPolygonMode(GLenum face, GLenum mode) AliasExport("glshim_glPolygonMode"); @@ -1660,14 +1720,14 @@ void glshim_glPushMatrix() { PUSH_IF_COMPILING(glPushMatrix); LOAD_GLES(glPushMatrix); // Alloc matrix stacks if needed - if (!glstate.projection_matrix) - alloc_matrix(&glstate.projection_matrix, MAX_STACK_PROJECTION); - if (!glstate.modelview_matrix) - alloc_matrix(&glstate.modelview_matrix, MAX_STACK_MODELVIEW); - if (!glstate.texture_matrix) { - glstate.texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX); + if (!glstate->projection_matrix) + alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION); + if (!glstate->modelview_matrix) + alloc_matrix(&glstate->modelview_matrix, MAX_STACK_MODELVIEW); + if (!glstate->texture_matrix) { + glstate->texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX); for (int i=0; itexture_matrix[i], MAX_STACK_TEXTURE); } // get matrix mode GLint matrix_mode; @@ -1676,20 +1736,20 @@ void glshim_glPushMatrix() { // go... switch(matrix_mode) { case GL_PROJECTION: - if (glstate.projection_matrix->topstack+16*glstate.projection_matrix->top++); + if (glstate->projection_matrix->topprojection_matrix->stack+16*glstate->projection_matrix->top++); } else errorShim(GL_STACK_OVERFLOW); break; case GL_MODELVIEW: - if (glstate.modelview_matrix->topstack+16*glstate.modelview_matrix->top++); + if (glstate->modelview_matrix->topmodelview_matrix->stack+16*glstate->modelview_matrix->top++); } else errorShim(GL_STACK_OVERFLOW); break; case GL_TEXTURE: - if (glstate.texture_matrix[glstate.texture.active]->topstack+16*glstate.texture_matrix[glstate.texture.active]->top++); + if (glstate->texture_matrix[glstate->texture.active]->toptexture_matrix[glstate->texture.active]->stack+16*glstate->texture_matrix[glstate->texture.active]->top++); } else errorShim(GL_STACK_OVERFLOW); break; @@ -1707,14 +1767,14 @@ void glshim_glPopMatrix() { PUSH_IF_COMPILING(glPopMatrix); LOAD_GLES(glPopMatrix); // Alloc matrix stacks if needed - if (!glstate.projection_matrix) - alloc_matrix(&glstate.projection_matrix, MAX_STACK_PROJECTION); - if (!glstate.modelview_matrix) - alloc_matrix(&glstate.modelview_matrix, MAX_STACK_MODELVIEW); - if (!glstate.texture_matrix) { - glstate.texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX); + if (!glstate->projection_matrix) + alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION); + if (!glstate->modelview_matrix) + alloc_matrix(&glstate->modelview_matrix, MAX_STACK_MODELVIEW); + if (!glstate->texture_matrix) { + glstate->texture_matrix = (matrixstack_t**)malloc(sizeof(matrixstack_t*)*MAX_TEX); for (int i=0; itexture_matrix[i], MAX_STACK_TEXTURE); } // get matrix mode GLint matrix_mode; @@ -1723,20 +1783,20 @@ void glshim_glPopMatrix() { noerrorShim(); switch(matrix_mode) { case GL_PROJECTION: - if (glstate.projection_matrix->top) { - glshim_glLoadMatrixf(glstate.projection_matrix->stack+16*--glstate.projection_matrix->top); + if (glstate->projection_matrix->top) { + glshim_glLoadMatrixf(glstate->projection_matrix->stack+16*--glstate->projection_matrix->top); } else errorShim(GL_STACK_UNDERFLOW); break; case GL_MODELVIEW: - if (glstate.modelview_matrix->top) { - glshim_glLoadMatrixf(glstate.modelview_matrix->stack+16*--glstate.modelview_matrix->top); + if (glstate->modelview_matrix->top) { + glshim_glLoadMatrixf(glstate->modelview_matrix->stack+16*--glstate->modelview_matrix->top); } else errorShim(GL_STACK_UNDERFLOW); break; case GL_TEXTURE: - if (glstate.texture_matrix[glstate.texture.active]->top) { - glshim_glLoadMatrixf(glstate.texture_matrix[glstate.texture.active]->stack+16*--glstate.texture_matrix[glstate.texture.active]->top); + if (glstate->texture_matrix[glstate->texture.active]->top) { + glshim_glLoadMatrixf(glstate->texture_matrix[glstate->texture.active]->stack+16*--glstate->texture_matrix[glstate->texture.active]->top); } else errorShim(GL_STACK_UNDERFLOW); break; @@ -1754,9 +1814,9 @@ GLenum glshim_glGetError() { LOAD_GLES(glGetError); if(glshim_noerror) return GL_NO_ERROR; - if (glstate.shim_error) { - GLenum tmp = glstate.last_error; - glstate.last_error = GL_NO_ERROR; + if (glstate->shim_error) { + GLenum tmp = glstate->last_error; + glstate->last_error = GL_NO_ERROR; return tmp; } return gles_glGetError(); @@ -1804,12 +1864,12 @@ void glBlendEquationSeparate(GLenum modeRGB, GLenum modeA) AliasExport("glshim_g void glBlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) AliasExport("glshim_glBlendEquationSeparate"); void glshim_glBlendFunc(GLenum sfactor, GLenum dfactor) { - if (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling)) { - if ((glstate.statebatch.blendfunc_s == sfactor) && (glstate.statebatch.blendfunc_d == dfactor)) + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { + if ((glstate->statebatch.blendfunc_s == sfactor) && (glstate->statebatch.blendfunc_d == dfactor)) return; // nothing to do... - if (!glstate.statebatch.blendfunc_s) { - glstate.statebatch.blendfunc_s = sfactor; - glstate.statebatch.blendfunc_d = dfactor; + if (!glstate->statebatch.blendfunc_s) { + glstate->statebatch.blendfunc_s = sfactor; + glstate->statebatch.blendfunc_d = dfactor; } else { flush(); } @@ -1889,41 +1949,42 @@ void glStencilMaskSeparate(GLenum face, GLuint mask) AliasExport("glshim_glStenc void init_statebatch() { - memset(&glstate.statebatch, 0, sizeof(statebatch_t)); + memset(&glstate->statebatch, 0, sizeof(statebatch_t)); } void flush() { // flush internal list - //printf("flush glstate.list.active=%p, gl_batch=%i(%i)\n", glstate.list.active, glstate.gl_batch, gl_batch); - renderlist_t *mylist = glstate.list.active; + //printf("flush glstate->list.active=%p, gl_batch=%i(%i)\n", glstate->list.active, glstate->gl_batch, gl_batch); + renderlist_t *mylist = glstate->list.active; if (mylist) { - GLuint old = glstate.gl_batch; - glstate.list.active = NULL; - glstate.gl_batch = 0; - end_renderlist(mylist); + GLuint old = glstate->gl_batch; + glstate->list.active = NULL; + glstate->gl_batch = 0; + mylist = end_renderlist(mylist); draw_renderlist(mylist); free_renderlist(mylist); - glstate.gl_batch = old; + glstate->gl_batch = old; } - if (glstate.gl_batch) init_statebatch(); - glstate.list.active = (glstate.gl_batch)?alloc_renderlist():NULL; + if (glstate->gl_batch) init_statebatch(); + glstate->list.active = (glstate->gl_batch)?alloc_renderlist():NULL; } void init_batch() { - glstate.list.active = alloc_renderlist(); + glstate->list.active = alloc_renderlist(); init_statebatch(); - glstate.gl_batch = 1; + glstate->gl_batch = 1; + glstate->init_batch = 1; } void glshim_glFlush() { LOAD_GLES(glFlush); - if (glstate.list.active && !glstate.gl_batch) { + if (glstate->list.active && !glstate->gl_batch) { errorShim(GL_INVALID_OPERATION); return; } - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); gles_glFlush(); errorGL(); @@ -1933,11 +1994,11 @@ void glFlush() AliasExport("glshim_glFlush"); void glshim_glFinish() { LOAD_GLES(glFinish); - if (glstate.list.active && !glstate.gl_batch) { + if (glstate->list.active && !glstate->gl_batch) { errorShim(GL_INVALID_OPERATION); return; } - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); gles_glFinish(); errorGL(); @@ -1947,10 +2008,10 @@ void glFinish() AliasExport("glshim_glFinish"); void glshim_glLoadMatrixf(const GLfloat * m) { LOAD_GLES(glLoadMatrixf); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_MATRIX); - glstate.list.active->matrix_op = 1; - memcpy(glstate.list.active->matrix_val, m, 16*sizeof(GLfloat)); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_MATRIX); + glstate->list.active->matrix_op = 1; + memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); return; } gles_glLoadMatrixf(m); @@ -1960,10 +2021,10 @@ void glLoadMatrixf(const GLfloat * m) AliasExport("glshim_glLoadMatrixf"); void glshim_glMultMatrixf(const GLfloat * m) { LOAD_GLES(glMultMatrixf); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_MATRIX); - glstate.list.active->matrix_op = 2; - memcpy(glstate.list.active->matrix_val, m, 16*sizeof(GLfloat)); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_MATRIX); + glstate->list.active->matrix_op = 2; + memcpy(glstate->list.active->matrix_val, m, 16*sizeof(GLfloat)); return; } gles_glMultMatrixf(m); @@ -1973,10 +2034,10 @@ void glMultMatrixf(const GLfloat * m) AliasExport("glshim_glMultMatrixf"); void glshim_glFogfv(GLenum pname, const GLfloat* params) { LOAD_GLES(glFogfv); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { if (pname == GL_FOG_COLOR) { - NewStage(glstate.list.active, STAGE_FOG); - rlFogOp(glstate.list.active, 1, params); + NewStage(glstate->list.active, STAGE_FOG); + rlFogOp(glstate->list.active, 1, params); return; } } @@ -2006,9 +2067,10 @@ void glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) AliasExport("glsh void glshim_glGetPointerv(GLenum pname, GLvoid* *params) { noerrorShim(); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); switch(pname) { case GL_COLOR_ARRAY_POINTER: - *params = (void*)glstate.vao->pointers.color.pointer; + *params = (void*)glstate->vao->pointers.color.pointer; break; case GL_EDGE_FLAG_ARRAY_POINTER: *params = NULL; @@ -2019,16 +2081,16 @@ void glshim_glGetPointerv(GLenum pname, GLvoid* *params) { case GL_INDEX_ARRAY_POINTER: *params = NULL; case GL_NORMAL_ARRAY_POINTER: - *params = (void*)glstate.vao->pointers.normal.pointer; + *params = (void*)glstate->vao->pointers.normal.pointer; break; case GL_TEXTURE_COORD_ARRAY_POINTER: - *params = (void*)glstate.vao->pointers.tex_coord[glstate.texture.client].pointer; + *params = (void*)glstate->vao->pointers.tex_coord[glstate->texture.client].pointer; break; case GL_SELECTION_BUFFER_POINTER: - *params = glstate.selectbuf.buffer; + *params = glstate->selectbuf.buffer; break; case GL_VERTEX_ARRAY_POINTER : - *params = (void*)glstate.vao->pointers.vertex.pointer; + *params = (void*)glstate->vao->pointers.vertex.pointer; break; default: errorShim(GL_INVALID_ENUM); @@ -2056,8 +2118,8 @@ void glPointParameteriv(GLenum pname, const GLint * params) AliasExport("glshim_ void glshim_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) { LOAD_GLES_OES(glMultiDrawArrays); - if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (glstate.list.active && (glstate.list.compiling || glstate.gl_batch)) - || (glstate.render_mode == GL_SELECT) || ((glstate.polygon_mode == GL_LINE) || (glstate.polygon_mode == GL_POINT)) ) + if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) + || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) ) { // divide the call // TODO optimize with forcing Batch mode @@ -2077,8 +2139,8 @@ void glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GL void glshim_glMultiDrawElements( GLenum mode, GLsizei *count, GLenum type, const void * const *indices, GLsizei primcount) { LOAD_GLES_OES(glMultiDrawElements); - if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (glstate.list.active && (glstate.list.compiling || glstate.gl_batch)) - || (glstate.render_mode == GL_SELECT) || ((glstate.polygon_mode == GL_LINE) || (glstate.polygon_mode == GL_POINT)) || (type != GL_UNSIGNED_SHORT) ) + if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) + || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) || (type != GL_UNSIGNED_SHORT) ) { // divide the call // TODO optimize with forcing Batch mode diff --git a/project/jni/glshim/src/gl/gl.h b/project/jni/glshim/src/gl/gl.h index 8142d759d..0de82cce6 100755 --- a/project/jni/glshim/src/gl/gl.h +++ b/project/jni/glshim/src/gl/gl.h @@ -21,6 +21,29 @@ #define AliasExport(name) __attribute__((alias(name))) __attribute__((visibility("default"))) #endif +#ifndef FASTMATH +#ifdef __GNUC__ + #ifdef __arm__ + #ifdef __ARM_PCS_VFP + //#warning Arm Hardfloat detected + #define FASTMATH + #else + #if defined(__ARM_FP) && defined(PANDORA) + //#warning Arm SoftFP detected + #define FASTMATH __attribute__((pcs("aapcs-vfp"))) + #else + //#warning Arm no FP detected + #define FASTMATH + #endif + #endif + #else + #define FASTMATH + #endif +#else + #define FASTMATH +#endif +#endif + #ifndef GL_H #define GL_H @@ -90,6 +113,7 @@ typedef EGLSurface (*eglCreateStreamProducerSurfaceKHR_PTR)(EGLDisplay dpy, EGLC #endif #include "loader.h" +packed_call_t* glCopyPackedCall(const packed_call_t *packed); #define checkError(code) \ {int error; while ((error = glGetError())) {} \ @@ -153,7 +177,7 @@ typedef EGLSurface (*eglCreateStreamProducerSurfaceKHR_PTR)(EGLDisplay dpy, EGLC #define GL_TYPE_SWITCH_MAX(name, var, type, code, extra) \ switch (type) { \ - GL_TYPE_CASE_MAX(name, var, GL_DOUBLE, GLdouble, code, 1.0d) \ + GL_TYPE_CASE_MAX(name, var, GL_DOUBLE, GLdouble, code, 1.0) \ GL_TYPE_CASE_MAX(name, var, GL_FLOAT, GLfloat, code, 1.0f) \ GL_TYPE_CASE_MAX(name, var, GL_INT, GLint, code, 2147483647l) \ GL_TYPE_CASE_MAX(name, var, GL_SHORT, GLshort, code, 32767) \ @@ -165,8 +189,8 @@ typedef EGLSurface (*eglCreateStreamProducerSurfaceKHR_PTR)(EGLDisplay dpy, EGLC } #define PUSH_IF_COMPILING_EXT(nam, ...) \ - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { \ - NewStage(glstate.list.active, STAGE_GLCALL); \ + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { \ + NewStage(glstate->list.active, STAGE_GLCALL); \ push_##nam(__VA_ARGS__); \ noerrorShim(); \ return (nam##_RETURN)0; \ @@ -402,16 +426,16 @@ void flush(); void init_batch(); #include "state.h" -extern glstate_t glstate; +extern glstate_t *glstate; GLuint gl_batch; // 0 = off, 1 = on static inline void errorGL() { // next glGetError will be from GL - glstate.shim_error = 0; + glstate->shim_error = 0; } static inline void errorShim(GLenum error) { // next glGetError will be "error" from glShim - glstate.shim_error = 1; - glstate.last_error = error; + glstate->shim_error = 1; + glstate->last_error = error; } static inline void noerrorShim() { errorShim(GL_NO_ERROR); diff --git a/project/jni/glshim/src/gl/light.c b/project/jni/glshim/src/gl/light.c index 04f58a009..960c38ff1 100755 --- a/project/jni/glshim/src/gl/light.c +++ b/project/jni/glshim/src/gl/light.c @@ -3,7 +3,7 @@ #ifndef USE_ES2 void glshim_glLightModelf(GLenum pname, GLfloat param) { //printf("%sglLightModelf(%04X, %.2f)\n", (state.list.compiling)?"list":"", pname, param); - if (glstate.list.compiling && glstate.list.active) { + if (glstate->list.compiling && glstate->list.active) { GLfloat dummy[4]; dummy[0]=param; glshim_glLightModelfv(pname, dummy); @@ -25,13 +25,13 @@ void glshim_glLightModelf(GLenum pname, GLfloat param) { void glshim_glLightModelfv(GLenum pname, const GLfloat* params) { //printf("%sglLightModelfv(%04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", pname, params[0], params[1], params[2], params[3]); - if (glstate.list.compiling && glstate.list.active) { - NewStage(glstate.list.active, STAGE_LIGHTMODEL); -/* if (glstate.list.active->lightmodel) - glstate.list.active = extend_renderlist(glstate.list.active);*/ - glstate.list.active->lightmodelparam = pname; - glstate.list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); - memcpy(glstate.list.active->lightmodel, params, 4*sizeof(GLfloat)); + if (glstate->list.compiling && glstate->list.active) { + NewStage(glstate->list.active, STAGE_LIGHTMODEL); +/* if (glstate->list.active->lightmodel) + glstate->list.active = extend_renderlist(glstate->list.active);*/ + glstate->list.active->lightmodelparam = pname; + glstate->list.active->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); + memcpy(glstate->list.active->lightmodel, params, 4*sizeof(GLfloat)); noerrorShim(); return; } @@ -50,10 +50,10 @@ void glshim_glLightModelfv(GLenum pname, const GLfloat* params) { } void glshim_glLightfv(GLenum light, GLenum pname, const GLfloat* params) { -//printf("%sglLightfv(%04X, %04X, [%.2f, %.2f, %.2f, %.2f])\n", (state.list.compiling)?"list":"", light, pname, params[0], params[1], params[2], params[3]); - if (glstate.list.compiling && glstate.list.active) { - NewStage(glstate.list.active, STAGE_LIGHT); - rlLightfv(glstate.list.active, light, pname, params); +//printf("%sglLightfv(%04X, %04X, %p=[%.2f, %.2f, %.2f, %.2f])\n", (glstate->list.compiling)?"list":"", light, pname, params, (params)?params[0]:0.0f, (params)?params[1]:0.0f, (params)?params[2]:0.0f, (params)?params[3]:0.0f); + if (glstate->list.compiling && glstate->list.active) { + NewStage(glstate->list.active, STAGE_LIGHT); + rlLightfv(glstate->list.active, light, pname, params); noerrorShim(); return; } diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 1e729d1a9..d480b72f0 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -19,11 +19,11 @@ renderlist_t *alloc_renderlist() { list->matrix_val[15] = 1.0f; list->lightmodelparam = GL_LIGHT_MODEL_AMBIENT; list->target_texture = GL_TEXTURE_2D; - list->tmu = glstate.texture.active; + list->tmu = glstate->texture.active; - memcpy(list->lastNormal, glstate.normal, 3*sizeof(GLfloat)); - memcpy(list->lastSecondaryColors, glstate.secondary, 3*sizeof(GLfloat)); - memcpy(list->lastColors, glstate.color, 4*sizeof(GLfloat)); + memcpy(list->lastNormal, glstate->normal, 3*sizeof(GLfloat)); + memcpy(list->lastSecondaryColors, glstate->secondary, 3*sizeof(GLfloat)); + memcpy(list->lastColors, glstate->color, 4*sizeof(GLfloat)); list->open = true; return list; @@ -33,8 +33,6 @@ bool ispurerender_renderlist(renderlist_t *list) { // return true if renderlist contains only rendering command, no state changes if (list->calls.len) return false; - if (list->glcall_list) - return false; if (list->matrix_op) return false; if (list->raster_op) @@ -59,6 +57,10 @@ bool ispurerender_renderlist(renderlist_t *list) { return true; } +bool isempty_renderlist(renderlist_t *list) { + return (list->stage == STAGE_NONE); +} + int rendermode_dimensions(GLenum mode) { // return 1 for points, 2 for any lines, 3 for any triangles, 4 for any Quad and 5 for polygon switch (mode) { @@ -222,7 +224,7 @@ void renderlist_quads2triangles(renderlist_t *a) { a->indices[j+5] = vind(i+3); } a->ilen = ilen; - if ((ind) && !a->shared_arrays) free(ind); + if ((ind) && (!a->shared_indices || ((*a->shared_indices)--)==0)) {free(ind); free(a->shared_indices);} a->mode = GL_TRIANGLES; } #undef vind @@ -266,7 +268,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { // lets append all the arrays unsigned long cap = a->cap; if (a->len + b->len >= cap) cap += b->cap + DEFAULT_RENDER_LIST_CAPACITY; - if (a->shared_arrays) { + if (a->shared_arrays && ((*a->shared_arrays)--)>0) { // Unshare if shared (shared array are not used for now) a->cap = cap; GLfloat *tmp; @@ -297,14 +299,6 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { memcpy(a->tex[i], tmp, 4*a->len*sizeof(GLfloat)); } } - if (a->indices) { - GLushort* tmpi = a->indices; - a->indice_cap = ((ilen_a)?ilen_a:a->len) + ((ilen_b)?ilen_b:b->len); - if (a->indice_cap > 48) a->indice_cap = (a->indice_cap+511)&~511; - a->indices = (GLushort*)malloc(a->indice_cap*sizeof(GLushort)); - memcpy(a->indices, tmpi, a->ilen*sizeof(GLushort)); - } - a->shared_arrays = false; } else { if (a->cap < cap) { a->cap = cap; @@ -316,6 +310,17 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { realloc_sublist(a->tex[i], 4, cap); } } + if(a->shared_arrays && *a->shared_arrays==0) {free(a->shared_arrays); a->shared_arrays=0;} + if (a->shared_indices && ((*a->shared_indices)--)>0) { + if (a->indices) { + GLushort* tmpi = a->indices; + a->indice_cap = ((ilen_a)?ilen_a:a->len) + ((ilen_b)?ilen_b:b->len); + if (a->indice_cap > 48) a->indice_cap = (a->indice_cap+511)&~511; + a->indices = (GLushort*)malloc(a->indice_cap*sizeof(GLushort)); + memcpy(a->indices, tmpi, a->ilen*sizeof(GLushort)); + } + } + if(a->shared_indices && *a->shared_indices==0) {free(a->shared_indices); a->shared_indices=0;} // append arrays if (a->vert) memcpy(a->vert+a->len*4, b->vert, b->len*4*sizeof(GLfloat)); if (a->normal) memcpy(a->normal+a->len*3, b->normal, b->len*3*sizeof(GLfloat)); @@ -427,6 +432,11 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { // lenghts a->len += b->len; a->ilen += ilen_b; + // copy the lastColors if needed + if(b->lastColorsSet) { + a->lastColorsSet = 1; + memcpy(a->lastColors, b->lastColors, 4*sizeof(GLfloat)); + } //all done a->stage = STAGE_DRAW; // just in case return; @@ -443,7 +453,6 @@ renderlist_t *extend_renderlist(renderlist_t *list) { // just in case memcpy(new->lastNormal, list->lastNormal, 3*sizeof(GLfloat)); memcpy(new->lastSecondaryColors, list->lastSecondaryColors, 3*sizeof(GLfloat)); - memcpy(new->lastColors, list->lastColors, 4*sizeof(GLfloat)); // detach list->prev = NULL; // free list now @@ -458,9 +467,123 @@ renderlist_t *extend_renderlist(renderlist_t *list) { memcpy(new->lastNormal, list->lastNormal, 3*sizeof(GLfloat)); memcpy(new->lastSecondaryColors, list->lastSecondaryColors, 3*sizeof(GLfloat)); memcpy(new->lastColors, list->lastColors, 4*sizeof(GLfloat)); + new->lastColorsSet = list->lastColorsSet; return new; } } +int Cap2BatchState(GLenum cap); + +renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) +{ + // go to end of list + while(list->next) list = list->next; + while(a) { + if(ispurerender_renderlist(a) && islistscompatible_renderlist(list, a)) { + // append list! + append_renderlist(list, a); + } else { + // create a new appended list + renderlist_t *new = alloc_renderlist(); + // prepared shared stuff... + if(a->len && !a->shared_arrays) { + a->shared_arrays = (int*)malloc(sizeof(int)); + *a->shared_arrays = 0; + } + if(a->ilen && !a->shared_indices) { + a->shared_indices = (int*)malloc(sizeof(int)); + *a->shared_indices = 0; + } + if(a->calls.cap && !a->shared_calls) { + a->shared_calls = (int*)malloc(sizeof(int)); + *a->shared_calls = 0; + } + // batch copy first + memcpy(new, a, sizeof(renderlist_t)); + list->next = new; + new->prev = list; + // ok, now on new list + list = new; + // copy the many list arrays + if(glstate->gl_batch) { + if (list->popattribute) { + // invalidate all batchstate + for (int i=0; istatebatch.bound_targ[i] = 0xffff; + glstate->statebatch.bound_tex[i] = 0xffffffff; + } + for (int i=0; istatebatch.enabled[i] = 3; //undefined + } + } + } + if (list->calls.cap > 0) { + ++(*list->shared_calls); + /* + list->calls.calls = (packed_call_t**)malloc(sizeof(packed_call_t*)*a->calls.cap); + for (int i = 0; i < list->calls.len; i++) { + list->calls.calls[i] = glCopyPackedCall(a->calls.calls[i]); + }*/ + // in case of batch mode, need to update the batchstate... + if(glstate->gl_batch) { + for (int i = 0; i < list->calls.len; i++) { + packed_call_t *p = list->calls.calls[i]; + if(p->func == &glshim_glEnable) { + int wich_cap = Cap2BatchState(((glEnable_PACKED*)p)->args.a1); + if(wich_cap!=ENABLED_LAST) glstate->statebatch.enabled[wich_cap] = 1; + } + if(p->func == &glshim_glDisable) { + int wich_cap = Cap2BatchState(((glDisable_PACKED*)p)->args.a1); + if(wich_cap!=ENABLED_LAST) glstate->statebatch.enabled[wich_cap] = 0; + } + } + } + } + if(list->len) { + ++(*list->shared_arrays); + } + #undef PROCESS + if(list->ilen) { + ++(*list->shared_indices); + } + #define PROCESS(W, T, C) if(list->W) { \ + list->W = kh_init(W); \ + T *m, *m2; \ + khint_t k; \ + int ret; \ + kh_foreach_value(a->W, m, \ + k = kh_put(W, list->W, C, &ret); \ + m2= kh_value(list->W, k) = malloc(sizeof(T)); \ + memcpy(m2, m, sizeof(T)); \ + ); \ + } + PROCESS(material, rendermaterial_t, m->pname); + PROCESS(light, renderlight_t, m->pname | ((m->which-GL_LIGHT0)<<16)); + PROCESS(texgen, rendertexgen_t, m->pname | ((m->coord-GL_S)<<16)); + #undef PROCESS + if (list->lightmodel) { + list->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); + memcpy(list->lightmodel, a->lightmodel, 4*sizeof(GLfloat)); + } + if (list->raster) { + (*list->raster->shared)++; + } + // Update other batchstate states + if(glstate->gl_batch) { + if (list->set_tmu) { + glstate->statebatch.active_tex = GL_TEXTURE0 + list->tmu; + glstate->statebatch.active_tex_changed = 1; + } + if (list->set_texture) { + const int batch_activetex = glstate->statebatch.active_tex_changed?(glstate->statebatch.active_tex-GL_TEXTURE0):glstate->texture.active; + glstate->statebatch.bound_targ[batch_activetex] = list->target_texture; + glstate->statebatch.bound_tex[batch_activetex] = list->texture; + } + } + } + a = a->next; + } + return list; +} void free_renderlist(renderlist_t *list) { // test if list is NULL @@ -472,20 +595,25 @@ void free_renderlist(renderlist_t *list) { renderlist_t *next; do { - if (list->calls.len > 0) { + if ((list->calls.cap > 0) && (!list->shared_calls || ((*list->shared_calls)--)==0)) { + if(list->shared_calls) free(list->shared_calls); for (int i = 0; i < list->calls.len; i++) { free(list->calls.calls[i]); } free(list->calls.calls); } int a; - if (!list->shared_arrays) { + if (!list->shared_arrays || ((*list->shared_arrays)--)==0) { + if (list->shared_arrays) free(list->shared_arrays); if (list->vert) free(list->vert); if (list->normal) free(list->normal); if (list->color) free(list->color); if (list->secondary) free(list->secondary); for (a=0; atex[a]) free(list->tex[a]); + } + if (!list->shared_indices || ((*list->shared_indices)--)==0) { + if (list->shared_indices) free(list->shared_indices); if (list->indices) free(list->indices); } @@ -514,7 +642,7 @@ void free_renderlist(renderlist_t *list) { if (list->lightmodel) free(list->lightmodel); - if (list->raster) { + if (list->raster && !(*(list->raster->shared)--)) { if (list->raster->texture) glshim_glDeleteTextures(1, &list->raster->texture); free(list->raster); @@ -525,7 +653,6 @@ void free_renderlist(renderlist_t *list) { } while ((list = next)); } -static inline void resize_renderlist(renderlist_t *list) { if (list->len >= list->cap) { list->cap += DEFAULT_RENDER_LIST_CAPACITY; @@ -545,7 +672,7 @@ void adjust_renderlist(renderlist_t *list) { list->stage = STAGE_LAST; list->open = false; for (int a=0; atexture.bound[a]; // in case of Texture bounding inside a list if (list->set_texture && (list->tmu == a)) bound = glshim_getTexture(list->target_texture, list->texture); @@ -554,15 +681,15 @@ void adjust_renderlist(renderlist_t *list) { tex_coord_npot(list->tex[a], list->len, bound->width, bound->height, bound->nwidth, bound->nheight); } // GL_ARB_texture_rectangle - if ((list->tex[a]) && glstate.texture.rect_arb[a] && (bound)) { + if ((list->tex[a]) && glstate->texture.rect_arb[a] && (bound)) { tex_coord_rect_arb(list->tex[a], list->len, bound->width, bound->height); } } } -void end_renderlist(renderlist_t *list) { +renderlist_t* end_renderlist(renderlist_t *list) { if (!list || ! list->open) - return; + return list; adjust_renderlist(list); @@ -581,6 +708,15 @@ void end_renderlist(renderlist_t *list) { list->mode = GL_TRIANGLE_STRIP; break; } + if(list->prev && isempty_renderlist(list)) { + renderlist_t *p = list; + list = list->prev; + list->next = NULL; + p->prev = NULL; + free_renderlist(p); + } + + return list; } void draw_renderlist(renderlist_t *list) { @@ -588,7 +724,7 @@ void draw_renderlist(renderlist_t *list) { // go to 1st... while (list->prev) list = list->prev; // ok, go on now, draw everything -//printf("draw_renderlist %p, gl_batch=%i, size=%i, mode=%s(%s), ilen=%d, next=%p, color=%p, secondarycolor=%p\n", list, glstate.gl_batch, list->len, PrintEnum(list->mode), PrintEnum(list->mode_init), list->ilen, list->next, list->color, list->secondary); +//printf("draw_renderlist %p, gl_batch=%i, size=%i, mode=%s(%s), ilen=%d, next=%p, color=%p, secondarycolor=%p\n", list, glstate->gl_batch, list->len, PrintEnum(list->mode), PrintEnum(list->mode_init), list->ilen, list->next, list->color, list->secondary); LOAD_GLES(glDrawArrays); LOAD_GLES(glDrawElements); #ifdef USE_ES2 @@ -611,15 +747,12 @@ void draw_renderlist(renderlist_t *list) { do { // close if needed! if (list->open) - end_renderlist(list); + list = end_renderlist(list); // push/pop attributes if (list->pushattribute) glshim_glPushAttrib(list->pushattribute); if (list->popattribute) glshim_glPopAttrib(); - // do call_list - if (list->glcall_list) - glshim_glCallList(list->glcall_list); call_list_t *cl = &list->calls; if (cl->len > 0) { for (int i = 0; i < cl->len; i++) { @@ -650,7 +783,7 @@ void draw_renderlist(renderlist_t *list) { glshim_glBindTexture(list->target_texture, list->texture); } // raster - old_tex = glstate.texture.active; + old_tex = glstate->texture.active; if (list->raster_op) { if (list->raster_op==1) { glshim_glRasterPos3f(list->raster_xyz[0], list->raster_xyz[1], list->raster_xyz[2]); @@ -719,19 +852,19 @@ void draw_renderlist(renderlist_t *list) { if (list->vert) { gles_glEnableClientState(GL_VERTEX_ARRAY); gles_glVertexPointer(4, GL_FLOAT, 0, list->vert); - glstate.clientstate.vertex_array = 1; + glstate->clientstate.vertex_array = 1; } else { gles_glDisableClientState(GL_VERTEX_ARRAY); - glstate.clientstate.vertex_array = false; + glstate->clientstate.vertex_array = false; } if (list->normal) { gles_glEnableClientState(GL_NORMAL_ARRAY); gles_glNormalPointer(GL_FLOAT, 0, list->normal); - glstate.clientstate.normal_array = 1; + glstate->clientstate.normal_array = 1; } else { gles_glDisableClientState(GL_NORMAL_ARRAY); - glstate.clientstate.normal_array = 0; + glstate->clientstate.normal_array = 0; } indices = list->indices; @@ -739,8 +872,8 @@ void draw_renderlist(renderlist_t *list) { final_colors = NULL; if (list->color) { gles_glEnableClientState(GL_COLOR_ARRAY); - glstate.clientstate.color_array = 1; - if (glstate.enable.color_sum && (list->secondary)) { + glstate->clientstate.color_array = 1; + if (glstate->enable.color_sum && (list->secondary)) { final_colors=(GLfloat*)malloc(list->len * 4 * sizeof(GLfloat)); if (indices) { for (int i=0; iilen; i++) @@ -759,14 +892,14 @@ void draw_renderlist(renderlist_t *list) { } } else { gles_glDisableClientState(GL_COLOR_ARRAY); - glstate.clientstate.color_array = 0; + glstate->clientstate.color_array = 0; } GLuint texture; bool stipple; stipple = false; if (! list->tex[0]) { // TODO: do we need to support GL_LINE_STRIP? - if (list->mode == GL_LINES && glstate.enable.line_stipple) { + if (list->mode == GL_LINES && glstate->enable.line_stipple) { stipple = true; glshim_glPushAttrib(GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT | GL_TEXTURE_BIT); glshim_glEnable(GL_BLEND); @@ -780,55 +913,54 @@ void draw_renderlist(renderlist_t *list) { for (int a=0; aenable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a])) { gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilenlen)?indices:NULL, (list->ilenlen)?list->ilen:0); - } else if (glstate.enable.texture_2d[a] && (list->tex[a]==NULL)) { + } else if (glstate->enable.texture_2d[a] && (list->tex[a]==NULL)) { gen_tex_coords(list->vert, list->normal, &texgened[a], list->len, &needclean[a], a, (list->ilenlen)?indices:NULL, (list->ilenlen)?list->ilen:0); } } - old_tex = glstate.texture.client; + old_tex = glstate->texture.client; + GLuint cur_tex = old_tex; + #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int a=0; atex[a] || texgened[a])/* && glstate.enable.texture_2d[a]*/) { - glshim_glClientActiveTexture(GL_TEXTURE0+a); + if ((list->tex[a] || texgened[a])/* && glstate->enable.texture_2d[a]*/) { + TEXTURE(a); gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[a] = 1; + glstate->clientstate.tex_coord_array[a] = 1; gles_glTexCoordPointer(4, GL_FLOAT, 0, (texgened[a])?texgened[a]:list->tex[a]); } else { - if (glstate.clientstate.tex_coord_array[a]) { - glshim_glClientActiveTexture(GL_TEXTURE0+a); + if (glstate->clientstate.tex_coord_array[a]) { + TEXTURE(a); gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[a] = 0; + glstate->clientstate.tex_coord_array[a] = 0; } -//else if (!glstate.enable.texgen_s[a] && glstate.enable.texture_2d[a]) printf("LIBGL: texture_2d[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len); +//else if (!glstate->enable.texgen_s[a] && glstate->enable.texture_2d[a]) printf("LIBGL: texture_2d[%i] without TexCoord, mode=0x%04X (init=0x%04X), listlen=%i\n", a, list->mode, list->mode_init, list->len); } - } - for (int aa=0; aaenable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) { + TEXTURE(a); gles_glEnable(GL_TEXTURE_2D); } } - if (glstate.texture.client != old_tex) glshim_glClientActiveTexture(GL_TEXTURE0+old_tex); - + if (glstate->texture.client != old_tex) TEXTURE(old_tex); + #undef TEXTURE GLenum mode; mode = list->mode; - if ((glstate.polygon_mode == GL_LINE) && (mode>=GL_TRIANGLES)) + if ((glstate->polygon_mode == GL_LINE) && (mode>=GL_TRIANGLES)) mode = GL_LINES; - if ((glstate.polygon_mode == GL_POINT) && (mode>=GL_TRIANGLES)) + if ((glstate->polygon_mode == GL_POINT) && (mode>=GL_TRIANGLES)) mode = GL_POINTS; if (indices) { - if (glstate.render_mode == GL_SELECT) { + if (glstate->render_mode == GL_SELECT) { pointer_state_t vtx; vtx.pointer = list->vert; vtx.type = GL_FLOAT; vtx.size = 4; vtx.stride = 0; - vtx.buffer = NULL; select_glDrawElements(&vtx, list->mode, list->ilen, GL_UNSIGNED_SHORT, indices); } else { - if (glstate.polygon_mode == GL_LINE && list->mode_init>=GL_TRIANGLES) { + if (glstate->polygon_mode == GL_LINE && list->mode_init>=GL_TRIANGLES) { int n, s; int ilen = list->ilen; GLushort ind_line[ilen*4+2]; @@ -911,17 +1043,16 @@ void draw_renderlist(renderlist_t *list) { } } } else { - if (glstate.render_mode == GL_SELECT) { + if (glstate->render_mode == GL_SELECT) { pointer_state_t vtx; vtx.pointer = list->vert; vtx.type = GL_FLOAT; vtx.size = 4; vtx.stride = 0; - vtx.buffer = NULL; select_glDrawArrays(&vtx, list->mode, 0, list->len); } else { int len = list->len; - if ((glstate.polygon_mode == GL_LINE) && (list->mode_init>=GL_TRIANGLES)) { + if ((glstate->polygon_mode == GL_LINE) && (list->mode_init>=GL_TRIANGLES)) { int n, s; GLushort ind_line[len*4+2]; int k=0; @@ -1005,22 +1136,24 @@ void draw_renderlist(renderlist_t *list) { } } } + #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} for (int a=0; aenable.texture_2d[a] && (glstate->enable.texture_1d[a] || glstate->enable.texture_3d[a])) { + TEXTURE(a); gles_glDisable(GL_TEXTURE_2D); } } - if (glstate.texture.client!=old_tex) - glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); + if (glstate->texture.client!=old_tex) + TEXTURE(old_tex); + #undef TEXTURE if (final_colors) free(final_colors); @@ -1034,7 +1167,7 @@ void draw_renderlist(renderlist_t *list) { // gl function wrappers -void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { +void FASTMATH rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { if (list->vert == NULL) { list->vert = alloc_sublist(4, list->cap); } else { @@ -1042,28 +1175,28 @@ void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) } if (list->normal) { - GLfloat *normal = list->normal + (list->len * 3); + GLfloat * const normal = list->normal + (list->len * 3); memcpy(normal, list->lastNormal, sizeof(GLfloat) * 3); } if (list->color) { - GLfloat *color = list->color + (list->len * 4); - memcpy(color, glstate.color, sizeof(GLfloat) * 4); + GLfloat * const color = list->color + (list->len * 4); + memcpy(color, glstate->color, sizeof(GLfloat) * 4); } if (list->secondary) { - GLfloat *secondary = list->secondary + (list->len * 4); - memcpy(secondary, glstate.secondary, sizeof(GLfloat) * 4); + GLfloat * const secondary = list->secondary + (list->len * 4); + memcpy(secondary, glstate->secondary, sizeof(GLfloat) * 4); } for (int a=0; atex[a]) { - GLfloat *tex = list->tex[a] + (list->len * 4); - memcpy(tex, glstate.texcoord[a], sizeof(GLfloat) * 4); + GLfloat * const tex = list->tex[a] + (list->len * 4); + memcpy(tex, glstate->texcoord[a], sizeof(GLfloat) * 4); } } - GLfloat *vert = list->vert + (list->len++ * 4); + GLfloat * const vert = list->vert + (list->len++ * 4); vert[0] = x; vert[1] = y; vert[2] = z; vert[3] = w; } @@ -1084,6 +1217,7 @@ void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) { void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) { if (list->color == NULL) { + list->lastColorsSet = 1; list->color = alloc_sublist(4, list->cap); // catch up int i; @@ -1096,8 +1230,9 @@ void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) { }*/ } - GLfloat *color = glstate.color; + GLfloat *color = glstate->color; color[0] = r; color[1] = g; color[2] = b; color[3] = a; + memcpy(list->lastColors, color, 4*sizeof(GLfloat)); } void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) { @@ -1111,7 +1246,7 @@ void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) { } } - GLfloat *color = glstate.secondary; + GLfloat *color = glstate->secondary; color[0] = r; color[1] = g; color[2] = b; color[3] = 0.0f; } @@ -1211,11 +1346,11 @@ void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q // catch up GLfloat *tex = list->tex[0]; if (list->len) for (int i = 0; i < list->len; i++) { - memcpy(tex, glstate.texcoord[0], sizeof(GLfloat) * 4); + memcpy(tex, glstate->texcoord[0], sizeof(GLfloat) * 4); tex += 4; } } - GLfloat *tex = glstate.texcoord[0]; + GLfloat *tex = glstate->texcoord[0]; tex[0] = s; tex[1] = t; tex[2] = r; tex[3] = q; } @@ -1227,11 +1362,11 @@ void rlMultiTexCoord4f(renderlist_t *list, GLenum target, GLfloat s, GLfloat t, // catch up GLfloat *tex = list->tex[tmu]; if (list->len) for (int i = 0; i < list->len; i++) { - memcpy(tex, glstate.texcoord[tmu], sizeof(GLfloat) * 4); + memcpy(tex, glstate->texcoord[tmu], sizeof(GLfloat) * 4); tex += 4; } } - GLfloat *tex = glstate.texcoord[tmu]; + GLfloat *tex = glstate->texcoord[tmu]; tex[0] = s; tex[1] = t; tex[2] = r; tex[3] = q; } @@ -1266,10 +1401,10 @@ void rlPushCall(renderlist_t *list, packed_call_t *data) { call_list_t *cl = &list->calls; if (!cl->calls) { cl->cap = DEFAULT_CALL_LIST_CAPACITY; - cl->calls = malloc(DEFAULT_CALL_LIST_CAPACITY * sizeof(uintptr_t)); + cl->calls = malloc(DEFAULT_CALL_LIST_CAPACITY * sizeof(void*)); } else if (list->calls.len == list->calls.cap) { cl->cap += DEFAULT_CALL_LIST_CAPACITY; - cl->calls = realloc(cl->calls, cl->cap * sizeof(uintptr_t)); + cl->calls = realloc(cl->calls, cl->cap * sizeof(void*)); } cl->calls[cl->len++] = data; } diff --git a/project/jni/glshim/src/gl/list.h b/project/jni/glshim/src/gl/list.h index 797f34adf..547a98516 100755 --- a/project/jni/glshim/src/gl/list.h +++ b/project/jni/glshim/src/gl/list.h @@ -74,6 +74,7 @@ typedef struct { GLfloat zoomy; GLboolean bitmap; GLuint texture; + int *shared; } rasterlist_t; KHASH_MAP_INIT_INT(material, rendermaterial_t *) @@ -94,20 +95,23 @@ typedef struct _renderlist_t { GLenum mode_init; // initial requested mode GLfloat lastNormal[3]; GLfloat lastColors[4]; - GLfloat lastSecondaryColors[3]; + GLfloat lastSecondaryColors[4]; + int lastColorsSet; + + int* shared_calls; call_list_t calls; - GLboolean shared_arrays; + int *shared_arrays; GLfloat *vert; GLfloat *normal; GLfloat *color; GLfloat *secondary; GLfloat *tex[MAX_TEX]; + int *shared_indices; GLushort *indices; unsigned int indice_cap; - GLuint glcall_list; rasterlist_t *raster; liststage_t stage; @@ -147,24 +151,24 @@ typedef struct _renderlist_t { renderlist_t* GetFirst(renderlist_t* list); -extern renderlist_t *alloc_renderlist(); -extern renderlist_t *extend_renderlist(renderlist_t *list); -extern void free_renderlist(renderlist_t *list); -extern void draw_renderlist(renderlist_t *list); -extern void end_renderlist(renderlist_t *list); +renderlist_t *alloc_renderlist(); +renderlist_t *extend_renderlist(renderlist_t *list); +void free_renderlist(renderlist_t *list); +void draw_renderlist(renderlist_t *list); +renderlist_t* end_renderlist(renderlist_t *list); -extern void rlActiveTexture(renderlist_t *list, GLenum texture ); -extern void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture); -extern void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a); -extern void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params); -extern void rlLightfv(renderlist_t *list, GLenum which, GLenum pname, const GLfloat * params); -extern void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * params); -extern void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z); -extern void rlPushCall(renderlist_t *list, packed_call_t *data); -extern void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -extern void rlMultiTexCoord4f(renderlist_t *list, GLenum texture, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -extern void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -extern void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b); -extern void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z); -extern void rlFogOp(renderlist_t *list, int op, const GLfloat* v); +void rlActiveTexture(renderlist_t *list, GLenum texture ); +void rlBindTexture(renderlist_t *list, GLenum target, GLuint texture); +void rlColor4f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b, GLfloat a) FASTMATH; +void rlMaterialfv(renderlist_t *list, GLenum face, GLenum pname, const GLfloat * params); +void rlLightfv(renderlist_t *list, GLenum which, GLenum pname, const GLfloat * params); +void rlTexGenfv(renderlist_t *list, GLenum coord, GLenum pname, const GLfloat * params); +void rlNormal3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z) FASTMATH; +void rlPushCall(renderlist_t *list, packed_call_t *data); +void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH; +void rlMultiTexCoord4f(renderlist_t *list, GLenum texture, GLfloat s, GLfloat t, GLfloat r, GLfloat q) FASTMATH; +void rlVertex4f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z, GLfloat w) FASTMATH; +void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b) FASTMATH; +void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) FASTMATH; +void rlFogOp(renderlist_t *list, int op, const GLfloat* v); #endif diff --git a/project/jni/glshim/src/gl/pixel.c b/project/jni/glshim/src/gl/pixel.c index 8b0481517..8ea82e08e 100755 --- a/project/jni/glshim/src/gl/pixel.c +++ b/project/jni/glshim/src/gl/pixel.c @@ -18,7 +18,7 @@ static const colorlayout_t *get_color_map(GLenum format) { map(GL_LUMINANCE, 0, 0, 0, -1); map(GL_ALPHA,-1, -1, -1, 0); default: - printf("libGL: unknown pixel format %s\n", PrintEnum(format)); + printf("LIBGL: unknown pixel format %s\n", PrintEnum(format)); break; } static colorlayout_t null = {0}; @@ -126,7 +126,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, ) default: // TODO: add glSetError? - printf("libGL: Unsupported source data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: Unsupported source data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -179,7 +179,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, (((GLushort)(color[3] * 15.0) & 0x0f)); ) default: - printf("libGL: Unsupported target data type: %s\n", PrintEnum(dst_type)); + printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(dst_type)); return false; break; } @@ -279,7 +279,7 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, ) default: // TODO: add glSetError? - printf("libGL: transform_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: transform_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -327,7 +327,7 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, ((GLushort)(color[0] * 15.0f) & 0x0f); ) default: - printf("libGL: Unsupported target data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -457,7 +457,7 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, ) default: // TODO: add glSetError? - printf("libGL: half_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: half_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -505,7 +505,7 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, ((GLushort)(color[3] * 15.0f) & 0x0f); ) default: - printf("libGL: half_pixel: Unsupported target data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: half_pixel: Unsupported target data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -611,7 +611,7 @@ bool quarter_pixel(const GLvoid *src[16], ) default: // TODO: add glSetError? - printf("libGL: quarter_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: quarter_pixel: Unsupported source data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -647,7 +647,7 @@ bool quarter_pixel(const GLvoid *src[16], ((GLushort)(color[3] * 15.0) & 0x0f); ) default: - printf("libGL: quarter_pixel Unsupported target data type: %s\n", PrintEnum(src_type)); + printf("LIBGL: quarter_pixel Unsupported target data type: %s\n", PrintEnum(src_type)); return false; break; } @@ -889,6 +889,38 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, dst_pos += dst_width; } return true; + } + if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && (src_type == GL_UNSIGNED_SHORT_4_4_4_4_REV)) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const GLushort pix = *(GLushort*)src_pos; + ((char*)dst_pos)[3] = ((pix>>12)&0x0f)<<4; + ((char*)dst_pos)[2] = ((pix>>8)&0x0f)<<4; + ((char*)dst_pos)[1] = ((pix>>4)&0x0f)<<4; + ((char*)dst_pos)[0] = ((pix)&0x0f)<<4; + src_pos += src_stride; + dst_pos += dst_stride; + } + if (stride) + dst_pos += dst_width; + } + return true; + } + if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && (src_type == GL_UNSIGNED_SHORT_5_5_5_1)) { + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + const GLushort pix = *(GLushort*)src_pos; + ((char*)dst_pos)[0] = ((pix>>11)&0x1f)<<3; + ((char*)dst_pos)[1] = ((pix>>6)&0x1f)<<3; + ((char*)dst_pos)[2] = ((pix>>1)&0x1f)<<3; + ((char*)dst_pos)[3] = ((pix)&0x01)?255:0; + src_pos += src_stride; + dst_pos += dst_stride; + } + if (stride) + dst_pos += dst_width; + } + return true; } if (! remap_pixel((const GLvoid *)src_pos, (GLvoid *)dst_pos, src_color, src_type, dst_color, dst_type)) { diff --git a/project/jni/glshim/src/gl/queries.c b/project/jni/glshim/src/gl/queries.c new file mode 100755 index 000000000..6c3e054c1 --- /dev/null +++ b/project/jni/glshim/src/gl/queries.c @@ -0,0 +1,193 @@ +#include "queries.h" + +static GLuint lastquery = 0; +static glquery_t *active_samples_passed = 0; +extern int glshim_queries; + +void glshim_glGenQueries(GLsizei n, GLuint * ids) { + noerrorShim(); + if (n<1) { + errorShim(GL_INVALID_VALUE); + return; + } + for (int i=0; iqueries; + khint_t k; + noerrorShim(); + if (list) { + k = kh_get(queries, list, id); + if (k != kh_end(list)) { + return GL_TRUE; + } + } + return GL_FALSE; +} + +void glshim_glDeleteQueries(GLsizei n, const GLuint* ids) { + khash_t(queries) *list = glstate->queries; + if (list) { + khint_t k; + glquery_t *query; + for (int i = 0; i < n; i++) { + GLuint t = ids[i]; + if (t) { // don't allow to remove default one + k = kh_get(queries, list, t); + if (k != kh_end(list)) { + query = kh_value(list, k); + kh_del(queries, list, k); + free(query); + if(active_samples_passed==query) + active_samples_passed = NULL; + } + } + } + } + noerrorShim(); +} + +void glshim_glBeginQuery(GLenum target, GLuint id) { + if(target!=GL_SAMPLES_PASSED) { + errorShim(GL_INVALID_ENUM); + return; + } + if (glstate->gl_batch) { + flush(); + } + khint_t k; + int ret; + glquery_t *query; + khash_t(queries) *list = glstate->queries; + if (! list) { + list = glstate->queries = kh_init(queries); + // segfaults if we don't do a single put + kh_put(queries, list, 1, &ret); + kh_del(queries, list, 1); + } + k = kh_get(queries, list, id); + if (k != kh_end(list)) { + query = kh_value(list, k); + } else { + k = kh_put(queries, list, id, &ret); + query = kh_value(list, k) = malloc(sizeof(glquery_t)); + } + query->target = target; + query->num = 0; + active_samples_passed = query; + noerrorShim(); +} + +void glshim_glEndQuery(GLenum target) { + if(target!=GL_SAMPLES_PASSED) { + errorShim(GL_INVALID_ENUM); + return; + } + if(!active_samples_passed) { + errorShim(GL_INVALID_OPERATION); + return; + } + if (glstate->gl_batch) { + flush(); + } + active_samples_passed = NULL; + noerrorShim(); +} + +void glshim_glGetQueryiv(GLenum target, GLenum pname, GLint* params) { + if(target!=GL_SAMPLES_PASSED) { + errorShim(GL_INVALID_ENUM); + return; + } + noerrorShim(); + switch (pname) { + case GL_CURRENT_QUERY: + *params = (active_samples_passed)?active_samples_passed->id:0; + break; + case GL_QUERY_COUNTER_BITS: + *params = 0; //no counter... + break; + default: + errorShim(GL_INVALID_ENUM); + } +} + +void glshim_glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) { + khint_t k; + int ret; + glquery_t *query = NULL; + khash_t(queries) *list = glstate->queries; + if (! list) { + list = glstate->queries = kh_init(queries); + // segfaults if we don't do a single put + kh_put(queries, list, 1, &ret); + kh_del(queries, list, 1); + } + k = kh_get(queries, list, id); + if (k != kh_end(list)) { + query = kh_value(list, k); + } + if(!query) { + errorShim(GL_INVALID_OPERATION); + return; + } + noerrorShim(); + switch (pname) { + case GL_QUERY_RESULT_AVAILABLE: + *params = GL_TRUE; + break; + case GL_QUERY_RESULT: + *params = query->num; + break; + default: + errorShim(GL_INVALID_ENUM); + break; + } +} + +void glshim_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) { + khint_t k; + int ret; + glquery_t *query = NULL; + khash_t(queries) *list = glstate->queries; + if (! list) { + list = glstate->queries = kh_init(queries); + // segfaults if we don't do a single put + kh_put(queries, list, 1, &ret); + kh_del(queries, list, 1); + } + k = kh_get(queries, list, id); + if (k != kh_end(list)) { + query = kh_value(list, k); + } + if(!query) { + errorShim(GL_INVALID_OPERATION); + return; + } + noerrorShim(); + switch (pname) { + case GL_QUERY_RESULT_AVAILABLE: + *params = GL_TRUE; + break; + case GL_QUERY_RESULT: + *params = query->num; + break; + default: + errorShim(GL_INVALID_ENUM); + break; + } +} + + +//Direct wrapper +void glGenQueries(GLsizei n, GLuint * ids) AliasExport("glshim_glGenQueries"); +GLboolean glIsQuery(GLuint id) AliasExport("glshim_glIsQuery"); +void glDeleteQueries(GLsizei n, const GLuint* ids) AliasExport("glshim_glDeleteQueries"); +void glBeginQuery(GLenum target, GLuint id) AliasExport("glshim_glBeginQuery"); +void glEndQuery(GLenum target) AliasExport("glshim_glEndQuery"); +void glGetQueryiv(GLenum target, GLenum pname, GLint* params) AliasExport("glshim_glGetQueryiv"); +void glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params) AliasExport("glshim_glGetQueryObjectiv"); +void glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params) AliasExport("glshim_glGetQueryObjectuiv"); diff --git a/project/jni/glshim/src/gl/queries.h b/project/jni/glshim/src/gl/queries.h new file mode 100644 index 000000000..2021e24c9 --- /dev/null +++ b/project/jni/glshim/src/gl/queries.h @@ -0,0 +1,23 @@ +#include "gl.h" + +#ifndef GL_QUERIES_H +#define GL_QUERIES_H + +void glshim_glBeginQuery(GLenum target, GLuint id); +void glshim_glEndQuery(GLenum target); +void glshim_glGenQueries(GLsizei n, GLuint * ids); +void glshim_glDeleteQueries(GLsizei n, const GLuint* ids); +GLboolean glshim_glIsQuery(GLuint id); +void glshim_glGetQueryiv(GLenum target, GLenum pname, GLint* params); +void glshim_glGetQueryObjectiv(GLuint id, GLenum pname, GLint* params); +void glshim_glGetQueryObjectuiv(GLuint id, GLenum pname, GLuint* params); + +typedef struct { + GLuint id; + GLenum target; + int num; +} glquery_t; + +KHASH_MAP_INIT_INT(queries, glquery_t *) + +#endif \ No newline at end of file diff --git a/project/jni/glshim/src/gl/raster.c b/project/jni/glshim/src/gl/raster.c index d8560d8f0..02184ce0d 100755 --- a/project/jni/glshim/src/gl/raster.c +++ b/project/jni/glshim/src/gl/raster.c @@ -18,13 +18,13 @@ static GLint raster_x1, raster_x2, raster_y1, raster_y2; GLfloat raster_scale[4] = {1.0f, 1.0f, 1.0f, 1.0f}; GLfloat raster_bias[4] = {0.0f, 0.0f, 0.0f, 0.0f}; -extern void matrix_column_row(const GLfloat *a, GLfloat *b); -extern void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c); +void matrix_column_row(const GLfloat *a, GLfloat *b); +void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c); void glshim_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_RASTER); - rlRasterOp(glstate.list.active, 1, x, y, z); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 1, x, y, z); noerrorShim(); return; } @@ -53,9 +53,9 @@ void glshim_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { } void glshim_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_RASTER); - rlRasterOp(glstate.list.active, 2, x, y, z); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 2, x, y, z); noerrorShim(); return; } @@ -74,10 +74,21 @@ void glshim_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { viewport.height = height; } +// hacky viewport temporary changes +void pushViewport(GLint x, GLint y, GLsizei width, GLsizei height) { + LOAD_GLES(glViewport); + gles_glViewport(x, y, width, height); +} +void popViewport() { + LOAD_GLES(glViewport); + gles_glViewport(viewport.x, viewport.y, viewport.width, viewport.height); +} + + void glshim_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_RASTER); - rlRasterOp(glstate.list.active, 3, xfactor, yfactor, 0.0f); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, 3, xfactor, yfactor, 0.0f); noerrorShim(); return; } @@ -87,9 +98,9 @@ void glshim_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { } void glshim_glPixelTransferf(GLenum pname, GLfloat param) { - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_RASTER); - rlRasterOp(glstate.list.active, pname|0x10000, param, 0.0f, 0.0f); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_RASTER); + rlRasterOp(glstate->list.active, pname|0x10000, param, 0.0f, 0.0f); noerrorShim(); return; } @@ -148,7 +159,7 @@ GLubyte raster_transform(GLubyte pix, GLubyte number) { if (a>1.0) a=1.0; return (GLubyte)(a*255.0f); } -GLfloat raster_transformf(GLfloat pix, GLubyte number) { +GLfloat FASTMATH raster_transformf(GLfloat pix, GLubyte number) { pix=pix*raster_scale[number]+raster_bias[number]; if (pix<0.0) pix=0.0; if (pix>1.0) pix=1.0; @@ -174,19 +185,19 @@ GLuint raster_to_texture() LOAD_GLES(glTexParameteriv); #endif - renderlist_t *old_list = glstate.list.active; - if (old_list) glstate.list.active = NULL; // deactivate list... - GLboolean compiling = glstate.list.compiling; - GLuint state_batch = glstate.gl_batch; - glstate.list.compiling = false; - glstate.gl_batch = 0; + renderlist_t *old_list = glstate->list.active; + if (old_list) glstate->list.active = NULL; // deactivate list... + GLboolean compiling = glstate->list.compiling; + GLuint state_batch = glstate->gl_batch; + glstate->list.compiling = false; + glstate->gl_batch = 0; glshim_glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT ); GLuint old_tex_unit, old_tex; glshim_glGetIntegerv(GL_ACTIVE_TEXTURE, &old_tex_unit); if (old_tex_unit!=GL_TEXTURE0) glshim_glActiveTexture(GL_TEXTURE0); old_tex = 0; - if (glstate.texture.bound[0]) - old_tex = glstate.texture.bound[0]->texture; + if (glstate->texture.bound[0]) + old_tex = glstate->texture.bound[0]->texture; GLuint raster_texture; glshim_glEnable(GL_TEXTURE_2D); gles_glGenTextures(1, &raster_texture); @@ -214,9 +225,9 @@ GLuint raster_to_texture() if (old_tex_unit!=GL_TEXTURE0) glshim_glActiveTexture(old_tex_unit); glshim_glPopAttrib(); - if (old_list) glstate.list.active = old_list; - glstate.list.compiling = compiling; - glstate.gl_batch = state_batch; + if (old_list) glstate->list.active = old_list; + glstate->list.compiling = compiling; + glstate->gl_batch = state_batch; return raster_texture; } @@ -228,10 +239,12 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig // TODO: negative width/height mirrors bitmap? noerrorShim(); if ((!width && !height) || (bitmap==0)) { - if (glstate.list.compiling || glstate.gl_batch) { - if (glstate.list.active->raster) - glstate.list.active = extend_renderlist(glstate.list.active); // already a raster in the list, create a new one - rasterlist_t *r = glstate.list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + if (glstate->list.compiling || glstate->gl_batch) { + if (glstate->list.active->raster) + glstate->list.active = extend_renderlist(glstate->list.active); // already a raster in the list, create a new one + rasterlist_t *r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + r->shared = (int*)malloc(sizeof(int)); + *r->shared = 0; r->texture = 0; r->xorig = 0; r->yorig = 0; @@ -285,9 +298,11 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig rasterlist_t rast; rasterlist_t *r; - if (glstate.list.compiling || glstate.gl_batch) { - NewStage(glstate.list.active, STAGE_RASTER); - r = glstate.list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + if (glstate->list.compiling || glstate->gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + r->shared = (int*)malloc(sizeof(int)); + *r->shared = 0; } else { r = &rast; } @@ -302,7 +317,7 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig r->zoomx = raster_zoomx; r->zoomy = raster_zoomy; LOAD_GLES(glDeleteTextures); - if (!(glstate.list.compiling || glstate.gl_batch)) { + if (!(glstate->list.compiling || glstate->gl_batch)) { render_raster_list(r); gles_glDeleteTextures(1, &r->texture); r->texture = 0; @@ -327,7 +342,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, init_raster(width, height); - GLsizei bmp_width = (glstate.texture.unpack_row_length)?glstate.texture.unpack_row_length:width; + GLsizei bmp_width = (glstate->texture.unpack_row_length)?glstate->texture.unpack_row_length:width; if (! pixel_convert(data, &dst, bmp_width, height, format, type, GL_RGBA, GL_UNSIGNED_BYTE, 0)) { @@ -341,7 +356,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, if (pixtrans) { for (int y = 0; y < height; y++) { to = raster + 4 * (GLint)(y * raster_width); - from = pixels + 4 * (glstate.texture.unpack_skip_pixels + (y + glstate.texture.unpack_skip_rows) * bmp_width); + from = pixels + 4 * (glstate->texture.unpack_skip_pixels + (y + glstate->texture.unpack_skip_rows) * bmp_width); for (int x = 0; x < width; x++) { *to++ = raster_transform(*from++, 0); *to++ = raster_transform(*from++, 1); @@ -352,7 +367,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, } else { for (int y = 0; y < height; y++) { to = raster + 4 * (GLint)(y * raster_width); - from = pixels + 4 * (glstate.texture.unpack_skip_pixels + (y + glstate.texture.unpack_skip_rows) * bmp_width); + from = pixels + 4 * (glstate->texture.unpack_skip_pixels + (y + glstate->texture.unpack_skip_rows) * bmp_width); for (int x = 0; x < width; x++) { *to++ = *from++; *to++ = *from++; @@ -364,11 +379,13 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, if (pixels != data) free(pixels); - static rasterlist_t rast = {.texture=0}; + static rasterlist_t rast = {.texture=0, .shared=NULL}; rasterlist_t *r; - if (glstate.list.compiling || gl_batch) { - NewStage(glstate.list.active, STAGE_RASTER); - rasterlist_t *r = glstate.list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + if (glstate->list.compiling || gl_batch) { + NewStage(glstate->list.active, STAGE_RASTER); + rasterlist_t *r = glstate->list.active->raster = (rasterlist_t*)malloc(sizeof(rasterlist_t)); + r->shared = (int*)malloc(sizeof(int)); + *r->shared = 0; } else { r = &rast; if(r->texture) @@ -384,7 +401,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, r->bitmap = false; r->zoomx = raster_zoomx; r->zoomy = raster_zoomy; - if (!(glstate.list.compiling || glstate.gl_batch)) { + if (!(glstate->list.compiling || glstate->gl_batch)) { render_raster_list(r); /* gles_glDeleteTextures(1, &r->texture); r->texture = 0;*/ @@ -409,14 +426,14 @@ void render_raster_list(rasterlist_t* rast) { LOAD_GLES(glClientActiveTexture); if (rast->texture) { - GLuint old_tex = glstate.texture.active; + GLuint old_tex = glstate->texture.active; if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0); - GLuint old_cli = glstate.texture.client; + GLuint old_cli = glstate->texture.client; if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0); #ifdef USE_DRAWTEX glshim_glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); - gltexture_t *old_bind = glstate.texture.bound[0]; + gltexture_t *old_bind = glstate->texture.bound[0]; glshim_glEnable(GL_TEXTURE_2D); gles_glBindTexture(GL_TEXTURE_2D, rast->texture); @@ -428,7 +445,7 @@ void render_raster_list(rasterlist_t* rast) { } gles_glDrawTexf(rPos.x-rast->xorig, rPos.y-rast->yorig, rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy); - if (!glstate.enable.texture_2d[0]) glshim_glDisable(GL_TEXTURE_2D); + if (!glstate->enable.texture_2d[0]) glshim_glDisable(GL_TEXTURE_2D); if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0+old_tex); if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0+old_cli); if (old_bind == NULL) @@ -485,32 +502,32 @@ void render_raster_list(rasterlist_t* rast) { gles_glBindTexture(GL_TEXTURE_2D, rast->texture); glshim_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - if(!glstate.clientstate.vertex_array) + if(!glstate->clientstate.vertex_array) { gles_glEnableClientState(GL_VERTEX_ARRAY); - glstate.clientstate.vertex_array = 1; + glstate->clientstate.vertex_array = 1; } gles_glVertexPointer(2, GL_FLOAT, 0, rast_vert); - if(!glstate.clientstate.tex_coord_array[0]) + if(!glstate->clientstate.tex_coord_array[0]) { gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[0] = 1; + glstate->clientstate.tex_coord_array[0] = 1; } gles_glTexCoordPointer(2, GL_FLOAT, 0, rast_tex); for (int a=1; a clientstate.tex_coord_array[a]) { gles_glClientActiveTexture(GL_TEXTURE0 + a); gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glstate.clientstate.tex_coord_array[a] = 0; + glstate->clientstate.tex_coord_array[a] = 0; gles_glClientActiveTexture(GL_TEXTURE0); } - if(glstate.clientstate.color_array) { + if(glstate->clientstate.color_array) { gles_glDisableClientState(GL_COLOR_ARRAY); - glstate.clientstate.color_array = 0; + glstate->clientstate.color_array = 0; } - if(glstate.clientstate.normal_array) { + if(glstate->clientstate.normal_array) { gles_glDisableClientState(GL_NORMAL_ARRAY); - glstate.clientstate.normal_array = 0; + glstate->clientstate.normal_array = 0; } diff --git a/project/jni/glshim/src/gl/render.c b/project/jni/glshim/src/gl/render.c index 87b6fb0b4..275032fe2 100755 --- a/project/jni/glshim/src/gl/render.c +++ b/project/jni/glshim/src/gl/render.c @@ -2,31 +2,31 @@ void push_hit() { // push current hit to hit list, and re-init current hit - if (glstate.selectbuf.hit) { - if (!glstate.selectbuf.overflow) { - if (glstate.selectbuf.zmin<0.0f) glstate.selectbuf.zmin=0.0f; // not really normalized... - if (glstate.selectbuf.zmax>1.0f) glstate.selectbuf.zmax=1.0f; // TODO, normalize for good? - int tocopy = glstate.namestack.top + 3; - if (tocopy+glstate.selectbuf.pos > glstate.selectbuf.size) { - glstate.selectbuf.overflow = 1; - tocopy = glstate.selectbuf.size - glstate.selectbuf.pos; + if (glstate->selectbuf.hit) { + if (!glstate->selectbuf.overflow) { + if (glstate->selectbuf.zmin<0.0f) glstate->selectbuf.zmin=0.0f; // not really normalized... + if (glstate->selectbuf.zmax>1.0f) glstate->selectbuf.zmax=1.0f; // TODO, normalize for good? + int tocopy = glstate->namestack.top + 3; + if (tocopy+glstate->selectbuf.pos > glstate->selectbuf.size) { + glstate->selectbuf.overflow = 1; + tocopy = glstate->selectbuf.size - glstate->selectbuf.pos; } if(tocopy>0) - glstate.selectbuf.buffer[glstate.selectbuf.pos+0] = glstate.namestack.top; + glstate->selectbuf.buffer[glstate->selectbuf.pos+0] = glstate->namestack.top; if(tocopy>1) - glstate.selectbuf.buffer[glstate.selectbuf.pos+1] = (unsigned int)(glstate.selectbuf.zmin * INT_MAX ); + glstate->selectbuf.buffer[glstate->selectbuf.pos+1] = (unsigned int)(glstate->selectbuf.zmin * INT_MAX ); if(tocopy>2) - glstate.selectbuf.buffer[glstate.selectbuf.pos+2] = (unsigned int)(glstate.selectbuf.zmax * INT_MAX ); + glstate->selectbuf.buffer[glstate->selectbuf.pos+2] = (unsigned int)(glstate->selectbuf.zmax * INT_MAX ); if(tocopy>3) - memcpy(glstate.selectbuf.buffer + glstate.selectbuf.pos + 3, glstate.namestack.names, (tocopy-3) * sizeof(GLuint)); + memcpy(glstate->selectbuf.buffer + glstate->selectbuf.pos + 3, glstate->namestack.names, (tocopy-3) * sizeof(GLuint)); - glstate.selectbuf.count++; - glstate.selectbuf.pos += tocopy; + glstate->selectbuf.count++; + glstate->selectbuf.pos += tocopy; } - glstate.selectbuf.hit = 0; + glstate->selectbuf.hit = 0; } - glstate.selectbuf.zmin = 1.0f; - glstate.selectbuf.zmax = 0.0f; + glstate->selectbuf.zmin = 1.0f; + glstate->selectbuf.zmax = 0.0f; } @@ -38,83 +38,83 @@ GLint glshim_glRenderMode(GLenum mode) { errorShim(GL_INVALID_ENUM); return 0; } - if (glstate.render_mode == GL_SELECT) { + if (glstate->render_mode == GL_SELECT) { push_hit(); - ret = glstate.selectbuf.count; + ret = glstate->selectbuf.count; } if (mode == GL_SELECT) { - if (glstate.selectbuf.buffer == NULL) {// error, cannot use Select Mode without select buffer + if (glstate->selectbuf.buffer == NULL) {// error, cannot use Select Mode without select buffer errorShim(GL_INVALID_OPERATION); return 0; } - glstate.selectbuf.count = 0; - glstate.selectbuf.pos = 0; - glstate.selectbuf.overflow = 0; - glstate.selectbuf.zmin = 1.0f; - glstate.selectbuf.zmax = 0.0f; - glstate.selectbuf.hit = 0; + glstate->selectbuf.count = 0; + glstate->selectbuf.pos = 0; + glstate->selectbuf.overflow = 0; + glstate->selectbuf.zmin = 1.0f; + glstate->selectbuf.zmax = 0.0f; + glstate->selectbuf.hit = 0; } - if((mode==GL_SELECT) && (glstate.gl_batch)) { - glstate.gl_batch = 0; + if((mode==GL_SELECT) && (glstate->gl_batch)) { + glstate->gl_batch = 0; flush(); } - if((mode==GL_RENDER) && (glstate.gl_batch==0) && (gl_batch==1)) { - glstate.gl_batch = 1; + if((mode==GL_RENDER) && (glstate->gl_batch==0) && (gl_batch==1)) { + glstate->gl_batch = 1; flush(); } - glstate.render_mode = mode; + glstate->render_mode = mode; return ret; } void glshim_glInitNames() { - if (glstate.namestack.names == 0) { - glstate.namestack.names = (GLuint*)malloc(1024*sizeof(GLuint)); + if (glstate->namestack.names == 0) { + glstate->namestack.names = (GLuint*)malloc(1024*sizeof(GLuint)); } - glstate.namestack.top = 0; + glstate->namestack.top = 0; noerrorShim(); } void glshim_glPopName() { noerrorShim(); - if (glstate.render_mode != GL_SELECT) + if (glstate->render_mode != GL_SELECT) return; push_hit(); - if (glstate.namestack.top>0) - glstate.namestack.top--; + if (glstate->namestack.top>0) + glstate->namestack.top--; else errorShim(GL_STACK_UNDERFLOW); } void glshim_glPushName(GLuint name) { noerrorShim(); - if (glstate.render_mode != GL_SELECT) + if (glstate->render_mode != GL_SELECT) return; - if (glstate.namestack.names==0) + if (glstate->namestack.names==0) return; push_hit(); - if (glstate.namestack.top < 1024) { - glstate.namestack.names[glstate.namestack.top++] = name; + if (glstate->namestack.top < 1024) { + glstate->namestack.names[glstate->namestack.top++] = name; } } void glshim_glLoadName(GLuint name) { noerrorShim(); - if (glstate.render_mode != GL_SELECT) + if (glstate->render_mode != GL_SELECT) return; - if (glstate.namestack.names == 0) + if (glstate->namestack.names == 0) return; push_hit(); - if (glstate.namestack.top == 0) + if (glstate->namestack.top == 0) return; - glstate.namestack.names[glstate.namestack.top-1] = name; + glstate->namestack.names[glstate->namestack.top-1] = name; } void glshim_glSelectBuffer(GLsizei size, GLuint *buffer) { noerrorShim(); - glstate.selectbuf.buffer = buffer; - glstate.selectbuf.size = size; + glstate->selectbuf.buffer = buffer; + glstate->selectbuf.size = size; } GLfloat projection[16], modelview[16]; @@ -221,7 +221,7 @@ GLboolean select_triangle_in_viewscreen(const GLfloat *a, const GLfloat *b, cons void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) { if (count == 0) return; if (vtx->pointer == NULL) return; - if (glstate.selectbuf.buffer == NULL) return; + if (glstate->selectbuf.buffer == NULL) return; GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, vtx->size, vtx->stride, GL_FLOAT, 4, 0, count+first); @@ -229,9 +229,9 @@ void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, init_select(); #define FOUND() { \ - if (zminglstate.selectbuf.zmax) glstate.selectbuf.zmax=zmax; \ - glstate.selectbuf.hit = 1; \ + if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; \ + if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \ + glstate->selectbuf.hit = 1; \ free(vert); \ return; \ } @@ -311,9 +311,9 @@ void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count if (zmax>1.0f) zmax = 1.0f; #define FOUND() { \ - if (zminglstate.selectbuf.zmax) glstate.selectbuf.zmax=zmax; \ - glstate.selectbuf.hit = 1; \ + if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; \ + if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \ + glstate->selectbuf.hit = 1; \ free(vert); \ return; \ } diff --git a/project/jni/glshim/src/gl/stack.c b/project/jni/glshim/src/gl/stack.c index 56e2876e9..bd559c68b 100755 --- a/project/jni/glshim/src/gl/stack.c +++ b/project/jni/glshim/src/gl/stack.c @@ -1,26 +1,23 @@ #include "stack.h" -glstack_t *stack = NULL; -glclientstack_t *clientStack = NULL; - void glshim_glPushAttrib(GLbitfield mask) { //printf("glPushAttrib(0x%04X)\n", mask); noerrorShim(); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_PUSH); - glstate.list.active->pushattribute = mask; + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_PUSH); + glstate->list.active->pushattribute = mask; return; } - if (stack == NULL) { - stack = (glstack_t *)malloc(STACK_SIZE * sizeof(glstack_t)); - stack->len = 0; - stack->cap = STACK_SIZE; - } else if (stack->len == stack->cap) { - stack->cap += STACK_SIZE; - stack = (glstack_t *)realloc(stack, stack->cap * sizeof(glstack_t)); + if (glstate->stack == NULL) { + glstate->stack = (glstack_t *)malloc(STACK_SIZE * sizeof(glstack_t)); + glstate->stack->len = 0; + glstate->stack->cap = STACK_SIZE; + } else if (glstate->stack->len == glstate->stack->cap) { + glstate->stack->cap += STACK_SIZE; + glstate->stack = (glstack_t *)realloc(glstate->stack, glstate->stack->cap * sizeof(glstack_t)); } - glstack_t *cur = stack + stack->len; + glstack_t *cur = glstate->stack + glstate->stack->len; cur->mask = mask; cur->clip_planes_enabled = NULL; cur->clip_planes = NULL; @@ -109,12 +106,12 @@ void glshim_glPushAttrib(GLbitfield mask) { cur->stencil_test = glshim_glIsEnabled(GL_STENCIL_TEST); int a; for (a=0; atexture_1d[a] = glstate.enable.texture_1d[a]; - cur->texture_2d[a] = glstate.enable.texture_2d[a]; - cur->texture_3d[a] = glstate.enable.texture_3d[a]; - cur->texgen_s[a] = glstate.enable.texgen_s[a]; - cur->texgen_r[a] = glstate.enable.texgen_r[a]; - cur->texgen_t[a] = glstate.enable.texgen_t[a]; + cur->texture_1d[a] = glstate->enable.texture_1d[a]; + cur->texture_2d[a] = glstate->enable.texture_2d[a]; + cur->texture_3d[a] = glstate->enable.texture_3d[a]; + cur->texgen_s[a] = glstate->enable.texgen_s[a]; + cur->texgen_r[a] = glstate->enable.texgen_r[a]; + cur->texgen_t[a] = glstate->enable.texgen_t[a]; } } @@ -165,7 +162,7 @@ void glshim_glPushAttrib(GLbitfield mask) { // GL_LIST_BIT if (mask & GL_LIST_BIT) { - cur->list_base = glstate.list.base; + cur->list_base = glstate->list.base; } if (mask & GL_MULTISAMPLE_BIT) { @@ -220,14 +217,14 @@ void glshim_glPushAttrib(GLbitfield mask) { } // GL_TEXTURE_BIT - TODO: incomplete if (mask & GL_TEXTURE_BIT) { - cur->active=glstate.texture.active; + cur->active=glstate->texture.active; int a; for (a=0; atexgen_r[a] = glstate.enable.texgen_r[a]; - cur->texgen_s[a] = glstate.enable.texgen_s[a]; - cur->texgen_t[a] = glstate.enable.texgen_t[a]; - cur->texgen[a] = glstate.texgen[a]; // all mode and planes per texture in 1 line - cur->texture[a] = (glstate.texture.bound[a])?glstate.texture.bound[a]->texture:0; + cur->texgen_r[a] = glstate->enable.texgen_r[a]; + cur->texgen_s[a] = glstate->enable.texgen_s[a]; + cur->texgen_t[a] = glstate->enable.texgen_t[a]; + cur->texgen[a] = glstate->texgen[a]; // all mode and planes per texture in 1 line + cur->texture[a] = (glstate->texture.bound[a])?glstate->texture.bound[a]->texture:0; } //glActiveTexture(GL_TEXTURE0+cur->active); } @@ -253,48 +250,54 @@ void glshim_glPushAttrib(GLbitfield mask) { glshim_glGetFloatv(GL_DEPTH_RANGE, cur->depth_range); } - stack->len++; + glstate->stack->len++; } void glshim_glPushClientAttrib(GLbitfield mask) { noerrorShim(); - if (clientStack == NULL) { - clientStack = (glclientstack_t *)malloc(STACK_SIZE * sizeof(glclientstack_t)); - clientStack->len = 0; - clientStack->cap = STACK_SIZE; - } else if (clientStack->len == clientStack->cap) { - clientStack->cap += STACK_SIZE; - clientStack = (glclientstack_t *)realloc(clientStack, clientStack->cap * sizeof(glclientstack_t)); + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { + flush(); + glstate->gl_batch = 0; + } + if (glstate->clientStack == NULL) { + glstate->clientStack = (glclientstack_t *)malloc(STACK_SIZE * sizeof(glclientstack_t)); + glstate->clientStack->len = 0; + glstate->clientStack->cap = STACK_SIZE; + } else if (glstate->clientStack->len == glstate->clientStack->cap) { + glstate->clientStack->cap += STACK_SIZE; + glstate->clientStack = (glclientstack_t *)realloc(glstate->clientStack, glstate->clientStack->cap * sizeof(glclientstack_t)); } - glclientstack_t *cur = clientStack + clientStack->len; + glclientstack_t *cur = glstate->clientStack + glstate->clientStack->len; cur->mask = mask; if (mask & GL_CLIENT_PIXEL_STORE_BIT) { glshim_glGetIntegerv(GL_PACK_ALIGNMENT, &cur->pack_align); glshim_glGetIntegerv(GL_UNPACK_ALIGNMENT, &cur->unpack_align); - cur->unpack_row_length = glstate.texture.unpack_row_length; - cur->unpack_skip_pixels = glstate.texture.unpack_skip_pixels; - cur->unpack_skip_rows = glstate.texture.unpack_skip_rows; - cur->pack_row_length = glstate.texture.pack_row_length; - cur->pack_skip_pixels = glstate.texture.pack_skip_pixels; - cur->pack_skip_rows = glstate.texture.pack_skip_rows; + cur->unpack_row_length = glstate->texture.unpack_row_length; + cur->unpack_skip_pixels = glstate->texture.unpack_skip_pixels; + cur->unpack_skip_rows = glstate->texture.unpack_skip_rows; + cur->pack_row_length = glstate->texture.pack_row_length; + cur->pack_skip_pixels = glstate->texture.pack_skip_pixels; + cur->pack_skip_rows = glstate->texture.pack_skip_rows; } if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) { - cur->vert_enable = glstate.vao->vertex_array; - cur->color_enable = glstate.vao->color_array; - cur->secondary_enable = glstate.vao->secondary_array; - cur->normal_enable = glstate.vao->normal_array; + cur->vert_enable = glstate->vao->vertex_array; + cur->color_enable = glstate->vao->color_array; + cur->secondary_enable = glstate->vao->secondary_array; + cur->normal_enable = glstate->vao->normal_array; int a; for (a=0; atex_enable[a] = glstate.vao->tex_coord_array[a]; + cur->tex_enable[a] = glstate->vao->tex_coord_array[a]; } - memcpy(&(cur->pointers), &glstate.vao->pointers, sizeof(pointer_states_t)); - cur->client = glstate.texture.client; + memcpy(&(cur->pointers), &glstate->vao->pointers, sizeof(pointer_states_t)); + cur->client = glstate->texture.client; } - clientStack->len++; + glstate->clientStack->len++; + glstate->gl_batch=old_glbatch; } #define maybe_free(x) \ @@ -311,17 +314,17 @@ void glshim_glPushClientAttrib(GLbitfield mask) { void glshim_glPopAttrib() { //printf("glPopAttrib()\n"); noerrorShim(); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_POP); - glstate.list.active->popattribute = true; + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_POP); + glstate->list.active->popattribute = true; return; } - if (stack == NULL || stack->len == 0) { + if (glstate->stack == NULL || glstate->stack->len == 0) { errorShim(GL_STACK_UNDERFLOW); return; } - glstack_t *cur = stack + stack->len-1; + glstack_t *cur = glstate->stack + glstate->stack->len-1; if (cur->mask & GL_COLOR_BUFFER_BIT) { enable_disable(GL_ALPHA_TEST, cur->alpha_test); @@ -398,25 +401,25 @@ void glshim_glPopAttrib() { enable_disable(GL_SCISSOR_TEST, cur->scissor_test); enable_disable(GL_STENCIL_TEST, cur->stencil_test); int a; - int old_tex = glstate.texture.active; + int old_tex = glstate->texture.active; for (a=0; atexture_1d[a]) { + if (glstate->enable.texture_1d[a] != cur->texture_1d[a]) { glshim_glActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_1D, cur->texture_1d[a]); } - if (glstate.enable.texture_2d[a] != cur->texture_2d[a]) { + if (glstate->enable.texture_2d[a] != cur->texture_2d[a]) { glshim_glActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_2D, cur->texture_2d[a]); } - if (glstate.enable.texture_3d[a] != cur->texture_3d[a]) { + if (glstate->enable.texture_3d[a] != cur->texture_3d[a]) { glshim_glActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_3D, cur->texture_3d[a]); } - glstate.enable.texgen_r[a] = cur->texgen_r[a]; - glstate.enable.texgen_s[a] = cur->texgen_s[a]; - glstate.enable.texgen_t[a] = cur->texgen_t[a]; + glstate->enable.texgen_r[a] = cur->texgen_r[a]; + glstate->enable.texgen_s[a] = cur->texgen_s[a]; + glstate->enable.texgen_t[a] = cur->texgen_t[a]; } - if (glstate.texture.active != old_tex) glshim_glActiveTexture(GL_TEXTURE0+old_tex); + if (glstate->texture.active != old_tex) glshim_glActiveTexture(GL_TEXTURE0+old_tex); } if (cur->mask & GL_FOG_BIT) { @@ -476,16 +479,16 @@ void glshim_glPopAttrib() { int a; //TODO: Enable bit for the 4 texture coordinates for (a=0; atexgen_r[a]; - glstate.enable.texgen_s[a] = cur->texgen_s[a]; - glstate.enable.texgen_t[a] = cur->texgen_t[a]; - glstate.texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line - if ((cur->texture[a]==0 && glstate.texture.bound[a] != 0) || (cur->texture[a]!=0 && glstate.texture.bound[a]==0)) { + glstate->enable.texgen_r[a] = cur->texgen_r[a]; + glstate->enable.texgen_s[a] = cur->texgen_s[a]; + glstate->enable.texgen_t[a] = cur->texgen_t[a]; + glstate->texgen[a] = cur->texgen[a]; // all mode and planes per texture in 1 line + if ((cur->texture[a]==0 && glstate->texture.bound[a] != 0) || (cur->texture[a]!=0 && glstate->texture.bound[a]==0)) { glshim_glActiveTexture(GL_TEXTURE0+a); glshim_glBindTexture(GL_TEXTURE_2D, cur->texture[a]); } } - if (glstate.texture.active!= cur->active) glshim_glActiveTexture(GL_TEXTURE0+cur->active); + if (glstate->texture.active!= cur->active) glshim_glActiveTexture(GL_TEXTURE0+cur->active); } if (cur->mask & GL_PIXEL_MODE_BIT) { @@ -522,7 +525,7 @@ void glshim_glPopAttrib() { maybe_free(cur->clip_planes); maybe_free(cur->lights_enabled); maybe_free(cur->lights); - stack->len--; + glstate->stack->len--; } #undef enable_disable @@ -532,17 +535,22 @@ void glshim_glPopAttrib() { void glshim_glPopClientAttrib() { noerrorShim(); + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { + flush(); + glstate->gl_batch = 0; + } //LOAD_GLES(glVertexPointer); //LOAD_GLES(glColorPointer); //LOAD_GLES(glNormalPointer); //LOAD_GLES(glTexCoordPointer); - if (clientStack == NULL || clientStack->len == 0) { + if (glstate->clientStack == NULL || glstate->clientStack->len == 0) { errorShim(GL_STACK_UNDERFLOW); return; } - glclientstack_t *cur = clientStack + clientStack->len-1; + glclientstack_t *cur = glstate->clientStack + glstate->clientStack->len-1; if (cur->mask & GL_CLIENT_PIXEL_STORE_BIT) { glshim_glPixelStorei(GL_PACK_ALIGNMENT, cur->pack_align); glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, cur->unpack_align); @@ -555,26 +563,27 @@ void glshim_glPopClientAttrib() { } if (cur->mask & GL_CLIENT_VERTEX_ARRAY_BIT) { - if (glstate.vao->vertex_array != cur->vert_enable) + if (glstate->vao->vertex_array != cur->vert_enable) enable_disable(GL_VERTEX_ARRAY, cur->vert_enable); - if (glstate.vao->normal_array != cur->normal_enable) + if (glstate->vao->normal_array != cur->normal_enable) enable_disable(GL_NORMAL_ARRAY, cur->normal_enable); - if (glstate.vao->color_array != cur->color_enable) + if (glstate->vao->color_array != cur->color_enable) enable_disable(GL_COLOR_ARRAY, cur->color_enable); - if (glstate.vao->secondary_array != cur->secondary_enable) + if (glstate->vao->secondary_array != cur->secondary_enable) enable_disable(GL_SECONDARY_COLOR_ARRAY, cur->secondary_enable); for (int a=0; atex_coord_array[a] != cur->tex_enable[a]) { + if (glstate->vao->tex_coord_array[a] != cur->tex_enable[a]) { glshim_glClientActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_COORD_ARRAY, cur->tex_enable[a]); } } - memcpy(&glstate.vao->pointers, &(cur->pointers), sizeof(pointer_states_t)); - if (glstate.texture.client != cur->client) glshim_glClientActiveTexture(GL_TEXTURE0+cur->client); + memcpy(&glstate->vao->pointers, &(cur->pointers), sizeof(pointer_states_t)); + if (glstate->texture.client != cur->client) glshim_glClientActiveTexture(GL_TEXTURE0+cur->client); } - clientStack->len--; + glstate->clientStack->len--; + glstate->gl_batch = old_glbatch; } #undef maybe_free diff --git a/project/jni/glshim/src/gl/stack.h b/project/jni/glshim/src/gl/stack.h index 75fa8d564..810888374 100755 --- a/project/jni/glshim/src/gl/stack.h +++ b/project/jni/glshim/src/gl/stack.h @@ -6,7 +6,7 @@ #define STACK_SIZE 16 -typedef struct { +typedef struct _glstack_t { GLbitfield mask; // GL_COLOR_BUFFER_BIT @@ -139,7 +139,7 @@ typedef struct { unsigned int cap; } glstack_t; -typedef struct { +typedef struct _glclientstack_t { GLbitfield mask; // GL_CLIENT_PIXEL_STORE_BIT diff --git a/project/jni/glshim/src/gl/state.h b/project/jni/glshim/src/gl/state.h index 6e8a302e1..caaadedcd 100755 --- a/project/jni/glshim/src/gl/state.h +++ b/project/jni/glshim/src/gl/state.h @@ -6,6 +6,10 @@ #include "eval.h" #include "texture.h" #include "buffers.h" +#include "queries.h" + +typedef struct _glstack_t glstack_t; +typedef struct _glclientstack_t glclientstack_t; typedef struct { GLboolean line_stipple, @@ -160,9 +164,14 @@ typedef struct { int shim_error; GLenum last_error; GLuint gl_batch; + int init_batch; GLint vp[4]; statebatch_t statebatch; clientstate_t clientstate; + khash_t(queries) *queries; + glstack_t *stack; + glclientstack_t *clientStack; + int shared_cnt; } glstate_t; #endif diff --git a/project/jni/glshim/src/gl/texgen.c b/project/jni/glshim/src/gl/texgen.c index 43e2766c4..ea351fe89 100755 --- a/project/jni/glshim/src/gl/texgen.c +++ b/project/jni/glshim/src/gl/texgen.c @@ -19,10 +19,10 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { generation function specified by pname. */ - //printf("glTexGenfv(0x%04X, 0x%04X, [%.02f, ...]), texture=%i\n", coord, pname, param[0], glstate.texture.active); - if ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active) { - NewStage(glstate.list.active, STAGE_TEXGEN); - rlTexGenfv(glstate.list.active, coord, pname, param); + //printf("glTexGenfv(%s, %s, [%s, ...]), texture=%i\n", PrintEnum(coord), PrintEnum(pname), PrintEnum(param[0]), glstate->texture.active); + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_TEXGEN); + rlTexGenfv(glstate->list.active, coord, pname, param); noerrorShim(); return; } @@ -32,9 +32,9 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { switch(pname) { case GL_TEXTURE_GEN_MODE: switch (coord) { - case GL_S: glstate.texgen[glstate.texture.active].S = param[0]; break; - case GL_T: glstate.texgen[glstate.texture.active].T = param[0]; break; - case GL_R: glstate.texgen[glstate.texture.active].R = param[0]; break; + case GL_S: glstate->texgen[glstate->texture.active].S = param[0]; break; + case GL_T: glstate->texgen[glstate->texture.active].T = param[0]; break; + case GL_R: glstate->texgen[glstate->texture.active].R = param[0]; break; default: errorShim(GL_INVALID_ENUM); return; @@ -42,13 +42,13 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { case GL_OBJECT_PLANE: switch (coord) { case GL_S: - memcpy(glstate.texgen[glstate.texture.active].S_O, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].S_O, param, 4 * sizeof(GLfloat)); break; case GL_T: - memcpy(glstate.texgen[glstate.texture.active].T_O, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].T_O, param, 4 * sizeof(GLfloat)); break; case GL_R: - memcpy(glstate.texgen[glstate.texture.active].R_O, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].R_O, param, 4 * sizeof(GLfloat)); break; default: errorShim(GL_INVALID_ENUM); @@ -57,13 +57,13 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { case GL_EYE_PLANE: switch (coord) { case GL_S: - memcpy(glstate.texgen[glstate.texture.active].S_E, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].S_E, param, 4 * sizeof(GLfloat)); break; case GL_T: - memcpy(glstate.texgen[glstate.texture.active].T_E, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].T_E, param, 4 * sizeof(GLfloat)); break; case GL_R: - memcpy(glstate.texgen[glstate.texture.active].R_E, param, 4 * sizeof(GLfloat)); + memcpy(glstate->texgen[glstate->texture.active].R_E, param, 4 * sizeof(GLfloat)); break; default: errorShim(GL_INVALID_ENUM); @@ -79,22 +79,22 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { switch(pname) { case GL_TEXTURE_GEN_MODE: switch (coord) { - case GL_S: *params = glstate.texgen[glstate.texture.active].S; break; - case GL_T: *params = glstate.texgen[glstate.texture.active].T; break; - case GL_R: *params = glstate.texgen[glstate.texture.active].R; break; + case GL_S: *params = glstate->texgen[glstate->texture.active].S; break; + case GL_T: *params = glstate->texgen[glstate->texture.active].T; break; + case GL_R: *params = glstate->texgen[glstate->texture.active].R; break; default: *params = GL_EYE_LINEAR; } break; case GL_OBJECT_PLANE: switch (coord) { case GL_S: - memcpy(params, glstate.texgen[glstate.texture.active].S_O, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].S_O, 4 * sizeof(GLfloat)); break; case GL_T: - memcpy(params, glstate.texgen[glstate.texture.active].T_O, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].T_O, 4 * sizeof(GLfloat)); break; case GL_R: - memcpy(params, glstate.texgen[glstate.texture.active].R_O, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].R_O, 4 * sizeof(GLfloat)); break; default: errorShim(GL_INVALID_ENUM); @@ -102,13 +102,13 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { case GL_EYE_PLANE: switch (coord) { case GL_S: - memcpy(params, glstate.texgen[glstate.texture.active].S_E, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].S_E, 4 * sizeof(GLfloat)); break; case GL_T: - memcpy(params, glstate.texgen[glstate.texture.active].T_E, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].T_E, 4 * sizeof(GLfloat)); break; case GL_R: - memcpy(params, glstate.texgen[glstate.texture.active].R_E, 4 * sizeof(GLfloat)); + memcpy(params, glstate->texgen[glstate->texture.active].R_E, 4 * sizeof(GLfloat)); break; default: errorShim(GL_INVALID_ENUM); @@ -120,34 +120,89 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { } -GLfloat dot(const GLfloat *a, const GLfloat *b) { +GLfloat FASTMATH dot(const GLfloat *a, const GLfloat *b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]; } -GLfloat dot4(const GLfloat *a, const GLfloat *b) { +GLfloat FASTMATH dot4(const GLfloat *a, const GLfloat *b) { return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; } -//TODO: NEONize all thoses functions, maybe also making the vector an array of 4 float can help. void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c) { +#ifdef __ARM_NEON__ + const float* a1 = a+8; + asm volatile ( + "vld4.f32 {d0,d2,d4,d6}, [%1] \n" + "vld4.f32 {d1,d3,d5,d7}, [%2] \n" // %q0-%q3 = a(0,4,8,12/1,5,9,13/2,6,10,14/3,7,11,15) + "vld1.f32 {q4}, [%3] \n" // %q4 = b + "vmul.f32 q0, q0, d8[0] \n" // %q0 = a(0,4,8,12)*b[0] + "vmla.f32 q0, q1, d8[1] \n" // %q0 = %q0 + a(1,5,9,13)*b[1] + "vmla.f32 q0, q2, d9[0] \n" // %q0 = %q0 + a(2,6,10,14)*b[2] + "vmla.f32 q0, q3, d9[1] \n" // %q0 = %q0 + a(3,7,11,15)*b[3] + "vst1.f32 {q0}, [%0] \n" + ::"r"(c), "r"(a), "r"(a1), "r"(b) + : "q0", "q1", "q2", "q3", "q4", "memory" + ); +#else c[0] = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3]; c[1] = a[4] * b[0] + a[5] * b[1] + a[6] * b[2] + a[7] * b[3]; c[2] = a[8] * b[0] + a[9] * b[1] + a[10] * b[2] + a[11] * b[3]; c[3] = a[12] * b[0] + a[13] * b[1] + a[14] * b[2] + a[15] * b[3]; +#endif } void vector_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c) { +#ifdef __ARM_NEON__ + const float* b2=b+4; + const float* b3=b+8; + const float* b4=b+12; + asm volatile ( + "vld1.f32 {q0}, [%1] \n" // %q0 = a(0..3) + "vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3) + "vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0] + "vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7) + "vmla.f32 q1, q2, d0[1] \n" // %q1 = %q1 + b(4..7)*a[1] + "vld1.f32 {q2}, [%4] \n" // %q2 = b(8..11) + "vmla.f32 q1, q2, d1[0] \n" // %q1 = %q1 + b(8..11)*a[2] + "vld1.f32 {q2}, [%5] \n" // %q2 = b(12..15) + "vmla.f32 q1, q2, d1[1] \n" // %q1 = %q1 + b(12..15)*a[3] + "vst1.f32 {q1}, [%0] \n" + ::"r"(c), "r"(a), "r"(b), "r"(b2), "r"(b3), "r"(b4) + : "%2", "q0", "q1", "q2", "memory" + ); +#else c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + a[3] * b[12]; c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + a[3] * b[13]; c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + a[3] * b[14]; c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + a[3] * b[15]; +#endif } void vector3_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c) { +#ifdef __ARM_NEON__ + const float* b2=b+4; + const float* b3=b+8; + const float* b4=b+12; + asm volatile ( + "vld1.f32 {q0}, [%1] \n" // %q0 = a(0..3) + "vld1.f32 {q1}, [%2] \n" // %q1 = b(0..3) + "vmul.f32 q1, q1, d0[0] \n" // %q1 = b(0..3)*a[0] + "vld1.f32 {q2}, [%3] \n" // %q2 = b(4..7) + "vmla.f32 q1, q2, d0[1] \n" // %q1 = %q1 + b(4..7)*a[1] + "vld1.f32 {q2}, [%4] \n" // %q2 = b(8..11) + "vmla.f32 q1, q2, d1[0] \n" // %q1 = %q1 + b(8..11)*a[2] + "vld1.f32 {q2}, [%5] \n" // %q2 = b(12..15) + "vadd.f32 q1, q1, q2 \n" // %q1 = %q1 + b(12..15) + "vst1.f32 {q1}, [%0] \n" + ::"r"(c), "r"(a), "r"(b), "r"(b2), "r"(b3), "r"(b4) + : "q0", "q1", "q2", "memory" + ); +#else c[0] = a[0] * b[0] + a[1] * b[4] + a[2] * b[8] + b[12]; c[1] = a[0] * b[1] + a[1] * b[5] + a[2] * b[9] + b[13]; c[2] = a[0] * b[2] + a[1] * b[6] + a[2] * b[10] + b[14]; c[3] = a[0] * b[3] + a[1] * b[7] + a[2] * b[11] + b[15]; +#endif } void vector_normalize(GLfloat *a) { @@ -264,7 +319,7 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint GLushort k = indices?indices[i]:i; matrix_vector(ModelviewMatrix, verts+k*4, eye); vector_normalize(eye); - vector3_matrix((norm)?(norm+k*3):glstate.normal, InvModelview, eye_norm); + vector3_matrix((norm)?(norm+k*3):glstate->normal, InvModelview, eye_norm); vector_normalize(eye_norm); a=dot(eye, eye_norm)*2.0f; for (int j=0; j<4; j++) @@ -313,26 +368,27 @@ static inline void tex_coord_loop(GLfloat *verts, GLfloat *norm, GLfloat *out, G } void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count, GLint *needclean, int texture, GLushort *indices, GLuint ilen) { +//printf("gen_tex_coords(%p, %p, %p, %d, %p, %d, %p, %d) texgen = S:%s T:%s R:%s\n", verts, norm, *coords, count, needclean, texture, indices, ilen, (glstate->enable.texgen_s[texture])?PrintEnum(glstate->texgen[texture].S):"-", (glstate->enable.texgen_t[texture])?PrintEnum(glstate->texgen[texture].T):"-", (glstate->enable.texgen_r[texture])?PrintEnum(glstate->texgen[texture].R):"-"); // TODO: do less work when called from glDrawElements? (*needclean) = 0; // special case : no texgen but texture activated, create a simple 1 repeated element - if (!glstate.enable.texgen_s[texture] && !glstate.enable.texgen_t[texture] && !glstate.enable.texgen_r[texture]) { + if (!glstate->enable.texgen_s[texture] && !glstate->enable.texgen_t[texture] && !glstate->enable.texgen_r[texture]) { if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); if (indices) for (int i=0; itexcoord[texture], sizeof(GLfloat)*4); } else for (int i=0; itexcoord[texture], sizeof(GLfloat)*4); } return; } // special case: SPHERE_MAP needs both texgen to make sense - if ((glstate.enable.texgen_s[texture] && (glstate.texgen[texture].S==GL_SPHERE_MAP)) && (glstate.enable.texgen_t[texture] && (glstate.texgen[texture].T==GL_SPHERE_MAP))) + if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_SPHERE_MAP)) && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_SPHERE_MAP))) { - if (!glstate.enable.texture_2d[texture]) + if (!glstate->enable.texture_2d[texture]) return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); @@ -340,13 +396,13 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count return; } // special case: REFLECTION_MAP needs the 3 texgen to make sense - if ((glstate.enable.texgen_s[texture] && (glstate.texgen[texture].S==GL_REFLECTION_MAP)) - && (glstate.enable.texgen_t[texture] && (glstate.texgen[texture].T==GL_REFLECTION_MAP)) - && (glstate.enable.texgen_r[texture] && (glstate.texgen[texture].R==GL_REFLECTION_MAP))) + if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_REFLECTION_MAP)) + && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_REFLECTION_MAP)) + && (glstate->enable.texgen_r[texture] && (glstate->texgen[texture].R==GL_REFLECTION_MAP))) { *needclean=1; // setup reflection map! - GLuint old_tex=glstate.texture.active; + GLuint old_tex=glstate->texture.active; if (old_tex!=texture) glshim_glActiveTexture(GL_TEXTURE0 + texture); LOAD_GLES_OES(glTexGeni); LOAD_GLES_OES(glTexGenfv); @@ -363,13 +419,13 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count return; } // special case: NORMAL_MAP needs the 3 texgen to make sense - if ((glstate.enable.texgen_s[texture] && (glstate.texgen[texture].S==GL_NORMAL_MAP)) - && (glstate.enable.texgen_t[texture] && (glstate.texgen[texture].T==GL_NORMAL_MAP)) - && (glstate.enable.texgen_r[texture] && (glstate.texgen[texture].R==GL_NORMAL_MAP))) + if ((glstate->enable.texgen_s[texture] && (glstate->texgen[texture].S==GL_NORMAL_MAP)) + && (glstate->enable.texgen_t[texture] && (glstate->texgen[texture].T==GL_NORMAL_MAP)) + && (glstate->enable.texgen_r[texture] && (glstate->texgen[texture].R==GL_NORMAL_MAP))) { *needclean=1; // setup reflection map! - GLuint old_tex=glstate.texture.active; + GLuint old_tex=glstate->texture.active; if (old_tex!=texture) glshim_glActiveTexture(GL_TEXTURE0 + texture); LOAD_GLES_OES(glTexGeni); LOAD_GLES_OES(glTexGenfv); @@ -385,14 +441,14 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count return; } - if (!glstate.enable.texture_2d[texture]) + if (!glstate->enable.texture_2d[texture]) return; if ((*coords)==NULL) *coords = (GLfloat *)malloc(count * 4 * sizeof(GLfloat)); - if (glstate.enable.texgen_s[texture]) - tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, glstate.texgen[texture].S, glstate.texgen[texture].S_O, glstate.texgen[texture].S_E, indices); - if (glstate.enable.texgen_t[texture]) - tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, glstate.texgen[texture].T, glstate.texgen[texture].T_O, glstate.texgen[texture].T_E, indices); + if (glstate->enable.texgen_s[texture]) + tex_coord_loop(verts, norm, *coords, (indices)?ilen:count, glstate->texgen[texture].S, glstate->texgen[texture].S_O, glstate->texgen[texture].S_E, indices); + if (glstate->enable.texgen_t[texture]) + tex_coord_loop(verts, norm, *coords+1, (indices)?ilen:count, glstate->texgen[texture].T, glstate->texgen[texture].T_O, glstate->texgen[texture].T_E, indices); for (int i=0; i<((indices)?ilen:count); i++) { GLushort k = indices?indices[i]:i; (*coords)[k*4+2] = 0.0f; @@ -404,11 +460,9 @@ void gen_tex_clean(GLint cleancode, int texture) { if (cleancode == 0) return; if (cleancode == 1) { - GLuint old_tex=glstate.texture.active; - if (old_tex!=texture) glshim_glActiveTexture(GL_TEXTURE0 + texture); + GLuint old_tex=glstate->texture.active; LOAD_GLES(glDisable); gles_glDisable(GL_TEXTURE_GEN_STR); - if (old_tex!=texture) glshim_glActiveTexture(GL_TEXTURE0 + old_tex); return; } } diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index 178af31ae..052310b7c 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -42,7 +42,7 @@ void tex_coord_rect_arb(GLfloat *tex, GLsizei len, void tex_coord_npot(GLfloat *tex, GLsizei len, GLsizei width, GLsizei height, GLsizei nwidth, GLsizei nheight) { - if (!tex || !width || !height) + if (!tex || !nwidth || !nheight) return; GLfloat wratio = (width / (GLfloat)nwidth); @@ -60,9 +60,9 @@ void tex_coord_npot(GLfloat *tex, GLsizei len, * Or some NPOT texture used * Or SHRINKED texure used */ -void tex_setup_texcoord(GLuint texunit, GLuint len) { +void tex_setup_texcoord(GLuint len) { LOAD_GLES(glTexCoordPointer); - GLuint old = glstate.texture.client; + GLuint texunit = glstate->texture.client; static void * tex[8] = {0,0,0,0,0,0,0,0}; // hugly but convenient... @@ -71,35 +71,32 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) { tex[texunit]=NULL; } - gltexture_t *bound = glstate.texture.bound[texunit]; + gltexture_t *bound = glstate->texture.bound[texunit]; // check if some changes are needed int changes = 0; - if ((glstate.texture.rect_arb[texunit]) || + if ((glstate->texture.rect_arb[texunit]) || (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight)|| - (bound->shrink && (glstate.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))))) + (bound->shrink && (glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))))) changes = 1; - if (old!=texunit) glshim_glClientActiveTexture(texunit+GL_TEXTURE0); if (changes) { // first convert to GLfloat, without normalization - tex[texunit] = copy_gl_pointer_tex(&glstate.vao->pointers.tex_coord[texunit], 4, 0, len, /*glstate.vao->pointers.tex_coord[texunit].buffer*/NULL); // the Buffer is already taken into account + tex[texunit] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[texunit], 4, 0, len); if (!tex[texunit]) { - printf("LibGL: Error with Texture tranform\n"); - gles_glTexCoordPointer(len, glstate.vao->pointers.tex_coord[texunit].type, glstate.vao->pointers.tex_coord[texunit].stride, glstate.vao->pointers.tex_coord[texunit].pointer); - if (old!=texunit) glshim_glClientActiveTexture(old+GL_TEXTURE0); + printf("LIBGL: Error with Texture tranform\n"); + gles_glTexCoordPointer(glstate->vao->pointers.tex_coord[texunit].size, glstate->vao->pointers.tex_coord[texunit].type, glstate->vao->pointers.tex_coord[texunit].stride, glstate->vao->pointers.tex_coord[texunit].pointer); return; } // Normalize if needed - if ((glstate.texture.rect_arb[texunit]) || ((glstate.vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate.vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))) + if ((glstate->texture.rect_arb[texunit]) || ((glstate->vao->pointers.tex_coord[texunit].type!=GL_FLOAT) && (glstate->vao->pointers.tex_coord[texunit].type!=GL_DOUBLE))) tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height); if ((bound->width!=bound->nwidth) || (bound->height!=bound->nheight)) tex_coord_npot(tex[texunit], len, bound->width, bound->height, bound->nwidth, bound->nheight); // All done, setup the texcoord array now gles_glTexCoordPointer(4, GL_FLOAT, 0, tex[texunit]); } else { - gles_glTexCoordPointer(glstate.vao->pointers.tex_coord[texunit].size, glstate.vao->pointers.tex_coord[texunit].type, glstate.vao->pointers.tex_coord[texunit].stride, glstate.vao->pointers.tex_coord[texunit].pointer); + gles_glTexCoordPointer(glstate->vao->pointers.tex_coord[texunit].size, glstate->vao->pointers.tex_coord[texunit].type, glstate->vao->pointers.tex_coord[texunit].stride, glstate->vao->pointers.tex_coord[texunit].pointer); } - if (old!=texunit) glshim_glClientActiveTexture(old+GL_TEXTURE0); } int nolumalpha = 0; @@ -265,7 +262,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, if (is_fake_compressed_rgba(intermediaryformat)) intermediaryformat=GL_RGBA; if (is_fake_compressed_rgb(internalformat)) internalformat=GL_RGB; if (is_fake_compressed_rgba(internalformat)) internalformat=GL_RGBA; - + if(*format != intermediaryformat || intermediaryformat!=internalformat) { internal2format_type(intermediaryformat, &dest_format, &dest_type); convert = true; @@ -275,7 +272,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, GLvoid *pixels = (GLvoid *)data; if (! pixel_convert(data, &pixels, width, height, *format, *type, dest_format, dest_type, 0)) { - printf("libGL swizzle error: (%s, %s -> %s, %s)\n", + printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n", PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); return NULL; } @@ -286,7 +283,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, internal2format_type(internalformat, &dest_format, &dest_type); if (! pixel_convert(pixels, &pix2, width, height, *format, *type, dest_format, dest_type, 0)) { - printf("libGL swizzle error: (%s, %s -> %s, %s)\n", + printf("LIBGL: swizzle error: (%s, %s -> %s, %s)\n", PrintEnum(dest_format), PrintEnum(dest_type), PrintEnum(internalformat), PrintEnum(dest_type)); return NULL; } @@ -302,7 +299,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, if (raster_need_transform()) if (!pixel_transform(data, &pixels, width, height, *format, *type, raster_scale, raster_bias)) { - printf("libGL swizzle/convert error: (%s, %s -> %s, %s)\n", + printf("LIBGL: swizzle/convert error: (%s, %s -> %s, %s)\n", PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); pix2 = pixels; } @@ -443,7 +440,7 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) { - //printf("glTexImage2D on target=%s with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%s(%s), type=%s, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i), glstate.list.compiling=%d\n", PrintEnum(target), glstate.texture.unpack_row_length, width, height, glstate.texture.unpack_skip_pixels, glstate.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->mipmap_need:0, (glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->mipmap_auto:0, (glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->texture:0, (glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->streamed:0, glstate.list.compiling); + //printf("glTexImage2D on target=%s with unpack_row_length(%i), size(%i,%i) and skip(%i,%i), format(internal)=%s(%s), type=%s, data=%08x, level=%i (mipmap_need=%i, mipmap_auto=%i) => texture=%u (streamed=%i), glstate->list.compiling=%d\n", PrintEnum(target), glstate->texture.unpack_row_length, width, height, glstate->texture.unpack_skip_pixels, glstate->texture.unpack_skip_rows, PrintEnum(format), PrintEnum(internalformat), PrintEnum(type), data, level, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->mipmap_need:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->mipmap_auto:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->texture:0, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->streamed:0, glstate->list.compiling); // proxy case if (target == GL_PROXY_TEXTURE_2D) { proxy_width = ((width<(texshrink>=8)?8192:2048)?0:width; @@ -452,27 +449,27 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, return; } //PUSH_IF_COMPILING(glTexImage2D); - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } GLvoid *datab = (GLvoid*)data; - if (glstate.vao->unpack) - datab += (uintptr_t)glstate.vao->pack->data; + if (glstate->vao->unpack) + datab += (uintptr_t)glstate->vao->pack->data; GLvoid *pixels = (GLvoid *)datab; border = 0; //TODO: something? noerrorShim(); - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; if (bound) bound->alpha = pixel_hasalpha(format); if (automipmap) { if (bound && (level>0)) if ((automipmap==1) || (automipmap==3) || bound->mipmap_need) { - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; // has been handled by auto_mipmap } else @@ -486,14 +483,14 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (datab) { // implements GL_UNPACK_ROW_LENGTH - if ((glstate.texture.unpack_row_length && glstate.texture.unpack_row_length != width) || glstate.texture.unpack_skip_pixels || glstate.texture.unpack_skip_rows) { + if ((glstate->texture.unpack_row_length && glstate->texture.unpack_row_length != width) || glstate->texture.unpack_skip_pixels || glstate->texture.unpack_skip_rows) { int imgWidth, pixelSize; pixelSize = pixel_sizeof(format, type); - imgWidth = ((glstate.texture.unpack_row_length)? glstate.texture.unpack_row_length:width) * pixelSize; + imgWidth = ((glstate->texture.unpack_row_length)? glstate->texture.unpack_row_length:width) * pixelSize; GLubyte *dst = (GLubyte *)malloc(width * height * pixelSize); pixels = (GLvoid *)dst; const GLubyte *src = (GLubyte *)datab; - src += glstate.texture.unpack_skip_pixels * pixelSize + glstate.texture.unpack_skip_rows * imgWidth; + src += glstate->texture.unpack_skip_pixels * pixelSize + glstate->texture.unpack_skip_rows * imgWidth; for (int y = 0; y < height; y += 1) { memcpy(dst, src, width * pixelSize); src += imgWidth; @@ -698,7 +695,7 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (bound->streamingID>-1) { // success bound->streamed = true; ApplyFilterID(bound->streamingID, bound->min_filter, bound->mag_filter); - GLboolean tmp = glstate.enable.texture_2d[glstate.texture.active]; + GLboolean tmp = glstate->enable.texture_2d[glstate->texture.active]; LOAD_GLES(glDisable); LOAD_GLES(glEnable); if (tmp) @@ -790,6 +787,12 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, break; default: { GLsizei nheight = npot(height), nwidth = npot(width); +#ifdef PANDORA + #define MIN_SIZE 2 + if(nwidth < MIN_SIZE) nwidth=MIN_SIZE; + if(nheight < MIN_SIZE) nheight=MIN_SIZE; + #undef MIN_SIZE +#endif if (texstream && bound && bound->streamed) { nwidth = width; nheight = height; @@ -853,7 +856,7 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (pixels != datab) { free(pixels); } - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; } void glshim_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, @@ -861,46 +864,46 @@ void glshim_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yof const GLvoid *data) { //PUSH_IF_COMPILING(glTexSubImage2D); - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } GLvoid *datab = (GLvoid*)data; - if (glstate.vao->unpack) - datab += (uintptr_t)glstate.vao->pack->data; + if (glstate->vao->unpack) + datab += (uintptr_t)glstate->vao->pack->data; GLvoid *pixels = (GLvoid*)datab; LOAD_GLES(glTexSubImage2D); LOAD_GLES(glTexParameteri); noerrorShim(); - //printf("glTexSubImage2D on target=%s with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%s, type=%s, level=%i, texture=%u\n", PrintEnum(target), glstate.texture.unpack_row_length, width, height, xoffset, yoffset, glstate.texture.unpack_skip_pixels, glstate.texture.unpack_skip_rows, PrintEnum(format), PrintEnum(type), level, glstate.texture.bound[glstate.texture.active]->texture); + //printf("glTexSubImage2D on target=%s with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, format=%s, type=%s, level=%i, texture=%u\n", PrintEnum(target), glstate->texture.unpack_row_length, width, height, xoffset, yoffset, glstate->texture.unpack_skip_pixels, glstate->texture.unpack_skip_rows, PrintEnum(format), PrintEnum(type), level, glstate->texture.bound[glstate->texture.active]->texture); if (width==0 || height==0) { - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } target = map_tex_target(target); - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; if (automipmap) { if (bound && (level>0)) if ((automipmap==1) || (automipmap==3) || bound->mipmap_need) { - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; // has been handled by auto_mipmap } else bound->mipmap_need = 1; } - if ((glstate.texture.unpack_row_length && glstate.texture.unpack_row_length != width) || glstate.texture.unpack_skip_pixels || glstate.texture.unpack_skip_rows) { + if ((glstate->texture.unpack_row_length && glstate->texture.unpack_row_length != width) || glstate->texture.unpack_skip_pixels || glstate->texture.unpack_skip_rows) { int imgWidth, pixelSize; pixelSize = pixel_sizeof(format, type); - imgWidth = ((glstate.texture.unpack_row_length)? glstate.texture.unpack_row_length:width) * pixelSize; + imgWidth = ((glstate->texture.unpack_row_length)? glstate->texture.unpack_row_length:width) * pixelSize; GLubyte *dst = (GLubyte *)malloc(width * height * pixelSize); pixels = (GLvoid *)dst; const GLubyte *src = (GLubyte *)datab; - src += glstate.texture.unpack_skip_pixels * pixelSize + glstate.texture.unpack_skip_rows * imgWidth; + src += glstate->texture.unpack_skip_pixels * pixelSize + glstate->texture.unpack_skip_rows * imgWidth; for (int y = 0; y < height; y ++) { memcpy(dst, src, width * pixelSize); src += imgWidth; @@ -925,7 +928,7 @@ void glshim_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yof tmp += (yoffset*bound->width+xoffset)*2; if (! pixel_convert(old, &tmp, width, height, format, type, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, bound->width)) { - printf("libGL swizzle error: (%#4x, %#4x -> GL_RGB, UNSIGNED_SHORT_5_6_5)\n", + printf("LIBGL: swizzle error: (%#4x, %#4x -> GL_RGB, UNSIGNED_SHORT_5_6_5)\n", format, type); } format = GL_RGB; @@ -969,7 +972,7 @@ void glshim_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yof // nothing to do... if (pixels != datab) free((GLvoid *)pixels); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } // ok, now standard cases.... @@ -1021,7 +1024,7 @@ void glshim_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yof if (pixels != datab) free((GLvoid *)pixels); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; } // 1d stubs @@ -1078,45 +1081,45 @@ void glshim_glTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yof void glshim_glPixelStorei(GLenum pname, GLint param) { // TODO: add to glGetIntegerv? -// if (glstate.gl_batch) flush(); +// if (glstate->gl_batch) flush(); LOAD_GLES(glPixelStorei); noerrorShim(); switch (pname) { case GL_UNPACK_ROW_LENGTH: - glstate.texture.unpack_row_length = param; + glstate->texture.unpack_row_length = param; break; case GL_UNPACK_SKIP_PIXELS: - glstate.texture.unpack_skip_pixels = param; + glstate->texture.unpack_skip_pixels = param; break; case GL_UNPACK_SKIP_ROWS: - glstate.texture.unpack_skip_rows = param; + glstate->texture.unpack_skip_rows = param; break; case GL_UNPACK_LSB_FIRST: - glstate.texture.unpack_lsb_first = param; + glstate->texture.unpack_lsb_first = param; break; case GL_UNPACK_IMAGE_HEIGHT: - glstate.texture.unpack_image_height = param; + glstate->texture.unpack_image_height = param; break; case GL_UNPACK_SWAP_BYTES: case GL_PACK_SWAP_BYTES: // Fake... TODO? - //glstate.texture.unpack_lsb_first = param; + //glstate->texture.unpack_lsb_first = param; break; case GL_PACK_ROW_LENGTH: - glstate.texture.pack_row_length = param; + glstate->texture.pack_row_length = param; break; case GL_PACK_SKIP_PIXELS: - glstate.texture.pack_skip_pixels = param; + glstate->texture.pack_skip_pixels = param; break; case GL_PACK_SKIP_ROWS: - glstate.texture.pack_skip_rows = param; + glstate->texture.pack_skip_rows = param; break; case GL_PACK_LSB_FIRST: - glstate.texture.pack_lsb_first = param; + glstate->texture.pack_lsb_first = param; break; case GL_PACK_IMAGE_HEIGHT: - glstate.texture.pack_image_height = param; + glstate->texture.pack_image_height = param; break; default: errorGL(); @@ -1131,7 +1134,7 @@ GLboolean glshim_glIsTexture( GLuint texture) { } int ret; khint_t k; - khash_t(tex) *list = glstate.texture.list; + khash_t(tex) *list = glstate->texture.list; if (! list) { return GL_FALSE; } @@ -1149,9 +1152,9 @@ gltexture_t* glshim_getTexture(GLenum target, GLuint texture) { if (texture == 0) return tex; int ret; khint_t k; - khash_t(tex) *list = glstate.texture.list; + khash_t(tex) *list = glstate->texture.list; if (! list) { - list = glstate.texture.list = kh_init(tex); + list = glstate->texture.list = kh_init(tex); // segfaults if we don't do a single put kh_put(tex, list, 1, &ret); kh_del(tex, list, 1); @@ -1184,38 +1187,38 @@ gltexture_t* glshim_getTexture(GLenum target, GLuint texture) { } return tex; } -#define batch_activetex (glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active) +#define batch_activetex (glstate->statebatch.active_tex_changed?(glstate->statebatch.active_tex-GL_TEXTURE0):glstate->texture.active) void glshim_glBindTexture(GLenum target, GLuint texture) { noerrorShim(); - if ((target!=GL_PROXY_TEXTURE_2D) && (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling))) { - //printf("=> glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate.texture.active, glstate.texture.client, batch_activetex, glstate.statebatch.bound_targ[batch_activetex], glstate.statebatch.bound_tex[batch_activetex]); - if ((glstate.statebatch.bound_targ[batch_activetex] == target) && (glstate.statebatch.bound_tex[batch_activetex] == texture)) + if ((target!=GL_PROXY_TEXTURE_2D) && (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling))) { + //printf("=> glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate->texture.active, glstate->texture.client, batch_activetex, glstate->statebatch.bound_targ[batch_activetex], glstate->statebatch.bound_tex[batch_activetex]); + if ((glstate->statebatch.bound_targ[batch_activetex] == target) && (glstate->statebatch.bound_tex[batch_activetex] == texture)) return; // nothing to do... - if (glstate.statebatch.bound_targ[batch_activetex]) { + if (glstate->statebatch.bound_targ[batch_activetex]) { flush(); } - glstate.statebatch.bound_targ[batch_activetex] = target; - glstate.statebatch.bound_tex[batch_activetex] = texture; - //printf(" <= glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate.texture.active, glstate.texture.client, batch_activetex, glstate.statebatch.bound_targ[batch_activetex], glstate.statebatch.bound_tex[batch_activetex]); + glstate->statebatch.bound_targ[batch_activetex] = target; + glstate->statebatch.bound_tex[batch_activetex] = texture; + //printf(" <= glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate->texture.active, glstate->texture.client, batch_activetex, glstate->statebatch.bound_targ[batch_activetex], glstate->statebatch.bound_tex[batch_activetex]); } - if ((target!=GL_PROXY_TEXTURE_2D) && ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active)) { + if ((target!=GL_PROXY_TEXTURE_2D) && ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active)) { // check if already a texture binded, if yes, create a new list - NewStage(glstate.list.active, STAGE_BINDTEX); - rlBindTexture(glstate.list.active, target, texture); + NewStage(glstate->list.active, STAGE_BINDTEX); + rlBindTexture(glstate->list.active, target, texture); } else { int tex_changed = 1; int streamingID = -1; gltexture_t *tex = NULL; - //printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, glstate.texture.active, glstate.texture.client); + //printf("glBindTexture(0x%04X, %u), active=%i, client=%i\n", target, texture, glstate->texture.active, glstate->texture.client); if (texture) { tex = glshim_getTexture(target, texture); - if (glstate.texture.bound[glstate.texture.active] == tex) + if (glstate->texture.bound[glstate->texture.active] == tex) tex_changed = 0; texture = tex->glname; if (texstream && tex->streamed) streamingID = tex->streamingID; } else { - if (glstate.texture.bound[glstate.texture.active] == NULL) + if (glstate->texture.bound[glstate->texture.active] == NULL) tex_changed = 0; } @@ -1225,10 +1228,10 @@ tex_changed=1; // seems buggy, temporary disabling that... if (tex_changed) { - GLboolean tmp = glstate.enable.texture_2d[glstate.texture.active]; + GLboolean tmp = glstate->enable.texture_2d[glstate->texture.active]; #ifdef TEXSTREAM if (texstream) { // unbind streaming texture if any... - gltexture_t *bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; if (bound && bound->streamed) { if (tmp) gles_glDisable(GL_TEXTURE_STREAM_IMG); @@ -1239,10 +1242,10 @@ tex_changed=1; // seems buggy, temporary disabling that... } #endif - glstate.texture.rect_arb[glstate.texture.active] = (target == GL_TEXTURE_RECTANGLE_ARB); + glstate->texture.rect_arb[glstate->texture.active] = (target == GL_TEXTURE_RECTANGLE_ARB); target = map_tex_target(target); - glstate.texture.bound[glstate.texture.active] = tex; + glstate->texture.bound[glstate->texture.active] = tex; LOAD_GLES(glBindTexture); #ifdef TEXSTREAM @@ -1268,7 +1271,7 @@ void glshim_glTexParameteri(GLenum target, GLenum pname, GLint param) { PUSH_IF_COMPILING(glTexParameteri); LOAD_GLES(glTexParameteri); target = map_tex_target(target); - gltexture_t *texture = glstate.texture.bound[glstate.texture.active]; + gltexture_t *texture = glstate->texture.bound[glstate->texture.active]; switch (pname) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: @@ -1301,6 +1304,8 @@ void glshim_glTexParameteri(GLenum target, GLenum pname, GLint param) { param = GL_CLAMP_TO_EDGE; break; } + if (pname==GL_TEXTURE_WRAP_S) if (texture) texture->wrap_s = param; + if (pname==GL_TEXTURE_WRAP_T) if (texture) texture->wrap_t = param; break; case GL_TEXTURE_MAX_LEVEL: if (texture) @@ -1329,10 +1334,10 @@ void glshim_glTexParameterf(GLenum target, GLenum pname, GLfloat param) { } void glshim_glDeleteTextures(GLsizei n, const GLuint *textures) { - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); noerrorShim(); LOAD_GLES(glDeleteTextures); - khash_t(tex) *list = glstate.texture.list; + khash_t(tex) *list = glstate->texture.list; if (list) { khint_t k; gltexture_t *tex; @@ -1343,8 +1348,8 @@ void glshim_glDeleteTextures(GLsizei n, const GLuint *textures) { tex = kh_value(list, k); int a; for (a=0; atexture.bound[a]) + glstate->texture.bound[a] = NULL; } gles_glDeleteTextures(1, &tex->glname); errorGL(); @@ -1371,16 +1376,16 @@ void glshim_glDeleteTextures(GLsizei n, const GLuint *textures) { void glshim_glGenTextures(GLsizei n, GLuint * textures) { if (n<=0) return; - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); LOAD_GLES(glGenTextures); gles_glGenTextures(n, textures); errorGL(); // now, add all the textures to the list int ret; khint_t k; - khash_t(tex) *list = glstate.texture.list; + khash_t(tex) *list = glstate->texture.list; if (! list) { - list = glstate.texture.list = kh_init(tex); + list = glstate->texture.list = kh_init(tex); // segfaults if we don't do a single put kh_put(tex, list, 1, &ret); kh_del(tex, list, 1); @@ -1424,10 +1429,10 @@ GLboolean glshim_glAreTexturesResident(GLsizei n, const GLuint *textures, GLbool void glshim_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { //printf("glGetTexLevelParameteriv(%s, %d, %s, %p)\n", PrintEnum(target), level, PrintEnum(pname), params); // simplification: (mostly) not taking "target" into account here - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); *params = 0; noerrorShim(); - gltexture_t* bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; switch (pname) { case GL_TEXTURE_WIDTH: if (target==GL_PROXY_TEXTURE_2D) @@ -1520,12 +1525,20 @@ void glshim_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, G } extern GLuint current_fb; // from framebuffers.c +// hacky viewport temporary changes +void pushViewport(GLint x, GLint y, GLsizei width, GLsizei height); +void popViewport(); + void glshim_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, GLvoid * img) { - if (glstate.gl_batch) flush(); - if (glstate.texture.bound[glstate.texture.active]==NULL) + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { + flush(); + glstate->gl_batch = 0; + } + if (glstate->texture.bound[glstate->texture.active]==NULL) return; // no texture bounded... - gltexture_t* bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; int width = bound->width; int height = bound->height; if (level != 0) { @@ -1542,27 +1555,34 @@ void glshim_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type } memcpy(img, tmp, width*height*pixel_sizeof(format, type)); free(tmp); + if (old_glbatch) + glstate->gl_batch=old_glbatch; return; } - if (target!=GL_TEXTURE_2D) + if (target!=GL_TEXTURE_2D) { + if (old_glbatch) + glstate->gl_batch=old_glbatch; return; + } - //printf("glGetTexImage(0x%04X, %i, 0x%04X, 0x%04X, 0x%p), texture=%u, size=%i,%i\n", target, level, format, type, img, bound->glname, width, height); + //printf("glGetTexImage(%s, %i, %s, %s, 0x%p), texture=0x%x, size=%i,%i\n", PrintEnum(target), level, PrintEnum(format), PrintEnum(type), img, bound->glname, width, height); GLvoid *dst = img; - if (glstate.vao->pack) - dst += (uintptr_t)glstate.vao->pack->data; + if (glstate->vao->pack) + dst += (uintptr_t)glstate->vao->pack->data; #ifdef TEXSTREAM if (texstream && bound->streamed) { noerrorShim(); pixel_convert(GetStreamingBuffer(bound->streamingID), &dst, width, height, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format, type, 0); readfboEnd(); + if (old_glbatch) + glstate->gl_batch=old_glbatch; return; } #endif if (texcopydata && bound->data) { - printf("texcopydata* glGetTexImage(0x%04X, %d, 0x%04x, 0x%04X, %p)\n", target, level, format, type, img); + //printf("texcopydata* glGetTexImage(0x%04X, %d, 0x%04x, 0x%04X, %p)\n", target, level, format, type, img); noerrorShim(); if (!pixel_convert(bound->data, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) printf("LIBGL: Error on pixel_convert while glGetTexImage\n"); @@ -1572,30 +1592,151 @@ void glshim_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type GLuint old_fbo = current_fb; GLuint fbo; - glshim_glGenFramebuffers(1, &fbo); - glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo); - glshim_glFramebufferTexture2D(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, oldBind, 0); - // Read the pixels! - glshim_glReadPixels(0, 0, width, height, format, type, img); // using "full" version with conversion of format/type - glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, old_fbo); - glshim_glDeleteFramebuffers(1, &fbo); - noerrorShim(); + // if the texture is not RGBA or RGB or ALPHA, the "just attach texture to the fbo" trick will not work, and a full Blit has to be done + if(bound->format==GL_RGBA || bound->format==GL_RGB || bound->format==GL_ALPHA) { + glshim_glGenFramebuffers(1, &fbo); + glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo); + glshim_glFramebufferTexture2D(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, oldBind, 0); + // Read the pixels! + glshim_glReadPixels(0, 0, width, height, format, type, img); // using "full" version with conversion of format/type + glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, old_fbo); + glshim_glDeleteFramebuffers(1, &fbo); + noerrorShim(); + } else { + glshim_glGenFramebuffers(1, &fbo); + glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, fbo); + GLuint temptex; + glshim_glGenTextures(1, &temptex); + glshim_glBindTexture(GL_TEXTURE_2D, temptex); + glshim_glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bound->nwidth, bound->nheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); + glshim_glFramebufferTexture2D(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_TEXTURE_2D, temptex, 0); + glshim_glBindTexture(GL_TEXTURE_2D, oldBind); + // blit the texture + // TODO: create a blitTexture function (to be used in raster too) + LOAD_GLES(glEnableClientState); + LOAD_GLES(glDisableClientState); + LOAD_GLES(glVertexPointer); + LOAD_GLES(glTexCoordPointer); + LOAD_GLES(glDrawArrays); + LOAD_GLES(glBindTexture); + LOAD_GLES(glActiveTexture); + LOAD_GLES(glClientActiveTexture); + glshim_glPushAttrib(GL_TEXTURE_BIT | GL_ENABLE_BIT | GL_TRANSFORM_BIT | GL_COLOR_BUFFER_BIT | GL_CURRENT_BIT); + GLfloat old_projection[16], old_modelview[16], old_texture[16]; + + glshim_glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + glshim_glClear(GL_COLOR_BUFFER_BIT); + + GLuint old_tex = glstate->texture.active; + if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0); + GLuint old_cli = glstate->texture.client; + if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0); + glshim_glGetFloatv(GL_TEXTURE_MATRIX, old_texture); + glshim_glGetFloatv(GL_PROJECTION_MATRIX, old_projection); + glshim_glGetFloatv(GL_MODELVIEW_MATRIX, old_modelview); + glshim_glMatrixMode(GL_TEXTURE); + glshim_glLoadIdentity(); + glshim_glMatrixMode(GL_PROJECTION); + glshim_glLoadIdentity(); + glshim_glMatrixMode(GL_MODELVIEW); + glshim_glLoadIdentity(); + + pushViewport(0,0,bound->nwidth, bound->nheight); + float w2 = 2.0f / bound->nwidth; + float h2 = 2.0f / bound->nheight; + float blit_x1=0; + float blit_x2=bound->nwidth; + float blit_y1=0; + float blit_y2=bound->nheight; + GLfloat blit_vert[] = { + blit_x1*w2-1.0f, blit_y1*h2-1.0f, + blit_x2*w2-1.0f, blit_y1*h2-1.0f, + blit_x2*w2-1.0f, blit_y2*h2-1.0f, + blit_x1*w2-1.0f, blit_y2*h2-1.0f + }; + GLfloat blit_tex[] = { + 0, 0, + 1, 0, + 1, 1, + 0, 1 + }; + + glshim_glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT | GL_CLIENT_PIXEL_STORE_BIT); + + glshim_glDisable(GL_DEPTH_TEST); + glshim_glDisable(GL_LIGHTING); + glshim_glDisable(GL_CULL_FACE); + glshim_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + glshim_glEnable(GL_TEXTURE_2D); + gles_glBindTexture(GL_TEXTURE_2D, oldBind); + glshim_glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + if(!glstate->clientstate.vertex_array) + { + gles_glEnableClientState(GL_VERTEX_ARRAY); + glstate->clientstate.vertex_array = 1; + } + gles_glVertexPointer(2, GL_FLOAT, 0, blit_vert); + if(!glstate->clientstate.tex_coord_array[0]) + { + gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glstate->clientstate.tex_coord_array[0] = 1; + } + gles_glTexCoordPointer(2, GL_FLOAT, 0, blit_tex); + for (int a=1; a clientstate.tex_coord_array[a]) { + gles_glClientActiveTexture(GL_TEXTURE0 + a); + gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glstate->clientstate.tex_coord_array[a] = 0; + gles_glClientActiveTexture(GL_TEXTURE0); + } + if(glstate->clientstate.color_array) { + gles_glDisableClientState(GL_COLOR_ARRAY); + glstate->clientstate.color_array = 0; + } + if(glstate->clientstate.normal_array) { + gles_glDisableClientState(GL_NORMAL_ARRAY); + glstate->clientstate.normal_array = 0; + } + gles_glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + // All the previous states are Pushed / Poped anyway... + if (old_tex!=0) gles_glActiveTexture(GL_TEXTURE0+old_tex); + if (old_cli!=0) gles_glClientActiveTexture(GL_TEXTURE0+old_cli); + glshim_glPopClientAttrib(); + glshim_glMatrixMode(GL_TEXTURE); + glshim_glLoadMatrixf(old_texture); + glshim_glMatrixMode(GL_MODELVIEW); + glshim_glLoadMatrixf(old_modelview); + glshim_glMatrixMode(GL_PROJECTION); + glshim_glLoadMatrixf(old_projection); + glshim_glPopAttrib(); + // Read the pixels! + glshim_glReadPixels(0, 0, width, height, format, type, img); // using "full" version with conversion of format/type + glshim_glBindFramebuffer(GL_FRAMEBUFFER_OES, old_fbo); + glshim_glDeleteFramebuffers(1, &fbo); + glshim_glDeleteTextures(1, &temptex); + popViewport(); + noerrorShim(); + } } + if (old_glbatch) + glstate->gl_batch=old_glbatch; } void glshim_glActiveTexture( GLenum texture ) { - if (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling)) { - if (glstate.statebatch.active_tex_changed) { - if(glstate.statebatch.active_tex == texture) + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) { + if (glstate->statebatch.active_tex_changed) { + if(glstate->statebatch.active_tex == texture) return; // nothing to do... flush(); } - glstate.statebatch.active_tex = texture; - glstate.statebatch.active_tex_changed = 1; + glstate->statebatch.active_tex = texture; + glstate->statebatch.active_tex_changed = 1; } - if (glstate.list.active) { - NewStage(glstate.list.active, STAGE_ACTIVETEX); - rlActiveTexture(glstate.list.active, texture); + if (glstate->list.active) { + NewStage(glstate->list.active, STAGE_ACTIVETEX); + rlActiveTexture(glstate->list.active, texture); return; } @@ -1603,7 +1744,7 @@ void glshim_glActiveTexture( GLenum texture ) { errorShim(GL_INVALID_ENUM); return; } - glstate.texture.active = texture - GL_TEXTURE0; + glstate->texture.active = texture - GL_TEXTURE0; LOAD_GLES(glActiveTexture); gles_glActiveTexture(texture); errorGL(); @@ -1615,10 +1756,10 @@ void glshim_glClientActiveTexture( GLenum texture ) { return; } // try to speed-up things... - if (glstate.texture.client == (texture - GL_TEXTURE0)) + if (glstate->texture.client == (texture - GL_TEXTURE0)) return; - if (glstate.gl_batch) flush(); - glstate.texture.client = texture - GL_TEXTURE0; + if (glstate->gl_batch) flush(); + glstate->texture.client = texture - GL_TEXTURE0; LOAD_GLES(glClientActiveTexture); gles_glClientActiveTexture(texture); errorGL(); @@ -1626,28 +1767,28 @@ void glshim_glClientActiveTexture( GLenum texture ) { void glshim_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid * data) { //printf("glReadPixels(%i, %i, %i, %i, 0x%04X, 0x%04X, 0x%p)\n", x, y, width, height, format, type, data); - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } - if (glstate.list.compiling && glstate.list.active) { + if (glstate->list.compiling && glstate->list.active) { errorShim(GL_INVALID_OPERATION); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; // never in list } LOAD_GLES(glReadPixels); errorGL(); GLvoid* dst = data; - if (glstate.vao->pack) - dst += (uintptr_t)glstate.vao->pack->data; + if (glstate->vao->pack) + dst += (uintptr_t)glstate->vao->pack->data; readfboBegin(); if (format == GL_RGBA && format == GL_UNSIGNED_BYTE) { // easy passthru gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst); readfboEnd(); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } // grab data in GL_RGBA format @@ -1655,38 +1796,38 @@ void glshim_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); if (! pixel_convert(pixels, &dst, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) { - printf("libGL ReadPixels error: (GL_RGBA, UNSIGNED_BYTE -> %#4x, %#4x )\n", - format, type); + printf("LIBGL: ReadPixels error: (GL_RGBA, UNSIGNED_BYTE -> %s, %s )\n", + PrintEnum(format), PrintEnum(type)); } free(pixels); readfboEnd(); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } void glshim_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height) { - //printf("glCopyTexSubImage2D(%s, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=%s, %s\n", PrintEnum(target), level, xoffset, yoffset, x, y, width, height, (glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->texture:0, PrintEnum((glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->format:0), PrintEnum((glstate.texture.bound[glstate.texture.active])?glstate.texture.bound[glstate.texture.active]->type:0)); + //printf("glCopyTexSubImage2D(%s, %i, %i, %i, %i, %i, %i, %i), bounded texture=%u format/type=%s, %s\n", PrintEnum(target), level, xoffset, yoffset, x, y, width, height, (glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->texture:0, PrintEnum((glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->format:0), PrintEnum((glstate->texture.bound[glstate->texture.active])?glstate->texture.bound[glstate->texture.active]->type:0)); // PUSH_IF_COMPILING(glCopyTexSubImage2D); - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } LOAD_GLES(glCopyTexSubImage2D); errorGL(); // "Unmap" if buffer mapped... - glbuffer_t *pack = glstate.vao->pack; - glbuffer_t *unpack = glstate.vao->unpack; - glstate.vao->pack = NULL; - glstate.vao->unpack = NULL; + glbuffer_t *pack = glstate->vao->pack; + glbuffer_t *unpack = glstate->vao->unpack; + glstate->vao->pack = NULL; + glstate->vao->unpack = NULL; - gltexture_t* bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; if (!bound) { errorShim(GL_INVALID_OPERATION); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } #ifdef TEXSTREAM @@ -1717,9 +1858,9 @@ void glshim_glCopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint } } // "Remap" if buffer mapped... - glstate.vao->pack = pack; - glstate.vao->unpack = unpack; - glstate.gl_batch = old_glbatch; + glstate->vao->pack = pack; + glstate->vao->unpack = unpack; + glstate->gl_batch = old_glbatch; } @@ -1727,19 +1868,19 @@ void glshim_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat GLsizei width, GLsizei height, GLint border) { //printf("glCopyTexImage2D(0x%04X, %i, 0x%04X, %i, %i, %i, %i, %i), current_fb=%u\n", target, level, internalformat, x, y, width, height, border, current_fb); //PUSH_IF_COMPILING(glCopyTexImage2D); - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } errorGL(); // "Unmap" if buffer mapped... - glbuffer_t *pack = glstate.vao->pack; - glbuffer_t *unpack = glstate.vao->unpack; - glstate.vao->pack = NULL; - glstate.vao->unpack = NULL; + glbuffer_t *pack = glstate->vao->pack; + glbuffer_t *unpack = glstate->vao->unpack; + glstate->vao->pack = NULL; + glstate->vao->unpack = NULL; if (copytex) { LOAD_GLES(glCopyTexImage2D); @@ -1752,10 +1893,10 @@ void glshim_glCopyTexImage2D(GLenum target, GLint level, GLenum internalformat } // "Remap" if buffer mapped... - glstate.vao->pack = pack; - glstate.vao->unpack = unpack; + glstate->vao->pack = pack; + glstate->vao->unpack = unpack; - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; } @@ -1838,17 +1979,17 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo proxy_height = (height>2048)?0:height; return; } - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } - if (glstate.texture.bound[glstate.texture.active]==NULL) { + if (glstate->texture.bound[glstate->texture.active]==NULL) { errorShim(GL_INVALID_OPERATION); return; // no texture bounded... } - //printf("glCompressedTexImage2D on target=%s with size(%i,%i), internalformat=%s, imagesize=%i, upackbuffer=%p\n", PrintEnum(target), width, height, PrintEnum(internalformat), imageSize, glstate.vao->unpack?glstate.vao->unpack->data:0); + //printf("glCompressedTexImage2D on target=%s with size(%i,%i), internalformat=%s, imagesize=%i, upackbuffer=%p data=%p\n", PrintEnum(target), width, height, PrintEnum(internalformat), imageSize, glstate->vao->unpack?glstate->vao->unpack->data:0, data); // hack... if (internalformat==GL_RGBA8) internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; @@ -1866,8 +2007,8 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo LOAD_GLES(glCompressedTexImage2D); errorGL(); - glbuffer_t *unpack = glstate.vao->unpack; - glstate.vao->unpack = NULL; + glbuffer_t *unpack = glstate->vao->unpack; + glstate->vao->unpack = NULL; GLvoid *datab = (GLvoid*)data; if (unpack) datab += (uintptr_t)unpack->data; @@ -1878,6 +2019,7 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo if (isDXTc(internalformat)) { GLvoid *pixels, *half; int fact = 0; + pixels = half = NULL; if (datab) { if (width<4 || height<4) { // can happens :( GLvoid *tmp; @@ -1896,21 +2038,20 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo } // automaticaly reduce the pixel size half=pixels; - glstate.texture.bound[glstate.texture.active]->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; + glstate->texture.bound[glstate->texture.active]->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; - glstate.texture.bound[glstate.texture.active]->format = format; //internalformat; + glstate->texture.bound[glstate->texture.active]->format = format; //internalformat; type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; - glstate.texture.bound[glstate.texture.active]->type = type; - glstate.texture.bound[glstate.texture.active]->compressed = true; + glstate->texture.bound[glstate->texture.active]->type = type; + glstate->texture.bound[glstate->texture.active]->compressed = true; if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) fact = 0; // if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE)) // fact = 1; else - glstate.texture.bound[glstate.texture.active]->type = GL_UNSIGNED_BYTE; + glstate->texture.bound[glstate->texture.active]->type = GL_UNSIGNED_BYTE; } else { - half = NULL; - fact = 1; + fact = 0; } int oldalign; glshim_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign); @@ -1924,41 +2065,41 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo if (pixels!=datab) free(pixels); } else { - glstate.texture.bound[glstate.texture.active]->alpha = true; - glstate.texture.bound[glstate.texture.active]->format = internalformat; - glstate.texture.bound[glstate.texture.active]->type = GL_UNSIGNED_BYTE; - glstate.texture.bound[glstate.texture.active]->compressed = true; + glstate->texture.bound[glstate->texture.active]->alpha = true; + glstate->texture.bound[glstate->texture.active]->format = internalformat; + glstate->texture.bound[glstate->texture.active]->type = GL_UNSIGNED_BYTE; + glstate->texture.bound[glstate->texture.active]->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } - glstate.vao->unpack = unpack; - glstate.gl_batch = old_glbatch; + glstate->vao->unpack = unpack; + glstate->gl_batch = old_glbatch; } void glshim_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { - GLuint old_glbatch = glstate.gl_batch; - if (glstate.gl_batch) { + GLuint old_glbatch = glstate->gl_batch; + if (glstate->gl_batch) { flush(); - glstate.gl_batch = 0; + glstate->gl_batch = 0; } - if (glstate.texture.bound[glstate.texture.active]==NULL) { + if (glstate->texture.bound[glstate->texture.active]==NULL) { errorShim(GL_INVALID_OPERATION); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; // no texture bounded... } if (level != 0) { noerrorShim(); //TODO //printf("STUBBED glCompressedTexSubImage2D with level=%i\n", level); - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; return; } - //printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%s, imagesize=%i\n", glstate.texture.unpack_row_length, width, height, xoffset, yoffset, glstate.texture.unpack_skip_pixels, glstate.texture.unpack_skip_rows, PrintEnum(format), imageSize); - glbuffer_t *unpack = glstate.vao->unpack; - glstate.vao->unpack = NULL; + //printf("glCompressedTexSubImage2D with unpack_row_length(%i), size(%i,%i), pos(%i,%i) and skip={%i,%i}, internalformat=%s, imagesize=%i, data=%p\n", glstate->texture.unpack_row_length, width, height, xoffset, yoffset, glstate->texture.unpack_skip_pixels, glstate->texture.unpack_skip_rows, PrintEnum(format), imageSize, data); + glbuffer_t *unpack = glstate->vao->unpack; + glstate->vao->unpack = NULL; GLvoid *datab = (GLvoid*)data; if (unpack) datab += (uintptr_t)unpack->data; @@ -1982,7 +2123,7 @@ void glshim_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, pixels = uncompressDXTc(width, height, format, imageSize, datab); } GLvoid *half=pixels; - #if 1 + #if 0 pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE); int oldalign; glshim_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign); @@ -1990,8 +2131,10 @@ void glshim_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, glshim_glTexSubImage2D(target, level, xoffset/2, yoffset/2, width/2, height/2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, half); if (oldalign!=1) glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign); #else - pixel_halfscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE); - glTexSubImage2D(target, level, xoffset/2, yoffset/2, width/2, height/2, GL_RGBA, GL_UNSIGNED_BYTE, half); + GLenum format = glstate->texture.bound[glstate->texture.active]->format; + GLenum type = glstate->texture.bound[glstate->texture.active]->type; + pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0); + glshim_glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, half); #endif if (half!=pixels) free(half); @@ -2000,13 +2143,13 @@ void glshim_glCompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, } else { gles_glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, datab); } - glstate.gl_batch = old_glbatch; + glstate->gl_batch = old_glbatch; } void glshim_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { - if (glstate.gl_batch) flush(); + if (glstate->gl_batch) flush(); - gltexture_t* bound = glstate.texture.bound[glstate.texture.active]; + gltexture_t* bound = glstate->texture.bound[glstate->texture.active]; //printf("glGetCompressedTexImage(%s, %i, %p), bound=%p, bound->orig_internal=%s\n", PrintEnum(target), lod, img, bound, (bound)?PrintEnum(bound->orig_internal):"nil"); errorShim(GL_INVALID_OPERATION); if(!bound) @@ -2020,10 +2163,10 @@ void glshim_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { int alpha = (bound->orig_internal==GL_COMPRESSED_RGBA)?1:0; - glbuffer_t *unpack = glstate.vao->unpack; - glbuffer_t *pack = glstate.vao->pack; - glstate.vao->unpack = NULL; - glstate.vao->pack = NULL; + glbuffer_t *unpack = glstate->vao->unpack; + glbuffer_t *pack = glstate->vao->pack; + glstate->vao->unpack = NULL; + glstate->vao->pack = NULL; GLvoid *datab = (GLvoid*)img; if (pack) datab += (uintptr_t)pack->data; @@ -2046,8 +2189,8 @@ void glshim_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { free(src); - glstate.vao->unpack = unpack; - glstate.vao->pack = pack; + glstate->vao->unpack = unpack; + glstate->vao->pack = pack; noerrorShim(); return; } diff --git a/project/jni/glshim/src/gl/texture.h b/project/jni/glshim/src/gl/texture.h index 856d5987b..e3cdbbd55 100755 --- a/project/jni/glshim/src/gl/texture.h +++ b/project/jni/glshim/src/gl/texture.h @@ -100,6 +100,8 @@ typedef struct { GLboolean mipmap_need; GLenum min_filter; GLenum mag_filter; + GLenum wrap_s; + GLenum wrap_t; GLboolean uploaded; GLboolean alpha; GLboolean compressed; @@ -131,6 +133,6 @@ void glshim_glClientActiveTexture( GLenum texture ); void glshim_glMultiTexCoord2f( GLenum target, GLfloat s, GLfloat t ); GLboolean glshim_glIsTexture( GLuint texture ); -void tex_setup_texcoord(GLuint texunit, GLuint len); +void tex_setup_texcoord(GLuint len); #endif diff --git a/project/jni/glshim/src/gl/wrap/gles.c b/project/jni/glshim/src/gl/wrap/gles.c index 5f48f5704..9f6320a22 100755 --- a/project/jni/glshim/src/gl/wrap/gles.c +++ b/project/jni/glshim/src/gl/wrap/gles.c @@ -1902,4 +1902,535 @@ void glPackedCall(const packed_call_t *packed) { } } } +/* +packed_call_t* glCopyPackedCall(const packed_call_t *packed) { + switch (packed->format) { + case FORMAT_void_GLenum: { + int sizeofpacked = sizeof(PACKED_void_GLenum); + PACKED_void_GLenum *newpacked = (PACKED_void_GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLclampf: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLclampf); + PACKED_void_GLenum_GLclampf *newpacked = (PACKED_void_GLenum_GLclampf*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLclampx: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLclampx); + PACKED_void_GLenum_GLclampx *newpacked = (PACKED_void_GLenum_GLclampx*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLuint: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLuint); + PACKED_void_GLenum_GLuint *newpacked = (PACKED_void_GLenum_GLuint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum); + PACKED_void_GLenum_GLenum *newpacked = (PACKED_void_GLenum_GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLsizeiptr_const_GLvoid___GENPT___GLenum: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLsizeiptr_const_GLvoid___GENPT___GLenum); + PACKED_void_GLenum_GLsizeiptr_const_GLvoid___GENPT___GLenum *newpacked = (PACKED_void_GLenum_GLsizeiptr_const_GLvoid___GENPT___GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLintptr_GLsizeiptr_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLintptr_GLsizeiptr_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLintptr_GLsizeiptr_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLintptr_GLsizeiptr_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLbitfield: { + int sizeofpacked = sizeof(PACKED_void_GLbitfield); + PACKED_void_GLbitfield *newpacked = (PACKED_void_GLbitfield*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampf_GLclampf_GLclampf_GLclampf: { + int sizeofpacked = sizeof(PACKED_void_GLclampf_GLclampf_GLclampf_GLclampf); + PACKED_void_GLclampf_GLclampf_GLclampf_GLclampf *newpacked = (PACKED_void_GLclampf_GLclampf_GLclampf_GLclampf*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampx_GLclampx_GLclampx_GLclampx: { + int sizeofpacked = sizeof(PACKED_void_GLclampx_GLclampx_GLclampx_GLclampx); + PACKED_void_GLclampx_GLclampx_GLclampx_GLclampx *newpacked = (PACKED_void_GLclampx_GLclampx_GLclampx_GLclampx*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampf: { + int sizeofpacked = sizeof(PACKED_void_GLclampf); + PACKED_void_GLclampf *newpacked = (PACKED_void_GLclampf*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampx: { + int sizeofpacked = sizeof(PACKED_void_GLclampx); + PACKED_void_GLclampx *newpacked = (PACKED_void_GLclampx*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLint: { + int sizeofpacked = sizeof(PACKED_void_GLint); + PACKED_void_GLint *newpacked = (PACKED_void_GLint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_const_GLfloat___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_const_GLfloat___GENPT__); + PACKED_void_GLenum_const_GLfloat___GENPT__ *newpacked = (PACKED_void_GLenum_const_GLfloat___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_const_GLfixed___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_const_GLfixed___GENPT__); + PACKED_void_GLenum_const_GLfixed___GENPT__ *newpacked = (PACKED_void_GLenum_const_GLfixed___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfloat_GLfloat_GLfloat_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat); + PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat *newpacked = (PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLubyte_GLubyte_GLubyte_GLubyte: { + int sizeofpacked = sizeof(PACKED_void_GLubyte_GLubyte_GLubyte_GLubyte); + PACKED_void_GLubyte_GLubyte_GLubyte_GLubyte *newpacked = (PACKED_void_GLubyte_GLubyte_GLubyte_GLubyte*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfixed_GLfixed_GLfixed_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed); + PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed *newpacked = (PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLboolean_GLboolean_GLboolean_GLboolean: { + int sizeofpacked = sizeof(PACKED_void_GLboolean_GLboolean_GLboolean_GLboolean); + PACKED_void_GLboolean_GLboolean_GLboolean_GLboolean *newpacked = (PACKED_void_GLboolean_GLboolean_GLboolean_GLboolean*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLint_GLenum_GLsizei_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLint_GLenum_GLsizei_const_GLvoid___GENPT__); + PACKED_void_GLint_GLenum_GLsizei_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLint_GLenum_GLsizei_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLenum_GLsizei_GLsizei_GLint_GLsizei_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLenum_GLsizei_GLsizei_GLint_GLsizei_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLint_GLenum_GLsizei_GLsizei_GLint_GLsizei_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLint_GLenum_GLsizei_GLsizei_GLint_GLsizei_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLsizei_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLsizei_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLsizei_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLsizei_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLenum_GLint_GLint_GLsizei_GLsizei_GLint: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLenum_GLint_GLint_GLsizei_GLsizei_GLint); + PACKED_void_GLenum_GLint_GLenum_GLint_GLint_GLsizei_GLsizei_GLint *newpacked = (PACKED_void_GLenum_GLint_GLenum_GLint_GLint_GLsizei_GLsizei_GLint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLint_GLint_GLint_GLint_GLsizei_GLsizei: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLint_GLint_GLint_GLint_GLsizei_GLsizei); + PACKED_void_GLenum_GLint_GLint_GLint_GLint_GLint_GLsizei_GLsizei *newpacked = (PACKED_void_GLenum_GLint_GLint_GLint_GLint_GLint_GLsizei_GLsizei*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLsizei_const_GLuint___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLsizei_const_GLuint___GENPT__); + PACKED_void_GLsizei_const_GLuint___GENPT__ *newpacked = (PACKED_void_GLsizei_const_GLuint___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLboolean: { + int sizeofpacked = sizeof(PACKED_void_GLboolean); + PACKED_void_GLboolean *newpacked = (PACKED_void_GLboolean*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampf_GLclampf: { + int sizeofpacked = sizeof(PACKED_void_GLclampf_GLclampf); + PACKED_void_GLclampf_GLclampf *newpacked = (PACKED_void_GLclampf_GLclampf*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampx_GLclampx: { + int sizeofpacked = sizeof(PACKED_void_GLclampx_GLclampx); + PACKED_void_GLclampx_GLclampx *newpacked = (PACKED_void_GLclampx_GLclampx*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLsizei: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLsizei); + PACKED_void_GLenum_GLint_GLsizei *newpacked = (PACKED_void_GLenum_GLint_GLsizei*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLsizei_GLenum_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLsizei_GLenum_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLsizei_GLenum_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLsizei_GLenum_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void: { + int sizeofpacked = sizeof(PACKED_void); + PACKED_void *newpacked = (PACKED_void*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfloat); + PACKED_void_GLenum_GLfloat *newpacked = (PACKED_void_GLenum_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfixed); + PACKED_void_GLenum_GLfixed *newpacked = (PACKED_void_GLenum_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat); + PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat *newpacked = (PACKED_void_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed); + PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed *newpacked = (PACKED_void_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLsizei_GLuint___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLsizei_GLuint___GENPT__); + PACKED_void_GLsizei_GLuint___GENPT__ *newpacked = (PACKED_void_GLsizei_GLuint___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLboolean___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLboolean___GENPT__); + PACKED_void_GLenum_GLboolean___GENPT__ *newpacked = (PACKED_void_GLenum_GLboolean___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLint___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLint___GENPT__); + PACKED_void_GLenum_GLenum_GLint___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_GLint___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfloat___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfloat___GENPT__); + PACKED_void_GLenum_GLfloat___GENPT__ *newpacked = (PACKED_void_GLenum_GLfloat___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfixed___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfixed___GENPT__); + PACKED_void_GLenum_GLfixed___GENPT__ *newpacked = (PACKED_void_GLenum_GLfixed___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_GLenum: { + int sizeofpacked = sizeof(PACKED_GLenum); + PACKED_GLenum *newpacked = (PACKED_GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint___GENPT__); + PACKED_void_GLenum_GLint___GENPT__ *newpacked = (PACKED_void_GLenum_GLint___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLfloat___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLfloat___GENPT__); + PACKED_void_GLenum_GLenum_GLfloat___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_GLfloat___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLfixed___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLfixed___GENPT__); + PACKED_void_GLenum_GLenum_GLfixed___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_GLfixed___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLvoid___GENPT____GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLvoid___GENPT____GENPT__); + PACKED_void_GLenum_GLvoid___GENPT____GENPT__ *newpacked = (PACKED_void_GLenum_GLvoid___GENPT____GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_const_GLubyte___GENPT___GLenum: { + int sizeofpacked = sizeof(PACKED_const_GLubyte___GENPT___GLenum); + PACKED_const_GLubyte___GENPT___GLenum *newpacked = (PACKED_const_GLubyte___GENPT___GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_GLboolean_GLuint: { + int sizeofpacked = sizeof(PACKED_GLboolean_GLuint); + PACKED_GLboolean_GLuint *newpacked = (PACKED_GLboolean_GLuint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_GLboolean_GLenum: { + int sizeofpacked = sizeof(PACKED_GLboolean_GLenum); + PACKED_GLboolean_GLenum *newpacked = (PACKED_GLboolean_GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLfloat); + PACKED_void_GLenum_GLenum_GLfloat *newpacked = (PACKED_void_GLenum_GLenum_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_const_GLfloat___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_const_GLfloat___GENPT__); + PACKED_void_GLenum_GLenum_const_GLfloat___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_const_GLfloat___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLfixed); + PACKED_void_GLenum_GLenum_GLfixed *newpacked = (PACKED_void_GLenum_GLenum_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_const_GLfixed___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_const_GLfixed___GENPT__); + PACKED_void_GLenum_GLenum_const_GLfixed___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_const_GLfixed___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLfloat); + PACKED_void_GLfloat *newpacked = (PACKED_void_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLfixed); + PACKED_void_GLfixed *newpacked = (PACKED_void_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_const_GLfloat___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_const_GLfloat___GENPT__); + PACKED_void_const_GLfloat___GENPT__ *newpacked = (PACKED_void_const_GLfloat___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_const_GLfixed___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_const_GLfixed___GENPT__); + PACKED_void_const_GLfixed___GENPT__ *newpacked = (PACKED_void_const_GLfixed___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfloat_GLfloat_GLfloat_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfloat_GLfloat_GLfloat_GLfloat); + PACKED_void_GLenum_GLfloat_GLfloat_GLfloat_GLfloat *newpacked = (PACKED_void_GLenum_GLfloat_GLfloat_GLfloat_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLfixed_GLfixed_GLfixed_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLfixed_GLfixed_GLfixed_GLfixed); + PACKED_void_GLenum_GLfixed_GLfixed_GLfixed_GLfixed *newpacked = (PACKED_void_GLenum_GLfixed_GLfixed_GLfixed_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfloat_GLfloat_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLfloat_GLfloat_GLfloat); + PACKED_void_GLfloat_GLfloat_GLfloat *newpacked = (PACKED_void_GLfloat_GLfloat_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfixed_GLfixed_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLfixed_GLfixed_GLfixed); + PACKED_void_GLfixed_GLfixed_GLfixed *newpacked = (PACKED_void_GLfixed_GLfixed_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLsizei_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLsizei_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLsizei_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLsizei_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint); + PACKED_void_GLenum_GLint *newpacked = (PACKED_void_GLenum_GLint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfloat_GLfloat: { + int sizeofpacked = sizeof(PACKED_void_GLfloat_GLfloat); + PACKED_void_GLfloat_GLfloat *newpacked = (PACKED_void_GLfloat_GLfloat*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLfixed_GLfixed: { + int sizeofpacked = sizeof(PACKED_void_GLfixed_GLfixed); + PACKED_void_GLfixed_GLfixed *newpacked = (PACKED_void_GLfixed_GLfixed*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_GLvoid___GENPT__); + PACKED_void_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_GLvoid___GENPT__ *newpacked = (PACKED_void_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampf_GLboolean: { + int sizeofpacked = sizeof(PACKED_void_GLclampf_GLboolean); + PACKED_void_GLclampf_GLboolean *newpacked = (PACKED_void_GLclampf_GLboolean*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLclampx_GLboolean: { + int sizeofpacked = sizeof(PACKED_void_GLclampx_GLboolean); + PACKED_void_GLclampx_GLboolean *newpacked = (PACKED_void_GLclampx_GLboolean*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLint_GLint_GLsizei_GLsizei: { + int sizeofpacked = sizeof(PACKED_void_GLint_GLint_GLsizei_GLsizei); + PACKED_void_GLint_GLint_GLsizei_GLsizei *newpacked = (PACKED_void_GLint_GLint_GLsizei_GLsizei*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLuint: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLuint); + PACKED_void_GLenum_GLint_GLuint *newpacked = (PACKED_void_GLenum_GLint_GLuint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLuint: { + int sizeofpacked = sizeof(PACKED_void_GLuint); + PACKED_void_GLuint *newpacked = (PACKED_void_GLuint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLenum: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLenum); + PACKED_void_GLenum_GLenum_GLenum *newpacked = (PACKED_void_GLenum_GLenum_GLenum*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_GLint: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_GLint); + PACKED_void_GLenum_GLenum_GLint *newpacked = (PACKED_void_GLenum_GLenum_GLint*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLenum_const_GLint___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLenum_const_GLint___GENPT__); + PACKED_void_GLenum_GLenum_const_GLint___GENPT__ *newpacked = (PACKED_void_GLenum_GLenum_const_GLint___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLint_GLint_GLsizei_GLsizei_GLint_GLenum_GLenum_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + case FORMAT_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__: { + int sizeofpacked = sizeof(PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__); + PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__ *newpacked = (PACKED_void_GLenum_GLint_GLint_GLint_GLsizei_GLsizei_GLenum_GLenum_const_GLvoid___GENPT__*)malloc(sizeofpacked); + memcpy(newpacked, packed, sizeofpacked); + return (packed_call_t*)newpacked; + break; + } + } +} +*/ #endif diff --git a/project/jni/glshim/src/gl/wrap/gles.h b/project/jni/glshim/src/gl/wrap/gles.h index be5d51190..7fc315f94 100755 --- a/project/jni/glshim/src/gl/wrap/gles.h +++ b/project/jni/glshim/src/gl/wrap/gles.h @@ -1387,6 +1387,7 @@ typedef struct { extern void glPushCall(void *data); void glPackedCall(const packed_call_t *packed); void glIndexedCall(const indexed_call_t *packed, void *ret_v); +/*packed_call_t* glCopyPackedCall(const packed_call_t *packed);*/ #define glActiveTexture_INDEX 1 #define glActiveTexture_RETURN void diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index ce32430f2..522f8b859 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -23,6 +23,7 @@ //#include #include "../gl/gl.h" #include "../glx/streaming.h" +#include "khash.h" #define EXPORT __attribute__((visibility("default"))) @@ -43,8 +44,44 @@ static struct sockaddr_un sun; static int sock = -2; #endif -extern void* egl; +typedef struct {int Width; int Height; EGLContext Context;} glx_buffSize; +#ifndef ANDROID +//PBuffer should work under ANDROID +static GLXPbuffer *pbufferlist = NULL; +static glx_buffSize *pbuffersize = NULL; +static int pbufferlist_cap = 0; +static int pbufferlist_size = 0; +static int isPBuffer(GLXDrawable drawable) { + for (int i=0; ivisualid; + //*value = 1; break; case GLX_FBCONFIG_ID: *value = 1; @@ -143,22 +181,21 @@ static int get_config_default(int attribute, int *value) { *value = 0; break; default: - printf("libGL: unknown attrib %i\n", attribute); + printf("LIBGL: unknown attrib %i\n", attribute); *value = 0; return 1; } return 0; } -// hmm... -static EGLContext eglContext; - -#ifndef ANDROID static Display *g_display = NULL; static GLXContext glxContext = NULL; static GLXContext fbContext = NULL; #endif //ANDROID +// hmm... +static EGLContext eglContext; + static int fbcontext_count = 0; #ifdef USE_FBIO @@ -189,7 +226,10 @@ extern int blendhack; extern int export_blendcolor; extern int glshim_noerror; extern char glshim_version[50]; +extern int glshim_nobanner; +extern int glshim_npot; int export_silentstub = 0; +int glshim_queries = 0; bool g_recyclefbo = false; static int g_width=0, g_height=0; @@ -199,6 +239,8 @@ static bool g_bcm_active = false; void (*bcm_host_init)(); void (*bcm_host_deinit)(); +#define SHUT(a) if(!glshim_nobanner) a + static int swap_interval = 1; #ifndef ANDROID static void init_display(Display *display) { @@ -218,7 +260,7 @@ static void init_vsync() { #ifdef USE_FBIO fbdev = open("/dev/fb0", O_RDONLY); if (fbdev < 0) { - fprintf(stderr, "Could not open /dev/fb0 for vsync.\n"); + fprintf(stderr, "LIBGL: Could not open /dev/fb0 for vsync.\n"); } #endif } @@ -254,7 +296,7 @@ static void signal_handler(int sig) { bcm_host_deinit(); } #endif - +#ifndef ANDROID if (g_stacktrace) { switch (sig) { case SIGBUS: @@ -264,15 +306,16 @@ static void signal_handler(int sig) { void *array[10]; size_t size = backtrace(array, 10); if (! size) { - printf("No stacktrace. Compile with -funwind-tables.\n"); + printf("LIBGL: No stacktrace. Compile with -funwind-tables.\n"); } else { - printf("Stacktrace: %zd\n", size); + printf("LIBGL: Stacktrace: %zd\n", size); backtrace_symbols_fd(array, size, 2); } break; } } } +#endif signal(sig, SIG_DFL); raise(sig); } @@ -320,17 +363,26 @@ static void scan_env() { initialize_glshim(); } /* Check for some corruption inside state.... */ - if ((glstate.texture.active < 0) || (glstate.texture.active > MAX_TEX) || - (glstate.vao->pointers.vertex.buffer!= 0) || (glstate.vao->vertex != 0) || (glstate.list.active!=0)) { - printf("LIBGL: Warning, memory corruption detected at init, trying to compensate\n"); + /* + if ((glstate->texture.active < 0) || (glstate->texture.active > MAX_TEX) || + (glstate->vao->pointers.vertex.buffer!= 0) || (glstate->vao->vertex != 0) || (glstate->list.active!=0)) { + SHUT(printf("LIBGL: Warning, memory corruption detected at init, trying to compensate\n")); initialize_glshim(); } + */ + // initialise MapDrawable too + { + int ret; + MapDrawable = kh_init(mapdrawable); + kh_put(mapdrawable, MapDrawable, 1, &ret); + kh_del(mapdrawable, MapDrawable, 1); + } first = false; - printf("libGL: built on %s %s\n", __DATE__, __TIME__); + SHUT(printf("LIBGL: built on %s %s\n", __DATE__, __TIME__)); #define env(name, global, message) \ char *env_##name = getenv(#name); \ if (env_##name && strcmp(env_##name, "1") == 0) { \ - printf("libGL: " message "\n"); \ + SHUT(printf("LIBGL: " message "\n")); \ global = true; \ } @@ -364,7 +416,7 @@ static void scan_env() { } env(LIBGL_FB, g_usefb, "framebuffer output enabled"); if (env_LIBGL_FB && strcmp(env_LIBGL_FB, "2") == 0) { - printf("libGL: using framebuffer + fbo\n"); + SHUT(printf("LIBGL: using framebuffer + fbo\n")); g_usefb = true; g_usefbo = true; } @@ -378,7 +430,7 @@ static void scan_env() { #ifdef PANDORA init_liveinfo(); if (sock>-1) { - printf("LIBGL: LiveInfo detected, fps will be shown\n"); + SHUT(printf("LIBGL: LiveInfo detected, fps will be shown\n")); } #endif env(LIBGL_RECYCLEFBO, g_recyclefbo, "Recycling of FBO enabled"); @@ -386,137 +438,152 @@ static void scan_env() { char *env_mipmap = getenv("LIBGL_MIPMAP"); if (env_mipmap && strcmp(env_mipmap, "1") == 0) { automipmap = 1; - printf("LIBGL: AutoMipMap forced\n"); + SHUT(printf("LIBGL: AutoMipMap forced\n")); } if (env_mipmap && strcmp(env_mipmap, "2") == 0) { automipmap = 2; - printf("LIBGL: guess AutoMipMap\n"); + SHUT(printf("LIBGL: guess AutoMipMap\n")); } if (env_mipmap && strcmp(env_mipmap, "3") == 0) { automipmap = 3; - printf("LIBGL: ignore MipMap\n"); + SHUT(printf("LIBGL: ignore MipMap\n")); } if (env_mipmap && strcmp(env_mipmap, "4") == 0) { automipmap = 4; - printf("LIBGL: ignore AutoMipMap on non-squared textures\n"); + SHUT(printf("LIBGL: ignore AutoMipMap on non-squared textures\n")); } char *env_texcopy = getenv("LIBGL_TEXCOPY"); if (env_texcopy && strcmp(env_texcopy, "1") == 0) { texcopydata = 1; - printf("LIBGL: Texture copy enabled\n"); + SHUT(printf("LIBGL: Texture copy enabled\n")); } char *env_shrink = getenv("LIBGL_SHRINK"); if (env_shrink && strcmp(env_shrink, "1") == 0) { texshrink = 1; - printf("LIBGL: Texture shink, mode 1 selected (everything / 2)\n"); + SHUT(printf("LIBGL: Texture shink, mode 1 selected (everything / 2)\n")); } if (env_shrink && strcmp(env_shrink, "2") == 0) { texshrink = 2; - printf("LIBGL: Texture shink, mode 2 selected (only > 512 /2 )\n"); + SHUT(printf("LIBGL: Texture shink, mode 2 selected (only > 512 /2 )\n")); } if (env_shrink && strcmp(env_shrink, "3") == 0) { texshrink = 3; - printf("LIBGL: Texture shink, mode 3 selected (only > 256 /2 )\n"); + SHUT(printf("LIBGL: Texture shink, mode 3 selected (only > 256 /2 )\n")); } if (env_shrink && strcmp(env_shrink, "4") == 0) { texshrink = 4; - printf("LIBGL: Texture shink, mode 4 selected (only > 256 /2, >=1024 /4 )\n"); + SHUT(printf("LIBGL: Texture shink, mode 4 selected (only > 256 /2, >=1024 /4 )\n")); } if (env_shrink && strcmp(env_shrink, "5") == 0) { texshrink = 5; - printf("LIBGL: Texture shink, mode 5 selected (every > 256 is downscaled to 256 ), but not for empty texture\n"); + SHUT(printf("LIBGL: Texture shink, mode 5 selected (every > 256 is downscaled to 256 ), but not for empty texture\n")); } if (env_shrink && strcmp(env_shrink, "6") == 0) { texshrink = 6; - printf("LIBGL: Texture shink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture\n"); + SHUT(printf("LIBGL: Texture shink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture\n")); } if (env_shrink && strcmp(env_shrink, "7") == 0) { texshrink = 7; - printf("LIBGL: Texture shink, mode 7 selected (only > 512 /2 ), but not for empty texture\n"); + SHUT(printf("LIBGL: Texture shink, mode 7 selected (only > 512 /2 ), but not for empty texture\n")); } if (env_shrink && strcmp(env_shrink, "8") == 0) { texshrink = 8; - printf("LIBGL: Texture shink, mode 8 selected (advertise 8192 max texture size, but >2048 are shrinked to 2048)\n"); + SHUT(printf("LIBGL: Texture shink, mode 8 selected (advertise 8192 max texture size, but >2048 are shrinked to 2048)\n")); } if (env_shrink && strcmp(env_shrink, "9") == 0) { texshrink = 9; - printf("LIBGL: Texture shink, mode 9 selected (advertise 8192 max texture size, but >4096 are quadshrinked and > 512 are shrinked), but not for empty texture\n"); + SHUT(printf("LIBGL: Texture shink, mode 9 selected (advertise 8192 max texture size, but >4096 are quadshrinked and > 512 are shrinked), but not for empty texture\n")); } if (env_shrink && strcmp(env_shrink, "10") == 0) { texshrink = 10; - printf("LIBGL: Texture shink, mode 10 selected (advertise 8192 max texture size, but >2048 are quadshrinked and > 512 are shrinked), but not for empty texture\n"); + SHUT(printf("LIBGL: Texture shink, mode 10 selected (advertise 8192 max texture size, but >2048 are quadshrinked and > 512 are shrinked), but not for empty texture\n")); } char *env_dump = getenv("LIBGL_TEXDUMP"); if (env_dump && strcmp(env_dump, "1") == 0) { texdump = 1; - printf("LIBGL: Texture dump enabled\n"); + SHUT(printf("LIBGL: Texture dump enabled\n")); } char *env_alpha = getenv("LIBGL_ALPHAHACK"); if (env_alpha && strcmp(env_alpha, "1") == 0) { alphahack = 1; - printf("LIBGL: Alpha Hack enabled\n"); + SHUT(printf("LIBGL: Alpha Hack enabled\n")); } #ifdef TEXSTREAM char *env_stream = getenv("LIBGL_STREAM"); if (env_stream && strcmp(env_stream, "1") == 0) { texstream = InitStreamingCache(); - printf("LIBGL: Streaming texture %s\n",(texstream)?"enabled":"not available"); + SHUT(printf("LIBGL: Streaming texture %s\n",(texstream)?"enabled":"not available")); //FreeStreamed(AddStreamed(1024, 512, 0)); } if (env_stream && strcmp(env_stream, "2") == 0) { texstream = InitStreamingCache()?2:0; - printf("LIBGL: Streaming texture %s\n",(texstream)?"forced":"not available"); + SHUT(printf("LIBGL: Streaming texture %s\n",(texstream)?"forced":"not available")); //FreeStreamed(AddStreamed(1024, 512, 0)); } #endif char *env_copy = getenv("LIBGL_COPY"); if (env_copy && strcmp(env_copy, "1") == 0) { - printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n"); + SHUT(printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n")); copytex = 1; } char *env_lumalpha = getenv("LIBGL_NOLUMALPHA"); if (env_lumalpha && strcmp(env_lumalpha, "1") == 0) { nolumalpha = 1; - printf("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n"); + SHUT(printf("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n")); } env(LIBGL_BLENDHACK, blendhack, "Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE"); env(LIBGL_BLENDCOLOR, export_blendcolor, "Export a (faked) glBlendColor"); env(LIBGL_NOERROR, glshim_noerror, "glGetError() always return GL_NOERROR"); env(LIBGL_SILENTSTUB, export_silentstub, "Stub/non present functions are not printed"); - + char *env_version = getenv("LIBGL_VERSION"); if (env_version) { - printf("LIBGL: Overide version string with \"%s\" (should be in the form of \"1.x\")\n", env_version); + SHUT(printf("LIBGL: Overide version string with \"%s\" (should be in the form of \"1.x\")\n", env_version)); } snprintf(glshim_version, 49, "%s glshim wrapper", (env_version)?env_version:"1.5"); #ifdef PANDORA char *env_gamma = getenv("LIBGL_GAMMA"); if (env_gamma) { pandora_gamma=atof(env_gamma); - printf("LIBGL: Set gamma to %.2f\n", pandora_gamma); + SHUT(printf("LIBGL: Set gamma to %.2f\n", pandora_gamma)); atexit(pandora_reset_gamma); } #endif char *env_srgb = getenv("LIBGL_SRGB"); if (env_srgb && strcmp(env_srgb, "1") == 0) { glx_surface_srgb = 1; - printf("LIBGL: enabling sRGB support\n"); + SHUT(printf("LIBGL: enabling sRGB support\n")); } char *env_fastmath = getenv("LIBGL_FASTMATH"); if (env_fastmath && strcmp(env_fastmath, "1") == 0) { #ifdef PANDORA - printf("LIBGL: Enable FastMath for cortex-a8\n"); + SHUT(printf("LIBGL: Enable FastMath for cortex-a8\n")); fast_math(); #else - printf("LIBGL: No FastMath on this platform\n"); + SHUT(printf("LIBGL: No FastMath on this platform\n")); #endif } - + char *env_npot = getenv("LIBGL_NPOT"); + if (env_npot && strcmp(env_npot, "1") == 0) { + glshim_npot = 1; + SHUT(printf("LIBGL: Expose limited NPOT extension\n")); + } + if (env_npot && strcmp(env_npot, "2") == 0) { + glshim_npot = 2; + SHUT(printf("LIBGL: Expose GL_ARB_texture_non_power_of_two extension\n")); + } + char *env_queries = getenv("LIBGL_GLQUERIES"); + if (env_queries && strcmp(env_queries, "1") == 0) { + glshim_queries = 1; + SHUT(printf("LIBGL: Expose fake glQueries functions\n")); + } + char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) - printf("LIBGL: Current folder is:%s\n", cwd); + SHUT(printf("LIBGL: Current folder is:%s\n", cwd)); } + #ifndef ANDROID EXPORT GLXContext glXCreateContext(Display *display, XVisualInfo *visual, @@ -540,13 +607,6 @@ EXPORT GLXContext glXCreateContext(Display *display, EGL_NONE }; - EGLint attrib_list[] = { -#ifdef USE_ES2 - EGL_CONTEXT_CLIENT_VERSION, 2, -#endif - EGL_NONE - }; - scan_env(); if (g_usefb && fbcontext_count>0) { @@ -573,6 +633,12 @@ EXPORT GLXContext glXCreateContext(Display *display, GLXContext fake = malloc(sizeof(struct __GLXContextRec)); memset(fake, 0, sizeof(struct __GLXContextRec)); + + fake->glstate = NewGLState((shareList)?shareList->glstate:NULL); +#if 1 + if(g_usefb) + fbContext = fake; +#else if (!g_usefb) { if (eglDisplay != NULL) egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); // just in case some context is already attached. *TODO: track that? @@ -597,12 +663,13 @@ EXPORT GLXContext glXCreateContext(Display *display, } fbContext = fake; } +#endif // make an egl context here... EGLBoolean result; if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { init_display(display); if (eglDisplay == EGL_NO_DISPLAY) { - printf("Unable to create EGL display.\n"); + printf("LIBGL: Unable to create EGL display.\n"); return fake; } } @@ -612,7 +679,7 @@ EXPORT GLXContext glXCreateContext(Display *display, egl_eglBindAPI(EGL_OPENGL_ES_API); result = egl_eglInitialize(eglDisplay, NULL, NULL); if (result != EGL_TRUE) { - printf("Unable to initialize EGL display.\n"); + printf("LIBGL: Unable to initialize EGL display.\n"); return fake; } eglInitialized = true; @@ -628,23 +695,19 @@ EXPORT GLXContext glXCreateContext(Display *display, } int configsFound; - if (!g_usefb) - result = egl_eglChooseConfig(eglDisplay, configAttribs, fake->eglConfigs, 1, &configsFound); - else - result = egl_eglChooseConfig(eglDisplay, configAttribs, eglConfigs, 1, &configsFound); + result = egl_eglChooseConfig(eglDisplay, configAttribs, fake->eglConfigs, 1, &configsFound); + if(g_usefb) + eglConfigs[0] = fake->eglConfigs[0]; CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { - printf("No EGL configs found.\n"); + printf("LIBGL: No EGL configs found.\n"); return fake; } EGLContext shared = (shareList)?shareList->eglContext:EGL_NO_CONTEXT; - if (!g_usefb) - fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, attrib_list); - else { - eglContext = egl_eglCreateContext(eglDisplay, eglConfigs[0], shared, attrib_list); - fake->eglContext = eglContext; - } + fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, egl_context_attrib); + if(g_usefb) + eglContext = fake->eglContext; CheckEGLErrors(); @@ -652,50 +715,131 @@ EXPORT GLXContext glXCreateContext(Display *display, fake->display = (g_usefb)?g_display:display; fake->direct = true; fake->xid = 1; //TODO: Proper handling of that id... + fake->contextType = 0; //Window + /* + // why unassign the context, it's not assigned yet if (!g_usefb) { // unassign the context, it's not supposed to be active at the creation egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); } + */ - // *TODO* put eglContext inside GLXcontext, to handle multiple Glxcontext + return fake; +} + +GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBConfig config) { + + EGLint configAttribs[] = { + EGL_RED_SIZE, (config)?config->redBits:0, + EGL_GREEN_SIZE, (config)?config->greenBits:0, + EGL_BLUE_SIZE, (config)?config->blueBits:0, + EGL_ALPHA_SIZE, (config)?config->alphaBits:0, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + LOAD_EGL(eglBindAPI); + LOAD_EGL(eglInitialize); + LOAD_EGL(eglChooseConfig); + LOAD_EGL(eglCreateContext); + + // Check that the config is for PBuffer + if(config->drawableType&GLX_PBUFFER_BIT!=GLX_PBUFFER_BIT) + return 0; + + // Init what need to be done + EGLBoolean result; + if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { + init_display(display); + if (eglDisplay == EGL_NO_DISPLAY) { + printf("LIBGL: Unable to create EGL display.\n"); + return 0; + } + } + + // first time? + if (eglInitialized == false) { + egl_eglBindAPI(EGL_OPENGL_ES_API); + result = egl_eglInitialize(eglDisplay, NULL, NULL); + if (result != EGL_TRUE) { + printf("LIBGL: Unable to initialize EGL display.\n"); + return 0; + } + eglInitialized = true; + } + + // select a configuration + int configsFound; + static EGLConfig pbufConfigs[1]; + result = egl_eglChooseConfig(eglDisplay, configAttribs, pbufConfigs, 1, &configsFound); + + CheckEGLErrors(); + if (result != EGL_TRUE || configsFound == 0) { + printf("LIBGL: No EGL configs found.\n"); + return 0; + } + + EGLContext shared = (shareList)?shareList->eglContext:EGL_NO_CONTEXT; + + GLXContext fake = malloc(sizeof(struct __GLXContextRec)); + memset(fake, 0, sizeof(struct __GLXContextRec)); + fake->glstate = NewGLState((shareList)?shareList->glstate:NULL); + + fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, egl_context_attrib); + + CheckEGLErrors(); + + // need to return a glx context pointing at it + fake->display = (g_usefb)?g_display:display; + fake->direct = true; + fake->xid = 1; //TODO: Proper handling of that id... + fake->contextType = 1; //PBuffer return fake; } -EXPORT GLXContext glXCreateContextAttribsARB(Display *display, void *config, +EXPORT GLXContext glXCreateContextAttribsARB(Display *display, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list) { - return glXCreateContext(display, NULL, NULL, direct); + if(config && config->drawableType==GLX_PBUFFER_BIT) { + return createPBufferContext(display, share_context, config); + } else + return glXCreateContext(display, NULL, share_context, direct); } EXPORT void glXDestroyContext(Display *display, GLXContext ctx) { //printf("glXDestroyContext(%p, %p)\n", display, ctx); - if (g_usefb) { + if (g_usefb && ctx->contextType==0) { if (fbcontext_count==0) return; // Should not happens! if (--fbcontext_count > 0) return; // Nothing to do... } if ((!g_usefb && ctx->eglContext) || (g_usefb && eglContext)) { - if (g_usefbo) { + if (g_usefbo && ctx->contextType==0) { deleteMainFBO(); } + + DeleteGLState(ctx->glstate); LOAD_EGL(eglDestroyContext); LOAD_EGL(eglDestroySurface); - EGLBoolean result = egl_eglDestroyContext(eglDisplay, (g_usefb)?eglContext:ctx->eglContext); - eglContext = NULL; - if (!g_usefb && ctx->eglSurface != NULL) { + EGLBoolean result = egl_eglDestroyContext(eglDisplay, ctx->eglContext); + ctx->eglContext = 0; + if (ctx->eglSurface != 0) { egl_eglDestroySurface(eglDisplay, ctx->eglSurface); - eglSurface = ctx->eglSurface = NULL; + ctx->eglSurface = 0; } - if (g_usefb && eglSurface != NULL) { - egl_eglDestroySurface(eglDisplay, eglSurface); - eglSurface = NULL; + if(g_usefb && ctx->contextType==0) { + // clean global eglFB too + eglSurface = 0; + eglContext = 0; } + if (result != EGL_TRUE) { - printf("Failed to destroy EGL context.\n"); + printf("LIBGL: Failed to destroy EGL context.\n"); } /*if (fbdev >= 0) { close(fbdev); @@ -730,11 +874,11 @@ EXPORT XVisualInfo *glXChooseVisual(Display *display, */ glx_default_depth = XDefaultDepth(display, screen); if (glx_default_depth != 16 && glx_default_depth != 24 && glx_default_depth != 32) - printf("libGL: unusual desktop color depth %d\n", glx_default_depth); + printf("LIBGL: unusual desktop color depth %d\n", glx_default_depth); XVisualInfo *visual = (XVisualInfo *)malloc(sizeof(XVisualInfo)); if (!XMatchVisualInfo(display, screen, glx_default_depth, TrueColor, visual)) { - printf("libGL: XMatchVisualInfo failed in glXChooseVisual\n"); + printf("LIBGL: XMatchVisualInfo failed in glXChooseVisual\n"); return NULL; } @@ -756,7 +900,40 @@ EXPORT Bool glXMakeCurrent(Display *display, LOAD_EGL(eglDestroySurface); LOAD_EGL(eglCreateWindowSurface); LOAD_EGL(eglQuerySurface); - + int created = (context)?isPBuffer(drawable):0; + EGLint const sRGB[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE}; +#if 1 + EGLContext eglContext = EGL_NO_CONTEXT; + EGLSurface eglSurf = 0; + EGLConfig eglConfig = 0; + if(context) { + eglContext = context->eglContext; + if(context->drawable==drawable && context->eglSurface) + // same-same, recycling... + eglSurf = context->eglSurface; + else { + // new one + if(created) { + eglSurf = context->eglSurface = (EGLSurface)drawable; + context->eglContext = eglContext = pbuffersize[created-1].Context; // this context is ok for the PBuffer + } else { + if(g_usefb) { + if(eglSurface) + eglSurf = context->eglSurface = eglSurface; + else + eglSurface = eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], 0, (glx_surface_srgb)?sRGB:NULL); + } else { + if(context->eglSurface) + egl_eglDestroySurface(eglDisplay, context->eglSurface); + eglSurf = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], drawable, (glx_surface_srgb)?sRGB:NULL); + } + } + } + eglConfig = context->eglConfigs[0]; + } + glxContext = context; + EGLBoolean result = egl_eglMakeCurrent(eglDisplay, eglSurf, eglSurf, eglContext); +#else if (eglDisplay != NULL) { if (!g_usefb) egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); @@ -778,11 +955,10 @@ EXPORT Bool glXMakeCurrent(Display *display, if (eglDisplay == NULL) { init_display(display); } - if (g_usefb) drawable = 0; EGLBoolean result; - EGLint const sRGB[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE}; + created = 1; if (!g_usefb) { // need current surface for eglSwapBuffer eglContext = context->eglContext; @@ -805,27 +981,46 @@ EXPORT Bool glXMakeCurrent(Display *display, } else result = EGL_TRUE; } - CheckEGLErrors(); - - context->drawable = drawable; - -#ifdef PANDORA - pandora_set_gamma(); #endif CheckEGLErrors(); - if (result) { - if (g_usefbo) { - // get size of the surface... - egl_eglQuerySurface(eglDisplay,eglSurface,EGL_WIDTH,&g_width); - egl_eglQuerySurface(eglDisplay,eglSurface,EGL_HEIGHT,&g_height); - // create the main_fbo... - printf("LIBGL: Create FBO of %ix%i 32bits\n", g_width, g_height); - createMainFBO(g_width, g_height); + { + // update MapDrawable + int ret; + khint_t k = kh_get(mapdrawable, MapDrawable, drawable); + map_drawable_t* map = NULL; + if (k == kh_end(MapDrawable)){ + k = kh_put(mapdrawable, MapDrawable, drawable, &ret); + map = kh_value(MapDrawable, k) = (map_drawable_t*)malloc(sizeof(map_drawable_t)); + map->drawable = drawable; + } else { + map = kh_value(MapDrawable, k); } - // finished - return true; + map->surface = eglSurf; + map->PBuffer = created; } - return false; + if (context) { + context->drawable = drawable; + + ActivateGLState(context->glstate); +#ifdef PANDORA + if(created) pandora_set_gamma(); +#endif + CheckEGLErrors(); + if (result) { + if (g_usefbo && created) { + // get size of the surface... + egl_eglQuerySurface(eglDisplay,eglSurf,EGL_WIDTH,&g_width); + egl_eglQuerySurface(eglDisplay,eglSurf,EGL_HEIGHT,&g_height); + // create the main_fbo... + printf("LIBGL: Create FBO of %ix%i 32bits\n", g_width, g_height); + createMainFBO(g_width, g_height); + } + // finished + return true; + } + return false; + } + return true; } EXPORT Bool glXMakeContextCurrent(Display *display, int drawable, @@ -838,12 +1033,25 @@ EXPORT void glXSwapBuffers(Display *display, static int frames = 0; LOAD_EGL(eglSwapBuffers); - int old_batch = glstate.gl_batch; - if (glstate.gl_batch || glstate.list.active){ + // TODO: what if active context is not on the drawable? + int old_batch = glstate->gl_batch; + if (glstate->gl_batch || glstate->list.active){ flush(); } + EGLSurface surface = eglSurface; + int PBuffer = 0; + { + // get MapDrawable surface + khint_t k = kh_get(mapdrawable, MapDrawable, drawable); + map_drawable_t* map = NULL; + if (k != kh_end(MapDrawable)){ + map = kh_value(MapDrawable, k); + surface = map->surface; + PBuffer = map->PBuffer; + } + } #ifdef USE_FBIO - if (g_vsync && fbdev >= 0) { + if (g_vsync && fbdev >= 0 && PBuffer==0) { // TODO: can I just return if I don't meet vsync over multiple frames? // this will just block otherwise. int arg = 0; @@ -852,14 +1060,14 @@ EXPORT void glXSwapBuffers(Display *display, } } #endif - if (g_usefbo) { - glstate.gl_batch = 0; + if (g_usefbo && PBuffer==0) { + glstate->gl_batch = 0; unbindMainFBO(); blitMainFBO(); // blit the main_fbo before swap } - egl_eglSwapBuffers(eglDisplay, eglSurface); + egl_eglSwapBuffers(eglDisplay, surface); CheckEGLErrors(); #ifdef PANDORA if (g_showfps || (sock>-1)) { @@ -886,7 +1094,7 @@ EXPORT void glXSwapBuffers(Display *display, current_frames = 0; avg = frame / (float)(now - frame1); - if (g_showfps) printf("libGL fps: %.2f, avg: %.2f\n", fps, avg); + if (g_showfps) printf("LIBGL: fps: %.2f, avg: %.2f\n", fps, avg); if (sock>-1) { char tmp[60]; snprintf(tmp, 60, "gl: %2.2f", fps); @@ -897,8 +1105,8 @@ EXPORT void glXSwapBuffers(Display *display, last_frame = now; } #endif - if (g_usefbo) { - glstate.gl_batch = old_batch; + if (g_usefbo && PBuffer==0) { + glstate->gl_batch = old_batch; bindMainFBO(); } } @@ -907,7 +1115,7 @@ EXPORT int glXGetConfig(Display *display, XVisualInfo *visual, int attribute, int *value) { - return get_config_default(attribute, value); + return get_config_default(display, attribute, value); } EXPORT const char *glXQueryExtensionsString(Display *display, int screen) { @@ -978,8 +1186,44 @@ EXPORT GLXContext glXGetCurrentContext() { EXPORT GLXFBConfig *glXChooseFBConfig(Display *display, int screen, const int *attrib_list, int *count) { +//printf("glXChooseFBConfig(%p, %d, %p, %p)\n", display, screen, attrib_list, count); *count = 1; - GLXFBConfig *configs = malloc(sizeof(GLXFBConfig) * *count); + GLXFBConfig *configs = (GLXFBConfig *)malloc(sizeof(GLXFBConfig) + sizeof(struct __GLXFBConfigRec)); + configs[0] = (GLXFBConfig)((char*)(&configs[0])+sizeof(GLXFBConfig)); + memset(configs[0], 0, sizeof(struct __GLXFBConfigRec)); + // fill that config with some of the attrib_list info... + configs[0]->drawableType = GLX_WINDOW_BIT | GLX_PBUFFER_BIT; + configs[0]->screen = 0; + configs[0]->maxPbufferWidth = configs[0]->maxPbufferHeight = 2048; + configs[0]->redBits = configs[0]->greenBits = configs[0]->blueBits = configs[0]->alphaBits = 0; + if(attrib_list) { + int i = 0; + while(attrib_list[i]!=0) { + switch(attrib_list[i++]) { + case GLX_RED_SIZE: + configs[0]->redBits = attrib_list[i++]; + if(configs[0]->redBits==GLX_DONT_CARE) configs[0]->redBits = 0; + break; + case GLX_GREEN_SIZE: + configs[0]->greenBits = attrib_list[i++]; + if(configs[0]->greenBits==GLX_DONT_CARE) configs[0]->greenBits = 0; + break; + case GLX_BLUE_SIZE: + configs[0]->blueBits = attrib_list[i++]; + if(configs[0]->blueBits==GLX_DONT_CARE) configs[0]->blueBits = 0; + break; + case GLX_ALPHA_SIZE: + configs[0]->alphaBits = attrib_list[i++]; + if(configs[0]->alphaBits==GLX_DONT_CARE) configs[0]->alphaBits = 0; + break; + case GLX_DRAWABLE_TYPE: + configs[0]->drawableType = attrib_list[i++]; + break; + // discard other stuffs + } + } + } + return configs; } EXPORT GLXFBConfig *glXChooseFBConfigSGIX(Display *display, int screen, @@ -988,16 +1232,24 @@ EXPORT GLXFBConfig *glXChooseFBConfigSGIX(Display *display, int screen, } EXPORT GLXFBConfig *glXGetFBConfigs(Display *display, int screen, int *count) { +//printf("glXGetFBConfigs(%p, %d, %p)\n", display, screen, count); *count = 1; - GLXFBConfig *configs = malloc(sizeof(GLXFBConfig) * *count); + // this is to only do 1 malloc instead of 1 for the array and one for the element... + GLXFBConfig *configs = (GLXFBConfig *)malloc(sizeof(GLXFBConfig) + sizeof(struct __GLXFBConfigRec)); + configs[0] = (GLXFBConfig)((char*)(&configs[0])+sizeof(GLXFBConfig)); + memset(configs[0], 0, sizeof(struct __GLXFBConfigRec)); + configs[0]->drawableType = GLX_WINDOW_BIT | GLX_PBUFFER_BIT; + configs[0]->redBits = configs[0]->greenBits = configs[0]->blueBits = configs[0]->alphaBits = 8; return configs; } EXPORT int glXGetFBConfigAttrib(Display *display, GLXFBConfig config, int attribute, int *value) { - return get_config_default(attribute, value); +//printf("glXGetFBConfigAttrib(%p, %p, 0x%04X, %p)\n", display, config, attribute, value); + return get_config_default(display, attribute, value); } EXPORT XVisualInfo *glXGetVisualFromFBConfig(Display *display, GLXFBConfig config) { +//printf("glXGetVisualFromFBConfig(%p, %p)\n", display, config); /*if (g_display == NULL) { g_display = XOpenDisplay(NULL); }*/ @@ -1011,15 +1263,18 @@ EXPORT XVisualInfo *glXGetVisualFromFBConfig(Display *display, GLXFBConfig confi EXPORT GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, int render_type, GLXContext share_list, Bool is_direct) { -printf("glXCreateNewContext(%p, %p, %d, %p, %i)\n", display, config, render_type, share_list, is_direct); - return glXCreateContext(display, 0, share_list, is_direct); +//printf("glXCreateNewContext(%p, %p, %d, %p, %i), drawableType=0x%02X\n", display, config, render_type, share_list, is_direct, (config)?config->drawableType:0); + if(config && config->drawableType==GLX_PBUFFER_BIT) { + return createPBufferContext(display, share_list, config); + } else + return glXCreateContext(display, 0, share_list, is_direct); } #endif //ANDROID EXPORT void glXSwapIntervalMESA(int interval) { - printf("glXSwapInterval(%i)\n", interval); +//printf("glXSwapInterval(%i)\n", interval); #ifdef USE_FBIO if (! g_vsync) - printf("Enable LIBGL_VSYNC=1 if you want to use vsync.\n"); + printf("LIBGL: Enable LIBGL_VSYNC=1 if you want to use vsync.\n"); swap_interval = interval; #else LOAD_EGL(eglSwapInterval); @@ -1190,13 +1445,14 @@ EXPORT void glXReleaseBuffersMESA() {} #ifndef ANDROID /* TODO proper implementation */ EXPORT int glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) { + int pbuf=isPBuffer(draw); *value = 0; switch(attribute) { case GLX_WIDTH: - *value = 800; + *value = (pbuf)?pbuffersize[pbuf-1].Width:800; return 1; case GLX_HEIGHT: - *value = 480; + *value = (pbuf)?pbuffersize[pbuf-1].Height:480; return 1; case GLX_PRESERVED_CONTENTS: return 0; @@ -1209,11 +1465,154 @@ EXPORT int glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsig return 0; } +GLXPbuffer addPBuffer(EGLSurface surface, int Width, int Height, EGLContext Context) +{ + if(pbufferlist_cap<=pbufferlist_size) { + pbufferlist_cap += 4; + pbufferlist = (GLXPbuffer*)realloc(pbufferlist, sizeof(GLXPbuffer)*pbufferlist_cap); + pbuffersize = (glx_buffSize*)realloc(pbuffersize, sizeof(glx_buffSize)*pbufferlist_cap); + } + pbufferlist[pbufferlist_size] = (GLXPbuffer)surface; + pbuffersize[pbufferlist_size].Width = Width; + pbuffersize[pbufferlist_size].Height = Height; + pbuffersize[pbufferlist_size].Context = Context; + return pbufferlist[pbufferlist_size++]; +} +void delPBuffer(int j) +{ + LOAD_EGL(eglDestroyContext); + pbufferlist[j] = 0; + pbuffersize[j].Width = 0; + pbuffersize[j].Height = 0; + egl_eglDestroyContext(eglDisplay, pbuffersize[j].Context); + // should pack, but I think it's useless for common use +} + EXPORT void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf) { - printf("LIBGL: Warning, stub glxDestroyPBuffer called\n"); +// printf("LIBGL: Warning, stub glxDestroyPBuffer called\n"); + LOAD_EGL(eglDestroySurface); + int j=0; + while(jredBits:0, + EGL_GREEN_SIZE, (config)?config->greenBits:0, + EGL_BLUE_SIZE, (config)?config->blueBits:0, + EGL_ALPHA_SIZE, (config)?config->alphaBits:0, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + // Check that the config is for PBuffer + if(config->drawableType&GLX_PBUFFER_BIT!=GLX_PBUFFER_BIT) + return 0; + + // Init what need to be done + EGLBoolean result; + if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { + init_display(dpy); + if (eglDisplay == EGL_NO_DISPLAY) { + printf("LIBGL: Unable to create EGL display.\n"); + return 0; + } + } + + // first time? + if (eglInitialized == false) { + egl_eglBindAPI(EGL_OPENGL_ES_API); + result = egl_eglInitialize(eglDisplay, NULL, NULL); + if (result != EGL_TRUE) { + printf("LIBGL: Unable to initialize EGL display.\n"); + return 0; + } + eglInitialized = true; + } + + // select a configuration + int configsFound; + static EGLConfig pbufConfigs[1]; + result = egl_eglChooseConfig(eglDisplay, configAttribs, pbufConfigs, 1, &configsFound); + + CheckEGLErrors(); + if (result != EGL_TRUE || configsFound == 0) { + printf("LIBGL: No EGL configs found.\n"); + return 0; + } + + // now, create the PBufferSurface + (*Surface) = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs); + + if((*Surface)==EGL_NO_SURFACE) { + printf("LIBGL: Error creating PBuffer\n"); + return 0; + } + + (*Context) = egl_eglCreateContext(eglDisplay, pbufConfigs[0], EGL_NO_CONTEXT, egl_context_attrib); + + return 1; +} + EXPORT GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int * attrib_list) { - printf("LIBGL: Warning, stub glxCreatePBuffer called\n"); - return 0; +//printf("glXCreatePbuffer(%p, %p, %p)\n", dpy, config, attrib_list); + LOAD_EGL(eglQuerySurface); + + EGLSurface Surface = 0; + EGLContext Context = 0; + //let's create a PBuffer attributes + EGLint egl_attribs[128]; // should be enough + int i = 0; + if(attrib_list) { + int j = 0; + while(attrib_list[j]!=0) { + switch(attrib_list[j++]) { + case GLX_PBUFFER_WIDTH: + egl_attribs[i++] = EGL_WIDTH; + egl_attribs[i++] = attrib_list[j++]; + break; + case GLX_PBUFFER_HEIGHT: + egl_attribs[i++] = EGL_HEIGHT; + egl_attribs[i++] = attrib_list[j++]; + break; + case GLX_LARGEST_PBUFFER: + egl_attribs[i++] = EGL_LARGEST_PBUFFER; + egl_attribs[i++] = (attrib_list[j++])?EGL_TRUE:EGL_FALSE; + break; + case GLX_PRESERVED_CONTENTS: + j++; + // ignore this one + break; + //nothing, ignore unknown attribs + } + } + } + egl_attribs[i++] = EGL_NONE; + + if(createPBuffer(dpy, config, egl_attribs, &Surface, &Context)==0) { + return 0; + } + + int Width, Height; + + egl_eglQuerySurface(eglDisplay,Surface,EGL_WIDTH,&Width); + egl_eglQuerySurface(eglDisplay,Surface,EGL_HEIGHT,&Height); + + return addPBuffer(Surface, Width, Height, Context); } + #endif //ANDROID diff --git a/project/jni/glshim/src/glx/glx.h b/project/jni/glshim/src/glx/glx.h index 2b0aa7425..4032467d7 100755 --- a/project/jni/glshim/src/glx/glx.h +++ b/project/jni/glshim/src/glx/glx.h @@ -138,6 +138,8 @@ struct __GLXContextRec { EGLSurface eglSurface; EGLConfig eglConfigs[1]; EGLContext eglContext; + void* glstate; + int contextType; // 0 = Window, 1 = PBuffer }; typedef struct __GLXContextRec *GLXContext; @@ -203,7 +205,7 @@ GLXContext glXCreateContext(Display *dpy, GLXContext shareList, Bool direct); -GLXContext glXCreateContextAttribsARB(Display *display, void *config, +GLXContext glXCreateContextAttribsARB(Display *display, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); diff --git a/project/jni/glshim/src/glx/lookup.c b/project/jni/glshim/src/glx/lookup.c index 606c2a922..8c93f862b 100755 --- a/project/jni/glshim/src/glx/lookup.c +++ b/project/jni/glshim/src/glx/lookup.c @@ -45,6 +45,7 @@ void glXStub(void *x, ...) { return; } +extern int glshim_queries; EXPORT void *glXGetProcAddressARB(const char *name) { LOAD_EGL(eglGetProcAddress); @@ -100,8 +101,8 @@ EXPORT void *glXGetProcAddressARB(const char *name) { EX(glXCreateWindow); EX(glXDestroyWindow); - STUB(glXCreatePbuffer); // to do, using Renderbuffers.... - STUB(glXDestroyPbuffer); + EX(glXCreatePbuffer); + EX(glXDestroyPbuffer); STUB(glXCreatePixmap); STUB(glXDestroyPixmap); STUB(glXGetCurrentReadDrawable); @@ -615,6 +616,17 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _EX(glMatrixMultTransposef); _EX(glMatrixMultTransposed); + if(glshim_queries) { + _EX(glGenQueries); + _EX(glIsQuery); + _EX(glDeleteQueries); + _EX(glBeginQuery); + _EX(glEndQuery); + _EX(glGetQueryiv); + _EX(glGetQueryObjectiv); + _EX(glGetQueryObjectuiv); + } + if (!export_silentstub) printf("glXGetProcAddress: %s not found.\n", name); return NULL; } diff --git a/project/jni/glshim/src/proxy/proxy.h b/project/jni/glshim/src/proxy/proxy.h index 34ed2787c..615197949 100644 --- a/project/jni/glshim/src/proxy/proxy.h +++ b/project/jni/glshim/src/proxy/proxy.h @@ -13793,6 +13793,7 @@ typedef struct { extern void glPushCall(void *data); void glPackedCall(const packed_call_t *packed); void glIndexedCall(const indexed_call_t *packed, void *ret_v); +packed_call_t* glCopyPackedCall(const packed_call_t *packed); #define glAccum_INDEX 1 #define glAccum_RETURN void @@ -43314,6 +43315,7 @@ typedef struct { extern void glPushCall(void *data); void glPackedCall(const packed_call_t *packed); void glIndexedCall(const indexed_call_t *packed, void *ret_v); +packed_call_t* glCopyPackedCall(const packed_call_t *packed); #define glAccum_INDEX 1 #define glAccum_RETURN void