diff --git a/project/jni/glshim/README.md b/project/jni/glshim/README.md index 223f78f7d..b0d4d8af2 100755 --- a/project/jni/glshim/README.md +++ b/project/jni/glshim/README.md @@ -21,7 +21,7 @@ Compiling ---- *for Pandora* - cmake . ; make GL + cmake . -DPANDORA=1; make GL *or for the Raspberry Pi* @@ -35,20 +35,17 @@ Compiling An Android.mk is provided that should compile with an NDK - *or use ccmake* -Alternatively, you can use the curses-bases ccmake to select wich platform to use interactively. + +Alternatively, you can use the curses-bases ccmake (or any other gui frontend for cmake) to select wich platform to use interactively. ---- GLU ---- + Standard GLU do works without any issues. -But you can also find a GLES optimized version og GLU there https://github.com/lunixbochs/glues - - git clone git@github.com:lunixbochs/glues.git; git checkout glu; cmake .; make - ---- Installation @@ -147,8 +144,13 @@ Experimental: Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE * 0 : Default, nothing special * 1 : Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE (can be usefull for Xash3D engine) +##### LIBGL_BLENDCOLOR +Hack: Export a (faked) glBlendColor + * 0 : Default, don't expose gBlendColor + * 1 : Exposed the function (if no hadware support, faked function willbe used) + ##### LIBGL_VERSION -Control the glGetString version. Overide version string (should be in the form of "1.x") +Hack: Control the glGetString version. Overide version string (should be in the form of "1.x") ##### LIBGL_BATCH Experimental: Batch mode (fuse of contigous Display list, to limit Draw calls) @@ -161,3 +163,18 @@ Hack: glGetError() always return GL_NOERROR * 0 : Default, glGetError behave as it should * 1 : glGetError never fail. +##### LIBGL_GAMMA +Pandora Hack: Set a Gamma value (in decimal formal, 1.0 means no gamma boost) + * X.Y : Use X.Y as gamma when creating context (typical value can be 1.6 or 2.0) + +##### LIBGL_SRGB +ODROID Hack: Enable sRGB Surface (so Gamma corrected), if Hardware support it + * 0 : Default, don't try to use sRGB surface + * 1 : Enable sRGB Surface (but support will be tested first, must have EGL_KHR_gl_colorspace extension) + +##### LIBGL_FASTMATH +Hack: Activate some Fast Math in processor/coprocessor + * 0 : Default, nothing special + * 1 : On OpenPandora, activate "RunFast" on Cortex-A8 (mode default NaN, flush-to-zero) + : Not implemented on other platforms (will do nothing) + diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index 423456f6d..aabb010da 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -232,6 +232,21 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text } } + if(attachment==GL_DEPTH_ATTACHMENT) { + 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); + glshim_glBindRenderbuffer(GL_RENDERBUFFER, render_depth); + glshim_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, twidth, theight); + glshim_glBindRenderbuffer(GL_RENDERBUFFER, 0); + errorGL(); + glshim_glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, render_depth); + return; + } + twidth = twidth >> level; if(twidth<1) twidth=1; theight = theight >> level; if(theight<1) theight=1; @@ -250,7 +265,7 @@ void glshim_glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum text } texture = scrap_tex; } - + errorGL(); gles_glFramebufferTexture2D(target, attachment, textarget, texture, 0); } @@ -414,6 +429,15 @@ void glshim_glGetFramebufferAttachmentParameteriv(GLenum target, GLenum attachme //printf("glGetFramebufferAttachmentParameteriv(%s, %s, %s, %p)\n", PrintEnum(target), PrintEnum(attachment), PrintEnum(pname), params); LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); + // hack to return DEPTH size + if(target==GL_FRAMEBUFFER && attachment==GL_DEPTH_ATTACHMENT && pname==GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE) { + noerrorShim(); + glshim_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, params); + if (params) + *params = 16; //Depth buffer is 16 on GLES. No check for 24 bits here... + return; + } + errorGL(); return gles_glGetFramebufferAttachmentParameteriv(target, attachment, pname, params); } diff --git a/project/jni/glshim/src/gl/gl.c b/project/jni/glshim/src/gl/gl.c index 9dec4bca0..928049db3 100755 --- a/project/jni/glshim/src/gl/gl.c +++ b/project/jni/glshim/src/gl/gl.c @@ -33,7 +33,7 @@ int blendhack = 0; int export_blendcolor = 0; char glshim_version[50]; int initialized = 0; -int noerror = 0; +int glshim_noerror = 0; __attribute__((constructor)) void initialize_glshim() { @@ -194,7 +194,7 @@ void transposeMatrix(float *matrix) } // glGet -extern float zoomx, zoomy; +extern float raster_zoomx, raster_zoomy; extern GLfloat raster_scale[4]; extern GLfloat raster_bias[4]; @@ -363,10 +363,10 @@ void glshim_glGetFloatv(GLenum pname, GLfloat *params) { *params = glstate.texture.pack_lsb_first; break; case GL_ZOOM_X: - *params = zoomx; + *params = raster_zoomx; break; case GL_ZOOM_Y: - *params = zoomy; + *params = raster_zoomy; break; case GL_RED_SCALE: *params = raster_scale[0]; @@ -522,7 +522,9 @@ void glshim_glEnable(GLenum cap) { case GL_BLEND: which_cap = ENABLED_BLEND; break; case GL_CULL_FACE: which_cap = ENABLED_CULL; break; case GL_DEPTH_TEST: which_cap = ENABLED_DEPTH; break; - case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D; break; + case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D_TEX0 + +(glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active); + break; default: which_cap = ENABLED_LAST; break; } if (which_cap!=ENABLED_LAST) { @@ -556,7 +558,9 @@ void glshim_glDisable(GLenum cap) { case GL_BLEND: which_cap = ENABLED_BLEND; break; case GL_CULL_FACE: which_cap = ENABLED_CULL; break; case GL_DEPTH_TEST: which_cap = ENABLED_DEPTH; break; - case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D; break; + case GL_TEXTURE_2D: which_cap = ENABLED_TEX2D_TEX0 + +(glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active); + break; default: which_cap = ENABLED_LAST; break; } if (which_cap!=ENABLED_LAST) { @@ -671,7 +675,7 @@ static inline bool should_intercept_render(GLenum mode) { } void glshim_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { -//printf("glDrawElements(0x%04X, %d, 0x%04X, %p), map=%p\n", mode, count, type, indices, (glstate.vao->elements)?glstate.vao->elements->data:NULL); + //printf("glDrawElements(0x%04X, %d, 0x%04X, %p), map=%p\n", mode, count, type, indices, (glstate.vao->elements)?glstate.vao->elements->data:NULL); // TODO: split for count > 65535? // special check for QUADS and TRIANGLES that need multiple of 4 or 3 vertex... if (mode == GL_QUADS) while(count%4) count--; @@ -1746,7 +1750,7 @@ void glPopMatrix() __attribute__((alias("glshim_glPopMatrix"))); GLenum glshim_glGetError() { LOAD_GLES(glGetError); - if(noerror) + if(glshim_noerror) return GL_NO_ERROR; if (glstate.shim_error) { GLenum tmp = glstate.last_error; @@ -1888,7 +1892,7 @@ 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); + //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; diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 6dcf22055..1e729d1a9 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -323,7 +323,6 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { 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) { @@ -436,9 +435,6 @@ void adjust_renderlist(renderlist_t *list); renderlist_t *extend_renderlist(renderlist_t *list) { if ((list->prev!=NULL) && ispurerender_renderlist(list) && islistscompatible_renderlist(list->prev, list)) { - // close first! - if (list->open) - adjust_renderlist(list); // append list! append_renderlist(list->prev, list); renderlist_t *new = alloc_renderlist(); @@ -462,8 +458,6 @@ renderlist_t *extend_renderlist(renderlist_t *list) { memcpy(new->lastNormal, list->lastNormal, 3*sizeof(GLfloat)); memcpy(new->lastSecondaryColors, list->lastSecondaryColors, 3*sizeof(GLfloat)); memcpy(new->lastColors, list->lastColors, 4*sizeof(GLfloat)); - if (list->open) - end_renderlist(list); return new; } } @@ -615,6 +609,9 @@ void draw_renderlist(renderlist_t *list) { int old_tex; GLushort *indices; do { + // close if needed! + if (list->open) + end_renderlist(list); // push/pop attributes if (list->pushattribute) glshim_glPushAttrib(list->pushattribute); @@ -1218,7 +1215,6 @@ void rlTexCoord4f(renderlist_t *list, GLfloat s, GLfloat t, GLfloat r, GLfloat q tex += 4; } } - GLfloat *tex = glstate.texcoord[0]; tex[0] = s; tex[1] = t; tex[2] = r; tex[3] = q; diff --git a/project/jni/glshim/src/gl/pixel.c b/project/jni/glshim/src/gl/pixel.c index c3fae5482..8b0481517 100755 --- a/project/jni/glshim/src/gl/pixel.c +++ b/project/jni/glshim/src/gl/pixel.c @@ -192,7 +192,7 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, #undef write_each } static inline -bool transform_pixel(const GLvoid *src, GLvoid *dst, +bool transform_pixel(const GLvoid *src, GLvoid *dst, const colorlayout_t *src_color, GLenum src_type, const GLfloat *scale, const GLfloat *bias) { @@ -342,9 +342,9 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, } static inline -bool half_pixel(const GLvoid *src0, const GLvoid *src1, - const GLvoid *src2, const GLvoid *src3, - GLvoid *dst, +bool half_pixel(const GLvoid *src0, const GLvoid *src1, + const GLvoid *src2, const GLvoid *src3, + GLvoid *dst, const colorlayout_t *src_color, GLenum src_type) { #define type_case(constant, type, ...) \ @@ -521,8 +521,8 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, static inline -bool quarter_pixel(const GLvoid *src[16], - GLvoid *dst, +bool quarter_pixel(const GLvoid *src[16], + GLvoid *dst, const colorlayout_t *src_color, GLenum src_type) { #define type_case(constant, type, ...) \ @@ -713,6 +713,23 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } + 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; + for (int i = 0; i < height; i++) { + for (int j = 0; j < width; j++) { + // invert 1555/BGRA to 5551/RGBA (0x1f / 0x3e0 / 7c00) + wtexmemp=(unsigned short*)src_pos-1; + wtexmem=*(wtexmemp); + *(GLushort*)dst_pos = ((wtexmem&0x8000)>>15) | ((wtexmem&0x7fff)<<1); + src_pos += src_stride; + dst_pos += dst_stride; + } + if (stride) + dst_pos += dst_width; + } + return true; + } 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++) { @@ -873,14 +890,14 @@ bool pixel_convert(const GLvoid *src, GLvoid **dst, } return true; } - if (! remap_pixel((const GLvoid *)src_pos, (GLvoid *)dst_pos, + if (! remap_pixel((const GLvoid *)src_pos, (GLvoid *)dst_pos, src_color, src_type, dst_color, dst_type)) { // fake convert, to get if it's ok or not return false; } for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { - remap_pixel((const GLvoid *)src_pos, (GLvoid *)dst_pos, + remap_pixel((const GLvoid *)src_pos, (GLvoid *)dst_pos, src_color, src_type, dst_color, dst_type); src_pos += src_stride; dst_pos += dst_stride; diff --git a/project/jni/glshim/src/gl/raster.c b/project/jni/glshim/src/gl/raster.c index 54668b05e..3d7d83640 100755 --- a/project/jni/glshim/src/gl/raster.c +++ b/project/jni/glshim/src/gl/raster.c @@ -1,18 +1,18 @@ #include "raster.h" #include "debug.h" -rasterpos_t rPos = {0, 0, 0}; -viewport_t viewport = {0, 0, 0, 0}; -GLubyte *raster = NULL; -GLfloat zoomx=1.0f; -GLfloat zoomy=1.0f; -GLuint raster_texture=0; -GLsizei raster_width=0; -GLsizei raster_height=0; -GLsizei raster_realwidth=0; -GLsizei raster_realheight=0; +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; +static GLsizei raster_realwidth=0; +static GLsizei raster_realheight=0; -GLint raster_x1, raster_x2, raster_y1, raster_y2; +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}; @@ -81,8 +81,8 @@ void glshim_glPixelZoom(GLfloat xfactor, GLfloat yfactor) { noerrorShim(); return; } - zoomx = xfactor; - zoomy = yfactor; + raster_zoomx = xfactor; + raster_zoomy = yfactor; //printf("LIBGL: glPixelZoom(%f, %f)\n", xfactor, yfactor); } @@ -223,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, zoomx, zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ + rPos.x, rPos.y, xorig, yorig, width, height, raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ // TODO: shouldn't be drawn if the raster pos is outside the viewport? // TODO: negative width/height mirrors bitmap? noerrorShim(); @@ -299,8 +299,8 @@ void glshim_glBitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig r->width = width; r->height = height; r->bitmap = true; - r->zoomx = zoomx; - r->zoomy = zoomy; + r->zoomx = raster_zoomx; + r->zoomy = raster_zoomy; LOAD_GLES(glDeleteTextures); if (!(glstate.list.compiling || glstate.gl_batch)) { render_raster_list(r); @@ -318,7 +318,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), zoomx, zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ + rPos.x, rPos.y, width, height, PrintEnum(format), PrintEnum(type), raster_zoomx, raster_zoomy, viewport.x, viewport.y, viewport.width, viewport.height);*/ // check of unsuported format... if ((format == GL_STENCIL_INDEX) || (format == GL_DEPTH_COMPONENT)) { errorShim(GL_INVALID_ENUM); @@ -382,8 +382,8 @@ void glshim_glDrawPixels(GLsizei width, GLsizei height, GLenum format, r->width = width; r->height = height; r->bitmap = false; - r->zoomx = zoomx; - r->zoomy = zoomy; + r->zoomx = raster_zoomx; + r->zoomy = raster_zoomy; if (!(glstate.list.compiling || glstate.gl_batch)) { render_raster_list(r); /* gles_glDeleteTextures(1, &r->texture); diff --git a/project/jni/glshim/src/gl/raster.h b/project/jni/glshim/src/gl/raster.h index 03c04cecc..f594652d5 100755 --- a/project/jni/glshim/src/gl/raster.h +++ b/project/jni/glshim/src/gl/raster.h @@ -22,8 +22,6 @@ typedef struct { GLsizei height; } viewport_t; -extern viewport_t viewport; - extern GLfloat raster_scale[4]; extern GLfloat raster_bias[4]; diff --git a/project/jni/glshim/src/gl/state.h b/project/jni/glshim/src/gl/state.h index 03ee69d6d..6e8a302e1 100755 --- a/project/jni/glshim/src/gl/state.h +++ b/project/jni/glshim/src/gl/state.h @@ -104,15 +104,22 @@ typedef enum { ENABLED_BLEND, ENABLED_CULL, ENABLED_DEPTH, - ENABLED_TEX2D, + ENABLED_TEX2D_TEX0, + ENABLED_TEX2D_TEX1, + ENABLED_TEX2D_TEX2, + ENABLED_TEX2D_TEX3, + ENABLED_TEX2D_TEX4, + ENABLED_TEX2D_TEX5, + ENABLED_TEX2D_TEX6, + ENABLED_TEX2D_TEX7, ENABLED_LAST } statbatch_enabled_t; typedef struct { int active_tex_changed; - GLenum active_tex; // only 1 active texture for now - GLenum bound_targ; - GLenum bound_tex; + GLenum active_tex; // current active texture + GLenum bound_targ[MAX_TEX]; + GLenum bound_tex[MAX_TEX]; int enabled[ENABLED_LAST]; // the enabled are: 0=not set, 1=enabled, 2=disabled GLenum blendfunc_s; GLenum blendfunc_d; diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index aed3afe37..e8c4bbd0e 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -82,7 +82,7 @@ void tex_setup_texcoord(GLuint texunit, GLuint len) { if (old!=texunit) glshim_glClientActiveTexture(texunit+GL_TEXTURE0); if (changes) { // first convert to GLfloat, without normalization - tex[texunit] = copy_gl_pointer_tex(&glstate.vao->pointers.tex_coord[texunit], 4, 0, len, glstate.vao->pointers.tex_coord[texunit].buffer); + tex[texunit] = copy_gl_pointer_tex(&glstate.vao->pointers.tex_coord[texunit], 4, 0, len, /*glstate.vao->pointers.tex_coord[texunit].buffer*/NULL); // the Buffer is already taken into account if (!tex[texunit]) { printf("LibGL: Error with Texture tranform\n"); gles_glTexCoordPointer(len, glstate.vao->pointers.tex_coord[texunit].type, glstate.vao->pointers.tex_coord[texunit].stride, glstate.vao->pointers.tex_coord[texunit].pointer); @@ -1184,18 +1184,19 @@ gltexture_t* glshim_getTexture(GLenum target, GLuint texture) { } return tex; } - +#define batch_activetex (glstate.statebatch.active_tex_changed?glstate.statebatch.active_tex:glstate.texture.active) void glshim_glBindTexture(GLenum target, GLuint texture) { noerrorShim(); if ((target!=GL_PROXY_TEXTURE_2D) && (glstate.list.active && (glstate.gl_batch && !glstate.list.compiling))) { - if ((glstate.statebatch.bound_targ == target) && (glstate.statebatch.bound_tex == texture)) + //printf("=> glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate.texture.active, glstate.texture.client, batch_activetex, glstate.statebatch.bound_targ[batch_activetex], glstate.statebatch.bound_tex[batch_activetex]); + if ((glstate.statebatch.bound_targ[batch_activetex] == target) && (glstate.statebatch.bound_tex[batch_activetex] == texture)) return; // nothing to do... - if (!glstate.statebatch.bound_targ) { - glstate.statebatch.bound_targ = target; - glstate.statebatch.bound_tex = texture; - } else { + if (glstate.statebatch.bound_targ[batch_activetex]) { flush(); } + glstate.statebatch.bound_targ[batch_activetex] = target; + glstate.statebatch.bound_tex[batch_activetex] = texture; + //printf(" <= glBindTexture(0x%04X, %u), active=%i, client=%i, batch_active=%i, batch_bound=0x%04X, batch_tex=%u\n", target, texture, glstate.texture.active, glstate.texture.client, batch_activetex, glstate.statebatch.bound_targ[batch_activetex], glstate.statebatch.bound_tex[batch_activetex]); } if ((target!=GL_PROXY_TEXTURE_2D) && ((glstate.list.compiling || glstate.gl_batch) && glstate.list.active)) { // check if already a texture binded, if yes, create a new list @@ -1260,6 +1261,7 @@ tex_changed=1; // seems buggy, temporary disabling that... } } } +#undef batch_activetex // TODO: also glTexParameterf(v)? void glshim_glTexParameteri(GLenum target, GLenum pname, GLint param) { diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index cf9f90464..a4551757a 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -2,8 +2,14 @@ #include #endif #include -#ifdef PANDORA +#if defined(PANDORA) || defined(ODROID) +#define USE_FBIO 1 +#endif + +#ifdef USE_FBIO #include +#endif +#ifdef PANDORA #include #include #endif @@ -18,10 +24,18 @@ #include "../gl/gl.h" #include "../glx/streaming.h" +#ifndef EGL_GL_COLORSPACE_KHR +#define EGL_GL_COLORSPACE_KHR 0x309D +#define EGL_GL_COLORSPACE_SRGB_KHR 0x3089 +#define EGL_GL_COLORSPACE_LINEAR_KHR 0x308A +#endif + static bool eglInitialized = false; 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; @@ -145,9 +159,11 @@ static GLXContext fbContext = NULL; static int fbcontext_count = 0; -#ifdef PANDORA +#ifdef USE_FBIO #ifndef FBIO_WAITFORVSYNC #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#endif +#ifdef PANDORA static float pandora_gamma = 0.0f; #endif static int fbdev = -1; @@ -169,7 +185,7 @@ extern int copytex; extern int nolumalpha; extern int blendhack; extern int export_blendcolor; -extern int noerror; +extern int glshim_noerror; extern char glshim_version[50]; bool g_recyclefbo = false; @@ -196,7 +212,7 @@ static void init_display(Display *display) { } #endif //ANDROID static void init_vsync() { -#ifdef PANDORA +#ifdef USE_FBIO fbdev = open("/dev/fb0", O_RDONLY); if (fbdev < 0) { fprintf(stderr, "Could not open /dev/fb0 for vsync.\n"); @@ -205,7 +221,7 @@ static void init_vsync() { } static void xrefresh() { - system("xrefresh"); + int dummy = system("xrefresh"); } #ifdef PANDORA @@ -217,7 +233,7 @@ static void pandora_set_gamma() { if(pandora_gamma>0.0f) { char buf[50]; sprintf(buf, "sudo /usr/pandora/scripts/op_gamma.sh %.2f", pandora_gamma); - system(buf); + int dummy = system(buf); } } #endif @@ -247,7 +263,7 @@ static void signal_handler(int sig) { if (! size) { printf("No stacktrace. Compile with -funwind-tables.\n"); } else { - printf("Stacktrace: %i\n", size); + printf("Stacktrace: %zd\n", size); backtrace_symbols_fd(array, size, 2); } break; @@ -278,6 +294,17 @@ static void init_liveinfo() { } else fcntl(sock, F_SETFL, O_NONBLOCK); } + +static void fast_math() { + // enable Cortex A8 RunFast + int v = 0; + __asm__ __volatile__ ( + "vmrs %0, fpscr\n" + "orr %0, #((1<<25)|(1<<24))\n" // default NaN, flush-to-zero + "vmsr fpscr, %0\n" + //"vmrs %0, fpscr\n" + : "=&r"(v)); +} #endif extern void initialize_glshim(); extern int initialized; @@ -339,11 +366,13 @@ static void scan_env() { g_usefbo = true; } env(LIBGL_FPS, g_showfps, "fps counter enabled"); -#ifdef PANDORA +#ifdef USE_FBIO env(LIBGL_VSYNC, g_vsync, "vsync enabled"); if (g_vsync) { init_vsync(); } +#endif +#ifdef PANDORA init_liveinfo(); if (sock>-1) { printf("LIBGL: LiveInfo detected, fps will be shown\n"); @@ -450,7 +479,7 @@ static void scan_env() { env(LIBGL_BLENDHACK, blendhack, "Change Blend GL_SRC_ALPHA, GL_ONE to GL_ONE, GL_ONE"); env(LIBGL_BLENDCOLOR, export_blendcolor, "Export a (faked) glBlendColor"); - env(LIBGL_NOERROR, noerror, "glGetError() always return GL_NOERROR"); + env(LIBGL_NOERROR, glshim_noerror, "glGetError() always return GL_NOERROR"); char *env_version = getenv("LIBGL_VERSION"); if (env_version) { @@ -465,6 +494,20 @@ static void scan_env() { atexit(pandora_reset_gamma); } #endif + char *env_srgb = getenv("LIBGL_SRGB"); + if (env_srgb && strcmp(env_srgb, "1") == 0) { + glx_surface_srgb = 1; + printf("LIBGL: enabling sRGB support\n"); + } + char *env_fastmath = getenv("LIBGL_FASTMATH"); + if (env_fastmath && strcmp(env_fastmath, "1") == 0) { +#ifdef PANDORA + printf("LIBGL: Enable FastMath for cortex-a8\n"); + fast_math(); +#else + printf("LIBGL: No FastMath on this platform\n"); +#endif + } char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) @@ -522,8 +565,8 @@ GLXContext glXCreateContext(Display *display, LOAD_EGL(eglInitialize); LOAD_EGL(eglCreateContext); LOAD_EGL(eglChooseConfig); + LOAD_EGL(eglQueryString); - GLXContext fake = malloc(sizeof(struct __GLXContextRec)); memset(fake, 0, sizeof(struct __GLXContextRec)); if (!g_usefb) { @@ -571,6 +614,15 @@ GLXContext glXCreateContext(Display *display, 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; if (!g_usefb) result = egl_eglChooseConfig(eglDisplay, configAttribs, fake->eglConfigs, 1, &configsFound); @@ -601,7 +653,7 @@ GLXContext glXCreateContext(Display *display, egl_eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT); } - //*TODO* put eglContext inside GLXcontext, to handle multiple Glxcontext + // *TODO* put eglContext inside GLXcontext, to handle multiple Glxcontext return fake; } @@ -672,12 +724,12 @@ XVisualInfo *glXChooseVisual(Display *display, g_display = XOpenDisplay(NULL); } */ - int default_depth = XDefaultDepth(display, screen); - if (default_depth != 16 && default_depth != 24) - printf("libGL: unusual desktop color depth %d\n", default_depth); + 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); XVisualInfo *visual = (XVisualInfo *)malloc(sizeof(XVisualInfo)); - if (!XMatchVisualInfo(display, screen, default_depth, TrueColor, visual)) { + if (!XMatchVisualInfo(display, screen, glx_default_depth, TrueColor, visual)) { printf("libGL: XMatchVisualInfo failed in glXChooseVisual\n"); return NULL; } @@ -726,6 +778,7 @@ Bool glXMakeCurrent(Display *display, if (g_usefb) drawable = 0; EGLBoolean result; + EGLint const sRGB[] = {EGL_GL_COLORSPACE_KHR, EGL_GL_COLORSPACE_SRGB_KHR, EGL_NONE}; if (!g_usefb) { // need current surface for eglSwapBuffer eglContext = context->eglContext; @@ -737,12 +790,13 @@ Bool glXMakeCurrent(Display *display, // 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, NULL); - result = egl_eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext); + 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, NULL); // create surface only if needed + 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; @@ -784,7 +838,7 @@ void glXSwapBuffers(Display *display, if (glstate.gl_batch || glstate.list.active){ flush(); } -#ifdef PANDORA +#ifdef USE_FBIO if (g_vsync && fbdev >= 0) { // TODO: can I just return if I don't meet vsync over multiple frames? // this will just block otherwise. @@ -886,7 +940,7 @@ Bool glXQueryVersion(Display *display, int *major, int *minor) { const char *glXGetClientString(Display *display, int name) { // TODO: return actual data here switch (name) { - case GLX_VENDOR: return "OpenPandora"; + case GLX_VENDOR: return "ptitSeb"; case GLX_VERSION: return "1.4 OpenPandora"; case GLX_EXTENSIONS: break; } @@ -943,8 +997,10 @@ XVisualInfo *glXGetVisualFromFBConfig(Display *display, GLXFBConfig config) { /*if (g_display == NULL) { g_display = XOpenDisplay(NULL); }*/ + if (glx_default_depth==0) + glx_default_depth = XDefaultDepth(display, 0); XVisualInfo *visual = (XVisualInfo *)malloc(sizeof(XVisualInfo)); - XMatchVisualInfo(display, 0, 16, TrueColor, visual); + XMatchVisualInfo(display, 0, glx_default_depth, TrueColor, visual); return visual; } @@ -956,7 +1012,7 @@ GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, #endif //ANDROID void glXSwapIntervalMESA(int interval) { printf("glXSwapInterval(%i)\n", interval); -#ifdef PANDORA +#ifdef USE_FBIO if (! g_vsync) printf("Enable LIBGL_VSYNC=1 if you want to use vsync.\n"); swap_interval = interval; @@ -982,7 +1038,7 @@ void glXCopyContext(Display *display, GLXContext src, GLXContext dst, GLuint mas } void glXCreateGLXPixmap(Display *display, XVisualInfo * visual, Pixmap pixmap) {} // should return GLXPixmap void glXDestroyGLXPixmap(Display *display, void *pixmap) {} // really wants a GLXpixmap -void glXCreateWindow(Display *display, GLXFBConfig config, Window win, int *attrib_list) {} // should return GLXWindow +Window glXCreateWindow(Display *display, GLXFBConfig config, Window win, int *attrib_list) {return win;} // should return GLXWindow void glXDestroyWindow(Display *display, void *win) {} // really wants a GLXWindow GLXDrawable glXGetCurrentDrawable() { diff --git a/project/jni/glshim/src/glx/glx.h b/project/jni/glshim/src/glx/glx.h index e9a7931cd..2b0aa7425 100755 --- a/project/jni/glshim/src/glx/glx.h +++ b/project/jni/glshim/src/glx/glx.h @@ -250,7 +250,7 @@ int glXGetFBConfigAttrib(Display *display, GLXFBConfig config, int attribute, in int glXQueryContext(Display *display, GLXContext ctx, int attribute, int *value); GLXFBConfig *glXChooseFBConfigSGIX(Display *display, int screen, const int *attrib_list, int *count); -void glXCreateWindow(Display *display, GLXFBConfig config, Window win, int *attrib_list); +Window glXCreateWindow(Display *display, GLXFBConfig config, Window win, int *attrib_list); void glXDestroyWindow(Display *display, void *win); Bool glXMakeContextCurrent(Display *display, int drawable, int readable, GLXContext context);