diff --git a/project/jni/glshim/Android.mk b/project/jni/glshim/Android.mk index e2c7e8508..a4144def2 100644 --- a/project/jni/glshim/Android.mk +++ b/project/jni/glshim/Android.mk @@ -38,11 +38,12 @@ LOCAL_SRC_FILES := \ src/gl/wrap/glesext.c \ src/gl/wrap/glstub.c \ src/gl/math/eval.c \ + src/glx/glx.c \ src/glx/lookup.c \ src/glx/streaming.c LOCAL_CFLAGS += -g -std=c99 -funwind-tables -O3 -DBCMHOST -include include/android_debug.h -LOCAL_LDLIBS := -ldl -llog -lEGL +#LOCAL_LDLIBS := -ldl -llog -lEGL -include $(BUILD_SHARED_LIBRARY) +include $(BUILD_STATIC_LIBRARY) diff --git a/project/jni/glshim/CMakeLists.txt.orig b/project/jni/glshim/CMakeLists.txt.orig new file mode 100755 index 000000000..45aead7b1 --- /dev/null +++ b/project/jni/glshim/CMakeLists.txt.orig @@ -0,0 +1,22 @@ +cmake_minimum_required(VERSION 2.6) + +project(glshim) + +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) + +link_directories(${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) + +# Raspberry PI +if(BCMHOST) + include_directories(/opt/vc/include /opt/vc/include/interface/vcos/pthreads /opt/vc/include/interface/vmcs_host/linux) + link_directories(/opt/vc/lib) + add_definitions(-DBCMHOST) +endif() + +link_directories(${CMAKE_BINARY_DIR}/lib) +add_definitions(-g -std=gnu99 -funwind-tables -O3) + +include_directories(include) +add_subdirectory(src) diff --git a/project/jni/glshim/CMakeLists.txt.rej b/project/jni/glshim/CMakeLists.txt.rej new file mode 100644 index 000000000..d63adc528 --- /dev/null +++ b/project/jni/glshim/CMakeLists.txt.rej @@ -0,0 +1,10 @@ +--- CMakeLists.txt 2015-02-28 07:35:40.000000000 +0200 ++++ CMakeLists.txt 2015-04-17 10:19:44.000000000 +0300 +@@ -15,7 +15,6 @@ + if(BCMHOST) + set(PI_LIBS bcm_host vcos pthread) + target_link_libraries(GL ${PI_LIBS} GLESv1_CM) +- target_link_libraries(GL2 ${PI_LIBS} GLESv2) + endif() + + if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") diff --git a/project/jni/glshim/include/GL/glx.h b/project/jni/glshim/include/GL/glx.h index a3a7d97c9..49d28a184 100644 --- a/project/jni/glshim/include/GL/glx.h +++ b/project/jni/glshim/include/GL/glx.h @@ -35,8 +35,8 @@ #pragma message disable nosimpint #endif #endif -#include -#include +//#include +//#include #ifdef __VMS # ifdef __cplusplus #pragma message enable nosimpint diff --git a/project/jni/glshim/src/config.h b/project/jni/glshim/src/config.h index 199a0e58f..640e5074f 100755 --- a/project/jni/glshim/src/config.h +++ b/project/jni/glshim/src/config.h @@ -38,6 +38,9 @@ #define skip_glGetBufferSubData #define skip_glBlendColor +#define skip_glBlendFunc + +#define skip_glFogfv /* #define skip_glBlendEquation #define skip_glBlendEquationSeparate @@ -64,6 +67,7 @@ #define skip_glGenTextures #define skip_glDeleteTextures #define skip_glPixelStorei +#define skip_glPixelStoref #define skip_glTexImage2D #define skip_glTexParameteri #define skip_glTexParameterf @@ -127,7 +131,8 @@ #define direct_glIsList #define direct_glNormalPointer #define direct_glPopClientAttrib -#define direct_glPixelStore +#define direct_glPixelStorei +#define direct_glPixelStoref #define direct_glPushClientAttrib #define direct_glRenderMode #define direct_glSelectBuffer diff --git a/project/jni/glshim/src/gl/const.h b/project/jni/glshim/src/gl/const.h index c2308f693..a65a58a07 100755 --- a/project/jni/glshim/src/gl/const.h +++ b/project/jni/glshim/src/gl/const.h @@ -139,6 +139,7 @@ #define GL_UNSIGNED_INT_2_10_10_10_REV 0x8368 #define GL_RGB8 0x8051 #define GL_RGB5 0x8050 +#define GL_RGBA8 0x8058 // types #define GL_BYTE 0x1400 @@ -267,6 +268,10 @@ #define GL_DST_COLOR 0x0306 #define GL_ONE_MINUS_DST_COLOR 0x0307 #define GL_SRC_ALPHA_SATURATE 0x0308 +#define GL_CONSTANT_COLOR 0x8001 +#define GL_ONE_MINUS_CONSTANT_COLOR 0x8002 +#define GL_CONSTANT_ALPHA 0x8003 +#define GL_ONE_MINUS_CONSTANT_ALPHA 0x8004 // glGet #define GL_AUX_BUFFERS 0x0C00 @@ -525,3 +530,4 @@ #define GL_TEXTURE_INTENSITY_TYPE 0x8C15 #define GL_DEPTH_COMPONENT24 0x81A6 #define GL_DEPTH_COMPONENT16 0x81A5 +#define GL_MAX_DRAW_BUFFERS_ARB 0x8824 diff --git a/project/jni/glshim/src/gl/framebuffers.c b/project/jni/glshim/src/gl/framebuffers.c index 6b0a08beb..4696fbe02 100755 --- a/project/jni/glshim/src/gl/framebuffers.c +++ b/project/jni/glshim/src/gl/framebuffers.c @@ -138,6 +138,12 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, LOAD_GLES(glTexImage2D); LOAD_GLES(glBindTexture); //printf("glFramebufferTexture2D(0x%04X, 0x%04X, 0x%04X, %u, %i)\n", target, attachment, textarget, texture, level); + + // Ignore Color attachment 1 .. 9 + if ((attachment>=GL_COLOR_ATTACHMENT0+1) && (attachment<=GL_COLOR_ATTACHMENT0+9)) { + errorShim(GL_INVALID_ENUM); + return; + } // find texture and get it's real name if (texture) { @@ -154,6 +160,7 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, k = kh_get(tex, list, texture); if (k == kh_end(list)){ +//printf("*WARNING* texture for FBO not found, name=%u\n", texture); } else { tex = kh_value(list, k); texture = tex->glname; @@ -168,7 +175,18 @@ void glFramebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, gltexture_t *bound = state.texture.bound[state.texture.active]; GLuint oldtex = (bound)?bound->glname:0; if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); - gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->width, tex->height, 0, tex->format, tex->type, NULL); + gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); + if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex); + } + if ((tex->width<32) || (tex->height<32)) { + printf("LIBGL: enlarging too-small texture for FBO\n"); + tex->nwidth = (tex->nwidth<32)?32:tex->nwidth; + tex->nheight = (tex->nheight<32)?32:tex->nheight; + tex->shrink = 0; + gltexture_t *bound = state.texture.bound[state.texture.active]; + GLuint oldtex = (bound)?bound->glname:0; + if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, tex->glname); + gles_glTexImage2D(GL_TEXTURE_2D, 0, tex->format, tex->nwidth, tex->nheight, 0, tex->format, tex->type, NULL); if (oldtex!=tex->glname) gles_glBindTexture(GL_TEXTURE_2D, oldtex); } //printf("found texture, glname=%u, size=%ix%i(%ix%i), format/type=0x%04X/0x%04X\n", texture, tex->width, tex->height, tex->nwidth, tex->nheight, tex->format, tex->type); @@ -197,7 +215,9 @@ void glGenRenderbuffers(GLsizei n, GLuint *renderbuffers) { void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) { LOAD_GLES_OES(glFramebufferRenderbuffer); + LOAD_GLES_OES(glGetFramebufferAttachmentParameteriv); //printf("glFramebufferRenderbuffer(0x%04X, 0x%04X, 0x%04X, %u)\n", target, attachment, renderbuffertarget, renderbuffer); + //TODO: handle target=READBUFFER or DRAWBUFFER... if (depthstencil && (attachment==GL_STENCIL_ATTACHMENT)) { khint_t k = kh_get(dsr, depthstencil, renderbuffer); @@ -207,6 +227,21 @@ void glFramebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbu } } + if ((current_fb!=0) && (renderbuffer==0)) { + //Hack, avoid unbind a renderbuffer on a framebuffer... + // TODO, avoid binding an already binded RB + noerrorShim(); + return; + } + if ((current_fb!=0) && (renderbuffer!=0) && ((attachment==GL_DEPTH_ATTACHMENT) || (attachment==GL_STENCIL_ATTACHMENT))) { + GLuint tmp; + gles_glGetFramebufferAttachmentParameteriv(target, attachment, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &tmp); + if (tmp==renderbuffer) { + noerrorShim(); + return; + } + } + errorGL(); gles_glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer); } @@ -575,6 +610,20 @@ void deleteMainFBO() { // all done... } +void glFramebufferTextureLayer( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { + glFramebufferTexture2D(target, attachment, GL_TEXTURE_2D, texture, level); // Force Texture2D, ignore layer... +} + +void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + // TODO! + // create a temp texture + // glCopyPixel of read FBO + // set viewport / matrixs + // glDraw of write FBO +printf("glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, 0x%04X, 0x%04X)\n", + srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} + // EXT direct wrapper void glGenFramebuffersEXT(GLsizei n, GLuint *ids) { @@ -628,3 +677,11 @@ void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, void glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint * params) { glGetRenderbufferParameteriv(target, pname, params); } + +void glFramebufferTextureLayerEXT( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer) { + glFramebufferTextureLayer(target, attachment, texture, level, layer); +} + +void glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { + glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); +} diff --git a/project/jni/glshim/src/gl/framebuffers.h b/project/jni/glshim/src/gl/framebuffers.h index ecc3a9182..e88cfc3de 100755 --- a/project/jni/glshim/src/gl/framebuffers.h +++ b/project/jni/glshim/src/gl/framebuffers.h @@ -23,7 +23,8 @@ void glGetRenderbufferParameteriv(GLenum target, GLenum pname, GLint * params); void glFramebufferTexture1D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); // naive Wrap void glFramebufferTexture3D(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint layer); // naive Wrap void glRenderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); //STUB - +void glFramebufferTextureLayer( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); // naive Wrap +void glBlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); // Direct creation of EXT versions... void glGenFramebuffersEXT(GLsizei n, GLuint *ids); @@ -43,6 +44,8 @@ GLboolean glIsRenderbufferEXT(GLuint renderbuffer); void glGenerateMipmapEXT(GLenum target); void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params); void glGetRenderbufferParameterivEXT(GLenum target, GLenum pname, GLint * params); +void glFramebufferTextureLayerEXT( GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +void glBlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); // Need to keep track of Renderbuffer that are created as DEPTH_STENCIL, to create 2 seperate buffers... typedef struct { diff --git a/project/jni/glshim/src/gl/gl.c b/project/jni/glshim/src/gl/gl.c index 0ef9ebc0a..daad06ea1 100755 --- a/project/jni/glshim/src/gl/gl.c +++ b/project/jni/glshim/src/gl/gl.c @@ -106,11 +106,13 @@ const GLubyte *glGetString(GLenum name) { "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 " "GL_EXT_blend_func_separate " "GL_EXT_blend_equation_separate " + "GL_ARB_draw_buffers " // "GL_EXT_blend_logic_op " // "GL_EXT_blend_color " // "GL_ARB_texture_cube_map " @@ -144,6 +146,10 @@ extern GLfloat raster_scale[4]; extern GLfloat raster_bias[4]; void glGetIntegerv(GLenum pname, GLint *params) { + if (params==NULL) { + errorShim(GL_INVALID_OPERATION); + return; + } GLint dummy; LOAD_GLES(glGetIntegerv); noerrorShim(); @@ -157,6 +163,9 @@ void glGetIntegerv(GLenum pname, GLint *params) { case GL_AUX_BUFFERS: *params = 0; break; + case GL_MAX_DRAW_BUFFERS_ARB: // fake... + *params = 1; + break; case GL_UNPACK_ROW_LENGTH: *params = state.texture.unpack_row_length; break; @@ -531,11 +540,16 @@ static inline bool should_intercept_render(GLenum mode) { } void 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, (state.buffers.elements)?state.buffers.elements->data:NULL); // TODO: split for count > 65535? if (count<0) { errorShim(GL_INVALID_VALUE); return; } + if (count==0) { + noerrorShim(); + return; + } noerrorShim(); GLushort *sindices = copy_gl_array((state.buffers.elements)?state.buffers.elements->data + (uintptr_t)indices:indices, @@ -705,6 +719,10 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { errorShim(GL_INVALID_VALUE); return; } + if (count==0) { + noerrorShim(); + return; + } noerrorShim(); LOAD_GLES(glNormalPointer); LOAD_GLES(glVertexPointer); @@ -715,10 +733,10 @@ void glDrawArrays(GLenum mode, GLint first, GLsizei count) { renderlist_t *list, *active = state.list.active; if (active && (state.list.compiling || state.gl_batch)) { - NewStage(state.list.active, STAGE_DRAW); list = state.list.active; - arrays_to_renderlist(list, mode, first, count+first); - state.list.active = extend_renderlist(list); + NewStage(list, STAGE_DRAW); + state.list.active = arrays_to_renderlist(list, mode, first, count+first); + //state.list.active = extend_renderlist(list); return; } @@ -1496,6 +1514,68 @@ void glBlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { printf("stub glBlendColor(%f, %f, %f, %f)\n", red, green, blue, alpha); } +void glBlendFunc(GLenum sfactor, GLenum dfactor) { + PUSH_IF_COMPILING(glBlendFunc); + LOAD_GLES(glBlendFunc); + LOAD_GLES_OES(glBlendFuncSeparate); + errorGL(); + // There are some limitations in GLES1.1 Blend functions + switch(sfactor) { + case GL_SRC_COLOR: + if (gles_glBlendFuncSeparate) { + gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); + return; + } + sfactor = GL_ONE; // approx... + break; + case GL_ONE_MINUS_SRC_COLOR: + if (gles_glBlendFuncSeparate) { + gles_glBlendFuncSeparate(sfactor, dfactor, sfactor, dfactor); + return; + } + sfactor = GL_ONE; // not sure it make sense... + break; + // here, we need support for glBlendColor... + case GL_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + sfactor = GL_ONE; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_ALPHA: + sfactor = GL_ZERO; + break; + default: + break; + } + + switch(dfactor) { + case GL_DST_COLOR: + sfactor = GL_ONE; // approx... + break; + case GL_ONE_MINUS_DST_COLOR: + sfactor = GL_ZERO; // not sure it make sense... + break; + // here, we need support for glBlendColor... + case GL_CONSTANT_COLOR: + case GL_CONSTANT_ALPHA: + sfactor = GL_ONE; + break; + case GL_ONE_MINUS_CONSTANT_COLOR: + case GL_ONE_MINUS_CONSTANT_ALPHA: + sfactor = GL_ZERO; + break; + default: + break; + } + + if ((sfactor==GL_SRC_ALPHA) && (dfactor==GL_ONE)) { + // special case, as seen in Xash3D + sfactor = GL_ONE; + } + + gles_glBlendFunc(sfactor, dfactor); +} + void flush() { // flush internal list //printf("flush state.list.active=%p, gl_batch=%i(%i)\n", state.list.active, state.gl_batch, gl_batch); @@ -1566,3 +1646,18 @@ void glMultMatrixf(const GLfloat * m) { } gles_glMultMatrixf(m); } + +void glFogfv(GLenum pname, const GLfloat* params) { + LOAD_GLES(glFogfv); + + if ((state.list.active || state.gl_batch) && state.list.active) { + if (pname == GL_FOG_COLOR) { + NewStage(state.list.active, STAGE_FOG); + rlFogOp(state.list.active, 1, params); + return; + } + } + PUSH_IF_COMPILING(glFogfv); + + gles_glFogfv(pname, params); +} diff --git a/project/jni/glshim/src/gl/gl.h b/project/jni/glshim/src/gl/gl.h index 60d4b50c1..38a7bd2c3 100755 --- a/project/jni/glshim/src/gl/gl.h +++ b/project/jni/glshim/src/gl/gl.h @@ -96,7 +96,11 @@ typedef EGLint (*eglWaitSyncKHR_PTR)(EGLDisplay dpy, EGLSyncKHR sync, EGLint fla // will become a reference to dlopen'd gles extern void *gles; +#ifdef ANDROID void *egl; +#else +extern void *egl; +#endif #ifndef EGL_LIB #define EGL_LIB "libEGL.so" @@ -330,10 +334,12 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) { break; case GL_RGB: case GL_BGR: + case GL_RGB8: width = 3; break; case GL_RGBA: case GL_BGRA: + case GL_RGBA8: width = 4; break; default: @@ -350,14 +356,16 @@ static const GLsizei pixel_sizeof(GLenum format, GLenum type) { static const GLboolean pixel_hasalpha(GLenum format) { switch (format) { case GL_ALPHA: - case GL_RGBA: - case GL_BGRA: + case GL_RGBA: + case GL_BGRA: + case GL_RGBA8: return true; case GL_RED: case GL_LUMINANCE: - case GL_RG: - case GL_RGB: - case GL_BGR: + case GL_RG: + case GL_RGB: + case GL_BGR: + case GL_RGB8: return false; default: return true; diff --git a/project/jni/glshim/src/gl/list.c b/project/jni/glshim/src/gl/list.c index 8b16f9a24..82a1debc5 100755 --- a/project/jni/glshim/src/gl/list.c +++ b/project/jni/glshim/src/gl/list.c @@ -22,6 +22,7 @@ renderlist_t *alloc_renderlist() { list->mode = 0; list->mode_init = 0; + list->shared_arrays = false; list->vert = NULL; list->normal = NULL; list->color = NULL; @@ -159,9 +160,8 @@ void renderlist_createindices(renderlist_t *a) { void renderlist_lineloop_lines(renderlist_t *a) { GLushort *ind = a->indices; - int ilen = a->ilen; - if (ilen==0) ilen = a->len; - ilen = ilen*2; // new size is 2* + return + int len = (ind)? a->ilen:a->len; + int ilen = len*2; // new size is 2* + return a->indices = (GLushort*)malloc(ilen*sizeof(GLushort)); for (int i = 0; iindices[i] = vind((i+1)/2); @@ -169,29 +169,27 @@ void renderlist_lineloop_lines(renderlist_t *a) { // go back to initial point a->indices[ilen-1] = a->indices[0]; a->ilen = ilen; - if (ind) free(ind); + if ((ind) && !a->shared_arrays) free(ind); a->mode = GL_LINES; } void renderlist_linestrip_lines(renderlist_t *a) { GLushort *ind = a->indices; - int ilen = a->ilen; - if (ilen==0) ilen = a->len; - ilen = ilen*2-2; // new size is 2* + int len = (ind)? a->ilen:a->len; + int ilen = len*2-2; // new size is 2* if (ilen<0) ilen=0; a->indices = (GLushort*)malloc(ilen*sizeof(GLushort)); for (int i = 0; iindices[i] = vind((i+1)/2); } a->ilen = ilen; - if (ind) free(ind); + if ((ind) && !a->shared_arrays) free(ind); a->mode = GL_LINES; } void renderlist_triangletrip_triangles(renderlist_t *a) { GLushort *ind = a->indices; - int len = a->ilen; - if (len==0) len = a->len; + int len = (ind)? a->ilen:a->len; int ilen = (len-2)*3; if (ilen<0) ilen=0; a->indices = (GLushort*)malloc(ilen*sizeof(GLushort)); @@ -201,14 +199,13 @@ void renderlist_triangletrip_triangles(renderlist_t *a) { a->indices[(i-2)*3+2] = vind(i); } a->ilen = ilen; - if (ind) free(ind); + if ((ind) && !a->shared_arrays) free(ind); a->mode = GL_TRIANGLES; } void renderlist_trianglefan_triangles(renderlist_t *a) { GLushort *ind = a->indices; - int len = a->ilen; - if (len==0) len = a->len; + int len = (ind)? a->ilen:a->len; int ilen = (len-2)*3; if (ilen<0) ilen=0; a->indices = (GLushort*)malloc(ilen*sizeof(GLushort)); @@ -218,16 +215,14 @@ void renderlist_trianglefan_triangles(renderlist_t *a) { a->indices[(i-2)*3+2] = vind(i); } a->ilen = ilen; - if (ind) free(ind); + if ((ind) && !a->shared_arrays) free(ind); a->mode = GL_TRIANGLES; } void renderlist_quads_triangles(renderlist_t *a) { GLushort *ind = a->indices; - int len = a->ilen; - if (len==0) len = a->len; - int ilen = len*3/2; - if (ilen<0) ilen=0; + int len = (ind)? a->ilen:a->len; + int ilen = len*3/2; a->indices = (GLushort*)malloc(ilen*sizeof(GLushort)); for (int i = 0; iindices[i*3/2+0] = vind(i+0); @@ -239,7 +234,7 @@ void renderlist_quads_triangles(renderlist_t *a) { a->indices[i*3/2+5] = vind(i+3); } a->ilen = ilen; - if (ind) free(ind); + if ((ind) && !a->shared_arrays) free(ind); a->mode = GL_TRIANGLES; } #undef vind @@ -266,8 +261,17 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { renderlist_quads_triangles(a); break; default: + if (a->shared_arrays && a->indices) { + // copy shared indices to non-shared copy + GLushort *ind = a->indices; + a->indices = (GLushort*)malloc(a->ilen*sizeof(GLushort)); + memcpy(a->indices, ind, a->ilen*sizeof(GLushort)); + } break; } + // save old b indices in case of shared + GLushort *ind_b = b->indices; + unsigned long ilen_b = b->ilen; // check if "b" needs to be converted switch (b->mode) { case GL_LINE_LOOP: @@ -288,6 +292,11 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { renderlist_quads_triangles(b); break; default: + if (b->shared_arrays && b->indices) { + // copy shared indices to non-shared copy + b->indices = (GLushort*)malloc(b->ilen*sizeof(GLushort)); + memcpy(b->indices, ind_b, b->ilen*sizeof(GLushort)); + } break; } // check for differences in "indices" in both list @@ -296,18 +305,42 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { if (b->indices==NULL) renderlist_createindices(b); } // lets append all the arrays - int cap = a->cap; - while (a->len + b->len >= cap) cap += DEFAULT_RENDER_LIST_CAPACITY; - if (a->cap != cap) { + unsigned long cap = a->cap; + //while (a->len + b->len >= cap) cap += DEFAULT_RENDER_LIST_CAPACITY; + if (a->len + b->len >= cap) cap += b->cap; + if (a->shared_arrays) { a->cap = cap; - realloc_sublist(a->vert, 3, cap); - realloc_sublist(a->normal, 3, cap); - realloc_sublist(a->color, 4, cap); - realloc_sublist(a->secondary, 4, cap); - for (int i=0; itex[i], 2, cap); + GLfloat *tmp; + tmp = a->vert; + a->vert = alloc_sublist(3, cap); + memcpy(a->vert, tmp, 3*a->len*sizeof(GLfloat)); + tmp = a->normal; + a->normal = alloc_sublist(3, cap); + memcpy(a->normal, tmp, 3*a->len*sizeof(GLfloat)); + tmp = a->color; + a->color = alloc_sublist(4, cap); + memcpy(a->color, tmp, 4*a->len*sizeof(GLfloat)); + tmp = a->secondary; + a->secondary = alloc_sublist(4, cap); + memcpy(a->secondary, tmp, 4*a->len*sizeof(GLfloat)); + for (int i=0; itex[i]; + a->tex[i] = alloc_sublist(2, cap); + memcpy(a->tex[i], tmp, 2*a->len*sizeof(GLfloat)); + } + a->shared_arrays = false; + } else { + if (a->cap != cap) { + a->cap = cap; + realloc_sublist(a->vert, 3, cap); + realloc_sublist(a->normal, 3, cap); + realloc_sublist(a->color, 4, cap); + realloc_sublist(a->secondary, 4, cap); + for (int i=0; itex[i], 2, cap); + } } - // arrays + // append arrays if (a->vert) memcpy(a->vert+a->len*3, b->vert, b->len*3*sizeof(GLfloat)); 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)); @@ -317,13 +350,21 @@ void append_renderlist(renderlist_t *a, renderlist_t *b) { // indices if (a->indices) { - a->indices = realloc(a->indices, (a->ilen+b->ilen)*sizeof(GLushort)); - for (int i=0; iilen; i++) a->indices[a->ilen+i]=b->indices[i]+a->len; + a->indices = (GLushort*)realloc(a->indices, (a->ilen+b->ilen)*sizeof(GLushort)); + for (int i=0; iilen; i++) + a->indices[a->ilen+i]=b->indices[i]+a->len; } // lenghts a->len += b->len; a->ilen += b->ilen; + if (b->shared_arrays) { + // restored shared indices copy... + if (b->indices) free(b->indices); + b->indices = ind_b; + b->ilen = ilen_b; + } + //all done return; } @@ -372,13 +413,18 @@ void free_renderlist(renderlist_t *list) { } free(list->calls.calls); } - if (list->vert) free(list->vert); - if (list->normal) free(list->normal); - if (list->color) free(list->color); - if (list->secondary) free(list->secondary); int a; - for (a=0; atex[a]) free(list->tex[a]); + if (!list->shared_arrays) { + if (list->vert) free(list->vert); + if (list->normal) free(list->normal); + if (list->color) free(list->color); + if (list->secondary) free(list->secondary); + for (a=0; atex[a]) free(list->tex[a]); + if (list->indices) + free(list->indices); + } + if (list->material) { rendermaterial_t *m; kh_foreach_value(list->material, m, @@ -403,9 +449,6 @@ void free_renderlist(renderlist_t *list) { if (list->lightmodel) free(list->lightmodel); - if (list->indices) - free(list->indices); - if (list->raster) { if (list->raster->texture) glDeleteTextures(1, &list->raster->texture); @@ -479,6 +522,8 @@ void draw_renderlist(renderlist_t *list) { LOAD_GLES(glColorPointer); LOAD_GLES(glTexCoordPointer); #endif + LOAD_GLES(glEnable); + LOAD_GLES(glDisable); glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); GLfloat *final_colors; @@ -499,6 +544,13 @@ void draw_renderlist(renderlist_t *list) { glPackedCall(cl->calls[i]); } } + if (list->fog_op) { + switch (list->fog_op) { + case 1: // GL_FOG_COLOR + glFogfv(GL_FOG_COLOR, list->fog_val); + break; + } + } if (list->matrix_op) { switch (list->matrix_op) { case 1: // load @@ -662,6 +714,12 @@ void draw_renderlist(renderlist_t *list) { } } + for (int aa=0; aacolor; - color[0] = r; color[1] = g; color[2] = b; color[3] = a; - } + color[0] = r; color[1] = g; color[2] = b; color[3] = a; + } } else { resize_renderlist(list); } @@ -1089,6 +1156,13 @@ void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z) { list->raster_xyz[2] = z; } +void rlFogOp(renderlist_t *list, int op, const GLfloat* v) { + list->fog_op = op; + list->fog_val[0] = v[0]; + list->fog_val[1] = v[1]; + list->fog_val[2] = v[2]; +} + void rlPushCall(renderlist_t *list, packed_call_t *data) { call_list_t *cl = &list->calls; if (!cl->calls) { diff --git a/project/jni/glshim/src/gl/list.h b/project/jni/glshim/src/gl/list.h index 921f1ff83..4fdb56428 100755 --- a/project/jni/glshim/src/gl/list.h +++ b/project/jni/glshim/src/gl/list.h @@ -9,6 +9,7 @@ typedef enum { STAGE_POP, STAGE_CALLLIST, STAGE_GLCALL, + STAGE_FOG, STAGE_MATRIX, STAGE_BINDTEX, STAGE_RASTER, @@ -27,6 +28,8 @@ static int StageExclusive[STAGE_LAST] = { 1, // STAGE_POP 1, // STAGE_CALLLIST 0, // STAGE_GLCALL + 1, // STAGE_FOG + 1, // STAGE_MATRIX 1, // STAGE_BINDTEX 1, // STAGE_RASTER 0, // STAGE_MATERIAL @@ -90,6 +93,8 @@ typedef struct _renderlist_t { GLfloat lastNormal[3]; call_list_t calls; + + GLboolean shared_arrays; GLfloat *vert; GLfloat *normal; GLfloat *color; @@ -111,6 +116,9 @@ typedef struct _renderlist_t { int matrix_op; GLfloat matrix_val[16]; + int fog_op; + GLfloat fog_val[3]; + khash_t(material) *material; khash_t(light) *light; khash_t(texgen) *texgen; @@ -128,7 +136,7 @@ typedef struct _renderlist_t { #define DEFAULT_CALL_LIST_CAPACITY 20 #define DEFAULT_RENDER_LIST_CAPACITY 20 -#define NewStage(l, s) if (l->stage+StageExclusive[s] > s) {l = extend_renderlist(l);} l->stage = s +#define NewStage(l, s) if (l->stage+StageExclusive[l->stage] > s) {l = extend_renderlist(l);} l->stage = s extern renderlist_t *alloc_renderlist(); extern renderlist_t *extend_renderlist(renderlist_t *list); @@ -148,4 +156,5 @@ extern void rlMultiTexCoord2f(renderlist_t *list, GLenum texture, GLfloat s, GLf extern void rlVertex3f(renderlist_t *list, GLfloat x, GLfloat y, GLfloat z); extern void rlSecondary3f(renderlist_t *list, GLfloat r, GLfloat g, GLfloat b); extern void rlRasterOp(renderlist_t *list, int op, GLfloat x, GLfloat y, GLfloat z); +extern void rlFogOp(renderlist_t *list, int op, const GLfloat* v); #endif diff --git a/project/jni/glshim/src/gl/texture.c b/project/jni/glshim/src/gl/texture.c index 4d83164ae..b78fd8012 100755 --- a/project/jni/glshim/src/gl/texture.c +++ b/project/jni/glshim/src/gl/texture.c @@ -103,21 +103,41 @@ static void *swizzle_texture(GLsizei width, GLsizei height, GLenum *format, GLenum *type, const GLvoid *data) { bool convert = false; + GLenum dest_format = GL_RGBA; + GLenum dest_type = GL_UNSIGNED_BYTE; switch (*format) { - case GL_ALPHA: case GL_RGB: - case GL_RGBA: case GL_LUMINANCE: + dest_format = GL_RGB; + break; + case GL_ALPHA: + case GL_RGBA: case GL_LUMINANCE_ALPHA: break; + case GL_RGB5: + dest_type = GL_UNSIGNED_SHORT_5_6_5; + convert = true; + break; + case GL_RGB8: + dest_format = GL_RGB; + *format = GL_RGB; + //convert = true; + break; + case GL_RGBA8: + dest_format = GL_RGBA; + *format = GL_RGBA; + break; default: convert = true; break; } switch (*type) { + case GL_UNSIGNED_SHORT_5_6_5: + if (dest_format==GL_RGB) + dest_type = GL_UNSIGNED_SHORT_5_6_5; + break; //case GL_FLOAT: case GL_UNSIGNED_BYTE: - case GL_UNSIGNED_SHORT_5_6_5: case GL_UNSIGNED_SHORT_4_4_4_4: case GL_UNSIGNED_SHORT_5_5_5_1: break; @@ -132,19 +152,19 @@ static void *swizzle_texture(GLsizei width, GLsizei height, if (convert) { GLvoid *pixels = (GLvoid *)data; if (! pixel_convert(data, &pixels, width, height, - *format, *type, GL_RGBA, GL_UNSIGNED_BYTE, 0)) { - printf("libGL swizzle error: (%#4x, %#4x -> GL_RGBA, UNSIGNED_BYTE)\n", - *format, *type); + *format, *type, dest_format, dest_type, 0)) { + printf("libGL swizzle error: (%#4x, %#4x -> %#4x, %#4x)\n", + *format, *type, dest_format, dest_type); return NULL; } - *type = GL_UNSIGNED_BYTE; - *format = GL_RGBA; + *type = dest_type; + *format = dest_format; GLvoid *pix2 = pixels; if (raster_need_transform()) if (!pixel_transform(data, &pixels, width, height, *format, *type, raster_scale, raster_bias)) { - printf("libGL swizzle/convert error: (%#4x, %#4x -> GL_RGBA, UNSIGNED_BYTE)\n", - *format, *type); + printf("libGL swizzle/convert error: (%#4x, %#4x -> %#4x, %#4x)\n", + *format, *type, dest_format, dest_type); pix2 = pixels; } if (pix2!=pixels && pixels!=data) @@ -153,8 +173,8 @@ static void *swizzle_texture(GLsizei width, GLsizei height, } } else { if (convert) { - *type = GL_UNSIGNED_BYTE; - *format = GL_RGBA; + *type = dest_type; + *format = dest_format; } } return (void *)data; @@ -167,6 +187,7 @@ int texshrink = 0; int texdump = 0; int alphahack = 0; int texstream = 0; +static int default_tex_mipmap = 0; static int proxy_width = 0; static int proxy_height = 0; @@ -209,6 +230,10 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, automipmap = 3; printf("LIBGL: ignore MipMap\n"); } + if (env_mipmap && strcmp(env_mipmap, "4") == 0) { + automipmap = 4; + printf("LIBGL: ignore AutoMipMap on non-squared textures\n"); + } char *env_texcopy = getenv("LIBGL_TEXCOPY"); if (env_texcopy && strcmp(env_texcopy, "1") == 0) { texcopydata = 1; @@ -432,7 +457,7 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, } } } - + /* TODO: GL_INVALID_VALUE is generated if border is not 0. GL_INVALID_OPERATION is generated if type is @@ -463,10 +488,24 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, bound->nheight = nheight; bound->format = format; bound->type = type; + bound->compressed = false; } + if ((bound) && (automipmap==4) && (nwidth!=nheight)) + bound->mipmap_auto = 0; + if (!(texstream && bound && bound->streamed)) { - if (bound && bound->mipmap_need && !bound->mipmap_auto && (automipmap!=3)) + if (bound && ((bound->mipmap_need && (automipmap!=3)) || (bound->mipmap_auto))) gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_TRUE ); + else { + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); + if ((bound) && (bound->mipmap_need)) { + // remove the need for mipmap... + bound->mipmap_need = 0; + glTexParameteri(target, GL_TEXTURE_MIN_FILTER, bound->min_filter); + glTexParameteri(target, GL_TEXTURE_MAG_FILTER, bound->mag_filter); + } + } + if (height != nheight || width != nwidth) { gles_glTexImage2D(target, level, format, nwidth, nheight, border, format, type, NULL); @@ -478,8 +517,8 @@ void glTexImage2D(GLenum target, GLint level, GLint internalformat, format, type, pixels); errorGL(); } - if (bound && bound->mipmap_need && !bound->mipmap_auto && (automipmap!=3)) - gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); + /*if (bound && bound->mipmap_need && !bound->mipmap_auto && (automipmap!=3)) + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );*/ } else { if (pixels) glTexSubImage2D(target, level, 0, 0, width, height, format, type, pixels); // (should never happens) updload the 1st data... @@ -768,7 +807,7 @@ void glBindTexture(GLenum target, GLuint texture) { tex->width = 0; tex->height = 0; tex->uploaded = false; - tex->mipmap_auto = 0; + tex->mipmap_auto = default_tex_mipmap; tex->mipmap_need = 0; tex->alpha = true; tex->streamed = false; @@ -844,7 +883,7 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_LINEAR_MIPMAP_LINEAR: if (texture) texture->mipmap_need = true; - if (automipmap==3) + if ((automipmap==3) || ((texture) && (texture->mipmap_auto==0))) switch (param) { case GL_NEAREST_MIPMAP_NEAREST: case GL_NEAREST_MIPMAP_LINEAR: @@ -876,9 +915,13 @@ void glTexParameteri(GLenum target, GLenum pname, GLint param) { case GL_TEXTURE_LOD_BIAS: return; // not on GLES case GL_GENERATE_MIPMAP: - if (texture) - texture->mipmap_auto = (param)?1:0; - break; + if (texture) { + texture->mipmap_auto = (param)?1:0; + if (texture->glname == 0) + default_tex_mipmap = texture->mipmap_auto; + } else + default_tex_mipmap = (param)?1:0; // default? + return; // We control the behavour later } gles_glTexParameteri(target, pname, param); errorGL(); @@ -959,6 +1002,8 @@ void glGenTextures(GLsizei n, GLuint * textures) { tex->mipmap_need = 0; tex->streamingID = -1; tex->streamed = false; + tex->alpha = true; + tex->compressed = false; tex->min_filter = tex->mag_filter = GL_NEAREST; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; @@ -978,7 +1023,8 @@ GLboolean glAreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *re } void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *params) { - // simplification: not taking "target" into account here +//printf("glGetTexLevelParameteriv(0x%04X, %d, 0x%04X, %p)\n", target, level, pname, params); + // simplification: (mostly) not taking "target" into account here if (state.gl_batch) flush(); *params = 0; noerrorShim(); @@ -988,16 +1034,23 @@ void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *p if (target==GL_PROXY_TEXTURE_2D) (*params) = proxy_width>>level; else - (*params) = ((bound)?bound->width:2048)>>level; + (*params) = ((bound)?bound->width:2048)>>level; + if (*params<=0) // 1 is the minimum, not 0 + *params = 1; break; case GL_TEXTURE_HEIGHT: if (target==GL_PROXY_TEXTURE_2D) (*params) = proxy_height>>level; else (*params) = ((bound)?bound->height:2048)>>level; + if (*params<=0) // 1 is the minimum, not 0 + *params = 1; break; case GL_TEXTURE_INTERNAL_FORMAT: - (*params) = GL_RGBA; + if (bound && bound->compressed) + (*params) = bound->format; + else + (*params) = GL_RGBA; break; case GL_TEXTURE_DEPTH: (*params) = 0; @@ -1019,7 +1072,10 @@ void glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GLint *p (*params) = 0; break; case GL_TEXTURE_COMPRESSED: - (*params) = GL_FALSE; + if (bound && bound->compressed) + (*params) = GL_TRUE; + else + (*params) = GL_FALSE; break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: (*params) = (bound)?(bound->width*bound->height*4):0; @@ -1234,6 +1290,18 @@ GLboolean isDXTc(GLenum format) { return false; } +GLboolean isNotCompressed(GLenum format) { + switch(format) { + case GL_RGBA: + case GL_RGB: + case GL_RGBA8: + case GL_RGB8: + case GL_RGB5: + return true; + } + return false; +} + GLvoid *uncompressDXTc(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data) { // uncompress a DXTc image // get pixel size of uncompressed image => fixed RGBA @@ -1295,13 +1363,17 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, errorShim(GL_INVALID_OPERATION); return; // no texture bounded... } +//printf("glCompressedTexImage2D on target=0x%04X with size(%i,%i), internalformat=%04x, imagesize=%i, upackbuffer=%p\n", target, width, height, internalformat, imageSize, state.buffers.unpack?state.buffers.unpack->data:0); + // hack... + if (internalformat==GL_RGBA8) + internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + // test if internalformat is not a compressed one if (level != 0) { noerrorShim(); //TODO //printf("STUBBED glCompressedTexImage2D with level=%i\n", level); //return; } -//printf("glCompressedTexImage2D on target=0x%04X with size(%i,%i), internalformat=%04x, imagesize=%i, upackbuffer=%p\n", target, width, height, internalformat, imageSize, state.buffers.unpack?state.buffers.unpack->data:0); if ((width<=0) || (height<=0)) { noerrorShim(); return; // nothing to do... @@ -1337,6 +1409,9 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, // automaticaly reduce the pixel size half=pixels; state.texture.bound[state.texture.active]->alpha = (internalformat==COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; + state.texture.bound[state.texture.active]->format = GL_RGBA; //internalformat; + state.texture.bound[state.texture.active]->type = GL_UNSIGNED_SHORT_4_4_4_4; //GL_UNSIGNED_BYTE; + state.texture.bound[state.texture.active]->compressed = true; if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE)) fact = 1; } else { @@ -1358,6 +1433,7 @@ void glCompressedTexImage2D(GLenum target, GLint level, GLenum internalformat, state.texture.bound[state.texture.active]->alpha = true; state.texture.bound[state.texture.active]->format = internalformat; state.texture.bound[state.texture.active]->type = GL_UNSIGNED_BYTE; + state.texture.bound[state.texture.active]->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } state.buffers.unpack = unpack; diff --git a/project/jni/glshim/src/gl/texture.h b/project/jni/glshim/src/gl/texture.h index c9f06ebb6..23f4e9117 100755 --- a/project/jni/glshim/src/gl/texture.h +++ b/project/jni/glshim/src/gl/texture.h @@ -96,6 +96,7 @@ typedef struct { GLenum mag_filter; GLboolean uploaded; GLboolean alpha; + GLboolean compressed; GLboolean streamed; int streamingID; GLvoid *data; // in case we want to keep a copy of it (it that case, always RGBA/GL_UNSIGNED_BYTE diff --git a/project/jni/glshim/src/glx/glx.c b/project/jni/glshim/src/glx/glx.c index 93a69f7ee..80435ee39 100755 --- a/project/jni/glshim/src/glx/glx.c +++ b/project/jni/glshim/src/glx/glx.c @@ -1,4 +1,6 @@ +#ifndef ANDROID #include +#endif #include #include #include @@ -115,6 +117,9 @@ static int get_config_default(int attribute, int *value) { case GLX_SAMPLES: *value = 0; break; + case GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB: + *value = 0; + break; default: printf("libGL: unknown attrib %i\n", attribute); *value = 0; @@ -125,8 +130,14 @@ static int get_config_default(int attribute, int *value) { // hmm... static EGLContext eglContext; + +#ifndef ANDROID static Display *g_display = NULL; static GLXContext glxContext = NULL; +static GLXContext fbContext = NULL; +#endif //ANDROID + +static int fbcontext_count = 0; #ifndef FBIO_WAITFORVSYNC #define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) @@ -147,7 +158,7 @@ static bool g_bcmhost = true; static int fbdev = -1; static int swap_interval = 1; - +#ifndef ANDROID static void init_display(Display *display) { LOAD_EGL(eglGetDisplay); @@ -160,7 +171,7 @@ static void init_display(Display *display) { eglDisplay = egl_eglGetDisplay(display); } } - +#endif //ANDROID static void init_vsync() { fbdev = open("/dev/fb0", O_RDONLY); if (fbdev < 0) { @@ -260,9 +271,11 @@ static void scan_env() { } if (g_xrefresh) atexit(xrefresh); +#ifndef ANDROID #ifdef BCMHOST atexit(bcm_host_deinit); #endif +#endif //ANDROID } env(LIBGL_FB, g_usefb, "framebuffer output enabled"); if (env_LIBGL_FB && strcmp(env_LIBGL_FB, "2") == 0) { @@ -283,7 +296,7 @@ static void scan_env() { printf("LIBGL: LiveInfo detected, fps will be shown\n"); } } - +#ifndef ANDROID GLXContext glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, @@ -314,6 +327,12 @@ GLXContext glXCreateContext(Display *display, }; 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) { @@ -355,6 +374,7 @@ GLXContext glXCreateContext(Display *display, eglSurface = NULL; } } + fbContext = fake; } // make an egl context here... EGLBoolean result; @@ -391,8 +411,10 @@ GLXContext glXCreateContext(Display *display, EGLContext shared = (shareList)?shareList->eglContext:EGL_NO_CONTEXT; if (!g_usefb) fake->eglContext = egl_eglCreateContext(eglDisplay, fake->eglConfigs[0], shared, attrib_list); - else + else { eglContext = egl_eglCreateContext(eglDisplay, eglConfigs[0], shared, attrib_list); + fake->eglContext = eglContext; + } CheckEGLErrors(); @@ -406,6 +428,7 @@ GLXContext glXCreateContext(Display *display, } //*TODO* put eglContext inside GLXcontext, to handle multiple Glxcontext + return fake; } @@ -417,6 +440,12 @@ GLXContext glXCreateContextAttribsARB(Display *display, void *config, void glXDestroyContext(Display *display, GLXContext ctx) { //printf("glXDestroyContext(%p, %p)\n", display, ctx); + if (g_usefb) { + if (fbcontext_count==0) + return; // Should not happens! + if (--fbcontext_count > 0) + return; // Nothing to do... + } if ((!g_usefb && ctx->eglContext) || (g_usefb && eglContext)) { if (g_usefbo) { deleteMainFBO(); @@ -443,6 +472,9 @@ void glXDestroyContext(Display *display, GLXContext ctx) { fbdev = -1; }*/ } + if (g_usefb) + fbContext = NULL; + return; } @@ -698,7 +730,7 @@ void glXQueryDrawable( Display *dpy, int draw, int attribute, GLXContext glXGetCurrentContext() { // hack to make some games start if (g_usefb) - return glxContext ? glxContext : (void *)1; + return glxContext ? glxContext : fbContext; else return glxContext; } @@ -709,6 +741,10 @@ GLXFBConfig *glXChooseFBConfig(Display *display, int screen, GLXFBConfig *configs = malloc(sizeof(GLXFBConfig) * *count); return configs; } +GLXFBConfig *glXChooseFBConfigSGIX(Display *display, int screen, + const int *attrib_list, int *count) { + return glXChooseFBConfig(display, screen, attrib_list, count); +} GLXFBConfig *glXGetFBConfigs(Display *display, int screen, int *count) { *count = 1; @@ -734,7 +770,7 @@ GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, Bool is_direct) { return glXCreateContext(display, 0, share_list, is_direct); } - +#endif //ANDROID void glXSwapIntervalMESA(int interval) { printf("glXSwapInterval(%i)\n", interval); if (! g_vsync) @@ -746,6 +782,7 @@ void glXSwapIntervalSGI(int interval) { glXSwapIntervalMESA(interval); } +#ifndef ANDROID void glXSwapIntervalEXT(Display *display, int drawable, int interval) { glXSwapIntervalMESA(interval); } @@ -897,10 +934,11 @@ void glXUseXFont(Font font, int first, int count, int listBase) { glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); // All done } +#endif //ANDROID void glXWaitGL() {} void glXWaitX() {} void glXReleaseBuffersMESA() {} - +#ifndef ANDROID /* TODO proper implementation */ int glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value) { *value = 0; @@ -921,3 +959,4 @@ int glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int } return 0; } +#endif //ANDROID \ No newline at end of file diff --git a/project/jni/glshim/src/glx/glx.h b/project/jni/glshim/src/glx/glx.h index 14bb2a472..eadde3ef1 100755 --- a/project/jni/glshim/src/glx/glx.h +++ b/project/jni/glshim/src/glx/glx.h @@ -1,4 +1,4 @@ -#ifdef BCMHOST +#if defined (BCMHOST) && !defined(ANDROID) #include "bcm_host.h" #endif @@ -127,9 +127,11 @@ #define GLX_SAMPLE_BUFFERS 0x186a0 /*100000*/ #define GLX_SAMPLES 0x186a1 /*100001*/ +#define GLX_FRAMEBUFFER_SRGB_CAPABLE_ARB 0x20B2 + typedef int GLXDrawable; - +#ifndef ANDROID struct __GLXContextRec { Display *display; GLXDrawable drawable; @@ -142,7 +144,7 @@ struct __GLXContextRec { EGLContext eglContext; }; typedef struct __GLXContextRec *GLXContext; - +#endif //ANDROID struct __GLXFBConfigRec { int visualType; int transparentType; @@ -197,7 +199,7 @@ struct __GLXFBConfigRec { double minAlpha, maxAlpha; }; typedef struct __GLXFBConfigRec *GLXFBConfig; - +#ifndef ANDROID GLXContext glXCreateContext(Display *dpy, XVisualInfo *visual, GLXContext shareList, @@ -208,10 +210,12 @@ GLXContext glXCreateContextAttribsARB(Display *display, void *config, const int *attrib_list); void glXSwapIntervalEXT(Display *display, int drawable, int interval); +#endif //ANDROID void glXSwapIntervalMESA(int interval); void glXSwapIntervalSGI(int interval); // GLX 1.1? +#ifndef ANDROID Bool glXIsDirect(Display * display, GLXContext ctx); Bool glXMakeCurrent(Display *display, int drawable, GLXContext context); Bool glXQueryExtension(Display *display, int *errorBase, int *eventBase); @@ -219,7 +223,9 @@ Bool glXQueryVersion(Display *display, int *major, int *minor); const char *glXGetClientString(Display *display, int name); const char *glXQueryExtensionsString(Display *display, int screen); 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); @@ -227,8 +233,10 @@ 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 void glXWaitGL(); void glXWaitX(); +#ifndef ANDROID XVisualInfo *glXChooseVisual(Display *display, int screen, int *attributes); int glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); @@ -237,13 +245,17 @@ Display *glXGetCurrentDisplay(); // GLX 1.3 GLXContext glXGetCurrentContext(); + XVisualInfo *glXGetVisualFromFBConfig(Display *display, GLXFBConfig config); GLXFBConfig *glXChooseFBConfig(Display *display, int screen, const int *attrib_list, int *count); GLXFBConfig *glXGetFBConfigs(Display *display, int screen, int *count); int glXGetFBConfigAttrib(Display *display, GLXFBConfig config, int attribute, int *value); +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); void glXDestroyWindow(Display *display, void *win); Bool glXMakeContextCurrent(Display *display, int drawable, int readable, GLXContext context); GLXContext glXCreateNewContext(Display *display, GLXFBConfig config, int render_type, GLXContext share_list, Bool is_direct); +#endif //ANDROID \ 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 55d0fdabb..f473affbd 100755 --- a/project/jni/glshim/src/glx/lookup.c +++ b/project/jni/glshim/src/glx/lookup.c @@ -1,5 +1,6 @@ #ifdef ANDROID #include "../gl/gl.h" +#include "glx.h" #else #include "glx.h" #endif @@ -57,8 +58,10 @@ void *glXGetProcAddressARB(const char *name) { EX(glXQueryServerString); EX(glXSwapBuffers); EX(glXSwapIntervalEXT); +#endif //ANDROID EX(glXSwapIntervalMESA); EX(glXSwapIntervalSGI); +#ifndef ANDROID EX(glXUseXFont); EX(glXWaitGL); EX(glXWaitX); @@ -69,11 +72,21 @@ void *glXGetProcAddressARB(const char *name) { EX(glXGetClientString); EX(glXGetFBConfigs); EX(glXChooseFBConfig); + EX(glXChooseFBConfigSGIX); EX(glXGetFBConfigAttrib); + EX(glXQueryContext); EX(glXGetVisualFromFBConfig); EX(glXCreateWindow); EX(glXDestroyWindow); -#endif + + STUB(glXCreatePbuffer); // to do, using Renderbuffers.... + STUB(glXDestroyPbuffer); + STUB(glXCreatePixmap); + STUB(glXDestroyPixmap); + STUB(glXGetCurrentReadDrawable); + STUB(glXGetSelectedEvent); + STUB(glXSelectEvent); +#endif //ANDROID // GL_ARB_vertex_buffer_object ARB(glBindBuffer); @@ -95,7 +108,9 @@ void *glXGetProcAddressARB(const char *name) { // GL_ARB_frameBuffer_ext EX(glFramebufferTexture1D); EX(glFramebufferTexture3D); + EX(glFramebufferTextureLayer); EX(glRenderbufferStorageMultisample); + EX(glBlitFramebuffer); EXT(glGenFramebuffers); EXT(glDeleteFramebuffers); EXT(glIsFramebuffer); @@ -114,6 +129,8 @@ void *glXGetProcAddressARB(const char *name) { EXT(glGenerateMipmap); EXT(glGetFramebufferAttachmentParameteriv); EXT(glGetRenderbufferParameteriv); + EXT(glFramebufferTextureLayer); + EXT(glBlitFramebuffer); ARB(glGenFramebuffers); ARB(glDeleteFramebuffers); ARB(glIsFramebuffer); @@ -132,6 +149,9 @@ void *glXGetProcAddressARB(const char *name) { ARB(glGenerateMipmap); ARB(glGetFramebufferAttachmentParameteriv); ARB(glGetRenderbufferParameteriv); + ARB(glFramebufferTextureLayer); + ARB(glBlitFramebuffer); + STUB(glDrawBuffersARB); /* MAP_EGL(glGenFramebuffersARB, glGenFramebuffersOES); @@ -435,7 +455,7 @@ void *glXGetProcAddressARB(const char *name) { STUB(glPixelMapfv); STUB(glPixelMapuiv); STUB(glPixelMapusv); - STUB(glPixelStoref); + EX(glPixelStoref); STUB(glPrioritizeTextures); STUB(glSelectBuffer); diff --git a/project/jni/glshim/src/glx/utils.h b/project/jni/glshim/src/glx/utils.h index e4dc1fff0..8bd699856 100755 --- a/project/jni/glshim/src/glx/utils.h +++ b/project/jni/glshim/src/glx/utils.h @@ -1,13 +1,15 @@ #ifndef UTILS_H #define UTILS_H +#ifndef ANDROID #include #include +#endif //ANDROID #include #include #include "../gl/gl.h" - +#ifndef ANDROID void fill_bitmap(Display * dpy, Window win, GC gc, unsigned int width, unsigned int height, @@ -15,5 +17,5 @@ fill_bitmap(Display * dpy, Window win, GC gc, XCharStruct * isvalid(XFontStruct * fs, int which); - +#endif //ANDROID #endif \ No newline at end of file