diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index 353994af1..ee7094c94 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -134,6 +134,11 @@ Experimental: enable Alpha test only when using texture that contains an alpha c * 0 : Default, nothing special * 1 : Alpha Hack enabled +##### LIBGL_NODOWNSAMPLING +Texture downsampling control + * 0 : Default, DXTc texture are downsampled to 16bits + * 1 : DXTc texture are left as 32bits RGBA + ##### LIBGL_STREAM PANDORA only: enable Texture Streaming (works only on RGB textures) * 0 : Default, nothing special @@ -220,11 +225,21 @@ Initial Hardware test * 0 : Default, perform intial hardware testing (using a PBuffer) * 1 : Do not perform test (no extensions tested or used) +##### LIBGL_NOVAOCACHE +VAO Caching + * 0 : Default, tr to cache vao to avoid memcpy in render list + * 1 : Don't cache VAO + ---- Version history ---- +##### current version + * Fixed (Added in fact) support for Multisampling on the GLX Context creation (a bit hacky, but seems to works) + * Added LIBGL_NODOWNSAMPLING and associated Hint + * Try to implement some caching on VAO to avoid some memcpy in renderlist (with a way to disable it just in case) + ##### 0.9.3 * Added support for Cube Mapping (with hardware support) * Improved Texture state tracking diff --git a/project/jni/gl4es/include/gl4eshint.h b/project/jni/gl4es/include/gl4eshint.h index 024845ed6..04c9ee0a0 100755 --- a/project/jni/gl4es/include/gl4eshint.h +++ b/project/jni/gl4es/include/gl4eshint.h @@ -23,5 +23,7 @@ #define GL_BATCH_HINT_GL4ES 0xA109 // same as using LIBGL_NOERROR=x #define GL_NOERROR_HINT_GL4ES 0xA10A +// same as using LIBGL_NODOWNSAMPLING=x +#define GL_NODOWNSAMPLING_HINT_GL4ES 0xA10B #endif \ No newline at end of file diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index 76f996062..b6987af1c 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -1,6 +1,7 @@ #define SYS_proxy 9999 #define MAX_EVAL_ORDER 30 #define MAX_TEX 8 +#define MAX_LIGHT 8 #define MAX_STACK_PROJECTION 16 #define MAX_STACK_TEXTURE 16 #define MAX_STACK_MODELVIEW 64 diff --git a/project/jni/gl4es/src/gl/buffers.c b/project/jni/gl4es/src/gl/buffers.c index 2735f4ba1..2ece32c9c 100755 --- a/project/jni/gl4es/src/gl/buffers.c +++ b/project/jni/gl4es/src/gl/buffers.c @@ -1,5 +1,6 @@ #include "buffers.h" #include "debug.h" +#include "../glx/hardext.h" static GLuint lastbuffer = 1; @@ -125,7 +126,11 @@ void gl4es_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLe } if (buff->data) { free(buff->data); + } + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + buff->size = size; buff->usage = usage; buff->data = malloc(size); @@ -147,6 +152,10 @@ void gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, cons // printf("LIBGL: Warning, null buffer for target=0x%04X for glBufferSubData\n", target); return; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + memcpy(buff->data + offset, data, size); //TODO, some check maybe? noerrorShim(); } @@ -157,6 +166,7 @@ void gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers) { flush(); } + VaoSharedClear(glstate->vao); khash_t(buff) *list = glstate->buffers; if (list) { khint_t k; @@ -247,6 +257,10 @@ void *gl4es_glMapBuffer(GLenum target, GLenum access) { errorShim(GL_INVALID_ENUM); return (void*)NULL; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + glbuffer_t *buff = getbuffer_buffer(target); if (buff==NULL) return (void*)NULL; // Should generate an error! @@ -262,6 +276,10 @@ GLboolean gl4es_glUnmapBuffer(GLenum target) { errorShim(GL_INVALID_ENUM); return GL_FALSE; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + glbuffer_t *buff = getbuffer_buffer(target); if (buff==NULL) return GL_FALSE; // Should generate an error! @@ -280,10 +298,11 @@ void gl4es_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, G return; } glbuffer_t *buff = getbuffer_buffer(target); + if (buff==NULL) return; // Should generate an error! // TODO, check parameter consistancie - memcpy(data, buff->data+offset, size); + memcpy(data, buff->data+offset, size); noerrorShim(); } @@ -406,6 +425,7 @@ void gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { k = kh_get(glvao, list, t); if (k != kh_end(list)) { glvao = kh_value(list, k); + VaoSharedClear(glvao); kh_del(glvao, list, k); free(glvao); } @@ -428,7 +448,28 @@ GLboolean gl4es_glIsVertexArray(GLuint array) { return GL_FALSE; } -//Dirzct wrapper +void VaoSharedClear(glvao_t *vao) { + if(vao==NULL || vao->shared_arrays==NULL) + return; + if(!(--(*vao->shared_arrays))) { + free(vao->vert.ptr); + free(vao->color.ptr); + free(vao->secondary.ptr); + free(vao->normal.ptr); + for (int i=0; itex[i].ptr); + free(vao->shared_arrays); + } + vao->vert.ptr = NULL; + vao->color.ptr = NULL; + vao->secondary.ptr = NULL; + vao->normal.ptr = NULL; + for (int i=0; itex[i].ptr = NULL; + vao->shared_arrays = NULL; +} + +//Direct wrapper void glGenVertexArrays(GLsizei n, GLuint *arrays) AliasExport("gl4es_glGenVertexArrays"); void glBindVertexArray(GLuint array) AliasExport("gl4es_glBindVertexArray"); void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) AliasExport("gl4es_glDeleteVertexArrays"); diff --git a/project/jni/gl4es/src/gl/buffers.h b/project/jni/gl4es/src/gl/buffers.h index efd56013c..57503d70e 100755 --- a/project/jni/gl4es/src/gl/buffers.h +++ b/project/jni/gl4es/src/gl/buffers.h @@ -65,6 +65,12 @@ typedef struct { pointer_state_t vertex, color, normal, tex_coord[MAX_TEX], secondary; } pointer_states_t; +typedef struct { + GLfloat *ptr; + pointer_state_t state; + GLboolean enabled; +} pointer_cache_t; + // VAO **************** typedef struct { GLuint array; @@ -81,8 +87,18 @@ typedef struct { normal_array, vertex_array, tex_coord_array[MAX_TEX]; + // VAO optimisation: keep a shared copy of the digested datas (unless the vao is the default one) + int *shared_arrays; + pointer_cache_t vert; + pointer_cache_t normal; + pointer_cache_t color; + pointer_cache_t secondary; + pointer_cache_t tex[MAX_TEX]; + int cache_count; } glvao_t; +void VaoSharedClear(glvao_t *vao); + KHASH_MAP_INIT_INT(glvao, glvao_t*) void gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays); diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h index b31b51a1f..a8705409e 100755 --- a/project/jni/gl4es/src/gl/const.h +++ b/project/jni/gl4es/src/gl/const.h @@ -17,6 +17,7 @@ #define GL_TEXTURE_GEN_T 0x0C61 #define GL_TEXTURE_GEN_MODE 0x2500 #define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 #define GL_TEXTURE_WIDTH 0x1000 #define GL_TEXTURE_HEIGHT 0x1001 #define GL_TEXTURE_BORDER 0x1005 diff --git a/project/jni/gl4es/src/gl/debug.c b/project/jni/gl4es/src/gl/debug.c index 71d71f19c..0a7cb4692 100755 --- a/project/jni/gl4es/src/gl/debug.c +++ b/project/jni/gl4es/src/gl/debug.c @@ -82,6 +82,8 @@ const char* PrintEnum(GLenum what) { p(GL_TEXTURE_WIDTH); p(GL_TEXTURE_HEIGHT); p(GL_TEXTURE_COMPRESSED); + p(GL_TEXTURE_BORDER); + p(GL_TEXTURE_INTERNAL_FORMAT); // texture pack/unpack p(GL_UNPACK_ALIGNMENT); // framebuffer diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c index 0c3f2ba29..7bd64a9f8 100755 --- a/project/jni/gl4es/src/gl/getter.c +++ b/project/jni/gl4es/src/gl/getter.c @@ -488,6 +488,9 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_NOERROR_HINT_GL4ES: *params=globals4es.noerror; break; + case GL_NODOWNSAMPLING_HINT_GL4ES: + *params=globals4es.nodownsampling; + break; default: errorGL(); gles_glGetFloatv(pname, params); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index 81dd333f0..6d0285841 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -369,6 +369,28 @@ GLboolean gl4es_glIsEnabled(GLenum cap) { #undef clientisenabled GLboolean glIsEnabled(GLenum cap) AliasExport("gl4es_glIsEnabled"); +static GLboolean is_cache_compatible(GLsizei count) { + #define T2(AA, A, B) \ + if(glstate->vao->AA!=glstate->vao->B.enabled) return GL_FALSE; \ + if(glstate->vao->B.enabled && memcmp(&glstate->vao->pointers.A, &glstate->vao->B.state, sizeof(pointer_state_t))) return GL_FALSE; + #define TEST(A,B) T2(A##_array, A, B) + #define TESTA(A,B,I) T2(A##_array[i], A[i], B[i]) + + if(glstate->vao == glstate->defaultvao) return GL_FALSE; + if(count > glstate->vao->cache_count) return GL_FALSE; + TEST(vertex, vert) + TEST(color, color) + TEST(secondary, secondary) + TEST(normal, normal) + for (int i=0; imode_init = mode; list->len = count-skip; list->cap = count-skip; + + // check cache if any + if(glstate->vao->shared_arrays) { + if (!is_cache_compatible(count)) + VaoSharedClear(glstate->vao); + } - if (glstate->vao->vertex_array) { - list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count); - } - if (glstate->vao->color_array) { - if(glstate->vao->pointers.color.size==GL_BGRA) - list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count); - else - list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count); - } - if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) { - if(glstate->vao->pointers.secondary.size==GL_BGRA) - list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count); - else - 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); - } - for (int i=0; ivao->tex_coord_array[i]) { - list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count); - } - } + if(glstate->vao->shared_arrays) { + #define OP(A, N) (A)?A+skip*N:NULL + list->vert = OP(glstate->vao->vert.ptr,4); + list->color = OP(glstate->vao->color.ptr,4); + list->secondary = OP(glstate->vao->secondary.ptr,4); + list->normal = OP(glstate->vao->normal.ptr,3); + for (int i=0; itex[i] = OP(glstate->vao->tex[i].ptr,4); + #undef OP + + list->shared_arrays = glstate->vao->shared_arrays; + (*glstate->vao->shared_arrays)++; + } else { + if(!globals4es.novaocache && glstate->vao != glstate->defaultvao) { + // prepare a vao cache object + list->shared_arrays = glstate->vao->shared_arrays = (int*)malloc(sizeof(int)); + *glstate->vao->shared_arrays = 1; + #define G2(AA, A, B) \ + glstate->vao->B.enabled = glstate->vao->AA; \ + if (glstate->vao->B.enabled) memcpy(&glstate->vao->B.state, &glstate->vao->pointers.A, sizeof(pointer_state_t)); + #define GO(A,B) G2(A##_array, A, B) + #define GOA(A,B,I) G2(A##_array[i], A[i], B[i]) + GO(vertex, vert) + GO(color, color) + GO(secondary, secondary) + GO(normal, normal) + for (int i=0; ivao->cache_count = count; + #undef GOA + #undef GO + #undef G2 + } + if (glstate->vao->vertex_array) { + if(glstate->vao->shared_arrays) { + glstate->vao->vert.ptr = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, 0, count); + list->vert = glstate->vao->vert.ptr + 4*skip; + } else + list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count); + } + if (glstate->vao->color_array) { + if(glstate->vao->shared_arrays) { + if(glstate->vao->pointers.color.size==GL_BGRA) + glstate->vao->color.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, 0, count); + else + glstate->vao->color.ptr = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count); + list->color = glstate->vao->color.ptr + 4*skip; + } else { + if(glstate->vao->pointers.color.size==GL_BGRA) + list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count); + else + list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count); + } + } + if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) { + if(glstate->vao->shared_arrays) { + if(glstate->vao->pointers.secondary.size==GL_BGRA) + glstate->vao->secondary.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, 0, count); + else + glstate->vao->secondary.ptr = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, count); // alpha chanel is always 0 for secondary... + list->secondary = glstate->vao->secondary.ptr + 4*skip; + } else { + if(glstate->vao->pointers.secondary.size==GL_BGRA) + list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count); + else + list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary... + } + } + if (glstate->vao->normal_array) { + if(glstate->vao->shared_arrays) { + glstate->vao->normal.ptr = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, 0, count); + list->normal = glstate->vao->normal.ptr + 3*skip; + } else + list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count); + } + for (int i=0; ivao->tex_coord_array[i]) { + if(glstate->vao->shared_arrays) { + glstate->vao->tex[i].ptr = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, 0, count); + list->tex[i] = glstate->vao->tex[i].ptr + 4*skip; + } else + list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count); + } + } + } return list; } @@ -628,6 +719,31 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES) mode = GL_POINTS; + if (glstate->polygon_mode != GL_LINES && mode==GL_QUADS) { + static GLushort *indices = NULL; + static int indcnt = 0; + if(indcnt < count+first) { + indcnt = count + first; + if (indices) free(indices); + indices = (GLushort*)malloc(sizeof(GLushort)*(indcnt*3/2)); + for (int i=0, j=0; i+3vao->elements; + glstate->vao->elements = NULL; + gl4es_glDrawElements(GL_TRIANGLES, count*3/2, GL_UNSIGNED_SHORT, indices+first*3/2); + glstate->vao->elements = old_vao_elements; + return; + } + if (should_intercept_render(mode)) { renderlist_t *list; list = arrays_to_renderlist(NULL, mode, first, count+first); diff --git a/project/jni/gl4es/src/gl/hint.c b/project/jni/gl4es/src/gl/hint.c index 0d24cc995..47c40ffc5 100755 --- a/project/jni/gl4es/src/gl/hint.c +++ b/project/jni/gl4es/src/gl/hint.c @@ -69,6 +69,12 @@ void gl4es_glHint(GLenum pname, GLenum mode) { else errorShim(GL_INVALID_ENUM); break; + case GL_NODOWNSAMPLING_HINT_GL4ES: + if (mode<=1) + globals4es.nodownsampling = mode; + else + errorShim(GL_INVALID_ENUM); + break; default: errorGL(); gles_glHint(pname, mode); diff --git a/project/jni/gl4es/src/gl/init.c b/project/jni/gl4es/src/gl/init.c index ee6d82b68..5e399f10e 100755 --- a/project/jni/gl4es/src/gl/init.c +++ b/project/jni/gl4es/src/gl/init.c @@ -257,8 +257,14 @@ void initialize_gl4es() { globals4es.queries = 0; SHUT(LOGD("LIBGL: Dont't expose fake glQueries functions\n")); } + char *env_nodownsampling = getenv("LIBGL_NODOWNSAMPLING"); + if (env_nodownsampling && strcmp(env_nodownsampling, "1") == 0) { + globals4es.nodownsampling = 1; + SHUT(LOGD("LIBGL: No downsampling of DXTc textures\n")); + } env(LIBGL_NOTEXMAT, globals4es.texmat, "Don't handle Texture Matrice internaly"); + env(LIBGL_NOVAOCACHE, globals4es.novaocache, "Don't use VAO cache"); char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) diff --git a/project/jni/gl4es/src/gl/init.h b/project/jni/gl4es/src/gl/init.h index 2c35a8089..dc3dd3219 100755 --- a/project/jni/gl4es/src/gl/init.h +++ b/project/jni/gl4es/src/gl/init.h @@ -33,10 +33,12 @@ typedef struct _globals4es { int queries; int silentstub; int glx_surface_srgb; + int nodownsampling; #ifdef PANDORA float gamma; #endif int texmat; + int novaocache; char version[50]; } globals4es_t; diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index f39122aa1..3ba734642 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -935,7 +935,7 @@ void draw_renderlist(renderlist_t *list) { old_tex = glstate->texture.client; GLuint cur_tex = old_tex; #define RS(A, len) if(texgenedsz[A]enable.texture[a]) { const GLint itarget = get_target(glstate->enable.texture[a]); diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c index 9fafd61ec..10eaa7319 100755 --- a/project/jni/gl4es/src/gl/matrix.c +++ b/project/jni/gl4es/src/gl/matrix.c @@ -56,6 +56,7 @@ static int send_to_hardware() { } void init_matrix(glstate_t* glstate) { +DBG(printf("init_matrix(%p)\n", glstate);) alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION); set_identity(TOP(projection_matrix)); glstate->projection_matrix->identity = 1; @@ -93,7 +94,7 @@ DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);) noerrorShim(); // go... switch(matrix_mode) { - #define P(A, B) if(glstate->A->topA->top+1A->top++; \ } else errorShim(GL_STACK_OVERFLOW) diff --git a/project/jni/gl4es/src/gl/pixel.c b/project/jni/gl4es/src/gl/pixel.c index 1c2fead8a..56326dfe2 100755 --- a/project/jni/gl4es/src/gl/pixel.c +++ b/project/jni/gl4es/src/gl/pixel.c @@ -73,58 +73,58 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - s = (GLushort[]){ - (v & 0x001f), - ((v & 0x03e0) >> 5), - ((v & 0x7c00) >> 10), - ((v & 0x8000) >> 15)*31, - }; - read_each(, / 31.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5_REV, GLushort, - s = (GLushort[]){ - (v & 0x001f)*2, - ((v & 0x07e0) >> 5), - ((v & 0xF800) >> 11)*2, + s = (const GLushort[]) { + ((v ) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v >> 11) & 0x1f)<<1, }; read_each(, / 63.0f); ) + type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, + s = (const GLushort[]) { + ((v ) & 0x1f), + ((v >> 5) & 0x1f), + ((v >> 10) & 0x1f), + ((v >> 15) & 0x01)*31, + }; + read_each(, / 31.0f); + ) type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, - s = (GLushort[]){ - (v & 0x000f), - ((v & 0x00f0) >> 4), - ((v & 0x0f00) >> 8), - ((v & 0xf000) >> 12) + s = (const GLushort[]) { + ((v ) & 0x0f), + ((v >> 4 ) & 0x0f), + ((v >> 8 ) & 0x0f), + ((v >> 12 ) & 0x0f) }; read_each(, / 15.0f); ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, - s = (GLushort[]){ - ((v & 0xF800) >>11)*2, - ((v & 0x07e0) >> 5), - ((v & 0x001f) )*2, + s = (const GLushort[]) { + ((v >> 11) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v ) & 0x1f)<<1, }; read_each(, / 63.0f); ) - type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, - s = (GLushort[]){ - ((v & 0xf000) >>12), - ((v & 0x0f00) >> 8), - ((v & 0x00f0) >> 4), - ((v & 0x000f) ) - }; - read_each(, / 15.0f); - ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, - s = (GLushort[]){ - ((v & 0xf800) >> 11), - ((v & 0x07c0) >> 6), - ((v & 0x003e) >> 1), - ((v & 1))*31, + s = (const GLushort[]) { + ((v >> 11) & 0x1f), + ((v >> 6) & 0x1f), + ((v >> 1) & 0x1f), + ((v ) & 0x01)*31, }; read_each(, / 31.0f); ) + type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, + s = (const GLushort[]) { + ((v >> 12) & 0x0f), + ((v >> 8) & 0x0f), + ((v >> 4) & 0x0f), + ((v ) & 0x0f) + }; + read_each(, / 15.0f); + ) default: // TODO: add glSetError? printf("LIBGL: Unsupported source data type: %s\n", PrintEnum(src_type)); @@ -149,35 +149,35 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, // TODO: force 565 to RGB? then we can change [4] -> 3 type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - *d = (((GLushort)(color[0] * 31.0f) & 0x1f) << 11) | - (((GLushort)(color[1] * 63.0f) & 0x3f) << 5) | - (((GLushort)(color[2] * 31.0f) & 0x1f)); + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - color[dst_color->alpha] = pixel.a; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = (((GLushort)(color[0] * 31.0f) & 0x1f) ) | - (((GLushort)(color[1] * 31.0f) & 0x1f) << 5) | - (((GLushort)(color[2] * 31.0f) & 0x1f) << 10) | - (((GLushort)(color[3] * 1) & 0x01) << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - color[dst_color->alpha] = pixel.a; - *d = (((GLushort)(color[0] * 15.0) & 0x0f) << 12) | - (((GLushort)(color[1] * 15.0) & 0x0f) << 8) | - (((GLushort)(color[2] * 15.0) & 0x0f) << 4) | - (((GLushort)(color[3] * 15.0) & 0x0f)); + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(dst_type)); @@ -243,38 +243,29 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - s = (GLushort[]){ - (v & 31), - ((v & 0x03e0) >> 5), - ((v & 0x7c00) >> 10), - ((v & 0x8000) >> 15)*31, - }; - read_each(, / 31.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, - s = (GLushort[]){ - (v & 31)*2, - ((v & 0x07e0) >> 5), - ((v & 0xF800) >> 11)*2, + s = (const GLushort[]) { + ((v >> 11) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v ) & 0x1f)<<1, }; read_each(, / 63.0f); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, - s = (GLushort[]){ - ((v & 0xf800) >> 11), - ((v & 0x07c0) >> 6), - ((v & 0x003e) >> 1), - ((v & 1))*31, + s = (const GLushort[]) { + ((v >> 11) & 0x1f), + ((v >> 6) & 0x1f), + ((v >> 1) & 0x1f), + ((v ) & 0x01)*31, }; read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, - s = (GLushort[]){ - (v & 0x000f), - ((v & 0x00f0) >> 4), - ((v & 0x0f00) >> 8), - ((v & 0xf000) >> 12) + s = (const GLushort[]) { + ((v >> 12) & 0x0f), + ((v >> 8) & 0x0f), + ((v >> 4) & 0x0f), + ((v ) & 0x0f) }; read_each(, / 15.0f); ) @@ -300,9 +291,9 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[2] * 31.0f) & 0x1f << 11) | - ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | - ((GLuint)(color[0] * 31.0f) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; @@ -311,10 +302,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | - ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | - ((GLuint)(color[3] * 1) & 0x01 << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -322,10 +313,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[3] * 15.0f) & 0x0f << 12) | - ((GLushort)(color[2] * 15.0f) & 0x0f << 8) | - ((GLushort)(color[1] * 15.0f) & 0x0f << 4) | - ((GLushort)(color[0] * 15.0f) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -402,59 +393,37 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - (v[ii] & 31), - ((v[ii] & 0x03e0) >> 5), - ((v[ii] & 0x7c00) >> 10), - ((v[ii] & 0x8000) >> 15)*31, - }; - }; - read_each(, / 31.0f); - ) - type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, - for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0x000f) ), - ((v[ii] & 0x00f0) >> 4), - ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0xf000) >>12) - }; - }; - read_each(, / 15.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0x001f) )*2, - ((v[ii] & 0x07e0) >> 5), - ((v[ii] & 0xF800) >>11)*2, + s[ii] = (const GLushort[]) { + ((v[ii] >> 11) & 0x1f)<<1, + ((v[ii] >> 5) & 0x3f), + ((v[ii] ) & 0x1f)<<1, }; + read_i_each(, / 63.0f, ii); }; - read_each(, / 63.0f); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0xf800) >>11), - ((v[ii] & 0x07c0) >> 6), - ((v[ii] & 0x003e) >> 1), - ((v[ii] & 1) )*31, + s[ii] = (const GLushort[]) { + ((v[ii] >> 11) & 0x1f), + ((v[ii] >> 6) & 0x1f), + ((v[ii] >> 1) & 0x1f), + ((v[ii] ) & 0x01)*31, }; + read_i_each(, / 31.0f, ii); }; - read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0xf000) >>12), - ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0x00f0) >> 4), - ((v[ii] & 0x000f) ) + s[ii] = (const GLushort[]) { + ((v[ii] >> 12) & 0x0f), + ((v[ii] >> 8) & 0x0f), + ((v[ii] >> 4) & 0x0f), + ((v[ii] ) & 0x0f) }; + read_i_each(, / 15.0f, ii); }; - read_each(, / 15.0f); ) default: // TODO: add glSetError? @@ -478,9 +447,9 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 11) | - ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; @@ -489,10 +458,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | - ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | - ((GLuint)(color[3] * 1) & 0x01 << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -500,10 +469,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[0] * 15.0f) & 0x0f << 12) | - ((GLushort)(color[1] * 15.0f) & 0x0f << 8) | - ((GLushort)(color[2] * 15.0f) & 0x0f << 4) | - ((GLushort)(color[3] * 15.0f) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: half_pixel: Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -588,27 +557,37 @@ bool quarter_pixel(const GLvoid *src[16], case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - for (int ii=0; ii<16; ii++) { + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + for (int ii=0; ii<4; ii++) { s[ii] = (GLushort[]) { - (v[ii] & 31), - ((v[ii] & 0x03e0) >> 5), - ((v[ii] & 0x7c00) >> 10), - ((v[ii] & 0x8000) >> 15)*31, + ((v[ii] & 0xf800) >>11), + ((v[ii] & 0x07c0) >> 6), + ((v[ii] & 0x003e) >> 1), + ((v[ii] & 1) )*31, }; + read_i_each(, / 31.0f, ii); + }; + ) + type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, + for (int ii=0; ii<4; ii++) { + s[ii] = (GLushort[]) { + ((v[ii] & 0xF800) >>11)*2, + ((v[ii] & 0x07e0) >> 5), + ((v[ii] & 0x001f) )*2, + }; + read_i_each(, / 63.0f, ii); }; - read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, for (int ii=0; ii<16; ii++) { s[ii] = (GLushort[]) { - (v[ii] & 0x000f), - ((v[ii] & 0x00f0) >> 4), + ((v[ii] & 0xf000) >> 12), ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0xf000) >> 12) + ((v[ii] & 0x00f0) >> 4), + (v[ii] & 0x000f) }; + read_i_each(, / 15.0f, ii); }; - read_each(, / 15.0f); ) default: // TODO: add glSetError? @@ -632,9 +611,21 @@ bool quarter_pixel(const GLvoid *src[16], color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[0] * 31) & 0x1f << 11) | - ((GLuint)(color[1] * 63) & 0x3f << 5) | - ((GLuint)(color[2] * 31) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + GLfloat color[4]; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + // TODO: can I macro this or something? it follows a pretty strict form. + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -642,10 +633,10 @@ bool quarter_pixel(const GLvoid *src[16], color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[0] * 15.0) & 0x0f << 12) | - ((GLushort)(color[1] * 15.0) & 0x0f << 8) | - ((GLushort)(color[2] * 15.0) & 0x0f << 4) | - ((GLushort)(color[3] * 15.0) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: quarter_pixel Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -1021,13 +1012,13 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height; - new_width = width / 2; if(new_width==0) new_width=1; - new_height = height / 2; if(new_height==0) new_height==1; + new_width = width / 2; if(!new_width) ++new_width; + new_height = height / 2; if(!new_height) ++new_height; /* if (new_width*2!=width || new_height*2!=height) { printf("LIBGL: halfscaling %ux%u failed\n", width, height); return false; }*/ -// printf("LIBGL: halfscaling %ux%u -> %ux%u\n", width, height, new_width, new_height); + //printf("LIBGL: halfscaling %ux%u -> %ux%u (%s / %s)\n", width, height, new_width, new_height, PrintEnum(format), PrintEnum(type)); const colorlayout_t *src_color; src_color = get_color_map(format); GLvoid *dst; @@ -1037,16 +1028,18 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new, dst = malloc(pixel_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dx = (width>1)?1:0; + const int dy = (height>1)?1:0; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { pix0 = src + ((x * 2) + (y * 2) * width) * pixel_size; - pix1 = src + ((x * 2 + 1) + + pix1 = src + ((x * 2 + dx) + (y * 2) * width) * pixel_size; pix2 = src + ((x * 2) + - (y * 2 + 1) * width) * pixel_size; - pix3 = src + ((x * 2 + 1) + - (y * 2 + 1) * width) * pixel_size; + (y * 2 + dy) * width) * pixel_size; + pix3 = src + ((x * 2 + dx) + + (y * 2 + dy) * width) * pixel_size; half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)pos, src_color, type); pos += pixel_size; } @@ -1059,8 +1052,8 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height, dest_size; - new_width = width / 2; - new_height = height / 2; + new_width = width / 2; if(!new_width) ++new_width; + new_height = height / 2; if(!new_height) ++new_height; if (new_width*2!=width || new_height*2!=height || format!=GL_RGBA || type!=GL_UNSIGNED_BYTE) { //printf("LIBGL: thirdscaling %ux%u failed\n", width, height); return false; @@ -1076,17 +1069,19 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new, dst = malloc(dest_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dx = (width>1)?1:0; + const int dy = (height>1)?1:0; GLubyte tmp[4]; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { pix0 = src + ((x * 2) + (y * 2) * width) * pixel_size; - pix1 = src + ((x * 2 + 1) + + pix1 = src + ((x * 2 + dx) + (y * 2) * width) * pixel_size; pix2 = src + ((x * 2) + - (y * 2 + 1) * width) * pixel_size; - pix3 = src + ((x * 2 + 1) + - (y * 2 + 1) * width) * pixel_size; + (y * 2 + dy) * width) * pixel_size; + pix3 = src + ((x * 2 + dx) + + (y * 2 + dy) * width) * pixel_size; half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)tmp, src_color, type); *((GLushort*)pos) = (((GLushort)tmp[0])&0xf0)<<8 | (((GLushort)tmp[1])&0xf0)<<4 | (((GLushort)tmp[2])&0xf0) | (((GLushort)tmp[3])>>4); pos += dest_size; @@ -1100,8 +1095,8 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height; - new_width = width / 4; - new_height = height / 4; + new_width = width / 4; if(!new_width) ++new_width; + new_height = height / 4; if(!new_height) ++new_height; /* if (new_width*4!=width || new_height*4!=height) { printf("LIBGL: quarterscaling %ux%u failed\n", width, height); return false; @@ -1116,12 +1111,14 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new, dst = malloc(pixel_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dxs[4] = {0, width>1?1:0, width>2?2:0, width>3?3:width>1?1:0}; + const int dys[4] = {0, height>1?1:0, height>2?2:0, height>3?3:height>1?1:0}; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { for (int dx=0; dx<4; dx++) { for (int dy=0; dy<4; dy++) { - pix[dx+dy*4] = src + ((x * 4 + dx) + - (y * 4 + dy) * width) * pixel_size; + pix[dx+dy*4] = src + ((x * 4 + dxs[dx]) + + (y * 4 + dys[dy]) * width) * pixel_size; } } quarter_pixel((const GLvoid **)pix, (GLvoid *)pos, src_color, type); diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 1bde96aa6..12c9144cd 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -25,6 +25,12 @@ int npot(int n) { return i; } +static int inline nlevel(int size, int level) { + size>>=level; + if(!size) size=1; + return size; +} + // conversions for GL_ARB_texture_rectangle void tex_coord_rect_arb(GLfloat *tex, GLsizei len, GLsizei width, GLsizei height) { @@ -435,6 +441,86 @@ GLenum swizzle_internalformat(GLenum *internalformat) { return sret; } +static int get_shrinklevel(int width, int height, int level) { + int shrink = 0; + int mipwidth = width << level; + int mipheight = height << level; + switch(globals4es.texshrink) { + case 0: // nothing + break; + case 1: //everything / 2 + if ((mipwidth > 1) && (mipheight > 1)) { + shrink = 1; + } + break; + case 2: //only > 512 /2 + case 7: //only > 512 /2 , but not for empty texture + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 512) && (mipheight > 8)) || ((mipheight > 512) && (mipwidth > 8))) { + shrink = 1; + } + break; + case 3: //only > 256 /2 + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + shrink = 1; + } + break; + case 4: //only > 256 /2, >=1024 /4 + case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same) + if (((mipwidth%4==0) && (mipheight%4==0)) && + ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + if ((mipwidth>=1024) || (mipheight>=1024)) { + shrink = 2; + } else { + shrink = 1; + } + } + break; + case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 128) && (mipheight > 8)) || ((mipheight > 128) && (mipwidth > 8))) { + if (((mipwidth%2==0) && (mipheight%2==0)) && (mipwidth>=512) || (mipheight>=512)) { + while (((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + width /= 2; + height /= 2; + mipwidth /= 2; + mipheight /= 2; + shrink+=1; + } + } else { + shrink = 1; + } + } + break; + case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 + if ((mipwidth>4096) || (mipheight>4096)) { + shrink=2; + } else + if ((mipwidth>2048) || (mipheight>2048)) { + shrink=1; + } + break; + case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture + if ((mipwidth>4096) || (mipheight>4096)) { + shrink=2; + } else + if ((mipwidth>512) || (mipheight>512)) { + shrink=1; + } + break; + case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture + if ((mipwidth>2048) || (mipheight>2048)) { + shrink=2; + } else + if ((mipwidth>512) || (mipheight>512)) { + shrink=1; + } + break; + } + return shrink; +} + static int default_tex_mipmap = 0; static int proxy_width = 0; @@ -487,6 +573,14 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, bound->orig_internal = internalformat; bound->internalformat = new_format; } + // shrink checking + int mipwidth = width << level; + int mipheight = height << level; + int shrink = 0; + if(bound) { + bound->shrink = shrink = get_shrinklevel(width, height, level); + } + if(width>>shrink==0 && height>>shrink==0) return; // nothing to do if (datab) { // implements GL_UNPACK_ROW_LENGTH @@ -511,13 +605,12 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, free(old); } - if (bound) { - bound->shrink = 0; - switch(globals4es.texshrink) { - case 0: // nothing + if (bound && bound->shrink!=0) { + switch(globals4es.texshrink) { + case 0: // nothing ??? break; case 1: //everything / 2 - if ((width > 1) && (height > 1)) { + if ((mipwidth > 1) && (mipheight > 1)) { GLvoid *out = pixels; GLfloat ratio = 0.5; pixel_scale(pixels, &out, width, height, ratio, format, type); @@ -529,163 +622,28 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, bound->shrink = 1; } break; - case 2: //only > 512 /2 - case 7: //only > 512 /2 , but not for empty texture - if (((width%2==0) && (height%2==0)) && - ((width > 512) && (height > 8)) || ((height > 512) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 3: //only > 256 /2 - if (((width%2==0) && (height%2==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 4: //only > 256 /2, >=1024 /4 - case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same) - if (((width%4==0) && (height%4==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - if ((width>=1024) || (height>=1024)) { + default: + while(shrink) { + if (shrink>1) { // quarterscale GLvoid *out = pixels; pixel_quarterscale(pixels, &out, width, height, format, type); if (out != pixels && pixels!=datab) free(pixels); pixels = out; - width /= 4; - height /= 4; - bound->shrink = 2; - } else { + width = nlevel(width, 2); + height = nlevel(height, 2); + shrink-=2; + } else { //halfscale GLvoid *out = pixels; pixel_halfscale(pixels, &out, width, height, format, type); if (out != pixels && pixels!=datab) free(pixels); pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; + width = nlevel(width, 1); + height = nlevel(height, 1); + shrink--; } } - break; - /*case 5: //every > 256 is downscaled to 256, but not for empty texture - while (((width%2==0) && (height%2==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink+=1; - } - break;*/ - case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture - if (((width%2==0) && (height%2==0)) && - ((width > 128) && (height > 8)) || ((height > 128) && (width > 8))) { - if (((width%2==0) && (height%2==0)) && (width>=512) || (height>=512)) { - while (((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - } else { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - } - break; - case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 - if ((width>4096) || (height>4096)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>2048) || (height>2048)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; - case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture - if ((width>4096) || (height>4096)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>512) || (height>512)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; - case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture - if ((width>2048) || (height>2048)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>512) || (height>512)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; } } @@ -700,6 +658,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, ((internalformat==GL_RGB) || (internalformat==3) || (internalformat==GL_RGB8) || (internalformat==GL_BGR) || (internalformat==GL_RGB5)) || (globals4es.texstream==2) ) { bound->streamingID = AddStreamed(width, height, bound->texture); if (bound->streamingID>-1) { // success + bound->shrink = 0; // no shrink on Stream texture bound->streamed = true; ApplyFilterID(bound->streamingID, bound->min_filter, bound->mag_filter); GLboolean tmp = IS_TEX2D(glstate->enable.texture[glstate->texture.active]); @@ -716,62 +675,10 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, } #endif if (bound) { - bound->shrink = 0; if (!bound->streamed) swizzle_texture(width, height, &format, &type, internalformat, new_format, NULL); // convert format even if data is NULL - if ((globals4es.texshrink>0) && !bound->streamed) { - switch(globals4es.texshrink) { - case 1: //everything / 2 - width /= 2; - height /= 2; - bound->shrink = 1; - break; - case 2: //only > 512 /2 - if((width>512) || (height>512)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 3: //only > 256 /2 - if((width>256) || (height>256)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 4: //only > 256 /2, >=1024 /4 - if((width>1024) || (height>1024)) { - width /= 4; - height /= 4; - bound->shrink = 2; - } else if((width>256) || (height>256)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 5: //every > 256 is downscaled to 256, but not for empty texture - break; - case 6: //only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture - break; - case 7: //only > 512 /2, but not for empty texture - break; - case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 - case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway) - case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway) - if((width>4096) || (height>4096)) { - width /= 4; - height /= 4; - bound->shrink = 2; - } else if((width>2048) || (height>2048)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - } - } + width = nlevel(width, bound->shrink); + height = nlevel(height, bound->shrink); } } @@ -1203,6 +1110,7 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { tex->type = GL_UNSIGNED_BYTE; tex->orig_internal = GL_RGBA; tex->internalformat = GL_RGBA; + tex->shrink = 0; tex->data = NULL; } else { tex = kh_value(list, k); @@ -1436,6 +1344,7 @@ void gl4es_glGenTextures(GLsizei n, GLuint * textures) { tex->min_filter = tex->mag_filter = GL_NEAREST; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; + tex->shrink = 0; tex->data = NULL; } else { tex = kh_value(list, k); @@ -1463,36 +1372,36 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL switch (pname) { case GL_TEXTURE_WIDTH: if (target==GL_PROXY_TEXTURE_2D) - (*params) = proxy_width>>level; + (*params) = nlevel(proxy_width,level); else - (*params) = ((bound)?bound->width:2048)>>level; - if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { + (*params) = nlevel((bound)?bound->width:2048,level); + /*if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { if (*params<4) // minimum size of a compressed block is 4 *params = 0; } else { if (*params<=0) // 1 is the minimum, not 0 *params = 1; - } + }*/ break; case GL_TEXTURE_HEIGHT: if (target==GL_PROXY_TEXTURE_2D) - (*params) = proxy_height>>level; + (*params) = nlevel(proxy_height,level); else - (*params) = ((bound)?bound->height:2048)>>level; - if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { + (*params) = nlevel((bound)?bound->height:2048,level); + /*if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { if (*params<4) // minimum size of a compressed block is 4 *params = 0; } else { if (*params<=0) // 1 is the minimum, not 0, but only on uncompressed textures *params = 1; - } + }*/ break; case GL_TEXTURE_INTERNAL_FORMAT: if (target==GL_PROXY_TEXTURE_2D) (*params) = proxy_intformat; else { if (bound && bound->compressed) - (*params) = bound->format; + (*params) = bound->internalformat; else { if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { if(bound->orig_internal==GL_COMPRESSED_RGB) @@ -1535,9 +1444,9 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { - int w = bound->width>>level; - int h = bound->height>>level; - w = ((w>>2)+1) << 2; h = ((h>>2)+1) << 2; //DXT works on 4x4 blocks... + int w = nlevel((bound->width>>level),2); //DXT works on 4x4 blocks... + int h = nlevel((bound->height>>level),2); + w<<=2; h<<=2; if (bound->orig_internal==GL_COMPRESSED_RGB) //DXT1, 64bits (i.e. size=8) for a 4x4 block (*params) = (w*h)/2; else //DXT5, 64+64 (i.e. size = 16) for a 4x4 block @@ -1545,9 +1454,25 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL } else (*params) = (bound)?(bound->width*bound->height*4):0; break; + case GL_TEXTURE_BORDER: + (*params) = 0; + break; + case GL_TEXTURE_INTENSITY_SIZE: + if(bound) + (*params) = 32; // is it correct ? GLES doesn't store Intensity... Shall I return 0 instead? Or fake it and return 8? + else + (*params) = 0; + break; + case GL_TEXTURE_LUMINANCE_SIZE: + if(bound) + (*params) = (bound->orig_internal==GL_LUMINANCE || bound->orig_internal==GL_LUMINANCE_ALPHA)?8:0; + else + (*params) = 0; + break; + break; default: errorShim(GL_INVALID_ENUM); //Wrong here... - printf("Stubbed glGetTexLevelParameteriv(%04x, %i, %04x, %p)\n", target, level, pname, params); + printf("Stubbed glGetTexLevelParameteriv(%s, %i, %s, %p)\n", PrintEnum(target), level, PrintEnum(pname), params); } } @@ -1582,8 +1507,8 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, pixel_halfscale(tmp, &tmp2, width, height, format, type); free(tmp); tmp = tmp2; - if(width>1) width>>=1; - if(height>1) height>>=1; + width = nlevel(width, 1); + height = nlevel(height, 1); } memcpy(img, tmp, width*height*pixel_sizeof(format, type)); free(tmp); @@ -2038,12 +1963,6 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor if (internalformat==GL_RGBA8) internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; // test if internalformat is not a compressed one - if (level != 0) { - noerrorShim(); - //TODO - //printf("STUBBED glCompressedTexImage2D with level=%i\n", level); - //return; - } if ((width<=0) || (height<=0)) { noerrorShim(); return; // nothing to do... @@ -2089,19 +2008,29 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor // automaticaly reduce the pixel size half=pixels; bound->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; - format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; - type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; - 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 { + if(globals4es.nodownsampling==1) { format = GL_RGBA; type = GL_UNSIGNED_BYTE; + } else { + format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; +#ifdef PANDORA + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4; +#else + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; +#endif + 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 { + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } } bound->format = format; //internalformat; bound->type = type; bound->compressed = true; + bound->internalformat = internalformat; } else { fact = 0; } @@ -2109,7 +2038,10 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor gl4es_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign); if (oldalign!=1) gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - gl4es_glTexImage2D(target, level, format, width>>fact, height>>fact, border, format, type, half); + gl4es_glTexImage2D(target, level, format==GL_RGBA?GL_COMPRESSED_RGBA:GL_COMPRESSED_RGB, nlevel(width,fact), nlevel(height,fact), border, format, type, half); + // re-update bounded texture info + bound->compressed = true; + bound->internalformat = internalformat; if (oldalign!=1) gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign); if (half!=pixels) @@ -2120,6 +2052,7 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor bound->alpha = true; bound->format = internalformat; bound->type = GL_UNSIGNED_BYTE; + bound->internalformat = internalformat; bound->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } @@ -2210,10 +2143,10 @@ void gl4es_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { return; if(bound->orig_internal!=GL_COMPRESSED_RGB && bound->orig_internal!=GL_COMPRESSED_RGBA) return; - int width = bound->width>>lod; - int height = bound->height>>lod; - int w = ((width>>2)+1)<<2; - int h = ((height>>2)+1)<<2; + int width = nlevel(bound->width,lod); + int height = nlevel(bound->height,lod); + int w = nlevel(width,2); w<<=2; + int h = nlevel(height,2); h<<=2; int alpha = (bound->orig_internal==GL_COMPRESSED_RGBA)?1:0; diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c index 9a1e95eea..17ee72938 100755 --- a/project/jni/gl4es/src/glx/glx.c +++ b/project/jni/gl4es/src/glx/glx.c @@ -388,34 +388,58 @@ void glx_init() { #endif } -#ifndef ANDROID +#ifndef ANDROID +static XVisualInfo *latest_visual = NULL; +static GLXFBConfig latest_glxfbconfig = NULL; + GLXContext gl4es_glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, Bool isDirect) { - DBG(printf("glXCreateContext(%p, %p, %p, %i)\n", display, visual, shareList, isDirect);) + DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p\n", display, visual, shareList, isDirect, latest_visual);) + + static struct __GLXFBConfigRec default_glxfbconfig; + GLXFBConfig glxfbconfig; + + if(visual==latest_visual) + glxfbconfig = latest_glxfbconfig; + else { + glxfbconfig = &default_glxfbconfig; + memset(glxfbconfig, 0, sizeof(struct __GLXFBConfigRec)); + default_glxfbconfig.redBits = (visual==0)?0:(visual->depth==16)?5:8; + default_glxfbconfig.greenBits = (visual==0)?0:(visual->depth==16)?6:8; + default_glxfbconfig.blueBits = (visual==0)?0:(visual->depth==16)?5:8; + default_glxfbconfig.alphaBits = (visual==0)?0:(visual->depth!=32)?0:8; + default_glxfbconfig.depthBits = 16; + default_glxfbconfig.stencilBits = 8; + } + EGLint configAttribs[] = { #ifdef PANDORA EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, #else - EGL_RED_SIZE, (visual==0)?0:(visual->depth==16)?5:8, - EGL_GREEN_SIZE, (visual==0)?0:(visual->depth==16)?6:8, - EGL_BLUE_SIZE, (visual==0)?0:(visual->depth==16)?5:8, - EGL_ALPHA_SIZE, (visual==0)?0:(visual->depth!=32)?0:8, + EGL_RED_SIZE, glxfbconfig->redBits, + EGL_GREEN_SIZE, glxfbconfig->greenBits, + EGL_BLUE_SIZE, glxfbconfig->blueBits, + EGL_ALPHA_SIZE, glxfbconfig->alphaBits, #endif EGL_DEPTH_SIZE, 16, #ifdef USE_ES2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else - EGL_BUFFER_SIZE, (visual==0)?16:visual->depth, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif + EGL_BUFFER_SIZE, glxfbconfig->depthBits, + EGL_STENCIL_SIZE, glxfbconfig->stencilBits, + + EGL_SAMPLE_BUFFERS, glxfbconfig->nMultiSampleBuffers, + EGL_SAMPLES, glxfbconfig->multiSampleSize, + + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_NONE }; - if (globals4es.usefb && fbcontext_count>0) { // don't create a new context, one FB is enough... fbcontext_count++; @@ -615,12 +639,14 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config #endif EGL_DEPTH_SIZE, config->depthBits, EGL_STENCIL_SIZE, config->stencilBits, + EGL_SAMPLES, config->multiSampleSize, + EGL_SAMPLE_BUFFERS, config->nMultiSampleBuffers, #ifdef USE_ES2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else - EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT), EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif + EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT), EGL_NONE }; @@ -785,6 +811,11 @@ XVisualInfo *gl4es_glXChooseVisual(Display *display, return NULL; } + // create and store the glxConfig that goes with thoses attributes + latest_visual = visual; + int count = 1; + latest_glxfbconfig = gl4es_glXChooseFBConfig(display, screen, attributes, &count)[0]; + return visual; } @@ -1124,6 +1155,7 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen, configs[0]->maxPbufferWidth = configs[0]->maxPbufferHeight = 2048; configs[0]->redBits = configs[0]->greenBits = configs[0]->blueBits = configs[0]->alphaBits = 0; configs[0]->nMultiSampleBuffers = 0; configs[0]->multiSampleSize = 0; + configs[0]->depthBits = 16; configs[0]->stencilBits = 8; if(attrib_list) { int i = 0; while(attrib_list[i]!=0) { @@ -1131,35 +1163,44 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen, case GLX_RED_SIZE: configs[0]->redBits = attrib_list[i++]; if(configs[0]->redBits==GLX_DONT_CARE) configs[0]->redBits = 0; + DBG(printf("FBConfig redBits=%d\n", configs[0]->redBits);) break; case GLX_GREEN_SIZE: configs[0]->greenBits = attrib_list[i++]; if(configs[0]->greenBits==GLX_DONT_CARE) configs[0]->greenBits = 0; + DBG(printf("FBConfig greenBits=%d\n", configs[0]->greenBits);) break; case GLX_BLUE_SIZE: configs[0]->blueBits = attrib_list[i++]; if(configs[0]->blueBits==GLX_DONT_CARE) configs[0]->blueBits = 0; + DBG(printf("FBConfig blueBits=%d\n", configs[0]->blueBits);) break; case GLX_ALPHA_SIZE: configs[0]->alphaBits = attrib_list[i++]; if(configs[0]->alphaBits==GLX_DONT_CARE) configs[0]->alphaBits = 0; + DBG(printf("FBConfig alphaBits=%d\n", configs[0]->alphaBits);) break; case GLX_DEPTH_SIZE: configs[0]->depthBits = attrib_list[i++]; if(configs[0]->depthBits==GLX_DONT_CARE) configs[0]->depthBits = 0; + DBG(printf("FBConfig depthBits=%d\n", configs[0]->depthBits);) break; case GLX_STENCIL_SIZE: configs[0]->stencilBits = attrib_list[i++]; if(configs[0]->stencilBits==GLX_DONT_CARE) configs[0]->stencilBits = 0; + DBG(printf("FBConfig stencilBits=%d\n", configs[0]->stencilBits);) break; case GLX_DRAWABLE_TYPE: configs[0]->drawableType = attrib_list[i++]; + DBG(printf("FBConfig drawableType=%d\n", configs[0]->drawableType);) break; case GLX_SAMPLE_BUFFERS: configs[0]->nMultiSampleBuffers = attrib_list[i++]; + DBG(printf("FBConfig multisampleBuffers=%d\n", configs[0]->nMultiSampleBuffers);) break; case GLX_SAMPLES: configs[0]->multiSampleSize = attrib_list[i++]; + DBG(printf("FBConfig multiSampleSize=%d\n", configs[0]->multiSampleSize);) break; default: ++i; diff --git a/project/jni/gl4es/src/glx/hardext.c b/project/jni/gl4es/src/glx/hardext.c index be6997a9c..177e3b52d 100755 --- a/project/jni/gl4es/src/glx/hardext.c +++ b/project/jni/gl4es/src/glx/hardext.c @@ -128,6 +128,7 @@ void GetHardwareExtensions(int notest) gles_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &hardext.maxtex); gles_glGetIntegerv(GL_MAX_LIGHTS, &hardext.maxlights); if(hardext.maxtex>MAX_TEX) hardext.maxtex=MAX_TEX; // caping, as there are some fixed-sized array... + if(hardext.maxlights>MAX_LIGHT) hardext.maxlights=MAX_LIGHT; // caping lights too SHUT(LOGD("LIBGL: Texture Units: %d, Max lights: %d\n", hardext.maxtex, hardext.maxlights)); #ifndef PANDORA // The IMPLEMENTATION_COLOR_READ is pretty buggy on the Pandora, so disabling it (it's just use to blit PBuffer to Drawable in glx.c) diff --git a/project/jni/gl4es/version.h b/project/jni/gl4es/version.h index d72f1a932..422ec3521 100755 --- a/project/jni/gl4es/version.h +++ b/project/jni/gl4es/version.h @@ -3,6 +3,6 @@ #define MAJOR 0 #define MINOR 9 -#define REVISION 2 +#define REVISION 3 #endif //_GL4ES_VERSION_H \ No newline at end of file