From 21867b6ddcfd885f632a49dfa9c590777045e19f Mon Sep 17 00:00:00 2001 From: lubomyr Date: Wed, 2 Nov 2016 20:21:36 +0200 Subject: [PATCH] glshim updated, added latest changes by ptitSeb --- project/jni/glshim/Android.mk | 6 +- project/jni/glshim/README.md | 14 +- project/jni/glshim/include/android_debug.h | 8 +- .../jni/glshim/{src/util => include}/khash.h | 0 project/jni/glshim/src/config.h | 6 + project/jni/glshim/src/gl/const.h | 5 +- project/jni/glshim/src/gl/debug.c | 1 + project/jni/glshim/src/gl/framebuffers.c | 38 +- project/jni/glshim/src/gl/gl.c | 349 +++---- project/jni/glshim/src/gl/gl.h | 10 +- project/jni/glshim/src/gl/list.c | 109 +- project/jni/glshim/src/gl/list.h | 13 + project/jni/glshim/src/gl/loader.c | 7 +- project/jni/glshim/src/gl/loader.h | 9 +- project/jni/glshim/src/gl/logs.h | 2 + project/jni/glshim/src/gl/pixel.c | 23 +- project/jni/glshim/src/gl/raster.c | 105 +- project/jni/glshim/src/gl/raster.h | 3 - project/jni/glshim/src/gl/render.c | 134 ++- project/jni/glshim/src/gl/stack.c | 122 ++- project/jni/glshim/src/gl/stack.h | 8 +- project/jni/glshim/src/gl/state.h | 20 + project/jni/glshim/src/gl/texgen.c | 170 +++- project/jni/glshim/src/gl/texgen.h | 3 +- project/jni/glshim/src/gl/texture.c | 129 ++- project/jni/glshim/src/gl/texture.h | 9 +- project/jni/glshim/src/glx/glx.c | 946 ++++++++++++++---- project/jni/glshim/src/glx/glx.h | 15 +- project/jni/glshim/src/glx/hardext.c | 147 +++ project/jni/glshim/src/glx/hardext.h | 33 + project/jni/glshim/src/glx/lookup.c | 155 +-- 31 files changed, 1884 insertions(+), 715 deletions(-) mode change 100644 => 100755 project/jni/glshim/include/android_debug.h rename project/jni/glshim/{src/util => include}/khash.h (100%) create mode 100755 project/jni/glshim/src/gl/logs.h create mode 100755 project/jni/glshim/src/glx/hardext.c create mode 100755 project/jni/glshim/src/glx/hardext.h diff --git a/project/jni/glshim/Android.mk b/project/jni/glshim/Android.mk index a69303515..0ef2936e1 100644 --- a/project/jni/glshim/Android.mk +++ b/project/jni/glshim/Android.mk @@ -11,8 +11,7 @@ include $(CLEAR_VARS) LOCAL_MODULE := glshim LOCAL_C_INCLUDES := $(LOCAL_PATH)/include \ - $(LOCAL_PATH)/src/util \ - $(LOCAL_PATH)/src/util/vectorial + $(LOCAL_PATH)/src/util LOCAL_EXPORT_C_INCLUDES := $(LOCAL_C_INCLUDES) -DBCMHOST @@ -43,10 +42,11 @@ LOCAL_SRC_FILES := \ src/gl/wrap/glstub.c \ src/gl/math/eval.c \ src/glx/glx.c \ + src/glx/hardext.c \ src/glx/lookup.c \ src/glx/streaming.c -LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -include include/android_debug.h +LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -fvisibility=hidden -include include/android_debug.h #LOCAL_LDLIBS := -ldl -llog -lEGL diff --git a/project/jni/glshim/README.md b/project/jni/glshim/README.md index e80823e62..837596cf6 100755 --- a/project/jni/glshim/README.md +++ b/project/jni/glshim/README.md @@ -6,13 +6,13 @@ This is a shim providing OpenGL 1.x functionality to OpenGL ES accelerated cards Most function of OpenGL up to 1.5 are supported, with some notable exceptions: * Reading of Depth or Stencil buffer will not work * GL_FEEDBACK mode is not implemented - * OcclusionQuery is not implemented Some know limitations: * GL_SELECT as some limitation in its implementation (for exemple, current Depth buffer or binded texture are not taken into account) * NPOT texture are supported, but not with GL_REPEAT / GL_MIRRORED, only GL_CLAMP will work properly * Framebuffer use FRAMEBUFFER_OES extension (that must be present in the GLES 1.1 stack) * Multiple Color attachment on Framebuffer are not supported + * OcclusionQuery is implemented, but with a 0 bits precision * Probably many other things ---- @@ -65,6 +65,7 @@ Controls the Framebuffer output * 0 : Default, using standard x11 rendering * 1 : Use Framebuffer output (x11 bypassed, only fullscreen) * 2 : Use Framebuffer, but also an intermediary FBO + * 3 : Use PBuffer, allowing x11 rendering even if driver doesn't support it ##### LIBGL_XREFRESH Debug helper in specific cases @@ -194,7 +195,12 @@ Expose NPOT (Non Power of Two) Support * 1 : Expose limited NPOT extension * 2 : Expose GL_ARB_texture_non_power_of_two extension -##### LIBGL_QUERIES +##### LIBGL_GLQUERIES Expose glQueries functions - * 0 : Default, don't expose the function (fake one will be used if called) - * 1 : Expose fake functions (always answer 0) + * 0 : Don't expose the function (fake one will be used if called) + * 1 : Default, expose fake functions (always answer 0) + +##### LIBGL_NOTEST +Initial Hardware test + * 0 : Default, perform intial hardware testing (using a PBuffer) + * 1 : Do not perform test (no extensions tested or used) diff --git a/project/jni/glshim/include/android_debug.h b/project/jni/glshim/include/android_debug.h old mode 100644 new mode 100755 index 17d089092..16b90b5cb --- a/project/jni/glshim/include/android_debug.h +++ b/project/jni/glshim/include/android_debug.h @@ -29,14 +29,14 @@ namespace std *((ostringstream*)this) << v; if( this->str().find('\n') != ::std::string::npos ) { - __android_log_print(ANDROID_LOG_INFO, "glshim", "%s", this->str().c_str()); + __android_log_print(ANDROID_LOG_INFO, "LIBGL", "%s", this->str().c_str()); this->str().clear(); } return *this; } ~android_cout() { - __android_log_print(ANDROID_LOG_INFO, "glshim", "%s", this->str().c_str()); + __android_log_print(ANDROID_LOG_INFO, "LIBGL", "%s", this->str().c_str()); this->str().clear(); } }; @@ -48,7 +48,7 @@ namespace std #endif -#define printf(...) __android_log_print(ANDROID_LOG_INFO, "glshim", __VA_ARGS__) +#define printf(...) __android_log_print(ANDROID_LOG_INFO, "LIBGL", __VA_ARGS__) // Override fprintf(stderr, ...) constructs static inline int __sdl_logged_fprintf(FILE *stream, const char *format, ...) @@ -57,7 +57,7 @@ static inline int __sdl_logged_fprintf(FILE *stream, const char *format, ...) va_list args; va_start(args, format); if( stream == stderr || stream == stdout ) - ret = __android_log_vprint(ANDROID_LOG_INFO, "glshim", format, args); + ret = __android_log_vprint(ANDROID_LOG_INFO, "LIBGL", format, args); else ret = vfprintf(stream, format, args); va_end(args); diff --git a/project/jni/glshim/src/util/khash.h b/project/jni/glshim/include/khash.h similarity index 100% rename from project/jni/glshim/src/util/khash.h rename to project/jni/glshim/include/khash.h diff --git a/project/jni/glshim/src/config.h b/project/jni/glshim/src/config.h index b2a48cf02..bc21dfeff 100755 --- a/project/jni/glshim/src/config.h +++ b/project/jni/glshim/src/config.h @@ -78,6 +78,12 @@ #define skip_glMultiTexCoord4f #define skip_glTexGeni #define skip_glTexGenfv +#define skip_glTexEnvf +#define skip_glTexEnvi +#define skip_glTexEnvfv +#define skip_glTexEnviv +#define skip_glGetTexEnvfv +#define skip_glGetTexEnviv #define skip_glReadPixels #define skip_glCompressedTexImage2D #define skip_glCompressedTexSubImage2D diff --git a/project/jni/glshim/src/gl/const.h b/project/jni/glshim/src/gl/const.h index 09454b675..b3f1414fd 100755 --- a/project/jni/glshim/src/gl/const.h +++ b/project/jni/glshim/src/gl/const.h @@ -59,7 +59,9 @@ #define GL_TEXTURE_GEN_STR 0x8D60 - +// GL_ARB_point_sprite +#define GL_POINT_SPRITE 0x8861 +#define GL_COORD_REPLACE 0x8862 // GL_ARB_texture_rectangle #define GL_TEXTURE_RECTANGLE_ARB 0x84F5 @@ -564,4 +566,5 @@ #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_DEPTH_COMPONENT 0x1902 #define GL_MAX_DRAW_BUFFERS_ARB 0x8824 diff --git a/project/jni/glshim/src/gl/debug.c b/project/jni/glshim/src/gl/debug.c index f64fbd4d0..0ee357e9b 100755 --- a/project/jni/glshim/src/gl/debug.c +++ b/project/jni/glshim/src/gl/debug.c @@ -57,6 +57,7 @@ const char* PrintEnum(GLenum what) { p(GL_COMPRESSED_RGB); p(GL_COMPRESSED_RGBA); // type + p(GL_BYTE); p(GL_UNSIGNED_BYTE); p(GL_UNSIGNED_BYTE_2_3_3_REV); p(GL_UNSIGNED_BYTE_3_3_2); diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index 70d1aa601..f7df11e54 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -1,6 +1,6 @@ #include "framebuffers.h" #include "debug.h" - +#include "../glx/hardext.h" #ifndef ANDROID #include #endif @@ -197,17 +197,17 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text k = kh_get(tex, list, texture); if (k == kh_end(list)){ - printf("*WARNING* texture for FBO not found, name=%u\n", texture); + LOGE("LIBGL: texture for FBO not found, name=%u\n", texture); } else { tex = kh_value(list, k); texture = tex->glname; // check if texture is shrinked... if (tex->shrink) { - printf("LIBGL: unshrinking shrinked texture for FBO\n"); + LOGD("LIBGL: unshrinking shrinked texture for FBO\n"); tex->width *= 2*tex->shrink; tex->height *= 2*tex->shrink; - tex->nwidth = npot(tex->width); - tex->nheight = npot(tex->height); + tex->nwidth = hardext.npot==2?tex->width:npot(tex->width); + tex->nheight = hardext.npot==2?tex->height:npot(tex->height); tex->shrink = 0; gltexture_t *bound = glstate->texture.bound[glstate->texture.active]; GLuint oldtex = (bound)?bound->glname:0; @@ -232,10 +232,9 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text } } - if(attachment==GL_DEPTH_ATTACHMENT) { + if(attachment==GL_DEPTH_ATTACHMENT /*&& hardext.depthtex==0*/) { noerrorShim(); if (level!=0) return; - // glshim doesn't support DEPTH Texture. So instead of ending with an incomplete FBO // let's create a renderbuffer and attach it instead of the (presumably) depth texture GLuint render_depth; // memory leak here... glshim_glGenRenderbuffers(1, &render_depth); @@ -353,14 +352,16 @@ void glshim_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei //printf("glRenderbufferStorage(0x%04X, 0x%04X, %i, %i)\n", target, internalformat, width, height); errorGL(); - width = npot(width); - height = npot(height); + width = hardext.npot==2?width:npot(width); + height = hardext.npot==2?height:npot(height); // check if internal format is GL_DEPTH_STENCIL_EXT + if (internalformat == GL_DEPTH_STENCIL) + internalformat = GL_DEPTH24_STENCIL8; // in that case, create first a STENCIL one then a DEPTH one.... - if ((internalformat == GL_DEPTH_STENCIL) || (internalformat == GL_DEPTH24_STENCIL8)) { + if ((internalformat == GL_DEPTH24_STENCIL8) && (hardext.depthstencil==0)) { khint_t k; int ret; - internalformat = GL_DEPTH_COMPONENT24; + internalformat = (hardext.depth24)?GL_DEPTH_COMPONENT24:GL_DEPTH_COMPONENT16; GLuint old_rb = current_rb; GLuint stencil; if (!depthstencil) { @@ -386,10 +387,13 @@ void glshim_glRenderbufferStorage(GLenum target, GLenum internalformat, GLsizei gles_glRenderbufferStorage(target, GL_STENCIL_INDEX8, width, height); gles_glBindRenderbuffer(GL_RENDERBUFFER, current_rb); } - else if (internalformat == GL_DEPTH_COMPONENT) { // Not much is supported on GLES... + else if (internalformat == GL_DEPTH_COMPONENT) // Not much is supported on GLES... internalformat = GL_DEPTH_COMPONENT16; - } - + else if (internalformat == GL_RGB8 && hardext.rgba8==0) + internalformat = GL_RGB565_OES; + else if (internalformat == GL_RGBA8 && hardext.rgba8==0) + internalformat = GL_RGBA4_OES; + gles_glRenderbufferStorage(target, internalformat, width, height); } @@ -430,7 +434,7 @@ void glshim_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachme LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); // hack to return DEPTH size - if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) { + if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE && hardext.depthtex==0) { noerrorShim(); glshim_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params); if (params) @@ -481,8 +485,8 @@ void createMainFBO(int width, int height) { mainfbo_width = width; mainfbo_height = height; - mainfbo_nwidth = width = npot(width); - mainfbo_nheight = height = npot(height); + mainfbo_nwidth = width = hardext.npot==2?width:npot(width); + mainfbo_nheight = height = hardext.npot==2?width:npot(height); // create the texture gles_glGenTextures(1, &mainfbo_tex); diff --git a/project/jni/glshim/src/gl/gl.c b/project/jni/glshim/src/gl/gl.c index 56f69c1c9..d8e44d729 100755 --- a/project/jni/glshim/src/gl/gl.c +++ b/project/jni/glshim/src/gl/gl.c @@ -1,5 +1,6 @@ #include "gl.h" #include "debug.h" +#include "../glx/hardext.h" /* glstate_t state = {.color = {1.0f, 1.0f, 1.0f, 1.0f}, .secondary = {0.0f, 0.0f, 0.0f, 0.0f}, @@ -88,6 +89,13 @@ void* NewGLState(void* shared_glstate) { glstate->gl_batch = gl_batch; + //raster & viewport + glstate->raster.raster_zoomx=1.0f; + glstate->raster.raster_zoomy=1.0f; + for(int i=0; i<4; i++) + glstate->raster.raster_scale[i] = 1.0f; + LOAD_GLES(glGetFloatv); + gles_glGetFloatv(GL_VIEWPORT, (GLfloat*)&glstate->raster.viewport); return (void*)glstate; } @@ -161,48 +169,56 @@ void DeleteGLState(void* oldstate) { 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; + glstate = (new_glstate)?(glstate_t*)new_glstate:default_glstate; + // check if viewport is correct + if(glstate->raster.viewport.width==0.0f || glstate->raster.viewport.height==0.0f) { + LOAD_GLES(glGetFloatv); + gles_glGetFloatv(GL_VIEWPORT, (GLfloat*)&glstate->raster.viewport); + } if (gl_batch && glstate->init_batch==0) init_batch(); - } +void scan_env(); __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"); + if(!glshim_nobanner) LOGD("LIBGL: Initialising glshim\n"); // init read hack char *env_readhack = getenv("LIBGL_READHACK"); if (env_readhack && strcmp(env_readhack, "1") == 0) { readhack = 1; - printf("LIBGL: glReadPixel Hack (for other-life, 1x1 reading multiple time)\n"); + LOGD("LIBGL: glReadPixel Hack (for other-life, 1x1 reading multiple time)\n"); } if (env_readhack && strcmp(env_readhack, "2") == 0) { readhack = 2; - printf("LIBGL: glReadPixel Depth Hack (for games that read GLDepth always at the same place, same 1x1 size)\n"); + LOGD("LIBGL: glReadPixel Depth Hack (for games that read GLDepth always at the same place, same 1x1 size)\n"); } char *env_batch = getenv("LIBGL_BATCH"); if (env_batch && strcmp(env_batch, "1") == 0) { gl_batch = 1; - printf("LIBGL: Batch mode enabled\n"); + LOGD("LIBGL: Batch mode enabled\n"); } if (env_batch && strcmp(env_batch, "0") == 0) { gl_batch = 0; - printf("LIBGL: Batch mode disabled\n"); + LOGD("LIBGL: Batch mode disabled\n"); } if (env_batch && strcmp(env_batch, "2") == 0) { gl_batch = 0; gl_mergelist = 0; - printf("LIBGL: Batch mode disabled, merging of list disabled too\n"); + LOGD("LIBGL: Batch mode disabled, merging of list disabled too\n"); } default_glstate = (glstate_t*)NewGLState(NULL); ActivateGLState(default_glstate); initialized = 1; +#ifdef ANDROID + scan_env(); +#endif } // config functions @@ -216,6 +232,7 @@ const GLubyte *glshim_glGetString(GLenum name) { strcpy(extensions, "GL_EXT_abgr " "GL_EXT_packed_pixels " + "GL_EXT_compiled_vertex_array " "GL_ARB_vertex_buffer_object " "GL_ARB_vertex_array_object " "GL_ARB_vertex_buffer " @@ -241,31 +258,42 @@ const GLubyte *glshim_glGetString(GLenum name) { "GL_EXT_texture_compression_dxt3 " "GL_EXT_texture_compression_dxt5 " "GL_EXT_texture_compression_dxt1 " - "GL_ARB_framebuffer_object " - "GL_EXT_framebuffer_object " - "GL_EXT_packed_depth_stencil " "GL_ARB_point_parameters " "GL_EXT_point_parameters " "GL_EXT_stencil_wrap " "SGIS_texture_edge_clamp " "GL_EXT_texture_edge_clamp " -#ifndef ODROID - "GL_EXT_blend_subtract " - "GL_EXT_blend_func_separate " - "GL_EXT_blend_equation_separate " -#endif - "GL_ARB_draw_buffers " "GL_EXT_direct_state_access " "GL_EXT_multi_draw_arrays " "GL_SUN_multi_draw_arrays " + "GL_ARB_multisample " + "GL_EXT_texture_object " + "GL_EXT_polygon_offset " // "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 "); + if(hardext.blendcolor) + strcat(extensions, "GL_EXT_blend_color "); + if(hardext.blendminmax) + strcat(extensions, "GL_EXT_blend_minmax "); + if(hardext.blendeq) + strcat(extensions, "GL_EXT_blend_equation_separate "); + if(hardext.blendfunc) + strcat(extensions, "GL_EXT_blend_func_separate "); + if(hardext.blendsub) + strcat(extensions, "GL_EXT_blend_subtract "); + if(hardext.fbo) + strcat(extensions, + "GL_ARB_framebuffer_object " + "GL_EXT_framebuffer_object " + "GL_EXT_packed_depth_stencil " + "GL_ARB_draw_buffers "); + if(hardext.pointsprite) + strcat(extensions, "GL_ARB_point_sprite "); } switch (name) { case GL_VERSION: @@ -295,10 +323,6 @@ void transposeMatrix(float *matrix) } // glGet -extern float raster_zoomx, raster_zoomy; -extern GLfloat raster_scale[4]; -extern GLfloat raster_bias[4]; - void glshim_glGetIntegerv(GLenum pname, GLint *params) { if (params==NULL) { errorShim(GL_INVALID_OPERATION); @@ -356,6 +380,28 @@ void glshim_glGetIntegerv(GLenum pname, GLint *params) { //Fake, *TODO* ? *params = 0; break; + case GL_ZOOM_X: + *params = glstate->raster.raster_zoomx; + break; + case GL_ZOOM_Y: + *params = glstate->raster.raster_zoomy; + break; + case GL_RED_SCALE: + *params = glstate->raster.raster_scale[0]; + break; + case GL_RED_BIAS: + *params = glstate->raster.raster_bias[0]; + break; + case GL_GREEN_SCALE: + case GL_BLUE_SCALE: + case GL_ALPHA_SCALE: + *params = glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1]; + break; + case GL_GREEN_BIAS: + case GL_BLUE_BIAS: + case GL_ALPHA_BIAS: + *params = glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1]; + break; case GL_POINT_SIZE_RANGE: gles_glGetIntegerv(GL_POINT_SIZE_MIN, params); gles_glGetIntegerv(GL_POINT_SIZE_MAX, params+1); @@ -466,26 +512,26 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) { *params = glstate->texture.pack_lsb_first; break; case GL_ZOOM_X: - *params = raster_zoomx; + *params = glstate->raster.raster_zoomx; break; case GL_ZOOM_Y: - *params = raster_zoomy; + *params = glstate->raster.raster_zoomy; break; case GL_RED_SCALE: - *params = raster_scale[0]; + *params = glstate->raster.raster_scale[0]; break; case GL_RED_BIAS: - *params = raster_bias[0]; + *params = glstate->raster.raster_bias[0]; break; case GL_GREEN_SCALE: case GL_BLUE_SCALE: case GL_ALPHA_SCALE: - *params = raster_scale[(pname-GL_GREEN_SCALE)/2+1]; + *params = glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1]; break; case GL_GREEN_BIAS: case GL_BLUE_BIAS: case GL_ALPHA_BIAS: - *params = raster_bias[(pname-GL_GREEN_BIAS)/2+1]; + *params = glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1]; break; case GL_POINT_SIZE_RANGE: gles_glGetFloatv(GL_POINT_SIZE_MIN, params); @@ -594,7 +640,11 @@ static void proxy_glEnable(GLenum cap, bool enable, void (*next)(GLenum)) { 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_TEXTURE_GEN_Q, texgen_q[glstate->texture.active]); enable(GL_LINE_STIPPLE, line_stipple); + + // point sprite + proxy_enable(GL_POINT_SPRITE, pointsprite); // Secondary color enable(GL_COLOR_SUM, color_sum); @@ -636,11 +686,9 @@ void glshim_glEnable(GLenum cap) { if (which_cap!=ENABLED_LAST) { if ((glstate->statebatch.enabled[which_cap] == 1)) return; // nothing to do... - if (!glstate->statebatch.enabled[which_cap]) { - glstate->statebatch.enabled[which_cap] = 1; - } else { + if (glstate->statebatch.enabled[which_cap]) flush(); - } + glstate->statebatch.enabled[which_cap] = 1; } } PUSH_IF_COMPILING(glEnable) @@ -662,11 +710,9 @@ void glshim_glDisable(GLenum cap) { if (which_cap!=ENABLED_LAST) { if ((glstate->statebatch.enabled[which_cap] == 2)) return; // nothing to do... - if (!glstate->statebatch.enabled[which_cap]) { - glstate->statebatch.enabled[which_cap] = 2; - } else { + if (glstate->statebatch.enabled[which_cap]) flush(); - } + glstate->statebatch.enabled[which_cap] = 2; } } PUSH_IF_COMPILING(glDisable) @@ -683,12 +729,18 @@ void glshim_glDisable(GLenum cap) { void glDisable(GLenum cap) AliasExport("glshim_glDisable"); void glshim_glEnableClientState(GLenum cap) { + // should flush for now... to be optimized later! + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + flush(); LOAD_GLES(glEnableClientState); proxy_glEnable(cap, true, gles_glEnableClientState); } void glEnableClientState(GLenum cap) AliasExport("glshim_glEnableClientState"); void glshim_glDisableClientState(GLenum cap) { + // should flush for now... to be optimized later! + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + flush(); LOAD_GLES(glDisableClientState); proxy_glEnable(cap, false, gles_glDisableClientState); } @@ -702,7 +754,8 @@ void glDisableClientState(GLenum cap) AliasExport("glshim_glDisableClientState") GLboolean glshim_glIsEnabled(GLenum cap) { // should flush for now... to be optimized later! - if (glstate->gl_batch) flush(); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) + flush(); LOAD_GLES(glIsEnabled); noerrorShim(); switch (cap) { @@ -711,7 +764,9 @@ GLboolean glshim_glIsEnabled(GLenum cap) { 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_Q, texgen_q[glstate->texture.active]); isenabled(GL_COLOR_SUM, color_sum); + isenabled(GL_POINT_SPRITE, pointsprite); 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]); @@ -732,7 +787,7 @@ 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) LOGD("arrary_to_renderlist while compiling list, skip=%d, count=%d\n", skip, count); list->mode = mode; list->mode_init = mode; list->len = count-skip; @@ -750,7 +805,7 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, 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); } @@ -760,22 +815,25 @@ static renderlist_t *arrays_to_renderlist(renderlist_t *list, GLenum mode, 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)) + if (bound && (bound->width!=bound->nwidth || bound->height!=bound->nheight)) + return true; + if ((glstate->enable.texgen_s[aa] || glstate->enable.texgen_t[aa] || glstate->enable.texgen_r[aa] || glstate->enable.texgen_q[aa])) return true; } } - + if(glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) + return true; + if ((glstate->vao->secondary_array) && (glstate->vao->color_array)) + return true; + if (glstate->vao->color_array && (glstate->vao->pointers.color.size != 4)) + 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)) ); @@ -814,9 +872,16 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid 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); - list->indices = (need_free)?sindices:copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); + if(need_free) { + normalize_indices(sindices, &max, &min, count); + list = arrays_to_renderlist(list, mode, min, max + 1); + list->indices = sindices; + } else { + getminmax_indices(sindices, &max, &min, count); + list = arrays_to_renderlist(list, mode, min, max + 1); + list->indices = copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); + if(min) normalize_indices(list->indices, &max, &min, count); + } list->ilen = count; list->indice_cap = count; //end_renderlist(list); @@ -829,9 +894,16 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid renderlist_t *list = NULL; GLsizei min, max; - normalize_indices(sindices, &max, &min, count); - list = arrays_to_renderlist(list, mode, min, max + 1); - list->indices = (need_free)?sindices:copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); + if(need_free) { + normalize_indices(sindices, &max, &min, count); + list = arrays_to_renderlist(list, mode, min, max + 1); + list->indices = sindices; + } else { + getminmax_indices(sindices, &max, &min, count); + list = arrays_to_renderlist(list, mode, min, max + 1); + list->indices = copy_gl_array(sindices, type, 1, 0, GL_UNSIGNED_SHORT, 1, 0, count); + if(min) normalize_indices(list->indices, &max, &min, count); + } list->ilen = count; list->indice_cap = count; list = end_renderlist(list); @@ -864,8 +936,8 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid GLenum mode_init = mode; - if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) - mode = GL_LINE_LOOP; + /*if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) + mode = GL_LINE_LOOP;*/ if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES) mode = GL_POINTS; @@ -876,27 +948,9 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid 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; + // secondry color and color sizef != 4 are "intercepted" and draw using a list 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); - GLfloat* seconds_colors=(GLfloat*)copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, len); - for (int i=0; ivao->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); - gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); - } else { - 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) + 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) @@ -905,8 +959,7 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid 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; - GLuint cur_tex = old_tex; - #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} + #define TEXTURE(A) glshim_glClientActiveTexture(A+GL_TEXTURE0); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { @@ -920,46 +973,9 @@ void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid } if (glstate->texture.client!=old_tex) TEXTURE(old_tex); - #undef TEXTURE - - if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { - int n, s; - switch (mode_init) { - case GL_TRIANGLES: - n = 3; - s = 3; - break; - case GL_TRIANGLE_STRIP: - n = 3; - s = 1; - break; - case GL_TRIANGLE_FAN: // wrong here... - n = count; - s = count; - break; - case GL_QUADS: - n = 4; - s = 4; - break; - case GL_QUAD_STRIP: - n = 4; - s = 1; - break; - default: // Polygon and other? - n = count; - s = count; - break; - } - for (int i=n; ienable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { TEXTURE(aa); @@ -1016,8 +1032,8 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { return; } - if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) - mode = GL_LINE_LOOP; + /*if (glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) + mode = GL_LINE_LOOP;*/ if (glstate->polygon_mode == GL_POINT && mode>=GL_TRIANGLES) mode = GL_POINTS; @@ -1028,8 +1044,6 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { draw_renderlist(list); free_renderlist(list); } else { - // TODO: some draw states require us to use the full pipeline here - // like texgen, stipple, npot LOAD_GLES(glDrawArrays); GLenum mode_init = mode; @@ -1042,27 +1056,8 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { 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); - 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))) { - // 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); - gles_glColorPointer(4, GL_UNSIGNED_BYTE, 0, final_colors); - } else { - 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) + client_state(color_array, GL_COLOR_ARRAY, ); + 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) @@ -1071,8 +1066,7 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { 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; - GLuint cur_tex = old_tex; - #define TEXTURE(A) if (cur_tex!=A) {glshim_glClientActiveTexture(A+GL_TEXTURE0); cur_tex=A;} + #define TEXTURE(A) glshim_glClientActiveTexture(A+GL_TEXTURE0); for (int aa=0; aaenable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { @@ -1088,53 +1082,18 @@ void glshim_glDrawArrays(GLenum mode, GLint first, GLsizei count) { } if (glstate->texture.client!=old_tex) TEXTURE(old_tex); - #undef TEXTURE - if (glstate->polygon_mode == GL_LINE && mode_init>=GL_TRIANGLES) { - int n, s; - switch (mode_init) { - case GL_TRIANGLES: - n = 3; - s = 3; - break; - case GL_TRIANGLE_STRIP: - n = 3; - s = 1; - break; - case GL_TRIANGLE_FAN: // wrong here... - n = count; - s = count; - break; - case GL_QUADS: - n = 4; - s = 4; - break; - case GL_QUAD_STRIP: - n = 4; - s = 1; - break; - default: // Polygon and other? - n = count; - s = count; - break; - } - for (int i=n; ienable.texture_2d[aa] && (glstate->enable.texture_1d[aa] || glstate->enable.texture_3d[aa])) { - glshim_glClientActiveTexture(aa+GL_TEXTURE0); + TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); } } if (glstate->texture.client!=old_tex) - glshim_glClientActiveTexture(old_tex+GL_TEXTURE0); + TEXTURE(old_tex); + #undef TEXTURE } } } @@ -1292,7 +1251,7 @@ 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->.. for (int a=0; aenable.texture_2d[a] && ((glstate->list.active->tex[a]==0) && (!glstate->enable.texgen_s[a]))) + if (glstate->enable.texture_2d[a] && ((glstate->list.active->tex[a]==0) && !(glstate->enable.texgen_s[a] || glstate->texture.pscoordreplace[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)) { @@ -1757,7 +1716,7 @@ void glshim_glPushMatrix() { default: //Warning? errorShim(GL_INVALID_OPERATION); - //printf("LIBGL: PushMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode); + //LOGE("LIBGL: PushMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode); //gles_glPushMatrix(); } } @@ -1804,7 +1763,7 @@ void glshim_glPopMatrix() { default: //Warning? errorShim(GL_INVALID_OPERATION); - //printf("LIBGL: PopMatrix withUnrecognise matrix mode (0x%04X)\n", matrix_mode); + //LOGE("LIBGL: PopMatrix with Unrecognise matrix mode (0x%04X)\n", matrix_mode); //gles_glPopMatrix(); } } @@ -1831,7 +1790,7 @@ void glshim_glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf a else { static int test = 1; if (test) { - printf("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha); + LOGD("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha); test = 0; } } @@ -1954,7 +1913,6 @@ void init_statebatch() { 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; if (mylist) { GLuint old = glstate->gl_batch; @@ -1965,7 +1923,7 @@ void flush() { free_renderlist(mylist); glstate->gl_batch = old; } - if (glstate->gl_batch) init_statebatch(); + init_statebatch(); glstate->list.active = (glstate->gl_batch)?alloc_renderlist():NULL; } @@ -1975,7 +1933,9 @@ void init_batch() { glstate->gl_batch = 1; glstate->init_batch = 1; } - +#ifndef ANDROID +extern void BlitEmulatedPixmap(); +#endif void glshim_glFlush() { LOAD_GLES(glFlush); @@ -1988,6 +1948,11 @@ void glshim_glFlush() { gles_glFlush(); errorGL(); + +#ifndef ANDROID + if(glstate->emulatedPixmap && !glstate->emulatedWin) + BlitEmulatedPixmap(); +#endif } void glFlush() AliasExport("glshim_glFlush"); @@ -2050,7 +2015,7 @@ void glFogfv(GLenum pname, const GLfloat* params) AliasExport("glshim_glFogfv"); void glshim_glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) { static bool warning = false; if(!warning) { - printf("Warning, stubbed glIndexPointer\n"); + LOGD("Warning, stubbed glIndexPointer\n"); warning = true; } } @@ -2059,7 +2024,7 @@ void glIndexPointer(GLenum type, GLsizei stride, const GLvoid * pointer) AliasEx void glshim_glEdgeFlagPointer(GLsizei stride, const GLvoid * pointer) { static bool warning = false; if(!warning) { - printf("Warning, stubbed glEdgeFlagPointer\n"); + LOGD("Warning, stubbed glEdgeFlagPointer\n"); warning = true; } } @@ -2117,7 +2082,7 @@ 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); + LOAD_GLES_EXT(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)) ) { @@ -2138,7 +2103,7 @@ 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); + LOAD_GLES_EXT(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) ) { diff --git a/project/jni/glshim/src/gl/gl.h b/project/jni/glshim/src/gl/gl.h index 0de82cce6..080aadbf4 100755 --- a/project/jni/glshim/src/gl/gl.h +++ b/project/jni/glshim/src/gl/gl.h @@ -12,6 +12,7 @@ #include #include #include "khash.h" +#include "logs.h" #ifdef __ARM_NEON__ #include @@ -235,10 +236,11 @@ static const GLsizei gl_sizeof(GLenum type) { case GL_UNSIGNED_BYTE: case GL_UNSIGNED_BYTE_2_3_3_REV: case GL_UNSIGNED_BYTE_3_3_2: + case GL_DEPTH_COMPONENT: return 1; } // formats - printf("libGL: Unsupported pixel data type: %s\n", PrintEnum(type)); + LOGD("LIBGL: Unsupported pixel data type: %s\n", PrintEnum(type)); return 0; } @@ -256,7 +258,7 @@ static const GLuint gl_max_value(GLenum type) { case GL_INT: return 2147483647; case GL_UNSIGNED_INT: return 4294967295; } - printf("libGL: unknown gl max value type: %s\n", PrintEnum(type)); + LOGD("LIBGL: unknown gl max value type: %s\n", PrintEnum(type)); return 0; } @@ -288,6 +290,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) { case GL_RED: case GL_ALPHA: case GL_LUMINANCE: + case GL_DEPTH_COMPONENT: width = 1; break; case GL_RG: @@ -305,7 +308,7 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) { width = 4; break; default: - printf("libGL: unsupported pixel format %s\n", PrintEnum(format)); + LOGD("LIBGL: unsupported pixel format %s\n", PrintEnum(format)); return 0; } @@ -329,6 +332,7 @@ static const GLboolean pixel_hasalpha(GLenum format) { case GL_RGB: case GL_BGR: case GL_RGB8: + case GL_DEPTH_COMPONENT: return false; default: return true; diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index d480b72f0..8f0b942ac 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -1,6 +1,7 @@ #include "gl.h" #include "list.h" #include "debug.h" +#include "../glx/hardext.h" #define alloc_sublist(n, cap) \ (GLfloat *)malloc(n * sizeof(GLfloat) * cap) @@ -43,12 +44,10 @@ bool ispurerender_renderlist(renderlist_t *list) { return false; if (list->popattribute) return false; - if (list->material || list->light || list->lightmodel || list->texgen) + if (list->material || list->light || list->lightmodel || list->texgen || list->texenv) return false; if (list->fog_op) return false; - if (list->texgen) - return false; if (list->mode_init == 0) return false; if (list->set_texture || list->set_tmu) @@ -115,7 +114,7 @@ bool islistscompatible_renderlist(renderlist_t *a, renderlist_t *b) { if ((a->secondary==NULL) != (b->secondary==NULL)) return false; // check the textures - for (int i=0; itex[i]==NULL) != (b->tex[i]==NULL)) return false; if ((a->set_texture==b->set_texture) && ((a->texture != b->texture) || (a->target_texture != b->target_texture))) @@ -292,7 +291,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { a->secondary = alloc_sublist(4, cap); memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat)); } - for (int i=0; itex[i]; if (tmp) { a->tex[i] = alloc_sublist(4, cap); @@ -306,7 +305,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { realloc_sublist(a->normal, 3, cap); realloc_sublist(a->color, 4, cap); realloc_sublist(a->secondary, 4, cap); - for (int i=0; itex[i], 4, cap); } } @@ -326,7 +325,7 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { if (a->normal) memcpy(a->normal+a->len*3, b->normal, b->len*3*sizeof(GLfloat)); if (a->color) memcpy(a->color+a->len*4, b->color, b->len*4*sizeof(GLfloat)); if (a->secondary) memcpy(a->secondary+a->len*4, b->secondary, b->len*4*sizeof(GLfloat)); - for (int i=0; itex[i]) memcpy(a->tex[i]+a->len*4, b->tex[i], b->len*4*sizeof(GLfloat)); // indices if (ilen_a + ilen_b) @@ -507,7 +506,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) 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; } @@ -559,6 +558,7 @@ renderlist_t* append_calllist(renderlist_t *list, renderlist_t *a) 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)); + PROCESS(texenv, rendertexenv_t, m->pname | ((m->target)<<16)); #undef PROCESS if (list->lightmodel) { list->lightmodel = (GLfloat*)malloc(4*sizeof(GLfloat)); @@ -609,7 +609,7 @@ void free_renderlist(renderlist_t *list) { 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) { @@ -639,6 +639,13 @@ void free_renderlist(renderlist_t *list) { ) kh_destroy(texgen, list->texgen); } + if (list->texenv) { + rendertexenv_t *m; + kh_foreach_value(list->texenv, m, + free(m); + ) + kh_destroy(texenv, list->texenv); + } if (list->lightmodel) free(list->lightmodel); @@ -660,7 +667,7 @@ void resize_renderlist(renderlist_t *list) { realloc_sublist(list->normal, 3, list->cap); realloc_sublist(list->color, 4, list->cap); realloc_sublist(list->secondary, 4, list->cap); - for (int a=0; atex[a], 4, list->cap); } } @@ -671,7 +678,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)) @@ -829,6 +836,14 @@ void draw_renderlist(renderlist_t *list) { glshim_glLightModelfv(list->lightmodelparam, list->lightmodel); } + if (list->texenv) { + khash_t(texenv) *tgn = list->texenv; + rendertexenv_t *m; + kh_foreach_value(tgn, m, + glshim_glTexEnvfv(m->target, m->pname, m->params); + ) + } + if (list->texgen) { khash_t(texgen) *tgn = list->texgen; rendertexgen_t *m; @@ -910,23 +925,25 @@ void draw_renderlist(renderlist_t *list) { } GLfloat *texgened[MAX_TEX]; GLint needclean[MAX_TEX]; - for (int a=0; aenable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a])) { + if ((glstate->enable.texgen_s[a] || glstate->enable.texgen_t[a] || glstate->enable.texgen_r[a] || glstate->enable.texgen_q[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) && !(list->mode==GL_POINT && glstate->texture.pscoordreplace[a])) { 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; 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]*/) { TEXTURE(a); - gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glstate->clientstate.tex_coord_array[a] = 1; + if(!glstate->clientstate.tex_coord_array[a]) { + gles_glEnableClientState(GL_TEXTURE_COORD_ARRAY); + 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]) { @@ -1137,7 +1154,7 @@ 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; asecondary, sizeof(GLfloat) * 4); } - for (int a=0; atex[a]) { GLfloat * const tex = list->tex[a] + (list->len * 4); memcpy(tex, glstate->texcoord[a], sizeof(GLfloat) * 4); @@ -1415,5 +1432,59 @@ renderlist_t* GetFirst(renderlist_t* list) { return list; } +void rlTexEnvfv(renderlist_t *list, GLenum target, GLenum pname, const GLfloat * params) { + int n = 1; + switch(target) { + case GL_POINT_SPRITE: n = 1; break; + default: + switch(pname) { + case GL_TEXTURE_ENV_MODE: n=4; break; + case GL_TEXTURE_ENV_COLOR: n=4; break; + case GL_TEXTURE_LOD_BIAS: n=4; break; + } + } + rendertexenv_t *m; + khash_t(texenv) *map; + khint_t k; + int ret; + if (! list->texenv) { + list->texenv = map = kh_init(texenv); + // segfaults if we don't do a single put + kh_put(texenv, map, 1, &ret); + kh_del(texenv, map, 1); + } else { + map = list->texenv; + } + + int key = pname | ((target)<<16); + k = kh_get(texenv, map, key); + if (k == kh_end(map)) { + k = kh_put(texenv, map, key, &ret); + m = kh_value(map, k) = malloc(sizeof(rendertexenv_t)); + } else { + m = kh_value(map, k); + } + + m->target = target; + m->pname = pname; + memcpy(m->params, params, n*sizeof(GLfloat)); +} +void rlTexEnviv(renderlist_t *list, GLenum target, GLenum pname, const GLint * params) { + GLfloat fparams[4]; + int n = 1; + switch(target) { + case GL_POINT_SPRITE: n = 1; break; + default: + switch(pname) { + case GL_TEXTURE_ENV_MODE: n=4; break; + case GL_TEXTURE_ENV_COLOR: n=4; break; + case GL_TEXTURE_LOD_BIAS: n=4; break; + } + } + for (int i=0; i void *gles = NULL, *egl = NULL, *bcm_host = NULL, *vcos = NULL; @@ -47,10 +48,10 @@ void *open_lib(const char **names, const char *override) { if (override) { if ((lib = dlopen(override, flags))) { strncpy(path_name, override, PATH_MAX); - printf("libGL:loaded: %s\n", path_name); + LOGD("LIBGL:loaded: %s\n", path_name); return lib; } else { - printf("LIBGL_GLES override failed: %s\n", dlerror()); + LOGE("LIBGL_GLES override failed: %s\n", dlerror()); } } for (int p = 0; path_prefix[p]; p++) { @@ -58,7 +59,7 @@ void *open_lib(const char **names, const char *override) { for (int e = 0; lib_ext[e]; e++) { snprintf(path_name, PATH_MAX, "%s%s.%s", path_prefix[p], names[i], lib_ext[e]); if ((lib = dlopen(path_name, flags))) { - printf("libGL:loaded: %s\n", path_name); + LOGD("LIBGL:loaded: %s\n", path_name); return lib; } } diff --git a/project/jni/glshim/src/gl/loader.h b/project/jni/glshim/src/gl/loader.h index a0a6d7d20..40cc4b6cf 100755 --- a/project/jni/glshim/src/gl/loader.h +++ b/project/jni/glshim/src/gl/loader.h @@ -15,7 +15,7 @@ extern void *open_lib(const char **names, const char *override); extern void load_libs(); #ifndef WARN_NULL -#define WARN_NULL(name) if (name == NULL) printf("libGL: warning, " #name " is NULL\n"); +#define WARN_NULL(name) if (name == NULL) LOGD("libGL: warning, " #name " is NULL\n"); #endif #ifndef LOAD_RAW @@ -52,4 +52,11 @@ extern void load_libs(); LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"OES")); \ } +#define LOAD_GLES_EXT(name) \ + DEFINE_RAW(gles, name); \ + { \ + LOAD_EGL(eglGetProcAddress); \ + LOAD_RAW(gles, name, egl_eglGetProcAddress(#name"EXT")); \ + } + #endif diff --git a/project/jni/glshim/src/gl/logs.h b/project/jni/glshim/src/gl/logs.h new file mode 100755 index 000000000..48bbfe8ff --- /dev/null +++ b/project/jni/glshim/src/gl/logs.h @@ -0,0 +1,2 @@ +#define LOGD(...) printf(__VA_ARGS__) +#define LOGE(...) fprintf(stderr, __VA_ARGS__) diff --git a/project/jni/glshim/src/gl/pixel.c b/project/jni/glshim/src/gl/pixel.c index 8ea82e08e..1c2fead8a 100755 --- a/project/jni/glshim/src/gl/pixel.c +++ b/project/jni/glshim/src/gl/pixel.c @@ -17,6 +17,7 @@ static const colorlayout_t *get_color_map(GLenum format) { map(GL_LUMINANCE_ALPHA, 0, 0, 0, 1); map(GL_LUMINANCE, 0, 0, 0, -1); map(GL_ALPHA,-1, -1, -1, 0); + map(GL_DEPTH_COMPONENT, 0, -1, -1, -1); default: printf("LIBGL: unknown pixel format %s\n", PrintEnum(format)); break; @@ -676,7 +677,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, dst_color = get_color_map(dst_format); if (!dst_size || !pixel_sizeof(src_format, src_type) || !src_color->type || !dst_color->type) { - printf("pixel conversion, anticipated abort\n"); + LOGE("LIBGL: pixel conversion, anticipated abort\n"); return false; } @@ -699,7 +700,10 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, uintptr_t src_pos = (uintptr_t)src; uintptr_t dst_pos = (uintptr_t)*dst; // fast optimized loop for common conversion cases first... - if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { + // TODO: Rewrite that with some Macro, it's obviously doable to simplify the reading (and writting) of all this + // simple BGRA <-> RGBA / UNSIGNED_BYTE + if ((((src_format == GL_BGRA) && (dst_format == GL_RGBA)) || ((src_format == GL_RGBA) && (dst_format == GL_BGRA))) + && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -713,6 +717,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGRA1555 -> RGBA5551 if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && (src_type == GL_UNSIGNED_SHORT_1_5_5_5_REV)) { GLuint tmp; unsigned short *wtexmemp = NULL, wtexmem; @@ -730,6 +735,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGBA -> LA if ((src_format == GL_RGBA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { @@ -745,6 +751,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGRA -> LA if ((src_format == GL_BGRA) && (dst_format == GL_LUMINANCE_ALPHA) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { @@ -760,6 +767,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGB(A) -> L if (((src_format == GL_RGBA)||(src_format == GL_RGB)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { @@ -775,6 +783,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGR(A) -> L if (((src_format == GL_BGRA)||(src_format == GL_BGR)) && (dst_format == GL_LUMINANCE) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { GLuint tmp; for (int i = 0; i < height; i++) { @@ -790,6 +799,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGR(A) -> RGB if (((src_format == GL_BGR)||(src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -804,6 +814,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGBA -> RGB if ((src_format == GL_RGBA) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_BYTE) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -818,6 +829,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGB(A) -> RGB565 if (((src_format == GL_RGB)||(src_format == GL_RGBA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -830,6 +842,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGR(A) -> RGB565 if (((src_format == GL_BGR) || (src_format == GL_BGRA)) && (dst_format == GL_RGB) && (dst_type == GL_UNSIGNED_SHORT_5_6_5) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -842,6 +855,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGBA -> RGBA5551 if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -854,6 +868,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGRA -> RGBA5551 if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_5_5_5_1) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -866,6 +881,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGBA -> RGBA4444 if ((src_format == GL_RGBA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -878,6 +894,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGRA -> RGBA4444 if ((src_format == GL_BGRA) && (dst_format == GL_RGBA) && (dst_type == GL_UNSIGNED_SHORT_4_4_4_4) && ((src_type == GL_UNSIGNED_BYTE)||(src_type == GL_UNSIGNED_INT_8_8_8_8_REV))) { for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { @@ -890,6 +907,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // BGRA4444 -> RGBA 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++) { @@ -906,6 +924,7 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + // RGBA5551 -> RGBA 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++) { diff --git a/project/jni/glshim/src/gl/raster.c b/project/jni/glshim/src/gl/raster.c index 02184ce0d..fed2cfc2c 100755 --- a/project/jni/glshim/src/gl/raster.c +++ b/project/jni/glshim/src/gl/raster.c @@ -1,11 +1,7 @@ #include "raster.h" #include "debug.h" -static rasterpos_t rPos = {0, 0, 0}; -static viewport_t viewport = {0, 0, 0, 0}; static GLubyte *raster = NULL; -GLfloat raster_zoomx=1.0f; -GLfloat raster_zoomy=1.0f; static GLuint raster_texture=0; static GLsizei raster_width=0; static GLsizei raster_height=0; @@ -15,10 +11,8 @@ static GLsizei raster_realheight=0; static GLint raster_x1, raster_x2, raster_y1, raster_y2; #define min(a, b) ((a)(b))?(a):(b) -GLfloat raster_scale[4] = {1.0f, 1.0f, 1.0f, 1.0f}; -GLfloat raster_bias[4] = {0.0f, 0.0f, 0.0f, 0.0f}; -void matrix_column_row(const GLfloat *a, GLfloat *b); +void matrix_transpose(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) { @@ -28,28 +22,21 @@ void glshim_glRasterPos3f(GLfloat x, GLfloat y, GLfloat z) { noerrorShim(); return; } - #if 1 // Transform xyz coordinates with current modelview and projection matrix... GLfloat glmatrix[16], projection[16], modelview[16]; GLfloat t[4], transl[4] = {x, y, z, 1.0f}; glshim_glGetFloatv(GL_PROJECTION_MATRIX, glmatrix); - matrix_column_row(glmatrix, projection); + matrix_transpose(glmatrix, projection); glshim_glGetFloatv(GL_MODELVIEW_MATRIX, glmatrix); - matrix_column_row(glmatrix, modelview); + matrix_transpose(glmatrix, modelview); matrix_vector(modelview, transl, t); matrix_vector(projection, t, transl); GLfloat w2, h2; - w2=viewport.width/2.0f; - h2=viewport.height/2.0f; - rPos.x = transl[0]*w2+w2; - rPos.y = transl[1]*h2+h2; - rPos.z = transl[2]; - - #else - rPos.x = x; - rPos.y = y; - rPos.z = z; - #endif + w2=glstate->raster.viewport.width/2.0f; + h2=glstate->raster.viewport.height/2.0f; + glstate->raster.rPos.x = transl[0]*w2+w2; + glstate->raster.rPos.y = transl[1]*h2+h2; + glstate->raster.rPos.z = transl[2]; } void glshim_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) { @@ -59,19 +46,21 @@ void glshim_glWindowPos3f(GLfloat x, GLfloat y, GLfloat z) { noerrorShim(); return; } - rPos.x = x; - rPos.y = y; - rPos.z = z; + glstate->raster.rPos.x = x; + glstate->raster.rPos.y = y; + glstate->raster.rPos.z = z; } void glshim_glViewport(GLint x, GLint y, GLsizei width, GLsizei height) { PUSH_IF_COMPILING(glViewport); LOAD_GLES(glViewport); - gles_glViewport(x, y, width, height); - viewport.x = x; - viewport.y = y; - viewport.width = width; - viewport.height = height; + if(glstate->raster.viewport.x!=x || glstate->raster.viewport.y!=y || glstate->raster.viewport.width!=width || glstate->raster.viewport.height!=height) { + gles_glViewport(x, y, width, height); + glstate->raster.viewport.x = x; + glstate->raster.viewport.y = y; + glstate->raster.viewport.width = width; + glstate->raster.viewport.height = height; + } } // hacky viewport temporary changes @@ -81,7 +70,7 @@ void pushViewport(GLint x, GLint y, GLsizei width, GLsizei height) { } void popViewport() { LOAD_GLES(glViewport); - gles_glViewport(viewport.x, viewport.y, viewport.width, viewport.height); + gles_glViewport(glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height); } @@ -92,8 +81,8 @@ void glshim_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { noerrorShim(); return; } - raster_zoomx = xfactor; - raster_zoomy = yfactor; + glstate->raster.raster_zoomx = xfactor; + glstate->raster.raster_zoomy = yfactor; //printf("LIBGL: glPixelZoom(%f, %f)\n", xfactor, yfactor); } @@ -107,20 +96,20 @@ void glshim_glPixelTransferf(GLenum pname, GLfloat param) { //printf("LIBGL: glPixelTransferf(%04x, %f)\n", pname, param); switch(pname) { case GL_RED_SCALE: - raster_scale[0]=param; + glstate->raster.raster_scale[0]=param; break; case GL_RED_BIAS: - raster_bias[0]=param; + glstate->raster.raster_bias[0]=param; break; case GL_GREEN_SCALE: case GL_BLUE_SCALE: case GL_ALPHA_SCALE: - raster_scale[(pname-GL_GREEN_SCALE)/2+1]=param; + glstate->raster.raster_scale[(pname-GL_GREEN_SCALE)/2+1]=param; break; case GL_GREEN_BIAS: case GL_BLUE_BIAS: case GL_ALPHA_BIAS: - raster_bias[(pname-GL_GREEN_BIAS)/2+1]=param; + glstate->raster.raster_bias[(pname-GL_GREEN_BIAS)/2+1]=param; break; /*default: printf("LIBGL: stubbed glPixelTransferf(%04x, %f)\n", pname, param);*/ @@ -154,21 +143,21 @@ void init_raster(int width, int height) { GLubyte raster_transform(GLubyte pix, GLubyte number) { GLfloat a = (GLfloat)pix*(1.0f/255.0f); - a=a*raster_scale[number]+raster_bias[number]; + a=a*glstate->raster.raster_scale[number]+glstate->raster.raster_bias[number]; if (a<0.0) a=0.0; if (a>1.0) a=1.0; return (GLubyte)(a*255.0f); } GLfloat FASTMATH raster_transformf(GLfloat pix, GLubyte number) { - pix=pix*raster_scale[number]+raster_bias[number]; + pix=pix*glstate->raster.raster_scale[number]+glstate->raster.raster_bias[number]; if (pix<0.0) pix=0.0; if (pix>1.0) pix=1.0; return pix; } int raster_need_transform() { - for (int i=0; i<4; i++) if (raster_scale[i]!=1.0f) return 1; - for (int i=0; i<4; i++) if (raster_bias[i]!=0.0f) return 1; + for (int i=0; i<4; i++) if (glstate->raster.raster_scale[i]!=1.0f) return 1; + for (int i=0; i<4; i++) if (glstate->raster.raster_bias[i]!=0.0f) return 1; return 0; } @@ -234,7 +223,7 @@ GLuint raster_to_texture() void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap) { /*printf("glBitmap, xy={%f, %f}, xyorig={%f, %f}, size={%u, %u}, zoom={%f, %f}, viewport={%i, %i, %i, %i}\n", - rPos.x, rPos.y, xorig, yorig, width, height, raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ + glstate->raster.rPos.x, glstate->raster.rPos.y, xorig, yorig, width, height, glstate->raster.raster_zoomx, glstate->raster.raster_zoomy, glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);*/ // TODO: shouldn't be drawn if the raster pos is outside the viewport? // TODO: negative width/height mirrors bitmap? noerrorShim(); @@ -254,8 +243,8 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig r->ymove = ymove; } else { - rPos.x += xmove; - rPos.y += ymove; + glstate->raster.rPos.x += xmove; + glstate->raster.rPos.y += ymove; } return; } @@ -314,8 +303,8 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig r->width = width; r->height = height; r->bitmap = true; - r->zoomx = raster_zoomx; - r->zoomy = raster_zoomy; + r->zoomx = glstate->raster.raster_zoomx; + r->zoomy = glstate->raster.raster_zoomy; LOAD_GLES(glDeleteTextures); if (!(glstate->list.compiling || glstate->gl_batch)) { render_raster_list(r); @@ -333,7 +322,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, noerrorShim(); /*printf("glDrawPixels, xy={%f, %f}, size={%i, %i}, format=%s, type=%s, zoom={%f, %f}, viewport={%i, %i, %i, %i}\n", - rPos.x, rPos.y, width, height, PrintEnum(format), PrintEnum(type), raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ + glstate->raster.rPos.x, glstate->raster.rPos.y, width, height, PrintEnum(format), PrintEnum(type), glstate->raster.raster_zoomx, glstate->raster.raster_zoomy, glstate->raster.viewport.x, glstate->raster.viewport.y, glstate->raster.viewport.width, glstate->raster.viewport.height);*/ // check of unsuported format... if ((format == GL_STENCIL_INDEX) || (format == GL_DEPTH_COMPONENT)) { errorShim(GL_INVALID_ENUM); @@ -399,8 +388,8 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, r->width = width; r->height = height; r->bitmap = false; - r->zoomx = raster_zoomx; - r->zoomy = raster_zoomy; + r->zoomx = glstate->raster.raster_zoomx; + r->zoomy = glstate->raster.raster_zoomy; if (!(glstate->list.compiling || glstate->gl_batch)) { render_raster_list(r); /* gles_glDeleteTextures(1, &r->texture); @@ -409,7 +398,7 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, } void render_raster_list(rasterlist_t* rast) { -//printf("render_raster_list, rast->x/y=%f/%f rast->width/height=%i/%i, rPos.x/y/z=%f/%f/%f, rast->zoomxy=%f/%f raster->texture=%u\n", rast->xorig, rast->yorig, rast->width, rast->height, rPos.x, rPos.y, rPos.z, rast->zoomx, rast->zoomy, rast->texture); +//printf("render_raster_list, rast->x/y=%f/%f rast->width/height=%i/%i, rPos.x/y/z=%f/%f/%f, rast->zoomxy=%f/%f raster->texture=%u\n", rast->xorig, rast->yorig, rast->width, rast->height, glstate->raster.rPos.x, glstate->raster.rPos.y, glstate->raster.rPos.z, rast->zoomx, rast->zoomy, rast->texture); #ifdef USE_DRAWTEX LOAD_GLES_OES(glDrawTexf); LOAD_GLES(glEnable); @@ -444,7 +433,7 @@ void render_raster_list(rasterlist_t* rast) { glshim_glColor4f(1.0f, 1.0f, 1.0f, 1.0f); } - gles_glDrawTexf(rPos.x-rast->xorig, rPos.y-rast->yorig, rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy); + gles_glDrawTexf(glstate->raster.rPos.x-rast->xorig, glstate->raster.rPos.y-rast->yorig, glstate->raster.rPos.z, rast->width * rast->zoomx, rast->height * rast->zoomy); 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); @@ -465,12 +454,12 @@ void render_raster_list(rasterlist_t* rast) { glshim_glLoadIdentity(); glshim_glMatrixMode(GL_MODELVIEW); glshim_glLoadIdentity(); - float w2 = 2.0f / viewport.width; - float h2 = 2.0f / viewport.height; - float raster_x1=rPos.x-rast->xorig; - float raster_x2=rPos.x-rast->xorig + rast->width * rast->zoomx ; - float raster_y1=rPos.y-rast->yorig; - float raster_y2=rPos.y-rast->yorig + rast->height * rast->zoomy ; + float w2 = 2.0f / glstate->raster.viewport.width; + float h2 = 2.0f / glstate->raster.viewport.height; + float raster_x1=glstate->raster.rPos.x-rast->xorig; + float raster_x2=glstate->raster.rPos.x-rast->xorig + rast->width * rast->zoomx ; + float raster_y1=glstate->raster.rPos.y-rast->yorig; + float raster_y2=glstate->raster.rPos.y-rast->yorig + rast->height * rast->zoomy ; GLfloat rast_vert[] = { raster_x1*w2-1.0f, raster_y1*h2-1.0f, raster_x2*w2-1.0f, raster_y1*h2-1.0f, @@ -547,8 +536,8 @@ void render_raster_list(rasterlist_t* rast) { #endif glshim_glPopAttrib(); } - rPos.x += rast->xmove; - rPos.y += rast->ymove; + glstate->raster.rPos.x += rast->xmove; + glstate->raster.rPos.y += rast->ymove; } //Direct wrapper diff --git a/project/jni/glshim/src/gl/raster.h b/project/jni/glshim/src/gl/raster.h index f594652d5..b038744b0 100755 --- a/project/jni/glshim/src/gl/raster.h +++ b/project/jni/glshim/src/gl/raster.h @@ -22,9 +22,6 @@ typedef struct { GLsizei height; } viewport_t; -extern GLfloat raster_scale[4]; -extern GLfloat raster_bias[4]; - int raster_need_transform(); void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, diff --git a/project/jni/glshim/src/gl/render.c b/project/jni/glshim/src/gl/render.c index 275032fe2..fb40319de 100755 --- a/project/jni/glshim/src/gl/render.c +++ b/project/jni/glshim/src/gl/render.c @@ -4,8 +4,11 @@ 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? + //Normalize zmin/zmax + if((glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall)!=0.0f) { + glstate->selectbuf.zmin = (glstate->selectbuf.zmin-glstate->selectbuf.zminoverall)/(glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall); + glstate->selectbuf.zmax = (glstate->selectbuf.zmax-glstate->selectbuf.zminoverall)/(glstate->selectbuf.zmaxoverall - glstate->selectbuf.zminoverall); + } int tocopy = glstate->namestack.top + 3; if (tocopy+glstate->selectbuf.pos > glstate->selectbuf.size) { glstate->selectbuf.overflow = 1; @@ -25,8 +28,10 @@ void push_hit() { } glstate->selectbuf.hit = 0; } - glstate->selectbuf.zmin = 1.0f; - glstate->selectbuf.zmax = 0.0f; + glstate->selectbuf.zmin = 1e10f; + glstate->selectbuf.zmax = -1e10f; + glstate->selectbuf.zminoverall = 1e10f; + glstate->selectbuf.zmaxoverall = -1e10f; } @@ -50,8 +55,10 @@ GLint glshim_glRenderMode(GLenum mode) { glstate->selectbuf.count = 0; glstate->selectbuf.pos = 0; glstate->selectbuf.overflow = 0; - glstate->selectbuf.zmin = 1.0f; - glstate->selectbuf.zmax = 0.0f; + glstate->selectbuf.zmin = 1e10f; + glstate->selectbuf.zmax = -1e10f; + glstate->selectbuf.zminoverall = 1e10f; + glstate->selectbuf.zmaxoverall = -1e10f; glstate->selectbuf.hit = 0; } @@ -124,9 +131,9 @@ void init_select() { */ GLfloat tmp[16]; glshim_glGetFloatv(GL_PROJECTION_MATRIX, tmp); - matrix_column_row(tmp, projection); + matrix_transpose(tmp, projection); glshim_glGetFloatv(GL_MODELVIEW_MATRIX, tmp); - matrix_column_row(tmp, modelview); + matrix_transpose(tmp, modelview); } void select_transform(GLfloat *a) { @@ -218,6 +225,12 @@ GLboolean select_triangle_in_viewscreen(const GLfloat *a, const GLfloat *b, cons return false; } +static void FASTMATH ZMinMax(GLfloat *zmin, GLfloat *zmax, GLfloat *vtx) { + if (vtx[2]<*zmin) *zmin=vtx[2]; + if (vtx[2]>*zmax) *zmax=vtx[2]; +} + + void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLuint count) { if (count == 0) return; if (vtx->pointer == NULL) return; @@ -225,59 +238,77 @@ void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, GLfloat *vert = copy_gl_array(vtx->pointer, vtx->type, vtx->size, vtx->stride, GL_FLOAT, 4, 0, count+first); - GLfloat zmin=1.0f, zmax=0.0f; + GLfloat zmin=1e10f, zmax=-1e10f; init_select(); + int found = 0; + + #define FOUND() { \ + found = 1; \ + glstate->selectbuf.hit = 1; \ + } - #define FOUND() { \ - if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; \ - if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \ - glstate->selectbuf.hit = 1; \ - free(vert); \ - return; \ - } // transform the points for (int i=first; izmax) zmax=vert[i*4+2]; + ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4); } // intersect with screen now GLfloat *vert2 = vert + first*4; for (int i=0; i0) { - if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) + if (select_segment_in_viewscreen(vert2+(i-1)*4, vert2+i*4)) { + ZMinMax(&zmin, &zmax, vert+(i-1)*4); + ZMinMax(&zmin, &zmax, vert+i*4); FOUND(); + } } break; case GL_TRIANGLES: if (i%3==2) { - if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) + if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) { + ZMinMax(&zmin, &zmax, vert+(i-2)*4); + ZMinMax(&zmin, &zmax, vert+(i-1)*4); + ZMinMax(&zmin, &zmax, vert+i*4); FOUND(); + } } break; case GL_TRIANGLE_STRIP: if (i>1) { - if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) + if (select_triangle_in_viewscreen(vert2+(i-2)*4, vert2+(i-1)*4, vert2+i*4)) { + ZMinMax(&zmin, &zmax, vert+(i-2)*4); + ZMinMax(&zmin, &zmax, vert+(i-1)*4); + ZMinMax(&zmin, &zmax, vert+i*4); FOUND(); + } } break; case GL_TRIANGLE_FAN: if (i>1) { - if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4)) + if (select_triangle_in_viewscreen(vert2, vert2+(i-1)*4, vert2+i*4)) { + ZMinMax(&zmin, &zmax, vert); + ZMinMax(&zmin, &zmax, vert+(i-1)*4); + ZMinMax(&zmin, &zmax, vert+i*4); FOUND(); + } } break; default: @@ -285,6 +316,10 @@ void select_glDrawArrays(const pointer_state_t* vtx, GLenum mode, GLuint first, } } free(vert); + if(found) { + if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; + if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; + } #undef FOUND } @@ -301,57 +336,71 @@ void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count vtx->size, vtx->stride, GL_FLOAT, 4, 0, max); init_select(); - GLfloat zmin=1.0f, zmax=0.0f; + GLfloat zmin=1e10f, zmax=-10e6f; + int found = 0; for (int i=min; izmax) zmax=vert[i*4+2]; + select_transform(vert+i*4); + ZMinMax(&glstate->selectbuf.zminoverall, &glstate->selectbuf.zmaxoverall, vert+i*4); } - if (zmin<0.0f) zmin = 0.0f; - if (zmax>1.0f) zmax = 1.0f; - #define FOUND() { \ - if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; \ - if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; \ + #define FOUND() { \ + found = 1; \ glstate->selectbuf.hit = 1; \ - free(vert); \ - return; \ } for (int i=0; i0) { - if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) + if (select_segment_in_viewscreen(vert+ind[(i-1)]*4, vert+ind[i]*4)) { + ZMinMax(&zmin, &zmax, vert+ind[i-1]*4); + ZMinMax(&zmin, &zmax, vert+ind[i]*4); FOUND(); + } } break; case GL_TRIANGLES: if (i%3==2) { - if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) + if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) { + ZMinMax(&zmin, &zmax, vert+ind[i-2]*4); + ZMinMax(&zmin, &zmax, vert+ind[i-1]*4); + ZMinMax(&zmin, &zmax, vert+ind[i]*4); FOUND(); + } } break; case GL_TRIANGLE_STRIP: if (i>1) { - if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) + if (select_triangle_in_viewscreen(vert+ind[(i-2)]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) { + ZMinMax(&zmin, &zmax, vert+ind[i-2]*4); + ZMinMax(&zmin, &zmax, vert+ind[i-1]*4); + ZMinMax(&zmin, &zmax, vert+ind[i]*4); FOUND(); + } } break; case GL_TRIANGLE_FAN: if (i>1) { if (select_triangle_in_viewscreen(vert+ind[0]*4, vert+ind[(i-1)]*4, vert+ind[i]*4)) + ZMinMax(&zmin, &zmax, vert+ind[0]*4); + ZMinMax(&zmin, &zmax, vert+ind[i-1]*4); + ZMinMax(&zmin, &zmax, vert+ind[i]*4); FOUND(); } break; @@ -360,6 +409,11 @@ void select_glDrawElements(const pointer_state_t* vtx, GLenum mode, GLuint count } } free(vert); + if(found) { + if (zminselectbuf.zmin) glstate->selectbuf.zmin=zmin; + if (zmax>glstate->selectbuf.zmax) glstate->selectbuf.zmax=zmax; + } + #undef FOUND } diff --git a/project/jni/glshim/src/gl/stack.c b/project/jni/glshim/src/gl/stack.c index bd559c68b..b16dd714f 100755 --- a/project/jni/glshim/src/gl/stack.c +++ b/project/jni/glshim/src/gl/stack.c @@ -1,4 +1,5 @@ #include "stack.h" +#include "../glx/hardext.h" void glshim_glPushAttrib(GLbitfield mask) { //printf("glPushAttrib(0x%04X)\n", mask); @@ -23,6 +24,7 @@ void glshim_glPushAttrib(GLbitfield mask) { cur->clip_planes = NULL; cur->lights_enabled = NULL; cur->lights = NULL; + cur->materials = NULL; // TODO: GL_ACCUM_BUFFER_BIT @@ -77,10 +79,8 @@ void glshim_glPushAttrib(GLbitfield mask) { cur->dither = glshim_glIsEnabled(GL_DITHER); cur->fog = glshim_glIsEnabled(GL_FOG); - GLint max_lights; - glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights); - cur->lights_enabled = (GLboolean *)malloc(max_lights * sizeof(GLboolean)); - for (i = 0; i < max_lights; i++) { + cur->lights_enabled = (GLboolean *)malloc(hardext.maxlights * sizeof(GLboolean)); + for (i = 0; i < hardext.maxlights; i++) { *(cur->lights_enabled + i) = glshim_glIsEnabled(GL_LIGHT0 + i); } @@ -105,15 +105,16 @@ void glshim_glPushAttrib(GLbitfield mask) { cur->scissor_test = glshim_glIsEnabled(GL_SCISSOR_TEST); 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->texgen_q[a] = glstate->enable.texgen_q[a]; } - + cur->pointsprite = glshim_glIsEnabled(GL_POINT_SPRITE); } // TODO: GL_EVAL_BIT @@ -137,20 +138,33 @@ void glshim_glPushAttrib(GLbitfield mask) { if (mask & GL_LIGHTING_BIT) { cur->lighting = glshim_glIsEnabled(GL_LIGHTING); - glshim_glGetIntegerv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient); + glshim_glGetFloatv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient); glshim_glGetIntegerv(GL_LIGHT_MODEL_TWO_SIDE, &cur->light_model_two_side); int i; - GLint max_lights; - glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights); - cur->lights_enabled = (GLboolean *)malloc(max_lights * sizeof(GLboolean)); - cur->lights = (GLfloat *)malloc(max_lights * sizeof(GLfloat)); - for (i = 0; i < max_lights; i++) { + int j=0; + cur->lights_enabled = (GLboolean *)malloc(hardext.maxlights * sizeof(GLboolean)); + cur->lights = (GLfloat *)malloc(hardext.maxlights * sizeof(GLfloat)*(10*4)); + for (i = 0; i < hardext.maxlights; i++) { *(cur->lights_enabled + i) = glshim_glIsEnabled(GL_LIGHT0 + i); - /* TODO: record all data about the lights - glGetFloatv(GL_LIGHT0 + i, cur->lights + i); - */ + #define L(A) glshim_glGetLightfv(GL_LIGHT0 + i, A, cur->lights+j); j+=4 + L(GL_AMBIENT); + L(GL_DIFFUSE); + L(GL_SPECULAR); + L(GL_POSITION); + L(GL_SPOT_CUTOFF); + L(GL_SPOT_DIRECTION); + L(GL_SPOT_EXPONENT); + L(GL_CONSTANT_ATTENUATION); + L(GL_LINEAR_ATTENUATION); + L(GL_QUADRATIC_ATTENUATION); + #undef L } + j=0; + cur->materials = (GLfloat *)malloc(1 * sizeof(GLfloat)*(5*4)); + #define M(A) glshim_glGetMaterialfv(GL_FRONT, A, cur->materials+j); j+=4 + M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point? + #undef M glshim_glGetIntegerv(GL_SHADE_MODEL, &cur->shade_model); } @@ -188,6 +202,13 @@ void glshim_glPushAttrib(GLbitfield mask) { if (mask & GL_POINT_BIT) { cur->point_smooth = glshim_glIsEnabled(GL_POINT_SMOOTH); glshim_glGetFloatv(GL_POINT_SIZE, &cur->point_size); + if(hardext.pointsprite) { + cur->pointsprite = glshim_glIsEnabled(GL_POINT_SPRITE); + int a; + for (a=0; apscoordreplace[a] = glstate->texture.pscoordreplace[a]; + } + } } // TODO: GL_POLYGON_BIT @@ -219,10 +240,11 @@ void glshim_glPushAttrib(GLbitfield mask) { if (mask & GL_TEXTURE_BIT) { 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_q[a] = glstate->enable.texgen_q[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; } @@ -289,7 +311,7 @@ void glshim_glPushClientAttrib(GLbitfield mask) { 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]; } memcpy(&(cur->pointers), &glstate->vao->pointers, sizeof(pointer_states_t)); @@ -374,9 +396,7 @@ void glshim_glPopAttrib() { enable_disable(GL_DITHER, cur->dither); enable_disable(GL_FOG, cur->fog); - GLint max_lights; - glshim_glGetIntegerv(GL_MAX_LIGHTS, &max_lights); - for (i = 0; i < max_lights; i++) { + for (i = 0; i < hardext.maxlights; i++) { enable_disable(GL_LIGHT0 + i, *(cur->lights_enabled + i)); } @@ -400,9 +420,10 @@ void glshim_glPopAttrib() { enable_disable(GL_SAMPLE_COVERAGE, cur->sample_coverage); enable_disable(GL_SCISSOR_TEST, cur->scissor_test); enable_disable(GL_STENCIL_TEST, cur->stencil_test); + enable_disable(GL_POINT_SPRITE, cur->pointsprite); int a; int old_tex = glstate->texture.active; - for (a=0; aenable.texture_1d[a] != cur->texture_1d[a]) { glshim_glActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_1D, cur->texture_1d[a]); @@ -418,6 +439,7 @@ void glshim_glPopAttrib() { 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_q[a] = cur->texgen_q[a]; } if (glstate->texture.active != old_tex) glshim_glActiveTexture(GL_TEXTURE0+old_tex); } @@ -432,12 +454,43 @@ void glshim_glPopAttrib() { } if (cur->mask & GL_HINT_BIT) { - enable_disable(GL_PERSPECTIVE_CORRECTION_HINT, cur->perspective_hint); - enable_disable(GL_POINT_SMOOTH_HINT, cur->point_smooth_hint); - enable_disable(GL_LINE_SMOOTH_HINT, cur->line_smooth_hint); - enable_disable(GL_FOG_HINT, cur->fog_hint); - enable_disable(GL_GENERATE_MIPMAP_HINT, cur->mipmap_hint); + glshim_glHint(GL_PERSPECTIVE_CORRECTION_HINT, cur->perspective_hint); + glshim_glHint(GL_POINT_SMOOTH_HINT, cur->point_smooth_hint); + glshim_glHint(GL_LINE_SMOOTH_HINT, cur->line_smooth_hint); + glshim_glHint(GL_FOG_HINT, cur->fog_hint); + glshim_glHint(GL_GENERATE_MIPMAP_HINT, cur->mipmap_hint); } + + if (cur->mask & GL_LIGHTING_BIT) { + enable_disable(GL_LIGHTING, cur->lighting); + glshim_glLightModelfv(GL_LIGHT_MODEL_AMBIENT, cur->light_model_ambient); + glshim_glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, cur->light_model_two_side); + + int i; + int j=0; + for (i = 0; i < hardext.maxlights; i++) { + enable_disable(GL_LIGHT0 + i, *(cur->lights_enabled + i)); + #define L(A) glshim_glLightfv(GL_LIGHT0 + i, A, cur->lights+j); j+=4 + L(GL_AMBIENT); + L(GL_DIFFUSE); + L(GL_SPECULAR); + L(GL_POSITION); + L(GL_SPOT_CUTOFF); + L(GL_SPOT_DIRECTION); + L(GL_SPOT_EXPONENT); + L(GL_CONSTANT_ATTENUATION); + L(GL_LINEAR_ATTENUATION); + L(GL_QUADRATIC_ATTENUATION); + #undef L + } + j=0; + #define M(A) glshim_glMaterialfv(GL_FRONT_AND_BACK, A, cur->materials+j); j+=4 + M(GL_AMBIENT); M(GL_DIFFUSE); M(GL_SPECULAR); M(GL_EMISSION); M(GL_SHININESS); // handle both face at some point? + #undef M + + glshim_glShadeModel(cur->shade_model); + } + // GL_LIST_BIT if (cur->mask & GL_LIST_BIT) { glshim_glListBase(cur->list_base); @@ -459,6 +512,17 @@ void glshim_glPopAttrib() { if (cur->mask & GL_POINT_BIT) { enable_disable(GL_POINT_SMOOTH, cur->point_smooth); glshim_glPointSize(cur->point_size); + if(hardext.pointsprite) { + enable_disable(GL_POINT_SPRITE, cur->pointsprite); + int a; + for (a=0; atexture.pscoordreplace[a]!=cur->pscoordreplace[a]) { + glshim_glActiveTexture(GL_TEXTURE0+a); + glshim_glTexEnvi(GL_POINT_SPRITE, GL_COORD_REPLACE, cur->pscoordreplace[a]); + } + } + if (glstate->texture.active!= cur->active) glshim_glActiveTexture(GL_TEXTURE0+cur->active); + } } if (cur->mask & GL_SCISSOR_BIT) { @@ -478,10 +542,11 @@ void glshim_glPopAttrib() { if (cur->mask & GL_TEXTURE_BIT) { int a; //TODO: Enable bit for the 4 texture coordinates - for (a=0; aenable.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_q[a] = cur->texgen_q[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); @@ -525,6 +590,7 @@ void glshim_glPopAttrib() { maybe_free(cur->clip_planes); maybe_free(cur->lights_enabled); maybe_free(cur->lights); + maybe_free(cur->materials); glstate->stack->len--; } @@ -571,7 +637,7 @@ void glshim_glPopClientAttrib() { enable_disable(GL_COLOR_ARRAY, cur->color_enable); if (glstate->vao->secondary_array != cur->secondary_enable) enable_disable(GL_SECONDARY_COLOR_ARRAY, cur->secondary_enable); - for (int a=0; avao->tex_coord_array[a] != cur->tex_enable[a]) { glshim_glClientActiveTexture(GL_TEXTURE0+a); enable_disable(GL_TEXTURE_COORD_ARRAY, cur->tex_enable[a]); diff --git a/project/jni/glshim/src/gl/stack.h b/project/jni/glshim/src/gl/stack.h index 810888374..9ac7ab179 100755 --- a/project/jni/glshim/src/gl/stack.h +++ b/project/jni/glshim/src/gl/stack.h @@ -20,6 +20,10 @@ typedef struct _glstack_t { GLboolean dither; + // point sprite + GLboolean pointsprite; + GLint pscoordreplace[MAX_TEX]; + GLboolean color_logic_op; GLint logic_op; @@ -56,6 +60,7 @@ typedef struct _glstack_t { GLboolean texgen_s[MAX_TEX]; GLboolean texgen_r[MAX_TEX]; GLboolean texgen_t[MAX_TEX]; + GLboolean texgen_q[MAX_TEX]; GLboolean colormaterial; GLboolean autonormal; @@ -78,8 +83,9 @@ typedef struct _glstack_t { GLboolean lighting; GLboolean *lights_enabled; GLfloat *lights; - GLint light_model_ambient[4]; + GLfloat light_model_ambient[4]; GLint light_model_two_side; + GLfloat *materials; GLint shade_model; // GL_LINE_BIT diff --git a/project/jni/glshim/src/gl/state.h b/project/jni/glshim/src/gl/state.h index caaadedcd..b658b5b5d 100755 --- a/project/jni/glshim/src/gl/state.h +++ b/project/jni/glshim/src/gl/state.h @@ -16,9 +16,11 @@ typedef struct { auto_normal, blend, color_sum, + pointsprite, texgen_s[MAX_TEX], texgen_t[MAX_TEX], texgen_r[MAX_TEX], + texgen_q[MAX_TEX], texture_2d[MAX_TEX], texture_3d[MAX_TEX], texture_1d[MAX_TEX]; @@ -29,12 +31,15 @@ typedef struct { GLenum S; GLenum T; GLenum R; + GLenum Q; GLfloat S_E[4]; // Eye Plane GLfloat T_E[4]; GLfloat R_E[4]; + GLfloat Q_E[4]; GLfloat S_O[4]; // Object Plane GLfloat T_O[4]; GLfloat R_O[4]; + GLfloat Q_O[4]; } texgen_state_t; typedef struct { @@ -52,6 +57,7 @@ typedef struct { // TODO: do we only need to worry about GL_TEXTURE_2D? GLboolean rect_arb[MAX_TEX]; gltexture_t *bound[MAX_TEX]; + GLboolean pscoordreplace[MAX_TEX]; khash_t(tex) *list; GLuint active; // active texture GLuint client; // client active texture @@ -69,6 +75,15 @@ typedef struct { GLuint cap; } displaylist_state_t; +typedef struct { + rasterpos_t rPos; + viewport_t viewport; + GLfloat raster_scale[4]; + GLfloat raster_bias[4]; + GLfloat raster_zoomx; + GLfloat raster_zoomy; +} raster_state_t; + typedef struct { map_state_t *vertex3, @@ -93,6 +108,8 @@ typedef struct { GLuint size; GLfloat zmin; GLfloat zmax; + GLfloat zminoverall; + GLfloat zmaxoverall; GLuint overflow; GLuint pos; GLboolean hit; @@ -171,6 +188,9 @@ typedef struct { khash_t(queries) *queries; glstack_t *stack; glclientstack_t *clientStack; + raster_state_t raster; + int emulatedPixmap; + int emulatedWin; int shared_cnt; } glstate_t; diff --git a/project/jni/glshim/src/gl/texgen.c b/project/jni/glshim/src/gl/texgen.c index ea351fe89..874db87af 100755 --- a/project/jni/glshim/src/gl/texgen.c +++ b/project/jni/glshim/src/gl/texgen.c @@ -35,6 +35,7 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { 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_Q: glstate->texgen[glstate->texture.active].Q = param[0]; break; default: errorShim(GL_INVALID_ENUM); return; @@ -50,6 +51,9 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { case GL_R: memcpy(glstate->texgen[glstate->texture.active].R_O, param, 4 * sizeof(GLfloat)); break; + case GL_Q: + memcpy(glstate->texgen[glstate->texture.active].Q_O, param, 4 * sizeof(GLfloat)); + break; default: errorShim(GL_INVALID_ENUM); return; @@ -65,6 +69,9 @@ void glshim_glTexGenfv(GLenum coord, GLenum pname, const GLfloat *param) { case GL_R: memcpy(glstate->texgen[glstate->texture.active].R_E, param, 4 * sizeof(GLfloat)); break; + case GL_Q: + memcpy(glstate->texgen[glstate->texture.active].Q_E, param, 4 * sizeof(GLfloat)); + break; default: errorShim(GL_INVALID_ENUM); return; @@ -82,6 +89,7 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { 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_Q: *params = glstate->texgen[glstate->texture.active].Q; break; default: *params = GL_EYE_LINEAR; } break; @@ -96,6 +104,9 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { case GL_R: memcpy(params, glstate->texgen[glstate->texture.active].R_O, 4 * sizeof(GLfloat)); break; + case GL_Q: + memcpy(params, glstate->texgen[glstate->texture.active].Q_O, 4 * sizeof(GLfloat)); + break; default: errorShim(GL_INVALID_ENUM); } @@ -110,6 +121,9 @@ void glshim_glGetTexGenfv(GLenum coord,GLenum pname,GLfloat *params) { case GL_R: memcpy(params, glstate->texgen[glstate->texture.active].R_E, 4 * sizeof(GLfloat)); break; + case GL_Q: + memcpy(params, glstate->texgen[glstate->texture.active].Q_E, 4 * sizeof(GLfloat)); + break; default: errorShim(GL_INVALID_ENUM); } @@ -125,7 +139,22 @@ GLfloat FASTMATH dot(const GLfloat *a, const GLfloat *b) { } GLfloat FASTMATH dot4(const GLfloat *a, const GLfloat *b) { +#ifdef __ARM_NEON__ + register float ret; + asm volatile ( + "vld1.f32 {d0-d1}, [%1] \n" //q0 = a(0..3) + "vld1.f32 {d2-d3}, [%2] \n" //q1 = b(0..3) + "vmul.f32 q0, q0, q1 \n" //q0 = a(0)*b(0),a(1)*b(1),a(2)*b(2),a(3)*b(3) + "vadd.f32 d0, d0, d1 \n" //d0 = a(0)*b(0)+a(2)*b(2),a(1)*b(1)+a(3)*b(3) + "vpadd.f32 d0,d0 \n" //d0 = a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3),a(0)*b(0)+a(2)*b(2)+a(1)*b(1)+a(3)*b(3) + "vmov.f32 %0, s0 \n" + :"=w"(ret): "r"(a), "r"(b) + : "q0", "q1" + ); + return ret; +#else return a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]; +#endif } void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c) { @@ -133,13 +162,13 @@ void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c) { 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" + "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" ); @@ -184,7 +213,10 @@ void vector3_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c) { const float* b3=b+8; const float* b4=b+12; asm volatile ( - "vld1.f32 {q0}, [%1] \n" // %q0 = a(0..3) + //"vld1.f32 {q0}, [%1] \n" // %q0 = a(0..2) + "vld1.32 {d4}, [%1] \n" + "flds s10, [%1, #8] \n" + "vsub.f32 s11, s11, s11 \n" "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) @@ -210,6 +242,7 @@ void vector_normalize(GLfloat *a) { asm volatile ( "vld1.32 {d4}, [%0] \n\t" //d4={x0,y0} "flds s10, [%0, #8] \n\t" //d5[0]={z0} + "vsub.f32 s11, s11, s11 \n\t" "vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4 "vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1] @@ -225,7 +258,7 @@ void vector_normalize(GLfloat *a) { "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough "vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4 - "vst1.32 d4, [%0] \n\t" // + "vst1.32 {d4}, [%0] \n\t" // "fsts s10, [%0, #8] \n\t" // :"+&r"(a): @@ -239,18 +272,58 @@ void vector_normalize(GLfloat *a) { #endif } -void matrix_column_row(const GLfloat *a, GLfloat *b) { +void vector4_normalize(GLfloat *a) { +#ifdef __ARM_NEON__ + asm volatile ( + "vld1.32 {q2}, [%0] \n\t" //q2={x0,y0,z0,00} + + "vmul.f32 d0, d4, d4 \n\t" //d0= d4*d4 + "vpadd.f32 d0, d0 \n\t" //d0 = d[0] + d[1] + "vmla.f32 d0, d5, d5 \n\t" //d0 = d0 + d5*d5 + + "vmov.f32 d1, d0 \n\t" //d1 = d0 + "vrsqrte.f32 d0, d0 \n\t" //d0 = ~ 1.0 / sqrt(d0) + "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 + "vrsqrts.f32 d3, d2, d0 \n\t" //d3 = (3 - d0 * d2) / 2 + "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d3 +/* "vmul.f32 d2, d0, d1 \n\t" //d2 = d0 * d1 + "vrsqrts.f32 d3, d2, d0 \n\t" //d4 = (3 - d0 * d3) / 2 + "vmul.f32 d0, d0, d3 \n\t" //d0 = d0 * d4 */ // 1 iteration should be enough + + "vmul.f32 q2, q2, d0[0] \n\t" //d0= d2*d4 + "vst1.32 {q2}, [%0] \n\t" // + + :"+&r"(a): + : "d0", "d1", "d2", "d3", "d4", "d5", "memory" + ); +#else + float det=1.0f/sqrtf(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]); + a[0]*=det; + a[1]*=det; + a[2]*=det; + // a[3] is ignored and left as 0.0f +#endif +} + +void FASTMATH matrix_transpose(const GLfloat *a, GLfloat *b) { // column major -> row major + // a(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) -> b(0,4,8,12,1,5,9,13,2,6,10,14,3,7,11,15) +#ifdef __ARM_NEON__ + const float* a1 = a+8; + float* b1=b+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) + "vst1.f32 {d0-d3}, [%0] \n" + "vst1.f32 {d4-d7}, [%3] \n" + ::"r"(b), "r"(a), "r"(a1), "r"(b1) + : "q0", "q1", "q2", "q3", "memory" + ); +#else for (int i=0; i<4; i++) for (int j=0; j<4; j++) b[i*4+j]=a[i+j*4]; -} - -void matrix_row_column(const GLfloat *a, GLfloat *b) { - // row major -> column major - for (int i=0; i<4; i++) - for (int j=0; j<4; j++) - b[i+j*4]=a[i*4+j]; +#endif } void matrix_inverse(const GLfloat *m, GLfloat *r) { @@ -318,14 +391,14 @@ void sphere_loop(const GLfloat *verts, const GLfloat *norm, GLfloat *out, GLint for (int i=0; inormal, InvModelview, eye_norm); - vector_normalize(eye_norm); - a=dot(eye, eye_norm)*2.0f; + vector4_normalize(eye_norm); + a=dot4(eye, eye_norm)*2.0f; for (int j=0; j<4; j++) reflect[j]=eye[j]-eye_norm[j]*a; reflect[2]+=1.0f; - a = 1.0f / (2.0f*sqrtf(dot(reflect, reflect))); + a = 0.5f / sqrtf(dot4(reflect, reflect)); out[k*4+0] = reflect[0]*a + 0.5f; out[k*4+1] = reflect[1]*a + 0.5f; out[k*4+2] = 0.0f; @@ -340,7 +413,7 @@ void eye_loop(const GLfloat *verts, const GLfloat *param, GLfloat *out, GLint co GLfloat ModelviewMatrix[16], InvModelview[16]; glGetFloatv(GL_MODELVIEW_MATRIX, InvModelview); // column major -> row major - matrix_column_row(InvModelview, ModelviewMatrix); + matrix_transpose(InvModelview, ModelviewMatrix); // And get the inverse matrix_inverse(ModelviewMatrix, InvModelview); GLfloat plane[4], tmp[4]; @@ -368,22 +441,22 @@ 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):"-"); +//printf("gen_tex_coords(%p, %p, %p, %d, %p, %d, %p, %d) texgen = S:%s T:%s R:%s Q:%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):"-", (glstate->enable.texgen_q[texture])?PrintEnum(glstate->texgen[texture].Q):"-"); // 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 ((*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; + if (!glstate->enable.texgen_s[texture] && !glstate->enable.texgen_t[texture] && !glstate->enable.texgen_r[texture] && !glstate->enable.texgen_q[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))) @@ -446,14 +519,23 @@ void gen_tex_coords(GLfloat *verts, GLfloat *norm, GLfloat **coords, GLint count 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); + 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; - (*coords)[k*4+3] = 1.0f; - } + 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_r[texture]) + tex_coord_loop(verts, norm, (*coords)+2, (indices)?ilen:count, glstate->texgen[texture].R, glstate->texgen[texture].R_O, glstate->texgen[texture].R_E, indices); + else + for (int i=0; i<((indices)?ilen:count); i++) { + GLushort k = indices?indices[i]:i; + (*coords)[k*4+2] = 0.0f; + } + if (glstate->enable.texgen_q[texture]) + tex_coord_loop(verts, norm, (*coords)+3, (indices)?ilen:count, glstate->texgen[texture].Q, glstate->texgen[texture].Q_O, glstate->texgen[texture].Q_E, indices); + else + for (int i=0; i<((indices)?ilen:count); i++) { + GLushort k = indices?indices[i]:i; + (*coords)[k*4+3] = 1.0f; + } } void gen_tex_clean(GLint cleancode, int texture) { @@ -469,7 +551,7 @@ void gen_tex_clean(GLint cleancode, int texture) { void glshim_glLoadTransposeMatrixf(const GLfloat *m) { GLfloat mf[16]; - matrix_row_column(m, mf); + matrix_transpose(m, mf); glshim_glLoadMatrixf(mf); errorGL(); } @@ -489,7 +571,7 @@ void glshim_glMultTransposeMatrixd(const GLdouble *m) { } void glshim_glMultTransposeMatrixf(const GLfloat *m) { GLfloat mf[16]; - matrix_row_column(m, mf); + matrix_transpose(m, mf); glshim_glMultMatrixf(mf); errorGL(); } diff --git a/project/jni/glshim/src/gl/texgen.h b/project/jni/glshim/src/gl/texgen.h index ccc0ef490..7929e925d 100755 --- a/project/jni/glshim/src/gl/texgen.h +++ b/project/jni/glshim/src/gl/texgen.h @@ -11,8 +11,7 @@ GLfloat dot(const GLfloat *a, const GLfloat *b); void matrix_vector(const GLfloat *a, const GLfloat *b, GLfloat *c); void vector_matrix(const GLfloat *a, const GLfloat *b, GLfloat *c); void vector_normalize(GLfloat *a); -void matrix_column_row(const GLfloat *a, GLfloat *b); -void matrix_row_column(const GLfloat *a, GLfloat *b); +void matrix_transpose(const GLfloat *a, GLfloat *b); void matrix_inverse(const GLfloat *m, GLfloat *r); void matrix_mul(const GLfloat *a, const GLfloat *b, GLfloat *c); diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index 052310b7c..0ca8799db 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -7,6 +7,7 @@ #include #include "gles.h" #include "../glx/streaming.h" +#include "../glx/hardext.h" #ifndef GL_TEXTURE_STREAM_IMG #define GL_TEXTURE_STREAM_IMG 0x8C0D @@ -151,6 +152,9 @@ void internal2format_type(GLenum internalformat, GLenum *format, GLenum *type) *format = GL_RGBA; *type = GL_UNSIGNED_BYTE; break; + case GL_DEPTH_COMPONENT: + *format = GL_DEPTH_COMPONENT; + *type = GL_UNSIGNED_SHORT; default: printf("LIBGL: Warning, unknown Internalformat (%s)\n", PrintEnum(internalformat)); *format = GL_RGBA; @@ -298,7 +302,7 @@ static void *swizzle_texture(GLsizei width, GLsizei height, GLvoid *pix2 = pixels; if (raster_need_transform()) if (!pixel_transform(data, &pixels, width, height, - *format, *type, raster_scale, raster_bias)) { + *format, *type, glstate->raster.raster_scale, glstate->raster.raster_bias)) { printf("LIBGL: swizzle/convert error: (%s, %s -> %s, %s)\n", PrintEnum(*format), PrintEnum(*type), PrintEnum(dest_format), PrintEnum(dest_type)); pix2 = pixels; @@ -786,11 +790,16 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, case GL_PROXY_TEXTURE_2D: break; default: { - GLsizei nheight = npot(height), nwidth = npot(width); + GLsizei nheight = (hardext.npot==2)?height:npot(height), nwidth = (hardext.npot==2)?width:npot(width); #ifdef PANDORA +#define NO_1x1 +#endif +#ifdef NO_1x1 #define MIN_SIZE 2 - if(nwidth < MIN_SIZE) nwidth=MIN_SIZE; - if(nheight < MIN_SIZE) nheight=MIN_SIZE; + if(level==0) { + if(nwidth < MIN_SIZE) nwidth=MIN_SIZE; + if(nheight < MIN_SIZE) nheight=MIN_SIZE; + } #undef MIN_SIZE #endif if (texstream && bound && bound->streamed) { @@ -828,6 +837,18 @@ void glshim_glTexImage2D(GLenum target, GLint level, GLint internalformat, if (pixels) gles_glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); errorGL(); +#ifdef NO_1x1 + if(level==0 && (width==1 || height==1 && pixels)) { + // complete the texture, juste in ase it use GL_REPEAT + // also, don't keep the fact we have resized, the non-adjusted coordinates will work (as the texture is enlarged) + if(width==1) {gles_glTexSubImage2D(target, level, 1, 0, width, height, format, type, pixels); nwidth=1;} + if(height==1) {gles_glTexSubImage2D(target, level, 0, 1, width, height, format, type, pixels); nheight=1;} + if(width==1 && height==1) { // create a manual mipmap just in case_state + gles_glTexSubImage2D(target, level, 1, 1, width, height, format, type, pixels); + gles_glTexImage2D(target, 1, format, 1, 1, 0, format, type, pixels); + } + } +#endif } else { gles_glTexImage2D(target, level, format, width, height, border, format, type, pixels); @@ -1764,9 +1785,8 @@ void glshim_glClientActiveTexture( GLenum texture ) { gles_glClientActiveTexture(texture); errorGL(); } - 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); + //printf("glReadPixels(%i, %i, %i, %i, %s, %s, 0x%p)\n", x, y, width, height, PrintEnum(format), PrintEnum(type), data); GLuint old_glbatch = glstate->gl_batch; if (glstate->gl_batch) { flush(); @@ -1784,20 +1804,26 @@ void glshim_glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum dst += (uintptr_t)glstate->vao->pack->data; readfboBegin(); - if (format == GL_RGBA && format == GL_UNSIGNED_BYTE) { + if ((format == GL_RGBA && type == GL_UNSIGNED_BYTE) // should not use default GL_RGBA on Pandora as it's very slow... + || (format == hardext.readf && type == hardext.readt) // use the IMPLEMENTATION_READ too... + || (format == GL_DEPTH_COMPONENT && type == GL_FLOAT)) // this one will probably fail, as DEPTH is not readable on most GLES hardware + { // easy passthru - gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, dst); + gles_glReadPixels(x, y, width, height, format, type, dst); readfboEnd(); glstate->gl_batch = old_glbatch; return; } // grab data in GL_RGBA format + int use_bgra = 0; + if(hardext.readf==GL_BGRA && hardext.readt==GL_UNSIGNED_BYTE) + use_bgra = 1; // if IMPLEMENTATION_READ is BGRA, then use it as it's probably faster then RGBA. GLvoid *pixels = malloc(width*height*4); - gles_glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + gles_glReadPixels(x, y, width, height, use_bgra?GL_BGRA: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 -> %s, %s )\n", - PrintEnum(format), PrintEnum(type)); + use_bgra?GL_BGRA:GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) { + LOGE("LIBGL: ReadPixels error: (%s, UNSIGNED_BYTE -> %s, %s )\n", + PrintEnum(use_bgra?GL_BGRA:GL_RGBA), PrintEnum(format), PrintEnum(type)); } free(pixels); readfboEnd(); @@ -2036,20 +2062,28 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo } else { pixels = uncompressDXTc(width, height, internalformat, imageSize, datab); } + // if RGBA / DXT1, then RGB 000 needs to have 0 alpha too + if(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { + GLuint *p = (GLuint*)pixels; + for(int i=0; itexture.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; 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; 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; + else { + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } + glstate->texture.bound[glstate->texture.active]->format = format; //internalformat; + glstate->texture.bound[glstate->texture.active]->type = type; + glstate->texture.bound[glstate->texture.active]->compressed = true; } else { fact = 0; } @@ -2057,7 +2091,7 @@ void glshim_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfo glshim_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign); if (oldalign!=1) glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glshim_glTexImage2D(target, level, GL_RGBA, width>>fact, height>>fact, border, format, type, half); + glshim_glTexImage2D(target, level, format, width>>fact, height>>fact, border, format, type, half); if (oldalign!=1) glshim_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign); if (half!=pixels) @@ -2223,6 +2257,60 @@ void glshim_glCompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, } +void glshim_glTexEnvf(GLenum target, GLenum pname, GLfloat param) { + LOAD_GLES(glTexEnvf); + PUSH_IF_COMPILING(glTexEnvf); + + if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) + glstate->texture.pscoordreplace[glstate->texture.active] = (param!=0.0f)?1:0; + gles_glTexEnvf(target, pname, param); +} +void glshim_glTexEnvi(GLenum target, GLenum pname, GLint param) { + LOAD_GLES(glTexEnvi); + PUSH_IF_COMPILING(glTexEnvi); + if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) + glstate->texture.pscoordreplace[glstate->texture.active] = (param!=0)?1:0; + gles_glTexEnvi(target, pname, param); +} +void glshim_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *param) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_TEXENV); + rlTexEnvfv(glstate->list.active, target, pname, param); + noerrorShim(); + return; + } + LOAD_GLES(glTexEnvfv); + gles_glTexEnvfv(target, pname, param); +} +void glshim_glTexEnviv(GLenum target, GLenum pname, const GLint *param) { + if ((glstate->list.compiling || glstate->gl_batch) && glstate->list.active) { + NewStage(glstate->list.active, STAGE_TEXENV); + rlTexEnviv(glstate->list.active, target, pname, param); + noerrorShim(); + return; + } + LOAD_GLES(glTexEnviv); + gles_glTexEnviv(target, pname, param); +} +void glshim_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) { + LOAD_GLES(glGetTexEnvfv); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); + if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) + *params = glstate->texture.pscoordreplace[glstate->texture.active]; + else + gles_glGetTexEnvfv(target, pname, params); + +} +void glshim_glGetTexEnviv(GLenum target, GLenum pname, GLint * params) { + LOAD_GLES(glGetTexEnviv); + if (glstate->list.active && (glstate->gl_batch && !glstate->list.compiling)) flush(); + if(target==GL_POINT_SPRITE && pname==GL_COORD_REPLACE) + *params = glstate->texture.pscoordreplace[glstate->texture.active]; + else + gles_glGetTexEnviv(target, pname, params); +} + + //Direct wrapper void glTexImage2D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexImage2D"); void glTexImage1D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexImage1D"); @@ -2255,6 +2343,11 @@ void glActiveTexture( GLenum texture ) AliasExport("glshim_glActiveTexture"); void glClientActiveTexture( GLenum texture ) AliasExport("glshim_glClientActiveTexture"); GLboolean glIsTexture( GLuint texture ) AliasExport("glshim_glIsTexture"); void glPixelStorei(GLenum pname, GLint param) AliasExport("glshim_glPixelStorei"); +void glTexEnvf(GLenum target, GLenum pname, GLfloat param) AliasExport("glshim_glTexEnvf"); +void glTexEnvi(GLenum target, GLenum pname, GLint param) AliasExport("glshim_glTexEnvi"); +void glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params) AliasExport("glshim_glGetTexEnvfv"); +void glGetTexEnviv(GLenum target, GLenum pname, GLint * params) AliasExport("glshim_glGetTexEnviv"); + //EXT mapper void glTexSubImage3DEXT(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const GLvoid *data) AliasExport("glshim_glTexSubImage3D"); void glCompressedTexImage2DEXT(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) AliasExport("glshim_glCompressedTexImage2D"); diff --git a/project/jni/glshim/src/gl/texture.h b/project/jni/glshim/src/gl/texture.h index e3cdbbd55..2dcc7090d 100755 --- a/project/jni/glshim/src/gl/texture.h +++ b/project/jni/glshim/src/gl/texture.h @@ -74,7 +74,14 @@ void glshim_glCopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint void glshim_glCopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); - + +void glshim_glTexEnvf(GLenum target, GLenum pname, GLfloat param); +void glshim_glTexEnvi(GLenum target, GLenum pname, GLint param); +void glshim_glTexEnvfv(GLenum target, GLenum pname, const GLfloat *param); +void glshim_glTexEnviv(GLenum target, GLenum pname, const GLint *param); +void glshim_glGetTexEnvfv(GLenum target, GLenum pname, GLfloat * params); +void glshim_glGetTexEnviv(GLenum target, GLenum pname, GLint * params); + void tex_coord_rect_arb(GLfloat *tex, GLsizei len, GLsizei width, GLsizei height); diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index 522f8b859..753977117 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -24,6 +24,7 @@ #include "../gl/gl.h" #include "../glx/streaming.h" #include "khash.h" +#include "hardext.h" #define EXPORT __attribute__((visibility("default"))) @@ -38,15 +39,26 @@ static EGLDisplay eglDisplay; static EGLSurface eglSurface; static EGLConfig eglConfigs[1]; static int glx_default_depth=0; -static int glx_surface_srgb=0; // default to not try to create an sRGB surface #ifdef PANDORA static struct sockaddr_un sun; static int sock = -2; #endif -typedef struct {int Width; int Height; EGLContext Context;} glx_buffSize; - #ifndef ANDROID +static int shm_tested = 0; +static int shm_shm = 0; +typedef struct { + int Width; + int Height; + EGLContext Context; + EGLSurface Surface; + int Depth; + Display *dpy; + int Type; GC gc; + XImage* frame; + GLXContext glxcontext; +} glx_buffSize; + //PBuffer should work under ANDROID static GLXPbuffer *pbufferlist = NULL; static glx_buffSize *pbuffersize = NULL; @@ -58,6 +70,9 @@ static int isPBuffer(GLXDrawable drawable) { return i+1; return 0; } +void BlitEmulatedPixmap(); +int createPBuffer(Display * dpy, const EGLint * egl_attribs, EGLSurface* Surface, EGLContext* Context, int redBits, int greenBits, int blueBits, int alphaBits, int samplebuffers, int samples); +GLXPbuffer addPixBuffer(Display *dpy, EGLSurface surface, int Width, int Height, EGLContext Context, Pixmap pixmap, int depth, int emulated); #endif static EGLint egl_context_attrib[] = { @@ -109,7 +124,7 @@ int8_t CheckEGLErrors() { default: errortext = "unknown"; break; } - printf("LIBGL: ERROR: EGL Error detected: %s (0x%X)\n", errortext, error); + LOGE("LIBGL: ERROR: EGL Error detected: %s (0x%X)\n", errortext, error); return 1; } @@ -146,6 +161,8 @@ static int get_config_default(Display *display, int attribute, int *value) { *value = 16; break; case GLX_STENCIL_SIZE: + *value = 8; + break; case GLX_ACCUM_RED_SIZE: case GLX_ACCUM_GREEN_SIZE: case GLX_ACCUM_BLUE_SIZE: @@ -156,7 +173,7 @@ static int get_config_default(Display *display, int attribute, int *value) { *value = GLX_NONE; break; case GLX_RENDER_TYPE: - *value = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; + *value = GLX_RGBA_TYPE; break; case GLX_VISUAL_ID: *value = glXChooseVisual(display, 0, NULL)->visualid; @@ -169,7 +186,7 @@ static int get_config_default(Display *display, int attribute, int *value) { *value = GLX_WINDOW_BIT; break; case GLX_BUFFER_SIZE: - *value = 16; + *value = 0; break; case GLX_X_VISUAL_TYPE: case GLX_CONFIG_CAVEAT: @@ -178,10 +195,10 @@ static int get_config_default(Display *display, int attribute, int *value) { *value = 0; break; case GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB: - *value = 0; + *value = hardext.srgb; break; default: - printf("LIBGL: unknown attrib %i\n", attribute); + LOGD("LIBGL: unknown attrib %i\n", attribute); *value = 0; return 1; } @@ -191,12 +208,14 @@ static int get_config_default(Display *display, int attribute, int *value) { static Display *g_display = NULL; static GLXContext glxContext = NULL; static GLXContext fbContext = NULL; +static bool g_usepbuffer = false; #endif //ANDROID // hmm... static EGLContext eglContext; static int fbcontext_count = 0; +static int glx_surface_srgb = 0; #ifdef USE_FBIO #ifndef FBIO_WAITFORVSYNC @@ -229,7 +248,7 @@ extern char glshim_version[50]; extern int glshim_nobanner; extern int glshim_npot; int export_silentstub = 0; -int glshim_queries = 0; +int glshim_queries = 1; bool g_recyclefbo = false; static int g_width=0, g_height=0; @@ -260,7 +279,7 @@ static void init_vsync() { #ifdef USE_FBIO fbdev = open("/dev/fb0", O_RDONLY); if (fbdev < 0) { - fprintf(stderr, "LIBGL: Could not open /dev/fb0 for vsync.\n"); + LOGE("LIBGL: Could not open /dev/fb0 for vsync.\n"); } #endif } @@ -306,9 +325,9 @@ static void signal_handler(int sig) { void *array[10]; size_t size = backtrace(array, 10); if (! size) { - printf("LIBGL: No stacktrace. Compile with -funwind-tables.\n"); + LOGD("LIBGL: No stacktrace. Compile with -funwind-tables.\n"); } else { - printf("LIBGL: Stacktrace: %zd\n", size); + LOGD("LIBGL: Stacktrace: %zd\n", size); backtrace_symbols_fd(array, size, 2); } break; @@ -354,10 +373,11 @@ static void fast_math() { #endif extern void initialize_glshim(); extern int initialized; -static void scan_env() { +void scan_env() { static bool first = true; if (! first) return; + first = false; if (! initialized) { initialize_glshim(); @@ -366,7 +386,7 @@ static void scan_env() { /* 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")); + SHUT(LOGD("LIBGL: Warning, memory corruption detected at init, trying to compensate\n")); initialize_glshim(); } */ @@ -377,12 +397,11 @@ static void scan_env() { kh_put(mapdrawable, MapDrawable, 1, &ret); kh_del(mapdrawable, MapDrawable, 1); } - first = false; - SHUT(printf("LIBGL: built on %s %s\n", __DATE__, __TIME__)); + SHUT(LOGD("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) { \ - SHUT(printf("LIBGL: " message "\n")); \ + SHUT(LOGD("LIBGL: " message "\n")); \ global = true; \ } @@ -414,12 +433,23 @@ static void scan_env() { #endif #endif //ANDROID } - env(LIBGL_FB, g_usefb, "framebuffer output enabled"); - if (env_LIBGL_FB && strcmp(env_LIBGL_FB, "2") == 0) { - SHUT(printf("LIBGL: using framebuffer + fbo\n")); + char *env_fb = getenv("LIBGL_FB"); + if (env_fb && strcmp(env_fb, "1") == 0) { + SHUT(LOGD("LIBGL: framebuffer output enabled\n")); + g_usefb = true; + } + if (env_fb && strcmp(env_fb, "2") == 0) { + SHUT(LOGD("LIBGL: using framebuffer + fbo\n")); g_usefb = true; g_usefbo = true; } +#ifndef ANDROID + if (env_fb && strcmp(env_fb, "3") == 0) { + SHUT(LOGD("LIBGL: using pbuffer\n")); + g_usefb = true; + g_usepbuffer = true; + } +#endif env(LIBGL_FPS, g_showfps, "fps counter enabled"); #ifdef USE_FBIO env(LIBGL_VSYNC, g_vsync, "vsync enabled"); @@ -430,106 +460,113 @@ static void scan_env() { #ifdef PANDORA init_liveinfo(); if (sock>-1) { - SHUT(printf("LIBGL: LiveInfo detected, fps will be shown\n")); + SHUT(LOGD("LIBGL: LiveInfo detected, fps will be shown\n")); } #endif + int glshim_notest = 0; + char *env_notest = getenv("LIBGL_NOTEST"); + if (env_notest && strcmp(env_notest, "1") == 0) { + glshim_notest = 1; + } + GetHardwareExtensions(glshim_notest); + env(LIBGL_RECYCLEFBO, g_recyclefbo, "Recycling of FBO enabled"); // Texture hacks char *env_mipmap = getenv("LIBGL_MIPMAP"); if (env_mipmap && strcmp(env_mipmap, "1") == 0) { automipmap = 1; - SHUT(printf("LIBGL: AutoMipMap forced\n")); + SHUT(LOGD("LIBGL: AutoMipMap forced\n")); } if (env_mipmap && strcmp(env_mipmap, "2") == 0) { automipmap = 2; - SHUT(printf("LIBGL: guess AutoMipMap\n")); + SHUT(LOGD("LIBGL: guess AutoMipMap\n")); } if (env_mipmap && strcmp(env_mipmap, "3") == 0) { automipmap = 3; - SHUT(printf("LIBGL: ignore MipMap\n")); + SHUT(LOGD("LIBGL: ignore MipMap\n")); } if (env_mipmap && strcmp(env_mipmap, "4") == 0) { automipmap = 4; - SHUT(printf("LIBGL: ignore AutoMipMap on non-squared textures\n")); + SHUT(LOGD("LIBGL: ignore AutoMipMap on non-squared textures\n")); } char *env_texcopy = getenv("LIBGL_TEXCOPY"); if (env_texcopy && strcmp(env_texcopy, "1") == 0) { texcopydata = 1; - SHUT(printf("LIBGL: Texture copy enabled\n")); + SHUT(LOGD("LIBGL: Texture copy enabled\n")); } char *env_shrink = getenv("LIBGL_SHRINK"); if (env_shrink && strcmp(env_shrink, "1") == 0) { texshrink = 1; - SHUT(printf("LIBGL: Texture shink, mode 1 selected (everything / 2)\n")); + SHUT(LOGD("LIBGL: Texture shink, mode 1 selected (everything / 2)\n")); } if (env_shrink && strcmp(env_shrink, "2") == 0) { texshrink = 2; - SHUT(printf("LIBGL: Texture shink, mode 2 selected (only > 512 /2 )\n")); + SHUT(LOGD("LIBGL: Texture shink, mode 2 selected (only > 512 /2 )\n")); } if (env_shrink && strcmp(env_shrink, "3") == 0) { texshrink = 3; - SHUT(printf("LIBGL: Texture shink, mode 3 selected (only > 256 /2 )\n")); + SHUT(LOGD("LIBGL: Texture shink, mode 3 selected (only > 256 /2 )\n")); } if (env_shrink && strcmp(env_shrink, "4") == 0) { texshrink = 4; - SHUT(printf("LIBGL: Texture shink, mode 4 selected (only > 256 /2, >=1024 /4 )\n")); + SHUT(LOGD("LIBGL: Texture shink, mode 4 selected (only > 256 /2, >=1024 /4 )\n")); } if (env_shrink && strcmp(env_shrink, "5") == 0) { texshrink = 5; - SHUT(printf("LIBGL: Texture shink, mode 5 selected (every > 256 is downscaled to 256 ), but not for empty texture\n")); + SHUT(LOGD("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; - SHUT(printf("LIBGL: Texture shink, mode 6 selected (only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture\n")); + SHUT(LOGD("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; - SHUT(printf("LIBGL: Texture shink, mode 7 selected (only > 512 /2 ), but not for empty texture\n")); + SHUT(LOGD("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; - SHUT(printf("LIBGL: Texture shink, mode 8 selected (advertise 8192 max texture size, but >2048 are shrinked to 2048)\n")); + SHUT(LOGD("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; - 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")); + SHUT(LOGD("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; - 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")); + SHUT(LOGD("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; - SHUT(printf("LIBGL: Texture dump enabled\n")); + SHUT(LOGD("LIBGL: Texture dump enabled\n")); } char *env_alpha = getenv("LIBGL_ALPHAHACK"); if (env_alpha && strcmp(env_alpha, "1") == 0) { alphahack = 1; - SHUT(printf("LIBGL: Alpha Hack enabled\n")); + SHUT(LOGD("LIBGL: Alpha Hack enabled\n")); } #ifdef TEXSTREAM char *env_stream = getenv("LIBGL_STREAM"); if (env_stream && strcmp(env_stream, "1") == 0) { texstream = InitStreamingCache(); - SHUT(printf("LIBGL: Streaming texture %s\n",(texstream)?"enabled":"not available")); + SHUT(LOGD("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; - SHUT(printf("LIBGL: Streaming texture %s\n",(texstream)?"forced":"not available")); + SHUT(LOGD("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) { - SHUT(printf("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n")); + SHUT(LOGD("LIBGL: No glCopyTexImage2D / glCopyTexSubImage2D hack\n")); copytex = 1; } char *env_lumalpha = getenv("LIBGL_NOLUMALPHA"); if (env_lumalpha && strcmp(env_lumalpha, "1") == 0) { nolumalpha = 1; - SHUT(printf("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n")); + SHUT(LOGD("LIBGL: GL_LUMINANCE_ALPHA hardware support disabled\n")); } env(LIBGL_BLENDHACK, blendhack, "Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE"); @@ -539,49 +576,50 @@ static void scan_env() { char *env_version = getenv("LIBGL_VERSION"); if (env_version) { - SHUT(printf("LIBGL: Overide version string with \"%s\" (should be in the form of \"1.x\")\n", env_version)); + SHUT(LOGD("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); - SHUT(printf("LIBGL: Set gamma to %.2f\n", pandora_gamma)); + SHUT(LOGD("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; - SHUT(printf("LIBGL: enabling sRGB support\n")); + if (env_srgb && strcmp(env_srgb, "1") == 0 && hardext.srgb) { + glx_surface_srgb = 2; + SHUT(LOGD("LIBGL: enabling sRGB support\n")); } char *env_fastmath = getenv("LIBGL_FASTMATH"); if (env_fastmath && strcmp(env_fastmath, "1") == 0) { #ifdef PANDORA - SHUT(printf("LIBGL: Enable FastMath for cortex-a8\n")); + SHUT(LOGD("LIBGL: Enable FastMath for cortex-a8\n")); fast_math(); #else - SHUT(printf("LIBGL: No FastMath on this platform\n")); + SHUT(LOGD("LIBGL: No FastMath on this platform\n")); #endif } char *env_npot = getenv("LIBGL_NPOT"); - if (env_npot && strcmp(env_npot, "1") == 0) { + glshim_npot = hardext.npot; + if (env_npot && strcmp(env_npot, "1") == 0 && glshim_npot<1) { glshim_npot = 1; - SHUT(printf("LIBGL: Expose limited NPOT extension\n")); + SHUT(LOGD("LIBGL: Expose limited NPOT extension\n")); } - if (env_npot && strcmp(env_npot, "2") == 0) { + if (env_npot && strcmp(env_npot, "2") == 0 && glshim_npot<2) { glshim_npot = 2; - SHUT(printf("LIBGL: Expose GL_ARB_texture_non_power_of_two extension\n")); + SHUT(LOGD("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")); + if (env_queries && strcmp(env_queries, "0") == 0) { + glshim_queries = 0; + SHUT(LOGD("LIBGL: Dont't expose fake glQueries functions\n")); } char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) - SHUT(printf("LIBGL: Current folder is:%s\n", cwd)); + SHUT(LOGD("LIBGL: Current folder is:%s\n", cwd)); } #ifndef ANDROID @@ -589,7 +627,7 @@ EXPORT GLXContext glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, Bool isDirect) { -//printf("glXCreateContext(%p, %p, %p, %i)\n", display, visual, shareList, isDirect); + //printf("glXCreateContext(%p, %p, %p, %i)\n", display, visual, shareList, isDirect); EGLint configAttribs[] = { #ifdef PANDORA EGL_RED_SIZE, 5, @@ -601,7 +639,7 @@ EXPORT GLXContext glXCreateContext(Display *display, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else EGL_BUFFER_SIZE, 16, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT, + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif EGL_NONE @@ -634,43 +672,16 @@ 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? - } else { - if (eglDisplay != NULL) { - if (eglSurface!=NULL) { - // A surface already exist.... - fake->display = g_display; - fake->direct = true; - fake->xid = 1; //TODO: Proper handling of that id... - return fake; // Do nothing - } - egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); - if (eglContext != NULL) { - egl_eglDestroyContext(eglDisplay, eglContext); - eglContext = NULL; - } - if (eglSurface != NULL) { - egl_eglDestroySurface(eglDisplay, eglSurface); - eglSurface = NULL; - } - } - 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("LIBGL: Unable to create EGL display.\n"); - return fake; + LOGE("LIBGL: Unable to create EGL display.\n"); + free(fake); + return 0; } } @@ -679,21 +690,13 @@ EXPORT GLXContext glXCreateContext(Display *display, 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 fake; + LOGE("LIBGL: Unable to initialize EGL display.\n"); + free(fake); + return 0; } eglInitialized = true; } - // With the display, try to check if sRGB surface are supported - if (glx_surface_srgb==1) { - if(strstr(egl_eglQueryString(eglDisplay, EGL_EXTENSIONS), "EGL_KHR_gl_colorspace")) { - printf("LIBGL: sRGB surface supported\n"); - glx_surface_srgb=2; // test only 1 time - } else - glx_surface_srgb=0; - } - int configsFound; result = egl_eglChooseConfig(eglDisplay, configAttribs, fake->eglConfigs, 1, &configsFound); if(g_usefb) @@ -701,8 +704,9 @@ EXPORT GLXContext glXCreateContext(Display *display, CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { - printf("LIBGL: No EGL configs found.\n"); - return fake; + LOGE("LIBGL: No EGL configs found.\n"); + free(fake); + return 0; } EGLContext shared = (shareList)?shareList->eglContext:EGL_NO_CONTEXT; fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, egl_context_attrib); @@ -716,6 +720,14 @@ EXPORT GLXContext glXCreateContext(Display *display, fake->direct = true; fake->xid = 1; //TODO: Proper handling of that id... fake->contextType = 0; //Window +#ifdef PANDORA + fake->rbits = 5; fake->gbits=6; fake->bbits=5; fake->abits=0; +#else + fake->rbits = 8; fake->gbits=8; fake->bbits=8; fake->abits=8; +#endif + fake->samples = 0; fake->samplebuffers = 0; + + fake->glstate = NewGLState((shareList)?shareList->glstate:NULL); /* // why unassign the context, it's not assigned yet if (!g_usefb) { @@ -736,6 +748,8 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon EGL_ALPHA_SIZE, (config)?config->alphaBits:0, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_SAMPLE_BUFFERS, (config)?config->nMultiSampleBuffers:0, + EGL_SAMPLES, (config)?config->multiSampleSize:0, EGL_NONE }; @@ -743,6 +757,7 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon LOAD_EGL(eglInitialize); LOAD_EGL(eglChooseConfig); LOAD_EGL(eglCreateContext); + LOAD_EGL(eglGetConfigAttrib); // Check that the config is for PBuffer if(config->drawableType&GLX_PBUFFER_BIT!=GLX_PBUFFER_BIT) @@ -751,9 +766,9 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon // Init what need to be done EGLBoolean result; if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { - init_display(display); + init_display((g_usefb)?g_display:display); if (eglDisplay == EGL_NO_DISPLAY) { - printf("LIBGL: Unable to create EGL display.\n"); + LOGE("LIBGL: Unable to create EGL display.\n"); return 0; } } @@ -763,7 +778,7 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon egl_eglBindAPI(EGL_OPENGL_ES_API); result = egl_eglInitialize(eglDisplay, NULL, NULL); if (result != EGL_TRUE) { - printf("LIBGL: Unable to initialize EGL display.\n"); + LOGE("LIBGL: Unable to initialize EGL display.\n"); return 0; } eglInitialized = true; @@ -776,7 +791,7 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { - printf("LIBGL: No EGL configs found.\n"); + LOGE("LIBGL: No EGL configs found.\n"); return 0; } @@ -795,6 +810,14 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon fake->direct = true; fake->xid = 1; //TODO: Proper handling of that id... fake->contextType = 1; //PBuffer + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_RED_SIZE, &fake->rbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_GREEN_SIZE, &fake->gbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_BLUE_SIZE, &fake->bbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_ALPHA_SIZE, &fake->abits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_DEPTH_SIZE, &fake->depth); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_STENCIL_SIZE, &fake->stencil); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_SAMPLES, &fake->samples); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_SAMPLE_BUFFERS, &fake->samplebuffers); return fake; } @@ -802,14 +825,123 @@ GLXContext createPBufferContext(Display *display, GLXContext shareList, GLXFBCon EXPORT GLXContext glXCreateContextAttribsARB(Display *display, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list) { + //printf("glXCreateContextAttribsARB(%p, %p, %p, %d) ", display, config, share_context, direct);if(config)printf("config is RGBA:%d%d%d%d, depth=%d, stencil=%d, drawable=%d\n", config->redBits, config->greenBits, config->blueBits, config->alphaBits, config->depthBits, config->stencilBits, config->drawableType); else printf("\n"); if(config && config->drawableType==GLX_PBUFFER_BIT) { return createPBufferContext(display, share_context, config); - } else - return glXCreateContext(display, NULL, share_context, direct); + } else { + EGLint configAttribs[] = { +#ifdef PANDORA + EGL_RED_SIZE, (config->drawableType)==GLX_PIXMAP_BIT?config->redBits:5, + EGL_GREEN_SIZE, (config->drawableType)==GLX_PIXMAP_BIT?config->greenBits:6, + EGL_BLUE_SIZE, (config->drawableType)==GLX_PIXMAP_BIT?config->blueBits:5, + EGL_ALPHA_SIZE, (config->drawableType)==GLX_PIXMAP_BIT?config->alphaBits:0, +#else + EGL_RED_SIZE, config->redBits, + EGL_GREEN_SIZE, config->greenBits, + EGL_BLUE_SIZE, config->blueBits, + EGL_ALPHA_SIZE, config->alphaBits, +#endif + EGL_DEPTH_SIZE, config->depthBits, + EGL_STENCIL_SIZE, config->stencilBits, +#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_NONE + }; + + scan_env(); + + if (g_usefb && fbcontext_count>0) { + // don't create a new context, one FB is enough... + fbcontext_count++; + return fbContext; + } + +#ifdef BCMHOST + if (! g_bcm_active) { + g_bcm_active = true; + bcm_host_init(); + } +#endif + + LOAD_EGL(eglMakeCurrent); + LOAD_EGL(eglDestroyContext); + LOAD_EGL(eglDestroySurface); + LOAD_EGL(eglBindAPI); + LOAD_EGL(eglInitialize); + LOAD_EGL(eglCreateContext); + LOAD_EGL(eglChooseConfig); + LOAD_EGL(eglQueryString); + LOAD_EGL(eglGetConfigAttrib); + + GLXContext fake = malloc(sizeof(struct __GLXContextRec)); + memset(fake, 0, sizeof(struct __GLXContextRec)); + + fake->glstate = NewGLState((share_context)?share_context->glstate:NULL); + if(g_usefb) + fbContext = fake; + // make an egl context here... + EGLBoolean result; + if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { + init_display(display); + if (eglDisplay == EGL_NO_DISPLAY) { + LOGE("LIBGL: Unable to create EGL display.\n"); + return fake; + } + } + + // first time? + if (eglInitialized == false) { + egl_eglBindAPI(EGL_OPENGL_ES_API); + result = egl_eglInitialize(eglDisplay, NULL, NULL); + if (result != EGL_TRUE) { + LOGE("LIBGL: Unable to initialize EGL display.\n"); + return fake; + } + eglInitialized = true; + } + + int 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) { + LOGE("LIBGL: No EGL configs found.\n"); + return fake; + } + EGLContext shared = (share_context)?share_context->eglContext:EGL_NO_CONTEXT; + fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, egl_context_attrib); + if(g_usefb) + eglContext = fake->eglContext; + + 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 = 0; //Window + + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_RED_SIZE, &fake->rbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_GREEN_SIZE, &fake->gbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_BLUE_SIZE, &fake->bbits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_ALPHA_SIZE, &fake->abits); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_DEPTH_SIZE, &fake->depth); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_STENCIL_SIZE, &fake->stencil); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_SAMPLES, &fake->samples); + egl_eglGetConfigAttrib(eglDisplay, fake->eglConfigs[0], EGL_SAMPLE_BUFFERS, &fake->samplebuffers); + + return fake; + } } EXPORT void glXDestroyContext(Display *display, GLXContext ctx) { -//printf("glXDestroyContext(%p, %p)\n", display, ctx); + //printf("glXDestroyContext(%p, %p)\n", display, ctx); if (g_usefb && ctx->contextType==0) { if (fbcontext_count==0) return; // Should not happens! @@ -839,7 +971,7 @@ EXPORT void glXDestroyContext(Display *display, GLXContext ctx) { } if (result != EGL_TRUE) { - printf("LIBGL: Failed to destroy EGL context.\n"); + LOGE("LIBGL: Failed to destroy EGL context.\n"); } /*if (fbdev >= 0) { close(fbdev); @@ -874,11 +1006,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); + LOGD("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"); + LOGE("LIBGL: XMatchVisualInfo failed in glXChooseVisual\n"); return NULL; } @@ -895,14 +1027,17 @@ not set to EGL_NO_CONTEXT. EXPORT Bool glXMakeCurrent(Display *display, GLXDrawable drawable, GLXContext context) { -//printf("glXMakeCurrent(%p, %p, %p)\n", display, drawable, context); + //printf("glXMakeCurrent(%p, %p, %p) 'isPBuffer(drawable)=%d\n", display, drawable, context, isPBuffer(drawable)); LOAD_EGL(eglMakeCurrent); LOAD_EGL(eglDestroySurface); LOAD_EGL(eglCreateWindowSurface); LOAD_EGL(eglQuerySurface); +#ifdef ANDROID + int created = 0; +#else int created = (context)?isPBuffer(drawable):0; +#endif 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; @@ -914,10 +1049,46 @@ EXPORT Bool glXMakeCurrent(Display *display, else { // new one if(created) { - eglSurf = context->eglSurface = (EGLSurface)drawable; +#ifndef ANDROID + eglSurf = context->eglSurface = pbuffersize[created-1].Surface; //(EGLSurface)drawable; context->eglContext = eglContext = pbuffersize[created-1].Context; // this context is ok for the PBuffer +#endif } else { +#ifndef ANDROID if(g_usefb) { + if(g_usepbuffer) { + // Get Window size and all... + unsigned int width, height, border, depth; + Window root; + int x, y; + XGetGeometry(display, drawable, &root, &x, &y, &width, &height, &border, &depth); + //let's create a PBuffer attributes + EGLint egl_attribs[10]; // should be enough + int i = 0; + egl_attribs[i++] = EGL_WIDTH; + egl_attribs[i++] = width; + egl_attribs[i++] = EGL_HEIGHT; + egl_attribs[i++] = height; + egl_attribs[i++] = EGL_NONE; + + if(createPBuffer(display, egl_attribs, &eglSurf, &eglContext, (depth>16)?8:5, (depth==15)?5:(depth>16)?8:6, (depth>16)?8:5, (depth==32)?8:0, context->samplebuffers, context->samples)==0) { + // fail too, abort + SHUT(LOGE("LIBGL: PBuffer creation failed too\n")); + return 0; + } + int Width, Height; + + egl_eglQuerySurface(eglDisplay,eglSurf,EGL_WIDTH,&Width); + egl_eglQuerySurface(eglDisplay,eglSurf,EGL_HEIGHT,&Height); + + addPixBuffer(display, eglSurf, Width, Height, eglContext, drawable, depth, 2); + context->eglSurface = eglSurf; + context->eglContext = eglContext; + // update, that context is a created emulated one... + created = isPBuffer(drawable); + } else +#endif + if(eglSurface) eglSurf = context->eglSurface = eglSurface; else @@ -933,55 +1104,6 @@ EXPORT Bool glXMakeCurrent(Display *display, } 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); - else { - if (!context) { - egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); - if (eglSurface != NULL) { - egl_eglDestroySurface(eglDisplay, eglSurface); - eglSurface = NULL; - } - } - } - } - glxContext = context; - // call with NULL to just destroy old stuff. - if (! context) { - return true; - } - if (eglDisplay == NULL) { - init_display(display); - } - if (g_usefb) - drawable = 0; - EGLBoolean result; - created = 1; - if (!g_usefb) { - // need current surface for eglSwapBuffer - eglContext = context->eglContext; - // if surface on a different drawable exist, destroy it first - if ((context->drawable != drawable) && (context->eglSurface)) { - egl_eglDestroySurface(eglDisplay, context->eglSurface); - context->eglSurface = NULL; - } - // Now get the Surface - if (context->eglSurface) - eglSurface = context->eglSurface; // reused previously created Surface - else { - eglSurface = context->eglSurface = egl_eglCreateWindowSurface(eglDisplay, context->eglConfigs[0], drawable, (glx_surface_srgb)?sRGB:NULL); - } - result = egl_eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); - } else { - if (!eglSurface) { - eglSurface = egl_eglCreateWindowSurface(eglDisplay, eglConfigs[0], drawable, (glx_surface_srgb)?sRGB:NULL); // create surface only if needed - result = egl_eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); - } else - result = EGL_TRUE; - } -#endif CheckEGLErrors(); { // update MapDrawable @@ -997,7 +1119,10 @@ EXPORT Bool glXMakeCurrent(Display *display, } map->surface = eglSurf; map->PBuffer = created; + + if(created) pbuffersize[created-1].glxcontext = context; } + if (context) { context->drawable = drawable; @@ -1005,6 +1130,13 @@ EXPORT Bool glXMakeCurrent(Display *display, #ifdef PANDORA if(created) pandora_set_gamma(); #endif + glstate->emulatedPixmap = 0; + glstate->emulatedWin = 0; + if(created && pbuffersize[created-1].Type >= 3) { + glstate->emulatedPixmap = created; + glstate->emulatedWin = pbuffersize[created-1].Type==4?1:0; + } + CheckEGLErrors(); if (result) { if (g_usefbo && created) { @@ -1012,7 +1144,7 @@ EXPORT Bool glXMakeCurrent(Display *display, 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); + LOGD("LIBGL: Create FBO of %ix%i 32bits\n", g_width, g_height); createMainFBO(g_width, g_height); } // finished @@ -1025,6 +1157,7 @@ EXPORT Bool glXMakeCurrent(Display *display, EXPORT Bool glXMakeContextCurrent(Display *display, int drawable, int readable, GLXContext context) { + //printf("glXMakeContextCurrent(%p, %X, %X, %p)\n", display, drawable, readable, context); return glXMakeCurrent(display, drawable, context); } @@ -1066,8 +1199,13 @@ EXPORT void glXSwapBuffers(Display *display, blitMainFBO(); // blit the main_fbo before swap } - - egl_eglSwapBuffers(eglDisplay, surface); + // check emulated Pixmap + if(PBuffer && glstate->emulatedPixmap) { + LOAD_GLES(glFlush); + gles_glFlush(); + BlitEmulatedPixmap(); + } else + egl_eglSwapBuffers(eglDisplay, surface); CheckEGLErrors(); #ifdef PANDORA if (g_showfps || (sock>-1)) { @@ -1094,7 +1232,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) LOGD("LIBGL: fps: %.2f, avg: %.2f\n", fps, avg); if (sock>-1) { char tmp[60]; snprintf(tmp, 60, "gl: %2.2f", fps); @@ -1122,8 +1260,9 @@ EXPORT const char *glXQueryExtensionsString(Display *display, int screen) { const char *extensions = { "GLX_ARB_create_context " "GLX_ARB_create_context_profile " - "GLX_EXT_create_context_es2_profile " "GLX_ARB_get_proc_address " + "GLX_ARB_multisample " +// "GLX_EXT_create_context_es2_profile " }; return extensions; } @@ -1186,16 +1325,21 @@ 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); + //printf("glXChooseFBConfig(%p, %d, %p, %p)\n", display, screen, attrib_list, count); + // this is not really good. A static table of all config should be build, and then a filter done according to attribs... + static struct __GLXFBConfigRec currentConfig[8]; + static int idx = 0; *count = 1; - GLXFBConfig *configs = (GLXFBConfig *)malloc(sizeof(GLXFBConfig) + sizeof(struct __GLXFBConfigRec)); - configs[0] = (GLXFBConfig)((char*)(&configs[0])+sizeof(GLXFBConfig)); + GLXFBConfig *configs = (GLXFBConfig *)malloc(sizeof(GLXFBConfig)); + configs[0] = ¤tConfig[idx]; + idx=(idx+1)%8; 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]->drawableType = GLX_WINDOW_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; + configs[0]->nMultiSampleBuffers = 0; configs[0]->multiSampleSize = 0; if(attrib_list) { int i = 0; while(attrib_list[i]!=0) { @@ -1216,9 +1360,25 @@ EXPORT GLXFBConfig *glXChooseFBConfig(Display *display, int screen, configs[0]->alphaBits = attrib_list[i++]; if(configs[0]->alphaBits==GLX_DONT_CARE) configs[0]->alphaBits = 0; break; + case GLX_DEPTH_SIZE: + configs[0]->depthBits = attrib_list[i++]; + if(configs[0]->depthBits==GLX_DONT_CARE) configs[0]->depthBits = 0; + break; + case GLX_STENCIL_SIZE: + configs[0]->stencilBits = attrib_list[i++]; + if(configs[0]->stencilBits==GLX_DONT_CARE) configs[0]->stencilBits = 0; + break; case GLX_DRAWABLE_TYPE: configs[0]->drawableType = attrib_list[i++]; break; + case GLX_SAMPLE_BUFFERS: + configs[0]->nMultiSampleBuffers = attrib_list[i++]; + break; + case GLX_SAMPLES: + configs[0]->multiSampleSize = attrib_list[i++]; + break; + default: + ++i; // discard other stuffs } } @@ -1232,7 +1392,7 @@ 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); + //printf("glXGetFBConfigs(%p, %d, %p)\n", display, screen, count); *count = 1; // 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)); @@ -1240,16 +1400,79 @@ EXPORT GLXFBConfig *glXGetFBConfigs(Display *display, int screen, int *count) { 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; + configs[0]->multiSampleSize = 0; configs[0]->nMultiSampleBuffers = 0; return configs; } EXPORT int glXGetFBConfigAttrib(Display *display, GLXFBConfig config, int attribute, int *value) { -//printf("glXGetFBConfigAttrib(%p, %p, 0x%04X, %p)\n", display, config, attribute, value); - return get_config_default(display, attribute, value); + //printf("glXGetFBConfigAttrib(%p, %p, 0x%04X, %p)\n", display, config, attribute, value); + if(!config) + return get_config_default(display, attribute, value); + + switch (attribute) { + case GLX_RGBA: + *value = config->alphaBits>0?1:0; + case GLX_RED_SIZE: + *value = config->redBits; + break; + case GLX_GREEN_SIZE: + *value = config->greenBits; + break; + case GLX_BLUE_SIZE: + *value = config->blueBits; + break; + case GLX_ALPHA_SIZE: + *value = config->alphaBits; + break; + case GLX_DEPTH_SIZE: + *value = config->depthBits; + break; + case GLX_STENCIL_SIZE: + *value = config->stencilBits; + break; + case GLX_ACCUM_RED_SIZE: + case GLX_ACCUM_GREEN_SIZE: + case GLX_ACCUM_BLUE_SIZE: + case GLX_ACCUM_ALPHA_SIZE: + *value = 0; + break; + case GLX_TRANSPARENT_TYPE: + *value = GLX_NONE; + break; + case GLX_RENDER_TYPE: + *value = GLX_RGBA_TYPE; + break; + case GLX_VISUAL_ID: + *value = glXChooseVisual(display, 0, NULL)->visualid; //config->associatedVisualId; + //*value = 1; + break; + case GLX_FBCONFIG_ID: + *value = 1; + break; + case GLX_DRAWABLE_TYPE: + *value = GLX_WINDOW_BIT; //config->drawableType; + break; + case GLX_X_VISUAL_TYPE: + case GLX_CONFIG_CAVEAT: + *value = 0; + break; + case GLX_SAMPLE_BUFFERS: + *value = config->nMultiSampleBuffers; + break; + case GLX_SAMPLES: + *value = config->multiSampleSize; + break; + case GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB: + *value = hardext.srgb; + break; + default: + return get_config_default(display, attribute, value); + } + return Success; } EXPORT XVisualInfo *glXGetVisualFromFBConfig(Display *display, GLXFBConfig config) { -//printf("glXGetVisualFromFBConfig(%p, %p)\n", display, config); + //printf("glXGetVisualFromFBConfig(%p, %p)\n", display, config); /*if (g_display == NULL) { g_display = XOpenDisplay(NULL); }*/ @@ -1263,18 +1486,21 @@ 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), drawableType=0x%02X\n", display, config, render_type, share_list, is_direct, (config)?config->drawableType:0); + //printf("glXCreateNewContext(%p, %p, %d, %p, %i), drawableType=0x%02X\n", display, config, render_type, share_list, is_direct, (config)?config->drawableType:0); + if(render_type!=GLX_RGBA_TYPE) + return 0; if(config && config->drawableType==GLX_PBUFFER_BIT) { return createPBufferContext(display, share_list, config); } else - return glXCreateContext(display, 0, share_list, is_direct); + return glXCreateContextAttribsARB(display, config, share_list, is_direct, NULL); + //return glXCreateContext(display, 0, share_list, is_direct); } #endif //ANDROID EXPORT void glXSwapIntervalMESA(int interval) { -//printf("glXSwapInterval(%i)\n", interval); +//LOGD("glXSwapInterval(%i)\n", interval); #ifdef USE_FBIO if (! g_vsync) - printf("LIBGL: Enable LIBGL_VSYNC=1 if you want to use vsync.\n"); + LOGD("LIBGL: Enable LIBGL_VSYNC=1 if you want to use vsync.\n"); swap_interval = interval; #else LOAD_EGL(eglSwapInterval); @@ -1296,8 +1522,6 @@ EXPORT void glXCopyContext(Display *display, GLXContext src, GLXContext dst, GLu // mask is ignored for now, but should include glPushAttrib / glPopAttrib memcpy(dst, src, sizeof(struct __GLXContextRec)); } -EXPORT void glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap) {} // should return GLXPixmap -EXPORT void glXDestroyGLXPixmap(Display *display, void *pixmap) {} // really wants a GLXpixmap EXPORT Window glXCreateWindow(Display *display, GLXFBConfig config, Window win, int *attrib_list) {return win;} // should return GLXWindow EXPORT void glXDestroyWindow(Display *display, void *win) {} // really wants a GLXWindow @@ -1338,7 +1562,7 @@ EXPORT void glXUseXFont(Font font, int first, int count, int listBase) { // Grab font params fs = XQueryFont(dpy, font); if (!fs) { - printf("LIBGL: error, no font set before call to glXUseFont\n"); + LOGE("LIBGL: error, no font set before call to glXUseFont\n"); return; } max_width = fs->max_bounds.rbearing - fs->min_bounds.lbearing; @@ -1476,6 +1700,9 @@ GLXPbuffer addPBuffer(EGLSurface surface, int Width, int Height, EGLContext Cont pbuffersize[pbufferlist_size].Width = Width; pbuffersize[pbufferlist_size].Height = Height; pbuffersize[pbufferlist_size].Context = Context; + pbuffersize[pbufferlist_size].Surface = surface; + pbuffersize[pbufferlist_size].gc = NULL; + pbuffersize[pbufferlist_size].Type = 1; // 1 = pbuffer return pbufferlist[pbufferlist_size++]; } void delPBuffer(int j) @@ -1484,12 +1711,13 @@ void delPBuffer(int j) pbufferlist[j] = 0; pbuffersize[j].Width = 0; pbuffersize[j].Height = 0; + pbuffersize[j].gc = 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("glxDestroyPBuffer(%p, %p)\n", dpy, pbuf); 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_RED_SIZE, redBits, + EGL_GREEN_SIZE, greenBits, + EGL_BLUE_SIZE, blueBits, + EGL_ALPHA_SIZE, alphaBits, + EGL_DEPTH_SIZE, 1, + EGL_STENCIL_SIZE, 1, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_SAMPLE_BUFFERS, samplebuffers, + EGL_SAMPLES, samples, 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); + init_display((g_usefb)?g_display:dpy); if (eglDisplay == EGL_NO_DISPLAY) { - printf("LIBGL: Unable to create EGL display.\n"); + LOGD("LIBGL: Unable to create EGL display.\n"); return 0; } } @@ -1538,7 +1766,7 @@ int createPBuffer(Display * dpy, GLXFBConfig config, const EGLint * egl_attribs, egl_eglBindAPI(EGL_OPENGL_ES_API); result = egl_eglInitialize(eglDisplay, NULL, NULL); if (result != EGL_TRUE) { - printf("LIBGL: Unable to initialize EGL display.\n"); + LOGD("LIBGL: Unable to initialize EGL display.\n"); return 0; } eglInitialized = true; @@ -1551,7 +1779,7 @@ int createPBuffer(Display * dpy, GLXFBConfig config, const EGLint * egl_attribs, CheckEGLErrors(); if (result != EGL_TRUE || configsFound == 0) { - printf("LIBGL: No EGL configs found.\n"); + LOGD("LIBGL: No EGL configs found.\n"); return 0; } @@ -1559,7 +1787,7 @@ int createPBuffer(Display * dpy, GLXFBConfig config, const EGLint * egl_attribs, (*Surface) = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs); if((*Surface)==EGL_NO_SURFACE) { - printf("LIBGL: Error creating PBuffer\n"); + LOGD("LIBGL: Error creating PBuffer\n"); return 0; } @@ -1569,7 +1797,7 @@ int createPBuffer(Display * dpy, GLXFBConfig config, const EGLint * egl_attribs, } EXPORT GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int * attrib_list) { -//printf("glXCreatePbuffer(%p, %p, %p)\n", dpy, config, attrib_list); + //printf("glXCreatePbuffer(%p, %p, %p)\n", dpy, config, attrib_list); LOAD_EGL(eglQuerySurface); EGLSurface Surface = 0; @@ -1603,7 +1831,12 @@ EXPORT GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int } egl_attribs[i++] = EGL_NONE; - if(createPBuffer(dpy, config, egl_attribs, &Surface, &Context)==0) { + // Check that the config is for PBuffer + if(config->drawableType&GLX_PBUFFER_BIT!=GLX_PBUFFER_BIT) + return 0; + + + if(createPBuffer(dpy, egl_attribs, &Surface, &Context, config->redBits, config->greenBits, config->blueBits, config->alphaBits, config->nMultiSampleBuffers, config->multiSampleSize)==0) { return 0; } @@ -1615,4 +1848,315 @@ EXPORT GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int return addPBuffer(Surface, Width, Height, Context); } +GLXPbuffer addPixBuffer(Display *dpy, EGLSurface surface, int Width, int Height, EGLContext Context, Pixmap pixmap, int depth, int emulated) +{ + 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)pixmap; + pbuffersize[pbufferlist_size].Width = Width; + pbuffersize[pbufferlist_size].Height = Height; + pbuffersize[pbufferlist_size].Context = Context; + pbuffersize[pbufferlist_size].Surface = surface; + pbuffersize[pbufferlist_size].Depth = depth; + pbuffersize[pbufferlist_size].dpy = dpy; + pbuffersize[pbufferlist_size].gc = (emulated)?XCreateGC(dpy, pixmap, 0, NULL):NULL; + pbuffersize[pbufferlist_size].frame = NULL; + + pbuffersize[pbufferlist_size].Type = 2+emulated; //2 = pixmap, 3 = emulated pixmap, 4 = emulated win + return pbufferlist[pbufferlist_size++]; +} +void delPixBuffer(int j) +{ + LOAD_EGL(eglDestroyContext); + if(pbuffersize[j].gc) + XFree(pbuffersize[j].gc); + if(pbuffersize[j].frame) { + XDestroyImage(pbuffersize[j].frame); + } + pbufferlist[j] = 0; + pbuffersize[j].Width = 0; + pbuffersize[j].Height = 0; + pbuffersize[j].Depth = 0; + pbuffersize[j].dpy = 0; + pbuffersize[j].gc = 0; + pbuffersize[j].Surface = 0; + egl_eglDestroyContext(eglDisplay, pbuffersize[j].Context); + // should pack, but I think it's useless for common use +} + +int createPixBuffer(Display * dpy, int bpp, const EGLint * egl_attribs, NativePixmapType nativepixmap, EGLSurface* Surface, EGLContext* Context) { + LOAD_EGL(eglChooseConfig); + LOAD_EGL(eglCreatePixmapSurface); + LOAD_EGL(eglInitialize); + LOAD_EGL(eglBindAPI); + LOAD_EGL(eglCreateContext); + + EGLint configAttribs[] = { + EGL_RED_SIZE, (bpp>16)?8:5, + EGL_GREEN_SIZE, (bpp==15)?5:(bpp>16)?8:6, + EGL_BLUE_SIZE, (bpp>16)?8:5, + EGL_ALPHA_SIZE, (bpp==32)?8:0, + EGL_DEPTH_SIZE, 1, // some depth + EGL_STENCIL_SIZE, 1, // some stencil too + EGL_SURFACE_TYPE, EGL_PIXMAP_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + // Init what need to be done + EGLBoolean result; + if (eglDisplay == NULL || eglDisplay == EGL_NO_DISPLAY) { + init_display((g_usefb)?g_display:dpy); + if (eglDisplay == EGL_NO_DISPLAY) { + LOGE("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) { + LOGE("LIBGL: Unable to initialize EGL display.\n"); + return 0; + } + eglInitialized = true; + } + + // select a configuration + int configsFound; + static EGLConfig pixbufConfigs[1]; + result = egl_eglChooseConfig(eglDisplay, configAttribs, pixbufConfigs, 1, &configsFound); + + CheckEGLErrors(); + if (result != EGL_TRUE || configsFound == 0) { + LOGE("LIBGL: No EGL configs found.\n"); + return 0; + } + + // now, create the PBufferSurface + (*Surface) = egl_eglCreatePixmapSurface(eglDisplay, pixbufConfigs[0], nativepixmap,egl_attribs); + + if((*Surface)==EGL_NO_SURFACE) { + LOGE("LIBGL: Error creating PBuffer\n"); + return 0; + } + + (*Context) = egl_eglCreateContext(eglDisplay, pixbufConfigs[0], EGL_NO_CONTEXT, egl_context_attrib); + + return 1; +} + +EXPORT GLXPixmap glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap) { + //LOGD("glXCreateGLXPixmap(%p, %p, %p)\n", display, visual, pixmap); + LOAD_EGL(eglQuerySurface); + + EGLSurface Surface = 0; + EGLContext Context = 0; + //first, analyse PixMap to get it's dimensions and color depth... + unsigned int width, height, border, depth; + Window root; + int x, y; + int emulated = 0; + XGetGeometry(display, pixmap, &root, &x, &y, &width, &height, &border, &depth); + // let's try to create a PixmapSurface directly + if(g_usefb || createPixBuffer(display, depth, NULL, (NativePixmapType)pixmap, &Surface, &Context)==0) { + // fail, so emulate with a PBuffer + SHUT(LOGE("LIBGL: Pixmap creation failed, trying PBuffer instead\n")); + //let's create a PixBuffer attributes + EGLint egl_attribs[10]; // should be enough + int i = 0; + egl_attribs[i++] = EGL_WIDTH; + egl_attribs[i++] = width; + egl_attribs[i++] = EGL_HEIGHT; + egl_attribs[i++] = height; + egl_attribs[i++] = EGL_NONE; + + if(createPBuffer(display, egl_attribs, &Surface, &Context, (depth>16)?8:5, (depth==15)?5:(depth>16)?8:6, (depth>16)?8:5, (depth==32)?8:0, 0, 0)==0) { + // fail too, abort + SHUT(LOGE("LIBGL: PBuffer creation failed too\n")); + return 0; + } + emulated = 1; + + } + int Width, Height; + + egl_eglQuerySurface(eglDisplay,Surface,EGL_WIDTH,&Width); + egl_eglQuerySurface(eglDisplay,Surface,EGL_HEIGHT,&Height); + + return addPixBuffer(display, Surface, Width, Height, Context, pixmap, depth, emulated); +} + +GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list) { +// LOGD("glXCreatePixmap(%p, %p, %p, %p)\n", dpy, config, pixmap, attrib_list); + // Check that the config is for PBuffer + if(config->drawableType&GLX_PIXMAP_BIT!=GLX_PIXMAP_BIT) + return 0; + + return glXCreateGLXPixmap(dpy, NULL, pixmap); +} + + +EXPORT void glXDestroyGLXPixmap(Display *display, void *pixmap) { +//LOGD("glXDestroyGLXPixmap(%p, %p)\n", display, pixmap); + LOAD_EGL(eglDestroySurface); + int j=0; + while(jemulatedPixmap) + return; + + Pixmap drawable = (Pixmap)pbufferlist[glstate->emulatedPixmap-1]; + + glx_buffSize *buff = &pbuffersize[glstate->emulatedPixmap-1]; + + int Width = buff->Width; + int Height = buff->Height; + int Depth = buff->Depth; + Display *dpy = buff->dpy; + GC gc = buff->gc; + // the reverse stuff can probably be better! + int reverse = buff->Type==4?1:0; + int sbuf = Width * Height * (Depth==16?2:4); + + // create things if needed + if(!buff->frame) { + buff->frame = XCreateImage(dpy, NULL /*visual*/, Depth, ZPixmap, 0, malloc(Width*(Height+reverse)*(Depth==16?2:4)), Width, Height, (Depth==16)?16:32, 0); + } + + XImage* frame = buff->frame; + if (!frame) { + return; + } + uintptr_t pix=(uintptr_t)frame->data; + + // grab framebuffer +#ifdef PANDORA + LOAD_GLES(glReadPixels); + if(Depth==16) { + void* tmp = malloc(Width*Height*4); + gles_glReadPixels(0, 0, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, tmp); + if(reverse) { + int stride = Width * 2; + uintptr_t src_pos = (uintptr_t)tmp; + uintptr_t dst_pos = (uintptr_t)pix+sbuf-stride; + for (int i = 0; i < Height; i++) { + for (int j = 0; j < Width; j++) { + *(GLushort*)dst_pos = ((GLushort)(((char*)src_pos)[0]&0xf8)>>(3)) | ((GLushort)(((char*)src_pos)[1]&0xfc)<<(5-2)) | ((GLushort)(((char*)src_pos)[2]&0xf8)<<(11-3)); + src_pos += 4; + dst_pos += 2; + } + dst_pos -= 2*stride; + } + } else + pixel_convert(tmp, (void**)&pix, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 0); + free(tmp); + } else { + gles_glReadPixels(0, 0, Width, Height, GL_BGRA, GL_UNSIGNED_BYTE, (void*)pix); + if(reverse) { + int stride = Width * 4; + uintptr_t end=pix+sbuf-stride; + uintptr_t beg=pix; + void* const tmp = (void*)(pix+sbuf); + for (; beg < end; beg+=stride, end-=stride) { + memcpy(tmp, (void*)end, stride); + memcpy((void*)end, (void*)beg, stride); + memcpy((void*)beg, tmp, stride); + } + } + } +#else + glshim_glReadPixels(0, 0, Width, Height, (Depth==16)?GL_RGB:GL_BGRA, (Depth==16)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_BYTE, (void*)pix); + if(reverse) { + int stride = Width * (Depth==16?2:4); + uintptr_t end=pix+sbuf-stride; + uintptr_t beg=pix; + void* const tmp = (void*)(pix+sbuf); + for (; beg < end; beg+=stride, end-=stride) { + memcpy(tmp, (void*)end, stride); + memcpy((void*)end, (void*)beg, stride); + memcpy((void*)beg, tmp, stride); + } + } +#endif + // blit + XPutImage(dpy, drawable, gc, frame, 0, 0, 0, 0, Width, Height); + + // grab the size of the drawable if it has changed + if(reverse) { + // Get Window size and all... + unsigned int width, height, border, depth; + Window root; + int x, y; + XGetGeometry(dpy, drawable, &root, &x, &y, &width, &height, &border, &depth); + if(width!=Width || height!=Height || depth!=Depth) { + LOAD_EGL(eglCreatePbufferSurface); + LOAD_EGL(eglDestroySurface); + LOAD_EGL(eglMakeCurrent); + LOAD_EGL(eglChooseConfig); + // destroy old stuff + XSync(dpy, False); // synch seems needed before the DestroyImage... + XDestroyImage(frame); + buff->frame = 0; + + + //let's create a PBuffer attributes + EGLint egl_attribs[10]; // should be enough + int i = 0; + egl_attribs[i++] = EGL_WIDTH; + egl_attribs[i++] = width; + egl_attribs[i++] = EGL_HEIGHT; + egl_attribs[i++] = height; + egl_attribs[i++] = EGL_NONE; + + EGLint configAttribs[] = { + EGL_RED_SIZE, (Depth>16)?8:5, + EGL_GREEN_SIZE, (Depth==15)?5:(Depth>16)?8:6, + EGL_BLUE_SIZE, (depth>16)?8:5, + EGL_ALPHA_SIZE, (depth==32)?8:0, + EGL_DEPTH_SIZE, 1, + EGL_STENCIL_SIZE, 1, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + int configsFound; + static EGLConfig pbufConfigs[1]; + egl_eglChooseConfig(eglDisplay, configAttribs, pbufConfigs, 1, &configsFound); + + EGLSurface Surface = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs); + + buff->glxcontext->eglSurface = Surface; + + egl_eglMakeCurrent(eglDisplay, Surface, Surface, eglContext); + + egl_eglDestroySurface(eglDisplay, buff->Surface); + buff->Surface = Surface; + buff->Width = width; + buff->Height = height; + buff->Depth = depth; + } + } +} + #endif //ANDROID diff --git a/project/jni/glshim/src/glx/glx.h b/project/jni/glshim/src/glx/glx.h index 4032467d7..ee8d45b8f 100755 --- a/project/jni/glshim/src/glx/glx.h +++ b/project/jni/glshim/src/glx/glx.h @@ -138,12 +138,18 @@ struct __GLXContextRec { EGLSurface eglSurface; EGLConfig eglConfigs[1]; EGLContext eglContext; + int samples; + int samplebuffers; + int depth; + int stencil; + int rbits, gbits, bbits, abits; void* glstate; - int contextType; // 0 = Window, 1 = PBuffer + int contextType; // 0 = Window, 1 = PBuffer, 2 = PixmapBuffer, 3 = Emulated PixmapBuffer (with PBuffer) }; typedef struct __GLXContextRec *GLXContext; typedef XID GLXPbuffer; +typedef XID GLXPixmap; #endif //ANDROID struct __GLXFBConfigRec { int visualType; @@ -226,11 +232,9 @@ const char *glXQueryServerString(Display *display, int screen, int name); #endif //ANDROID GLXDrawable glXGetCurrentDrawable(); #ifndef ANDROID -void glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap); int glXGetConfig(Display *display, XVisualInfo *visual, int attribute, int *value); void glXCopyContext(Display *display, GLXContext src, GLXContext dst, GLuint mask); void glXDestroyContext(Display *display, GLXContext ctx); -void glXDestroyGLXPixmap(Display *display, void *pixmap); void glXSwapBuffers(Display *display, int drawable); void glXUseXFont(Font font, int first, int count, int listBase); #endif //ANDROID @@ -260,4 +264,9 @@ GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, int render_ void glXDestroyPbuffer(Display * dpy, GLXPbuffer pbuf); GLXPbuffer glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int * attrib_list); + +GLXPixmap glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list); +void glXDestroyPixmap(Display *display, void *pixmap); +GLXPixmap glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap); +void glXDestroyGLXPixmap(Display *display, void *pixmap); #endif //ANDROID diff --git a/project/jni/glshim/src/glx/hardext.c b/project/jni/glshim/src/glx/hardext.c new file mode 100755 index 000000000..bec57b7bd --- /dev/null +++ b/project/jni/glshim/src/glx/hardext.c @@ -0,0 +1,147 @@ +#include "../gl/gl.h" +#include "hardext.h" + +static int tested = 0; + +hardext_t hardext; + +extern int glshim_nobanner; +#define SHUT(a) if(!glshim_nobanner) a + +void GetHardwareExtensions(int notest) +{ + // used EGL & GLES functions + LOAD_EGL(eglBindAPI); + LOAD_EGL(eglInitialize); + LOAD_EGL(eglGetDisplay); + LOAD_EGL(eglCreatePbufferSurface); + LOAD_EGL(eglDestroySurface); + LOAD_EGL(eglDestroyContext); + LOAD_EGL(eglMakeCurrent); + LOAD_EGL(eglChooseConfig); + LOAD_EGL(eglCreateContext); + LOAD_EGL(eglQueryString); + LOAD_GLES(glGetString); + LOAD_GLES(glGetIntegerv); + + EGLDisplay eglDisplay; + EGLSurface eglSurface; + EGLContext eglContext; + + if(tested) return; + // put some default values + memset(&hardext, 0, sizeof(hardext)); + hardext.maxtex = 1; + hardext.maxsize = 2048; + hardext.readf = GL_RGBA; + hardext.readt = GL_UNSIGNED_BYTE; + + if(notest) { + SHUT(LOGD("LIBGL: Hardware test disabled, nothing activated...\n")); + } + + // Create a PBuffer first... + EGLint egl_context_attrib[] = { + #ifdef USE_ES2 + EGL_CONTEXT_CLIENT_VERSION, 2, + #endif + EGL_NONE + }; + + //let's create a PBuffer attributes + EGLint egl_attribs[10]; // should be enough + int i = 0; + egl_attribs[i++] = EGL_WIDTH; + egl_attribs[i++] = 32; + egl_attribs[i++] = EGL_HEIGHT; + egl_attribs[i++] = 32; + egl_attribs[i++] = EGL_NONE; + + EGLint configAttribs[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, + EGL_NONE + }; + + int configsFound; + static EGLConfig pbufConfigs[1]; + + eglDisplay = egl_eglGetDisplay(EGL_DEFAULT_DISPLAY); + + egl_eglBindAPI(EGL_OPENGL_ES_API); + if (egl_eglInitialize(eglDisplay, NULL, NULL) != EGL_TRUE) { + LOGE("LIBGL: Error while gathering supported extension (Init issue), default to none\n"); + return; + } + + egl_eglChooseConfig(eglDisplay, configAttribs, pbufConfigs, 1, &configsFound); + if(!configsFound) { + SHUT(LOGE("LIBGL: Error while gathering supported extension (Config issue), default to none\n")); + return; + } + eglContext = egl_eglCreateContext(eglDisplay, pbufConfigs[0], EGL_NO_CONTEXT, egl_context_attrib); + if(!eglContext) { + SHUT(LOGE("LIBGL: Error while gathering supported extension (Context issue), default to none\n")); + return; + } + eglSurface = egl_eglCreatePbufferSurface(eglDisplay, pbufConfigs[0], egl_attribs); + if(!eglSurface) { + SHUT(LOGE("LIBGL: Error while gathering supported extension (Surface issue), default to none\n")); + egl_eglDestroyContext(eglDisplay, eglContext); + return; + } + egl_eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); + + // Now get extensions + const char* Exts = gles_glGetString(GL_EXTENSIONS); + // Parse them! + #define S(A, B, C) if(strstr(Exts, A)) { hardext.B = 1; SHUT(LOGD("LIBGL: Extension %s detected%s",A, C?" and used\n":"\n")); } + if(strstr(Exts, "GL_APPLE_texture_2D_limited_npot")) hardext.npot = 1; + if(strstr(Exts, "GL_ARB_texture_non_power_of_two ")) hardext.npot = 2; + if(hardext.npot>0) { + SHUT(LOGD("LIBGL: Hardware %s NPOT detected and used\n", hardext.npot==2?"Full":"Limited")); + } + S("GL_OES_blend_subtract", blendsub, 1); + S("GL_OES_blend_func_separate", blendfunc, 1); + S("GL_OES_blend_equation_separate", blendeq, 1); + S("GL_EXT_blend_minmax", blendminmax, 1); + S("GL_EXT_blend_color", blendcolor, 1); + S("GL_OES_point_sprite", pointsprite, 1); + S("GL_OES_point_size_array", pointsize, 0); + S("GL_OES_element_index_uint", elementuint, 0); + S("GL_OES_framebuffer_object", fbo, 1); + S("GL_OES_packed_depth_stencil", depthstencil, 1); + S("GL_OES_depth24", depth24, 1); + S("GL_OES_rgb8_rgba8", rgba8, 1); + S("GL_EXT_multi_draw_arrays", multidraw, 1); + S("GL_EXT_texture_format_BGRA8888", bgra8888, 0); + S("GL_OES_depth_texture", depthtex, 1); + + // Now get some max stuffs + gles_glGetIntegerv(GL_MAX_TEXTURE_SIZE, &hardext.maxsize); + SHUT(LOGD("LIBGL: Max texture size: %d\n", hardext.maxsize)); + 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... + 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) + gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &hardext.readf); + gles_glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &hardext.readt); + SHUT(LOGD("LIBGL: Implementation Read is %s/%s\n", PrintEnum(hardext.readf), PrintEnum(hardext.readt))); +#endif + + if(strstr(egl_eglQueryString(eglDisplay, EGL_EXTENSIONS), "EGL_KHR_gl_colorspace")) { + LOGD("LIBGL: sRGB surface supported\n"); + hardext.srgb = 1; + } + + // End, cleanup + egl_eglMakeCurrent(eglDisplay, 0, 0, EGL_NO_CONTEXT); + egl_eglDestroySurface(eglDisplay, eglSurface); + egl_eglDestroyContext(eglDisplay, eglContext); +} \ No newline at end of file diff --git a/project/jni/glshim/src/glx/hardext.h b/project/jni/glshim/src/glx/hardext.h new file mode 100755 index 000000000..9deb7838f --- /dev/null +++ b/project/jni/glshim/src/glx/hardext.h @@ -0,0 +1,33 @@ +#ifndef _GLX_HARDEXT_H_ +#define _GLX_HARDEXT_H_ + +typedef struct _hardext { + int npot; // 0 = no npot capability, 1 = limited npot, 2 = full npot + int maxtex; // maximum number of texture + int maxlights; // maximum number of light + int maxsize; // maximum texture size + int blendsub; // GL_OES_blend_subtract + int blendfunc; // GL_OES_blend_func_separate + int blendeq; // GL_OES_blend_equation_separate + int blendminmax; // GL_EXT_blend_minmax + int blendcolor; // GL_EXT_blend_color + int pointsprite; // GL_OES_point_sprite (not used yet) + int pointsize; // GL_OES_point_size_array (not used yet) + int elementuint; // GL_OES_element_index_uint (not used yet) + int fbo; // GL_OES_framebuffer_object + int depthstencil; // GL_OES_packed_depth_stencil + int depth24; // GL_OES_depth24 + int rgba8; // GL_OES_rgb8_rgba8 + int multidraw; // GL_EXT_multi_draw_arrays + int bgra8888; // GL_EXT_texture_format_BGRA8888 (not used yet) + int depthtex; // GL_OES_depth_texture + unsigned int readf; // implementation Read Format + unsigned int readt; // implementation Read Type + int srgb; // EGL_KHR_gl_colorspace +} hardext_t; + +extern hardext_t hardext; + +void GetHardwareExtensions(int test); + +#endif \ No newline at end of file diff --git a/project/jni/glshim/src/glx/lookup.c b/project/jni/glshim/src/glx/lookup.c index 8c93f862b..f004ecd7c 100755 --- a/project/jni/glshim/src/glx/lookup.c +++ b/project/jni/glshim/src/glx/lookup.c @@ -2,6 +2,7 @@ #include "../gl/gl.h" #endif #include "glx.h" +#include "hardext.h" #include "../gl/directstate.h" @@ -37,7 +38,7 @@ extern int export_silentstub; #define STUB(func_name) \ if (strcmp(name, #func_name) == 0) { \ - if(!export_silentstub) printf("glX stub: %s\n", #func_name); \ + if(!export_silentstub) LOGD("glX stub: %s\n", #func_name); \ return (void *)glXStub; \ } @@ -67,9 +68,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) { EX(glXCreateContext); EX(glXCreateNewContext); EX(glXCreateContextAttribsARB); - EX(glXCreateGLXPixmap); EX(glXDestroyContext); - EX(glXDestroyGLXPixmap); EX(glXGetConfig); EX(glXGetCurrentDisplay); EX(glXGetCurrentDrawable); @@ -103,13 +102,25 @@ EXPORT void *glXGetProcAddressARB(const char *name) { EX(glXCreatePbuffer); EX(glXDestroyPbuffer); - STUB(glXCreatePixmap); - STUB(glXDestroyPixmap); + EX(glXCreatePixmap); + EX(glXDestroyPixmap); + EX(glXCreateGLXPixmap); + EX(glXDestroyGLXPixmap); STUB(glXGetCurrentReadDrawable); STUB(glXGetSelectedEvent); STUB(glXSelectEvent); #endif //ANDROID - + // GL_EXT_texture_object (yeah, super old!) + _EXT(glGenTextures); + _EXT(glBindTexture); + _EXT(glDeleteTextures); + _EXT(glIsTexture); + _EXT(glAreTexturesResident); + _EXT(glPrioritizeTextures); + + // GL_EXT_polygonoffset + _EXT(glPolygonOffset); + // GL_ARB_vertex_buffer_object _ARB(glBindBuffer); _ARB(glBufferData); @@ -138,52 +149,54 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _ARB(glIsVertexArray); // GL_ARB_frameBuffer_ext - _EX(glFramebufferTexture1D); - _EX(glFramebufferTexture3D); - _EX(glFramebufferTextureLayer); - _EX(glRenderbufferStorageMultisample); - _EX(glBlitFramebuffer); - _EXT(glGenFramebuffers); - _EXT(glDeleteFramebuffers); - _EXT(glIsFramebuffer); - _EXT(glCheckFramebufferStatus); - _EXT(glBindFramebuffer); - _EXT(glFramebufferTexture2D); - _EXT(glFramebufferTexture1D); - _EXT(glFramebufferTexture3D); - _EXT(glGenRenderbuffers); - _EXT(glFramebufferRenderbuffer); - _EXT(glDeleteRenderbuffers); - _EXT(glRenderbufferStorage); - _EXT(glRenderbufferStorageMultisample); - _EXT(glBindRenderbuffer); - _EXT(glIsRenderbuffer); - _EXT(glGenerateMipmap); - _EXT(glGetFramebufferAttachmentParameteriv); - _EXT(glGetRenderbufferParameteriv); - _EXT(glFramebufferTextureLayer); - _EXT(glBlitFramebuffer); - _ARB(glGenFramebuffers); - _ARB(glDeleteFramebuffers); - _ARB(glIsFramebuffer); - _ARB(glCheckFramebufferStatus); - _ARB(glBindFramebuffer); - _ARB(glFramebufferTexture2D); - _ARB(glFramebufferTexture1D); - _ARB(glFramebufferTexture3D); - _ARB(glGenRenderbuffers); - _ARB(glFramebufferRenderbuffer); - _ARB(glDeleteRenderbuffers); - _ARB(glRenderbufferStorage); - _ARB(glRenderbufferStorageMultisample); - _ARB(glBindRenderbuffer); - _ARB(glIsRenderbuffer); - _ARB(glGenerateMipmap); - _ARB(glGetFramebufferAttachmentParameteriv); - _ARB(glGetRenderbufferParameteriv); - _ARB(glFramebufferTextureLayer); - _ARB(glBlitFramebuffer); - STUB(glDrawBuffersARB); + if(hardext.fbo) { + _EX(glFramebufferTexture1D); + _EX(glFramebufferTexture3D); + _EX(glFramebufferTextureLayer); + _EX(glRenderbufferStorageMultisample); + _EX(glBlitFramebuffer); + _EXT(glGenFramebuffers); + _EXT(glDeleteFramebuffers); + _EXT(glIsFramebuffer); + _EXT(glCheckFramebufferStatus); + _EXT(glBindFramebuffer); + _EXT(glFramebufferTexture2D); + _EXT(glFramebufferTexture1D); + _EXT(glFramebufferTexture3D); + _EXT(glGenRenderbuffers); + _EXT(glFramebufferRenderbuffer); + _EXT(glDeleteRenderbuffers); + _EXT(glRenderbufferStorage); + _EXT(glRenderbufferStorageMultisample); + _EXT(glBindRenderbuffer); + _EXT(glIsRenderbuffer); + _EXT(glGenerateMipmap); + _EXT(glGetFramebufferAttachmentParameteriv); + _EXT(glGetRenderbufferParameteriv); + _EXT(glFramebufferTextureLayer); + _EXT(glBlitFramebuffer); + _ARB(glGenFramebuffers); + _ARB(glDeleteFramebuffers); + _ARB(glIsFramebuffer); + _ARB(glCheckFramebufferStatus); + _ARB(glBindFramebuffer); + _ARB(glFramebufferTexture2D); + _ARB(glFramebufferTexture1D); + _ARB(glFramebufferTexture3D); + _ARB(glGenRenderbuffers); + _ARB(glFramebufferRenderbuffer); + _ARB(glDeleteRenderbuffers); + _ARB(glRenderbufferStorage); + _ARB(glRenderbufferStorageMultisample); + _ARB(glBindRenderbuffer); + _ARB(glIsRenderbuffer); + _ARB(glGenerateMipmap); + _ARB(glGetFramebufferAttachmentParameteriv); + _ARB(glGetRenderbufferParameteriv); + _ARB(glFramebufferTextureLayer); + _ARB(glBlitFramebuffer); + STUB(glDrawBuffersARB); + } /* MAP_EGL(glGenFramebuffersARB, glGenFramebuffersOES); @@ -317,7 +330,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _EX(glArrayElement); _EX(glBegin); _EX(glBitmap); - if(export_blendcolor) { + if(export_blendcolor || hardext.blendcolor) { _EX(glBlendColor); _EXT(glBlendColor); _ARB(glBlendColor); @@ -326,18 +339,21 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _ARB(glBlendEquation); _EXT(glBlendFunc); _ARB(glBlendFunc); -#ifndef ODROID - _EXT(glBlendEquationSeparate); - _ARB(glBlendEquationSeparate); - _EX(glBlendEquationSeparatei); - _EXT(glBlendEquationSeparatei); - _ARB(glBlendEquationSeparatei); - _EXT(glBlendFuncSeparate); - _ARB(glBlendFuncSeparate); - _EX(glBlendFuncSeparatei); - _EXT(glBlendFuncSeparatei); - _ARB(glBlendFuncSeparatei); -#endif + + if(hardext.blendeq) { + _EXT(glBlendEquationSeparate); + _ARB(glBlendEquationSeparate); + _EX(glBlendEquationSeparatei); + _EXT(glBlendEquationSeparatei); + _ARB(glBlendEquationSeparatei); + } + if(hardext.blendfunc) { + _EXT(glBlendFuncSeparate); + _ARB(glBlendFuncSeparate); + _EX(glBlendFuncSeparatei); + _EXT(glBlendFuncSeparatei); + _ARB(glBlendFuncSeparatei); + } _EX(glStencilMaskSeparate); _EXT(glStencilMaskSeparate); _EX(glCallList); @@ -444,6 +460,8 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _EX(glTexImage3D); _EX(glTexSubImage1D); _EX(glTexSubImage3D); + _EXT(glTexImage3D); + _EXT(glTexSubImage3D); _EX(glCompressedTexImage1D); _EX(glCompressedTexSubImage1D); _EX(glCompressedTexImage3D); @@ -478,7 +496,7 @@ EXPORT void *glXGetProcAddressARB(const char *name) { STUB(glClearAccum); STUB(glColorMaterial); STUB(glCopyTexImage3D); - STUB(glCopyTexSubImage3D); + _EX(glCopyTexSubImage3D); // It's a stub, calling the 2D one STUB(glFeedbackBuffer); STUB(glGetClipPlane); STUB(glGetLightiv); @@ -627,7 +645,10 @@ EXPORT void *glXGetProcAddressARB(const char *name) { _EX(glGetQueryObjectuiv); } - if (!export_silentstub) printf("glXGetProcAddress: %s not found.\n", name); + // GL_ARB_multisample + _ARB(glSampleCoverage); + + if (!export_silentstub) LOGD("glXGetProcAddress: %s not found.\n", name); return NULL; }