diff --git a/project/java/DataDownloader.java b/project/java/DataDownloader.java index 5fa4a6a74..c0d276ae8 100644 --- a/project/java/DataDownloader.java +++ b/project/java/DataDownloader.java @@ -750,14 +750,19 @@ class DataDownloader extends Thread ret = check.read(buf, 0, buf.length); } check.close(); + + + // NOTE: For some reason this not work properly on older Android versions (4.4 and below). + // Setting this to become a warning if( check.getChecksum().getValue() != entry.getCrc() || count != entry.getSize() ) { - File ff = new File(path); - ff.delete(); + //File ff = new File(path); + //ff.delete(); Log.i("SDL", "Saving file '" + path + "' - CRC check failed, ZIP: " + String.format("%x", entry.getCrc()) + " actual file: " + String.format("%x", check.getChecksum().getValue()) + " file size in ZIP: " + entry.getSize() + " actual size " + count ); - throw new Exception(); + Log.i("SDL", "If you still get problems try to reset the app or delete file at path " + path ); + //throw new Exception(); } } catch( Exception e ) { Status.setText( res.getString(R.string.error_write, path) + ": " + e.getMessage() ); diff --git a/project/java/Globals.java b/project/java/Globals.java index 2d8ca7d5b..b632eebc3 100644 --- a/project/java/Globals.java +++ b/project/java/Globals.java @@ -112,6 +112,7 @@ class Globals public static int MoveMouseWithGyroscopeSpeed = 2; public static boolean ClickMouseWithDpad = false; public static boolean RelativeMouseMovement = ForceRelativeMouseMode; // Laptop touchpad mode + public static boolean ForceHardwareMouse = false; public static int RelativeMouseMovementSpeed = 2; public static int RelativeMouseMovementAccel = 0; public static int ShowScreenUnderFinger = Mouse.ZOOM_NONE; diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index 8fd8caacc..eb13182c7 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -820,7 +820,6 @@ public class MainActivity extends Activity _parent.hideScreenKeyboard(); return true; } - /* if (keyCode == KeyEvent.KEYCODE_DEL || keyCode == KeyEvent.KEYCODE_CLEAR) { // EditText deletes two characters at a time, here's a hacky fix @@ -830,12 +829,12 @@ public class MainActivity extends Activity int start = t.getSelectionStart(); //get cursor starting position int end = t.getSelectionEnd(); //get cursor ending position if ( start < 0 ) - return true; + return false; if ( end < 0 || end == start ) { start --; if ( start < 0 ) - return true; + return false; end = start + 1; } t.setText(t.getText().toString().substring(0, start) + t.getText().toString().substring(end)); @@ -843,7 +842,6 @@ public class MainActivity extends Activity return true; } } - */ //Log.i("SDL", "Key " + keyCode + " flags " + event.getFlags() + " action " + event.getAction()); return false; } diff --git a/project/java/Settings.java b/project/java/Settings.java index da85b52b9..1ba99c6c8 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -186,6 +186,7 @@ public class Settings out.writeBoolean(Globals.ImmersiveMode); out.writeBoolean(Globals.AutoDetectOrientation); out.writeBoolean(Globals.TvBorders); + out.writeBoolean(Globals.ForceHardwareMouse); out.close(); settingsLoaded = true; @@ -379,6 +380,7 @@ public class Settings Globals.ImmersiveMode = settingsFile.readBoolean(); Globals.AutoDetectOrientation = settingsFile.readBoolean(); Globals.TvBorders = settingsFile.readBoolean(); + Globals.ForceHardwareMouse = settingsFile.readBoolean(); settingsLoaded = true; diff --git a/project/java/SettingsMenuMouse.java b/project/java/SettingsMenuMouse.java index e1f5feeb1..cf5160070 100644 --- a/project/java/SettingsMenuMouse.java +++ b/project/java/SettingsMenuMouse.java @@ -124,21 +124,25 @@ class SettingsMenuMouse extends SettingsMenu p.getResources().getString(R.string.display_size_small), p.getResources().getString(R.string.display_size_small_touchpad), p.getResources().getString(R.string.display_size_large), + p.getResources().getString(R.string.display_size_desktop), }; int _size_small = 0; int _size_small_touchpad = 1; int _size_large = 2; - int _more_options = 3; + int _size_desktop = 3; + int _more_options = 4; if( ! Globals.SwVideoMode ) { CharSequence[] items2 = { p.getResources().getString(R.string.display_size_small_touchpad), p.getResources().getString(R.string.display_size_large), + p.getResources().getString(R.string.display_size_desktop), }; items = items2; _size_small_touchpad = 0; _size_large = 1; + _size_desktop = 2; _size_small = 1000; } if( firstStart ) @@ -147,6 +151,7 @@ class SettingsMenuMouse extends SettingsMenu p.getResources().getString(R.string.display_size_small), p.getResources().getString(R.string.display_size_small_touchpad), p.getResources().getString(R.string.display_size_large), + p.getResources().getString(R.string.display_size_desktop), p.getResources().getString(R.string.show_more_options), }; items = items2; @@ -155,6 +160,7 @@ class SettingsMenuMouse extends SettingsMenu CharSequence[] items3 = { p.getResources().getString(R.string.display_size_small_touchpad), p.getResources().getString(R.string.display_size_large), + p.getResources().getString(R.string.display_size_desktop), p.getResources().getString(R.string.show_more_options), }; items = items3; @@ -165,6 +171,7 @@ class SettingsMenuMouse extends SettingsMenu final int size_small = _size_small; final int size_small_touchpad = _size_small_touchpad; final int size_large = _size_large; + final int size_desktop = _size_desktop; final int more_options = _more_options; AlertDialog.Builder builder = new AlertDialog.Builder(p); @@ -174,23 +181,33 @@ class SettingsMenuMouse extends SettingsMenu public void onClick(DialogInterface dialog, int item) { dialog.dismiss(); + if( item == size_desktop ) + { + Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL; + Globals.RelativeMouseMovement = false; + Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE; + Globals.ForceHardwareMouse = true; + } if( item == size_large ) { Globals.LeftClickMethod = Mouse.LEFT_CLICK_NORMAL; Globals.RelativeMouseMovement = false; Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE; + Globals.ForceHardwareMouse = false; } if( item == size_small ) { Globals.LeftClickMethod = Mouse.LEFT_CLICK_NEAR_CURSOR; Globals.RelativeMouseMovement = false; Globals.ShowScreenUnderFinger = Mouse.ZOOM_MAGNIFIER; + Globals.ForceHardwareMouse = false; } if( item == size_small_touchpad ) { Globals.LeftClickMethod = Mouse.LEFT_CLICK_WITH_TAP_OR_TIMEOUT; Globals.RelativeMouseMovement = true; Globals.ShowScreenUnderFinger = Mouse.ZOOM_NONE; + Globals.ForceHardwareMouse = false; } if( item == more_options ) { diff --git a/project/java/Video.java b/project/java/Video.java index 3454ad472..cb0eb8761 100644 --- a/project/java/Video.java +++ b/project/java/Video.java @@ -106,8 +106,8 @@ abstract class DifferentTouchInput public abstract void process(final MotionEvent event); public abstract void processGenericEvent(final MotionEvent event); - public static int ExternalMouseDetected = 0; - + public static int ExternalMouseDetected = Mouse.MOUSE_HW_INPUT_FINGER; + public static DifferentTouchInput touchInput = getInstance(); public static DifferentTouchInput getInstance() @@ -315,8 +315,8 @@ abstract class DifferentTouchInput } public void process(final MotionEvent event) { - int hwMouseEvent = ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) ? Mouse.MOUSE_HW_INPUT_STYLUS : - ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE) ? Mouse.MOUSE_HW_INPUT_MOUSE : + int hwMouseEvent = ((event.getSource() & InputDevice.SOURCE_MOUSE) == InputDevice.SOURCE_MOUSE || Globals.ForceHardwareMouse) ? Mouse.MOUSE_HW_INPUT_MOUSE : + ((event.getSource() & InputDevice.SOURCE_STYLUS) == InputDevice.SOURCE_STYLUS) ? Mouse.MOUSE_HW_INPUT_STYLUS : Mouse.MOUSE_HW_INPUT_FINGER; if( ExternalMouseDetected != hwMouseEvent ) { diff --git a/project/java/translations/values/strings.xml b/project/java/translations/values/strings.xml index 834ce24d7..74ca529f0 100644 --- a/project/java/translations/values/strings.xml +++ b/project/java/translations/values/strings.xml @@ -163,6 +163,7 @@ Mouse emulation mode Display size for mouse emulation + Desktop, no emulation Large (tablets) Small, magnifying glass Small, touchpad mode diff --git a/project/jni/application/Android.mk b/project/jni/application/Android.mk index f162fbeea..2f8fdf47a 100644 --- a/project/jni/application/Android.mk +++ b/project/jni/application/Android.mk @@ -49,9 +49,6 @@ LOCAL_SHARED_LIBRARIES := sdl-$(SDL_VERSION) $(filter-out $(APP_AVAILABLE_STATIC LOCAL_STATIC_LIBRARIES := $(filter $(APP_AVAILABLE_STATIC_LIBS), $(COMPILED_LIBRARIES)) -$(warning APP LOCAL_SHARED_LIBRARIES $(LOCAL_SHARED_LIBRARIES)) -$(warning APP LOCAL_STATIC_LIBRARIES $(LOCAL_STATIC_LIBRARIES)) - APP_STL := gnustl_static LOCAL_LDLIBS := $(APPLICATION_GLES_LIBRARY) -ldl -llog -lz # -lgnustl_static diff --git a/project/jni/application/ballfield/ballfield.cpp b/project/jni/application/ballfield/ballfield.cpp index 78cd94345..7756c6c72 100644 --- a/project/jni/application/ballfield/ballfield.cpp +++ b/project/jni/application/ballfield/ballfield.cpp @@ -689,11 +689,12 @@ int main(int argc, char* argv[]) if(evt.key.keysym.sym == SDLK_0) { SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 1); + SDL_ANDROID_SetMouseEmulationMode(0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); } if(evt.key.keysym.sym == SDLK_1) { SDL_ANDROID_SetScreenKeyboardButtonShown(SDL_ANDROID_SCREENKEYBOARD_BUTTON_2, 0); - SDL_ANDROID_OpenExternalWebBrowser("http:/google.com/"); + SDL_ANDROID_SetMouseEmulationMode(1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1); } if(evt.key.keysym.sym == SDLK_2) { diff --git a/project/jni/application/commandergenius/AndroidAppSettings.cfg b/project/jni/application/commandergenius/AndroidAppSettings.cfg index 66fa305bc..0f1c7582e 100644 --- a/project/jni/application/commandergenius/AndroidAppSettings.cfg +++ b/project/jni/application/commandergenius/AndroidAppSettings.cfg @@ -7,10 +7,10 @@ AppName="Commander Genius" AppFullName=net.sourceforge.clonekeenplus # Application version code (integer) -AppVersionCode=198300 +AppVersionCode=198600 # Application user-visible version name (string) -AppVersionName="1.9.8.3 Beta" +AppVersionName="1.9.8.6 Beta" # Specify path to download application data in zip archive in the form 'Description|URL|MirrorURL^Description2|URL2|MirrorURL2^...' # If you'll start Description with '!' symbol it will be enabled by default, other downloads should be selected by user from startup config menu diff --git a/project/jni/application/commandergenius/commandergenius b/project/jni/application/commandergenius/commandergenius index 3cadca295..2dc893395 160000 --- a/project/jni/application/commandergenius/commandergenius +++ b/project/jni/application/commandergenius/commandergenius @@ -1 +1 @@ -Subproject commit 3cadca29551ca2fa1f01a64120acf8f25b3cd1bd +Subproject commit 2dc893395b6720d118dda626de8f09561758e66a diff --git a/project/jni/application/ninslash/src b/project/jni/application/ninslash/src index 721417db3..9b2cee79d 160000 --- a/project/jni/application/ninslash/src +++ b/project/jni/application/ninslash/src @@ -1 +1 @@ -Subproject commit 721417db327fc76628adcf673b068a7a75810d49 +Subproject commit 9b2cee79d1e00fb3a19953c43b2e8a1e55538d63 diff --git a/project/jni/application/openttd/src b/project/jni/application/openttd/src index f03484e84..b394d53be 160000 --- a/project/jni/application/openttd/src +++ b/project/jni/application/openttd/src @@ -1 +1 @@ -Subproject commit f03484e84ba64a806d59da435d68398bda32caf9 +Subproject commit b394d53be82ec280e9c0909ce42779e6625c107c diff --git a/project/jni/curl/lib/Makefile.inc b/project/jni/curl/lib/Makefile.inc index b573e932e..a3e4a15c3 100644 --- a/project/jni/curl/lib/Makefile.inc +++ b/project/jni/curl/lib/Makefile.inc @@ -78,3 +78,4 @@ LIB_RCFILES = libcurl.rc CSOURCES = $(LIB_CFILES) $(LIB_VAUTH_CFILES) $(LIB_VTLS_CFILES) HHEADERS = $(LIB_HFILES) $(LIB_VAUTH_HFILES) $(LIB_VTLS_HFILES) + diff --git a/project/jni/fontconfig/Android.mk b/project/jni/fontconfig/Android.mk index 7b447f214..ef941b83f 100644 --- a/project/jni/fontconfig/Android.mk +++ b/project/jni/fontconfig/Android.mk @@ -13,7 +13,7 @@ LOCAL_CFLAGS += -DHAVE_CONFIG_H LOCAL_SHARED_LIBRARIES := freetype expat -LOCAL_LDLIBS := -lz +#LOCAL_LDLIBS := -lz LOCAL_C_INCLUDES := \ $(LOCAL_PATH)/include \ diff --git a/project/jni/gl4es/README.md b/project/jni/gl4es/README.md index 353994af1..ee7094c94 100755 --- a/project/jni/gl4es/README.md +++ b/project/jni/gl4es/README.md @@ -134,6 +134,11 @@ Experimental: enable Alpha test only when using texture that contains an alpha c * 0 : Default, nothing special * 1 : Alpha Hack enabled +##### LIBGL_NODOWNSAMPLING +Texture downsampling control + * 0 : Default, DXTc texture are downsampled to 16bits + * 1 : DXTc texture are left as 32bits RGBA + ##### LIBGL_STREAM PANDORA only: enable Texture Streaming (works only on RGB textures) * 0 : Default, nothing special @@ -220,11 +225,21 @@ Initial Hardware test * 0 : Default, perform intial hardware testing (using a PBuffer) * 1 : Do not perform test (no extensions tested or used) +##### LIBGL_NOVAOCACHE +VAO Caching + * 0 : Default, tr to cache vao to avoid memcpy in render list + * 1 : Don't cache VAO + ---- Version history ---- +##### current version + * Fixed (Added in fact) support for Multisampling on the GLX Context creation (a bit hacky, but seems to works) + * Added LIBGL_NODOWNSAMPLING and associated Hint + * Try to implement some caching on VAO to avoid some memcpy in renderlist (with a way to disable it just in case) + ##### 0.9.3 * Added support for Cube Mapping (with hardware support) * Improved Texture state tracking diff --git a/project/jni/gl4es/include/gl4eshint.h b/project/jni/gl4es/include/gl4eshint.h index 024845ed6..04c9ee0a0 100755 --- a/project/jni/gl4es/include/gl4eshint.h +++ b/project/jni/gl4es/include/gl4eshint.h @@ -23,5 +23,7 @@ #define GL_BATCH_HINT_GL4ES 0xA109 // same as using LIBGL_NOERROR=x #define GL_NOERROR_HINT_GL4ES 0xA10A +// same as using LIBGL_NODOWNSAMPLING=x +#define GL_NODOWNSAMPLING_HINT_GL4ES 0xA10B #endif \ No newline at end of file diff --git a/project/jni/gl4es/src/config.h b/project/jni/gl4es/src/config.h index 76f996062..b6987af1c 100755 --- a/project/jni/gl4es/src/config.h +++ b/project/jni/gl4es/src/config.h @@ -1,6 +1,7 @@ #define SYS_proxy 9999 #define MAX_EVAL_ORDER 30 #define MAX_TEX 8 +#define MAX_LIGHT 8 #define MAX_STACK_PROJECTION 16 #define MAX_STACK_TEXTURE 16 #define MAX_STACK_MODELVIEW 64 diff --git a/project/jni/gl4es/src/gl/buffers.c b/project/jni/gl4es/src/gl/buffers.c index 2735f4ba1..2ece32c9c 100755 --- a/project/jni/gl4es/src/gl/buffers.c +++ b/project/jni/gl4es/src/gl/buffers.c @@ -1,5 +1,6 @@ #include "buffers.h" #include "debug.h" +#include "../glx/hardext.h" static GLuint lastbuffer = 1; @@ -125,7 +126,11 @@ void gl4es_glBufferData(GLenum target, GLsizeiptr size, const GLvoid * data, GLe } if (buff->data) { free(buff->data); + } + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + buff->size = size; buff->usage = usage; buff->data = malloc(size); @@ -147,6 +152,10 @@ void gl4es_glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, cons // printf("LIBGL: Warning, null buffer for target=0x%04X for glBufferSubData\n", target); return; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + memcpy(buff->data + offset, data, size); //TODO, some check maybe? noerrorShim(); } @@ -157,6 +166,7 @@ void gl4es_glDeleteBuffers(GLsizei n, const GLuint * buffers) { flush(); } + VaoSharedClear(glstate->vao); khash_t(buff) *list = glstate->buffers; if (list) { khint_t k; @@ -247,6 +257,10 @@ void *gl4es_glMapBuffer(GLenum target, GLenum access) { errorShim(GL_INVALID_ENUM); return (void*)NULL; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + glbuffer_t *buff = getbuffer_buffer(target); if (buff==NULL) return (void*)NULL; // Should generate an error! @@ -262,6 +276,10 @@ GLboolean gl4es_glUnmapBuffer(GLenum target) { errorShim(GL_INVALID_ENUM); return GL_FALSE; } + + if(target==GL_ARRAY_BUFFER) + VaoSharedClear(glstate->vao); + glbuffer_t *buff = getbuffer_buffer(target); if (buff==NULL) return GL_FALSE; // Should generate an error! @@ -280,10 +298,11 @@ void gl4es_glGetBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, G return; } glbuffer_t *buff = getbuffer_buffer(target); + if (buff==NULL) return; // Should generate an error! // TODO, check parameter consistancie - memcpy(data, buff->data+offset, size); + memcpy(data, buff->data+offset, size); noerrorShim(); } @@ -406,6 +425,7 @@ void gl4es_glDeleteVertexArrays(GLsizei n, const GLuint *arrays) { k = kh_get(glvao, list, t); if (k != kh_end(list)) { glvao = kh_value(list, k); + VaoSharedClear(glvao); kh_del(glvao, list, k); free(glvao); } @@ -428,7 +448,28 @@ GLboolean gl4es_glIsVertexArray(GLuint array) { return GL_FALSE; } -//Dirzct wrapper +void VaoSharedClear(glvao_t *vao) { + if(vao==NULL || vao->shared_arrays==NULL) + return; + if(!(--(*vao->shared_arrays))) { + free(vao->vert.ptr); + free(vao->color.ptr); + free(vao->secondary.ptr); + free(vao->normal.ptr); + for (int i=0; itex[i].ptr); + free(vao->shared_arrays); + } + vao->vert.ptr = NULL; + vao->color.ptr = NULL; + vao->secondary.ptr = NULL; + vao->normal.ptr = NULL; + for (int i=0; itex[i].ptr = NULL; + vao->shared_arrays = NULL; +} + +//Direct wrapper void glGenVertexArrays(GLsizei n, GLuint *arrays) AliasExport("gl4es_glGenVertexArrays"); void glBindVertexArray(GLuint array) AliasExport("gl4es_glBindVertexArray"); void glDeleteVertexArrays(GLsizei n, const GLuint *arrays) AliasExport("gl4es_glDeleteVertexArrays"); diff --git a/project/jni/gl4es/src/gl/buffers.h b/project/jni/gl4es/src/gl/buffers.h index efd56013c..57503d70e 100755 --- a/project/jni/gl4es/src/gl/buffers.h +++ b/project/jni/gl4es/src/gl/buffers.h @@ -65,6 +65,12 @@ typedef struct { pointer_state_t vertex, color, normal, tex_coord[MAX_TEX], secondary; } pointer_states_t; +typedef struct { + GLfloat *ptr; + pointer_state_t state; + GLboolean enabled; +} pointer_cache_t; + // VAO **************** typedef struct { GLuint array; @@ -81,8 +87,18 @@ typedef struct { normal_array, vertex_array, tex_coord_array[MAX_TEX]; + // VAO optimisation: keep a shared copy of the digested datas (unless the vao is the default one) + int *shared_arrays; + pointer_cache_t vert; + pointer_cache_t normal; + pointer_cache_t color; + pointer_cache_t secondary; + pointer_cache_t tex[MAX_TEX]; + int cache_count; } glvao_t; +void VaoSharedClear(glvao_t *vao); + KHASH_MAP_INIT_INT(glvao, glvao_t*) void gl4es_glGenVertexArrays(GLsizei n, GLuint *arrays); diff --git a/project/jni/gl4es/src/gl/const.h b/project/jni/gl4es/src/gl/const.h index b31b51a1f..a8705409e 100755 --- a/project/jni/gl4es/src/gl/const.h +++ b/project/jni/gl4es/src/gl/const.h @@ -17,6 +17,7 @@ #define GL_TEXTURE_GEN_T 0x0C61 #define GL_TEXTURE_GEN_MODE 0x2500 #define GL_TEXTURE_BORDER_COLOR 0x1004 +#define GL_TEXTURE_BORDER 0x1005 #define GL_TEXTURE_WIDTH 0x1000 #define GL_TEXTURE_HEIGHT 0x1001 #define GL_TEXTURE_BORDER 0x1005 diff --git a/project/jni/gl4es/src/gl/debug.c b/project/jni/gl4es/src/gl/debug.c index 71d71f19c..0a7cb4692 100755 --- a/project/jni/gl4es/src/gl/debug.c +++ b/project/jni/gl4es/src/gl/debug.c @@ -82,6 +82,8 @@ const char* PrintEnum(GLenum what) { p(GL_TEXTURE_WIDTH); p(GL_TEXTURE_HEIGHT); p(GL_TEXTURE_COMPRESSED); + p(GL_TEXTURE_BORDER); + p(GL_TEXTURE_INTERNAL_FORMAT); // texture pack/unpack p(GL_UNPACK_ALIGNMENT); // framebuffer diff --git a/project/jni/gl4es/src/gl/getter.c b/project/jni/gl4es/src/gl/getter.c index 0c3f2ba29..ddc9cd50e 100755 --- a/project/jni/gl4es/src/gl/getter.c +++ b/project/jni/gl4es/src/gl/getter.c @@ -9,7 +9,8 @@ GLenum gl4es_glGetError() { if(globals4es.noerror) return GL_NO_ERROR; if (glstate->shim_error) { - GLenum tmp = glstate->last_error; + GLenum tmp = gles_glGetError(); // to purge GLES error stack + tmp = glstate->last_error; glstate->last_error = GL_NO_ERROR; return tmp; } @@ -488,6 +489,9 @@ void gl4es_glGetFloatv(GLenum pname, GLfloat *params) { case GL_NOERROR_HINT_GL4ES: *params=globals4es.noerror; break; + case GL_NODOWNSAMPLING_HINT_GL4ES: + *params=globals4es.nodownsampling; + break; default: errorGL(); gles_glGetFloatv(pname, params); diff --git a/project/jni/gl4es/src/gl/gl.c b/project/jni/gl4es/src/gl/gl.c index 81dd333f0..f3d3e27ad 100755 --- a/project/jni/gl4es/src/gl/gl.c +++ b/project/jni/gl4es/src/gl/gl.c @@ -276,13 +276,13 @@ void gl4es_glEnable(GLenum cap) { } } PUSH_IF_COMPILING(glEnable) - +#ifdef TEXSTREAM if (globals4es.texstream && (cap==GL_TEXTURE_2D)) { if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]) if (glstate->texture.bound[glstate->texture.active][ENABLED_TEX2D]->streamed) cap = GL_TEXTURE_STREAM_IMG; } - +#endif LOAD_GLES(glEnable); proxy_glEnable(cap, true, gles_glEnable); } @@ -369,6 +369,28 @@ GLboolean gl4es_glIsEnabled(GLenum cap) { #undef clientisenabled GLboolean glIsEnabled(GLenum cap) AliasExport("gl4es_glIsEnabled"); +static GLboolean is_cache_compatible(GLsizei count) { + #define T2(AA, A, B) \ + if(glstate->vao->AA!=glstate->vao->B.enabled) return GL_FALSE; \ + if(glstate->vao->B.enabled && memcmp(&glstate->vao->pointers.A, &glstate->vao->B.state, sizeof(pointer_state_t))) return GL_FALSE; + #define TEST(A,B) T2(A##_array, A, B) + #define TESTA(A,B,I) T2(A##_array[i], A[i], B[i]) + + if(glstate->vao == glstate->defaultvao) return GL_FALSE; + if(count > glstate->vao->cache_count) return GL_FALSE; + TEST(vertex, vert) + TEST(color, color) + TEST(secondary, secondary) + TEST(normal, normal) + for (int i=0; imode_init = mode; list->len = count-skip; list->cap = count-skip; + + // check cache if any + if(glstate->vao->shared_arrays) { + if (!is_cache_compatible(count)) + VaoSharedClear(glstate->vao); + } - if (glstate->vao->vertex_array) { - list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count); - } - if (glstate->vao->color_array) { - if(glstate->vao->pointers.color.size==GL_BGRA) - list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count); - else - list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count); - } - if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) { - if(glstate->vao->pointers.secondary.size==GL_BGRA) - list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count); - else - list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary... - } - if (glstate->vao->normal_array) { - list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count); - } - for (int i=0; ivao->tex_coord_array[i]) { - list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count); - } - } + if(glstate->vao->shared_arrays) { + #define OP(A, N) (A)?A+skip*N:NULL + list->vert = OP(glstate->vao->vert.ptr,4); + list->color = OP(glstate->vao->color.ptr,4); + list->secondary = OP(glstate->vao->secondary.ptr,4); + list->normal = OP(glstate->vao->normal.ptr,3); + for (int i=0; itex[i] = OP(glstate->vao->tex[i].ptr,4); + #undef OP + + list->shared_arrays = glstate->vao->shared_arrays; + (*glstate->vao->shared_arrays)++; + } else { + if(!globals4es.novaocache && glstate->vao != glstate->defaultvao) { + // prepare a vao cache object + list->shared_arrays = glstate->vao->shared_arrays = (int*)malloc(sizeof(int)); + *glstate->vao->shared_arrays = 1; + #define G2(AA, A, B) \ + glstate->vao->B.enabled = glstate->vao->AA; \ + if (glstate->vao->B.enabled) memcpy(&glstate->vao->B.state, &glstate->vao->pointers.A, sizeof(pointer_state_t)); + #define GO(A,B) G2(A##_array, A, B) + #define GOA(A,B,I) G2(A##_array[i], A[i], B[i]) + GO(vertex, vert) + GO(color, color) + GO(secondary, secondary) + GO(normal, normal) + for (int i=0; ivao->cache_count = count; + #undef GOA + #undef GO + #undef G2 + } + if (glstate->vao->vertex_array) { + if(glstate->vao->shared_arrays) { + glstate->vao->vert.ptr = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, 0, count); + list->vert = glstate->vao->vert.ptr + 4*skip; + } else + list->vert = copy_gl_pointer_tex(&glstate->vao->pointers.vertex, 4, skip, count); + } + if (glstate->vao->color_array) { + if(glstate->vao->shared_arrays) { + if(glstate->vao->pointers.color.size==GL_BGRA) + glstate->vao->color.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, 0, count); + else + glstate->vao->color.ptr = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, 0, count); + list->color = glstate->vao->color.ptr + 4*skip; + } else { + if(glstate->vao->pointers.color.size==GL_BGRA) + list->color = copy_gl_pointer_color_bgra(&glstate->vao->pointers.color, 4, skip, count); + else + list->color = copy_gl_pointer_color(&glstate->vao->pointers.color, 4, skip, count); + } + } + if (glstate->vao->secondary_array/* && glstate->enable.color_array*/) { + if(glstate->vao->shared_arrays) { + if(glstate->vao->pointers.secondary.size==GL_BGRA) + glstate->vao->secondary.ptr = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, 0, count); + else + glstate->vao->secondary.ptr = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, 0, count); // alpha chanel is always 0 for secondary... + list->secondary = glstate->vao->secondary.ptr + 4*skip; + } else { + if(glstate->vao->pointers.secondary.size==GL_BGRA) + list->secondary = copy_gl_pointer_color_bgra(&glstate->vao->pointers.secondary, 4, skip, count); + else + list->secondary = copy_gl_pointer(&glstate->vao->pointers.secondary, 4, skip, count); // alpha chanel is always 0 for secondary... + } + } + if (glstate->vao->normal_array) { + if(glstate->vao->shared_arrays) { + glstate->vao->normal.ptr = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, 0, count); + list->normal = glstate->vao->normal.ptr + 3*skip; + } else + list->normal = copy_gl_pointer_raw(&glstate->vao->pointers.normal, 3, skip, count); + } + for (int i=0; ivao->tex_coord_array[i]) { + if(glstate->vao->shared_arrays) { + glstate->vao->tex[i].ptr = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, 0, count); + list->tex[i] = glstate->vao->tex[i].ptr + 4*skip; + } else + list->tex[i] = copy_gl_pointer_tex(&glstate->vao->pointers.tex_coord[i], 4, skip, count); + } + } + } return list; } @@ -411,6 +502,10 @@ static inline bool should_intercept_render(GLenum mode) { if (glstate->enable.texture[aa]) { 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->vao->tex_coord_array[aa]) && !(mode==GL_POINT && glstate->texture.pscoordreplace[aa])) + return true; + if ((glstate->vao->tex_coord_array[aa]) && (glstate->vao->pointers.tex_coord[aa].size == 1)) + return true; } } if(glstate->polygon_mode == GL_LINE && mode>=GL_TRIANGLES) @@ -422,7 +517,7 @@ static inline bool should_intercept_render(GLenum mode) { return ( (glstate->vao->vertex_array && ! valid_vertex_type(glstate->vao->pointers.vertex.type)) || (mode == GL_LINES && glstate->enable.line_stipple) || - (mode == GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) + /*(mode == GL_QUADS) ||*/ (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) ); } @@ -477,7 +572,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid return; } - if (should_intercept_render(mode)) { + if (should_intercept_render(mode) || (mode==GL_QUADS)) { renderlist_t *list = NULL; GLsizei min, max; @@ -508,6 +603,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid LOAD_GLES(glDisable); LOAD_GLES(glEnableClientState); LOAD_GLES(glDisableClientState); + LOAD_GLES(glMultiTexCoord4f); GLuint len = 0; for (int i=0; ivao->pointers.vertex.size, glstate->vao->pointers.vertex.type, glstate->vao->pointers.vertex.stride, glstate->vao->pointers.vertex.pointer); GLuint old_tex = glstate->texture.client; #define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0); - for (int aa=0; aaenable.texture[aa]); @@ -559,7 +655,13 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid if (glstate->vao->tex_coord_array[aa]) { TEXTURE(aa); tex_setup_texcoord(len, itarget); - } + } else + gles_glMultiTexCoord4f(GL_TEXTURE0+aa, glstate->texcoord[aa][0], glstate->texcoord[aa][1], glstate->texcoord[aa][2], glstate->texcoord[aa][3]); + } else if (glstate->clientstate.tex_coord_array[aa]) { + // special case, Tex disable but CoordArray enabled... disabling it temporarly + TEXTURE(aa); + glstate->clientstate.tex_coord_array[aa] = 0; + gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } if (glstate->texture.client!=old_tex) @@ -567,7 +669,7 @@ void gl4es_glDrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid // POLYGON mode as LINE is "intercepted" and drawn using list gles_glDrawElements(mode, count, GL_UNSIGNED_SHORT, sindices); - for (int aa=0; aaenable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) { TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); @@ -615,6 +717,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { LOAD_GLES(glDisable); LOAD_GLES(glEnableClientState); LOAD_GLES(glDisableClientState); + LOAD_GLES(glMultiTexCoord4f); if (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) { NewStage(glstate->list.active, STAGE_DRAW); @@ -635,6 +738,35 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { draw_renderlist(list); free_renderlist(list); } else { + if (mode==GL_QUADS) { + static GLushort *indices = NULL; + static int indcnt = 0; + static int indfirst = 0; + if((indcnt < count) || (indfirst!=first)) { + if(indcnt < count) { + indcnt = count; + if (indices) free(indices); + indices = (GLushort*)malloc(sizeof(GLushort)*(indcnt*3/2)); + } + indfirst = first; + for (int i=0, j=0; i+3vao->elements; + glstate->vao->elements = NULL; + gl4es_glDrawElements(GL_TRIANGLES, count*3/2, GL_UNSIGNED_SHORT, indices); + glstate->vao->elements = old_vao_elements; + return; + } + LOAD_GLES(glDrawArrays); GLenum mode_init = mode; @@ -658,7 +790,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { 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; #define TEXTURE(A) gl4es_glClientActiveTexture(A+GL_TEXTURE0); - for (int aa=0; aaenable.texture[aa]); @@ -670,9 +802,13 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { if (glstate->vao->tex_coord_array[aa]) { TEXTURE(aa); tex_setup_texcoord(count+first, itarget); - /*glClientActiveTexture(aa+GL_TEXTURE0); - gles_glTexCoordPointer(glstate->pointers.tex_coord[aa].size, glstate->pointers.tex_coord[aa].type, glstate->pointers.tex_coord[aa].stride, glstate->pointers.tex_coord[aa].pointer);*/ - } + } else + gles_glMultiTexCoord4f(GL_TEXTURE0+aa, glstate->texcoord[aa][0], glstate->texcoord[aa][1], glstate->texcoord[aa][2], glstate->texcoord[aa][3]); + } else if (glstate->clientstate.tex_coord_array[aa]) { + // special case, Tex disable but CoordArray enabled... disabling it temporarly + TEXTURE(aa); + glstate->clientstate.tex_coord_array[aa] = 0; + gles_glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } if (glstate->texture.client!=old_tex) @@ -680,7 +816,7 @@ void gl4es_glDrawArrays(GLenum mode, GLint first, GLsizei count) { gles_glDrawArrays(mode, first, count); - for (int aa=0; aaenable.texture[aa]) && (IS_ANYTEX(glstate->enable.texture[aa]))) { TEXTURE(aa); gles_glDisable(GL_TEXTURE_2D); @@ -1544,9 +1680,10 @@ void glPointParameterfv(GLenum pname, const GLfloat * params) AliasExport("gl4es void gl4es_glMultiDrawArrays(GLenum mode, const GLint *first, const GLsizei *count, GLsizei primcount) { LOAD_GLES_EXT(glMultiDrawArrays); - if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) + if((!gles_glMultiDrawArrays) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) ) { + // GL_QUADS special case can probably by improved // divide the call // TODO optimize with forcing Batch mode for (int i=0; ilist.active && (glstate->list.compiling || glstate->gl_batch)) + if((!gles_glMultiDrawElements) || should_intercept_render(mode) || (mode==GL_QUADS) || (glstate->list.active && (glstate->list.compiling || glstate->gl_batch)) || (glstate->render_mode == GL_SELECT) || ((glstate->polygon_mode == GL_LINE) || (glstate->polygon_mode == GL_POINT)) || (type != GL_UNSIGNED_SHORT) ) { // divide the call diff --git a/project/jni/gl4es/src/gl/hint.c b/project/jni/gl4es/src/gl/hint.c index 0d24cc995..47c40ffc5 100755 --- a/project/jni/gl4es/src/gl/hint.c +++ b/project/jni/gl4es/src/gl/hint.c @@ -69,6 +69,12 @@ void gl4es_glHint(GLenum pname, GLenum mode) { else errorShim(GL_INVALID_ENUM); break; + case GL_NODOWNSAMPLING_HINT_GL4ES: + if (mode<=1) + globals4es.nodownsampling = mode; + else + errorShim(GL_INVALID_ENUM); + break; default: errorGL(); gles_glHint(pname, mode); diff --git a/project/jni/gl4es/src/gl/init.c b/project/jni/gl4es/src/gl/init.c index ee6d82b68..5e399f10e 100755 --- a/project/jni/gl4es/src/gl/init.c +++ b/project/jni/gl4es/src/gl/init.c @@ -257,8 +257,14 @@ void initialize_gl4es() { globals4es.queries = 0; SHUT(LOGD("LIBGL: Dont't expose fake glQueries functions\n")); } + char *env_nodownsampling = getenv("LIBGL_NODOWNSAMPLING"); + if (env_nodownsampling && strcmp(env_nodownsampling, "1") == 0) { + globals4es.nodownsampling = 1; + SHUT(LOGD("LIBGL: No downsampling of DXTc textures\n")); + } env(LIBGL_NOTEXMAT, globals4es.texmat, "Don't handle Texture Matrice internaly"); + env(LIBGL_NOVAOCACHE, globals4es.novaocache, "Don't use VAO cache"); char cwd[1024]; if (getcwd(cwd, sizeof(cwd))!= NULL) diff --git a/project/jni/gl4es/src/gl/init.h b/project/jni/gl4es/src/gl/init.h index 2c35a8089..dc3dd3219 100755 --- a/project/jni/gl4es/src/gl/init.h +++ b/project/jni/gl4es/src/gl/init.h @@ -33,10 +33,12 @@ typedef struct _globals4es { int queries; int silentstub; int glx_surface_srgb; + int nodownsampling; #ifdef PANDORA float gamma; #endif int texmat; + int novaocache; char version[50]; } globals4es_t; diff --git a/project/jni/gl4es/src/gl/list.c b/project/jni/gl4es/src/gl/list.c index f39122aa1..df33de80e 100755 --- a/project/jni/gl4es/src/gl/list.c +++ b/project/jni/gl4es/src/gl/list.c @@ -681,12 +681,13 @@ void adjust_renderlist(renderlist_t *list) { list->stage = STAGE_LAST; list->open = false; for (int a=0; atexture.bound[a][ENABLED_TEX2D]; //TODO check if hardcoded TEX2D is ok + const GLint itarget = get_target(glstate->enable.texture[a]); + gltexture_t *bound = glstate->texture.bound[a][itarget]; // in case of Texture bounding inside a list if (list->set_texture && (list->tmu == a)) bound = gl4es_getTexture(list->target_texture, list->texture); // GL_ARB_texture_rectangle - if ((list->tex[a]) && glstate->texture.rect_arb[a] && (bound)) { + if ((list->tex[a]) && (itarget == ENABLED_TEXTURE_RECTANGLE) && (bound)) { tex_coord_rect_arb(list->tex[a], list->len, bound->width, bound->height); } } @@ -935,7 +936,7 @@ void draw_renderlist(renderlist_t *list) { old_tex = glstate->texture.client; GLuint cur_tex = old_tex; #define RS(A, len) if(texgenedsz[A]enable.texture[a]) { const GLint itarget = get_target(glstate->enable.texture[a]); diff --git a/project/jni/gl4es/src/gl/matrix.c b/project/jni/gl4es/src/gl/matrix.c index 9fafd61ec..10eaa7319 100755 --- a/project/jni/gl4es/src/gl/matrix.c +++ b/project/jni/gl4es/src/gl/matrix.c @@ -56,6 +56,7 @@ static int send_to_hardware() { } void init_matrix(glstate_t* glstate) { +DBG(printf("init_matrix(%p)\n", glstate);) alloc_matrix(&glstate->projection_matrix, MAX_STACK_PROJECTION); set_identity(TOP(projection_matrix)); glstate->projection_matrix->identity = 1; @@ -93,7 +94,7 @@ DBG(printf("glPushMatrix(), list=%p\n", glstate->list.active);) noerrorShim(); // go... switch(matrix_mode) { - #define P(A, B) if(glstate->A->topA->top+1A->top++; \ } else errorShim(GL_STACK_OVERFLOW) diff --git a/project/jni/gl4es/src/gl/pixel.c b/project/jni/gl4es/src/gl/pixel.c index 1c2fead8a..56326dfe2 100755 --- a/project/jni/gl4es/src/gl/pixel.c +++ b/project/jni/gl4es/src/gl/pixel.c @@ -73,58 +73,58 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - s = (GLushort[]){ - (v & 0x001f), - ((v & 0x03e0) >> 5), - ((v & 0x7c00) >> 10), - ((v & 0x8000) >> 15)*31, - }; - read_each(, / 31.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5_REV, GLushort, - s = (GLushort[]){ - (v & 0x001f)*2, - ((v & 0x07e0) >> 5), - ((v & 0xF800) >> 11)*2, + s = (const GLushort[]) { + ((v ) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v >> 11) & 0x1f)<<1, }; read_each(, / 63.0f); ) + type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, + s = (const GLushort[]) { + ((v ) & 0x1f), + ((v >> 5) & 0x1f), + ((v >> 10) & 0x1f), + ((v >> 15) & 0x01)*31, + }; + read_each(, / 31.0f); + ) type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, - s = (GLushort[]){ - (v & 0x000f), - ((v & 0x00f0) >> 4), - ((v & 0x0f00) >> 8), - ((v & 0xf000) >> 12) + s = (const GLushort[]) { + ((v ) & 0x0f), + ((v >> 4 ) & 0x0f), + ((v >> 8 ) & 0x0f), + ((v >> 12 ) & 0x0f) }; read_each(, / 15.0f); ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, - s = (GLushort[]){ - ((v & 0xF800) >>11)*2, - ((v & 0x07e0) >> 5), - ((v & 0x001f) )*2, + s = (const GLushort[]) { + ((v >> 11) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v ) & 0x1f)<<1, }; read_each(, / 63.0f); ) - type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, - s = (GLushort[]){ - ((v & 0xf000) >>12), - ((v & 0x0f00) >> 8), - ((v & 0x00f0) >> 4), - ((v & 0x000f) ) - }; - read_each(, / 15.0f); - ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, - s = (GLushort[]){ - ((v & 0xf800) >> 11), - ((v & 0x07c0) >> 6), - ((v & 0x003e) >> 1), - ((v & 1))*31, + s = (const GLushort[]) { + ((v >> 11) & 0x1f), + ((v >> 6) & 0x1f), + ((v >> 1) & 0x1f), + ((v ) & 0x01)*31, }; read_each(, / 31.0f); ) + type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, + s = (const GLushort[]) { + ((v >> 12) & 0x0f), + ((v >> 8) & 0x0f), + ((v >> 4) & 0x0f), + ((v ) & 0x0f) + }; + read_each(, / 15.0f); + ) default: // TODO: add glSetError? printf("LIBGL: Unsupported source data type: %s\n", PrintEnum(src_type)); @@ -149,35 +149,35 @@ bool remap_pixel(const GLvoid *src, GLvoid *dst, // TODO: force 565 to RGB? then we can change [4] -> 3 type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - *d = (((GLushort)(color[0] * 31.0f) & 0x1f) << 11) | - (((GLushort)(color[1] * 63.0f) & 0x3f) << 5) | - (((GLushort)(color[2] * 31.0f) & 0x1f)); + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - color[dst_color->alpha] = pixel.a; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = (((GLushort)(color[0] * 31.0f) & 0x1f) ) | - (((GLushort)(color[1] * 31.0f) & 0x1f) << 5) | - (((GLushort)(color[2] * 31.0f) & 0x1f) << 10) | - (((GLushort)(color[3] * 1) & 0x01) << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; - color[dst_color->red] = pixel.r; - color[dst_color->green] = pixel.g; - color[dst_color->blue] = pixel.b; - color[dst_color->alpha] = pixel.a; - *d = (((GLushort)(color[0] * 15.0) & 0x0f) << 12) | - (((GLushort)(color[1] * 15.0) & 0x0f) << 8) | - (((GLushort)(color[2] * 15.0) & 0x0f) << 4) | - (((GLushort)(color[3] * 15.0) & 0x0f)); + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(dst_type)); @@ -243,38 +243,29 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - s = (GLushort[]){ - (v & 31), - ((v & 0x03e0) >> 5), - ((v & 0x7c00) >> 10), - ((v & 0x8000) >> 15)*31, - }; - read_each(, / 31.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, - s = (GLushort[]){ - (v & 31)*2, - ((v & 0x07e0) >> 5), - ((v & 0xF800) >> 11)*2, + s = (const GLushort[]) { + ((v >> 11) & 0x1f)<<1, + ((v >> 5) & 0x3f), + ((v ) & 0x1f)<<1, }; read_each(, / 63.0f); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, - s = (GLushort[]){ - ((v & 0xf800) >> 11), - ((v & 0x07c0) >> 6), - ((v & 0x003e) >> 1), - ((v & 1))*31, + s = (const GLushort[]) { + ((v >> 11) & 0x1f), + ((v >> 6) & 0x1f), + ((v >> 1) & 0x1f), + ((v ) & 0x01)*31, }; read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, - s = (GLushort[]){ - (v & 0x000f), - ((v & 0x00f0) >> 4), - ((v & 0x0f00) >> 8), - ((v & 0xf000) >> 12) + s = (const GLushort[]) { + ((v >> 12) & 0x0f), + ((v >> 8) & 0x0f), + ((v >> 4) & 0x0f), + ((v ) & 0x0f) }; read_each(, / 15.0f); ) @@ -300,9 +291,9 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[2] * 31.0f) & 0x1f << 11) | - ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | - ((GLuint)(color[0] * 31.0f) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; @@ -311,10 +302,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | - ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | - ((GLuint)(color[3] * 1) & 0x01 << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -322,10 +313,10 @@ bool transform_pixel(const GLvoid *src, GLvoid *dst, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[3] * 15.0f) & 0x0f << 12) | - ((GLushort)(color[2] * 15.0f) & 0x0f << 8) | - ((GLushort)(color[1] * 15.0f) & 0x0f << 4) | - ((GLushort)(color[0] * 15.0f) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -402,59 +393,37 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - (v[ii] & 31), - ((v[ii] & 0x03e0) >> 5), - ((v[ii] & 0x7c00) >> 10), - ((v[ii] & 0x8000) >> 15)*31, - }; - }; - read_each(, / 31.0f); - ) - type_case(GL_UNSIGNED_SHORT_4_4_4_4_REV, GLushort, - for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0x000f) ), - ((v[ii] & 0x00f0) >> 4), - ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0xf000) >>12) - }; - }; - read_each(, / 15.0f); - ) type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0x001f) )*2, - ((v[ii] & 0x07e0) >> 5), - ((v[ii] & 0xF800) >>11)*2, + s[ii] = (const GLushort[]) { + ((v[ii] >> 11) & 0x1f)<<1, + ((v[ii] >> 5) & 0x3f), + ((v[ii] ) & 0x1f)<<1, }; + read_i_each(, / 63.0f, ii); }; - read_each(, / 63.0f); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0xf800) >>11), - ((v[ii] & 0x07c0) >> 6), - ((v[ii] & 0x003e) >> 1), - ((v[ii] & 1) )*31, + s[ii] = (const GLushort[]) { + ((v[ii] >> 11) & 0x1f), + ((v[ii] >> 6) & 0x1f), + ((v[ii] >> 1) & 0x1f), + ((v[ii] ) & 0x01)*31, }; + read_i_each(, / 31.0f, ii); }; - read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, for (int ii=0; ii<4; ii++) { - s[ii] = (GLushort[]) { - ((v[ii] & 0xf000) >>12), - ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0x00f0) >> 4), - ((v[ii] & 0x000f) ) + s[ii] = (const GLushort[]) { + ((v[ii] >> 12) & 0x0f), + ((v[ii] >> 8) & 0x0f), + ((v[ii] >> 4) & 0x0f), + ((v[ii] ) & 0x0f) }; + read_i_each(, / 15.0f, ii); }; - read_each(, / 15.0f); ) default: // TODO: add glSetError? @@ -478,9 +447,9 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 11) | - ((GLuint)(color[1] * 63.0f) & 0x3f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); ) type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, GLfloat color[4]; @@ -489,10 +458,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; // TODO: can I macro this or something? it follows a pretty strict form. - *d = ((GLuint)(color[0] * 31.0f) & 0x1f << 0) | - ((GLuint)(color[1] * 31.0f) & 0x1f << 5) | - ((GLuint)(color[2] * 31.0f) & 0x1f << 10) | - ((GLuint)(color[3] * 1) & 0x01 << 15); + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -500,10 +469,10 @@ bool half_pixel(const GLvoid *src0, const GLvoid *src1, color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[0] * 15.0f) & 0x0f << 12) | - ((GLushort)(color[1] * 15.0f) & 0x0f << 8) | - ((GLushort)(color[2] * 15.0f) & 0x0f << 4) | - ((GLushort)(color[3] * 15.0f) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: half_pixel: Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -588,27 +557,37 @@ bool quarter_pixel(const GLvoid *src[16], case GL_UNSIGNED_INT_8_8_8_8_REV: type_case(GL_UNSIGNED_BYTE, GLubyte, read_each(, / 255.0f)) type_case(GL_UNSIGNED_INT_8_8_8_8, GLubyte, read_each(max_a - , / 255.0f)) - type_case(GL_UNSIGNED_SHORT_1_5_5_5_REV, GLushort, - for (int ii=0; ii<16; ii++) { + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + for (int ii=0; ii<4; ii++) { s[ii] = (GLushort[]) { - (v[ii] & 31), - ((v[ii] & 0x03e0) >> 5), - ((v[ii] & 0x7c00) >> 10), - ((v[ii] & 0x8000) >> 15)*31, + ((v[ii] & 0xf800) >>11), + ((v[ii] & 0x07c0) >> 6), + ((v[ii] & 0x003e) >> 1), + ((v[ii] & 1) )*31, }; + read_i_each(, / 31.0f, ii); + }; + ) + type_case(GL_UNSIGNED_SHORT_5_6_5, GLushort, + for (int ii=0; ii<4; ii++) { + s[ii] = (GLushort[]) { + ((v[ii] & 0xF800) >>11)*2, + ((v[ii] & 0x07e0) >> 5), + ((v[ii] & 0x001f) )*2, + }; + read_i_each(, / 63.0f, ii); }; - read_each(, / 31.0f); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, for (int ii=0; ii<16; ii++) { s[ii] = (GLushort[]) { - (v[ii] & 0x000f), - ((v[ii] & 0x00f0) >> 4), + ((v[ii] & 0xf000) >> 12), ((v[ii] & 0x0f00) >> 8), - ((v[ii] & 0xf000) >> 12) + ((v[ii] & 0x00f0) >> 4), + (v[ii] & 0x000f) }; + read_i_each(, / 15.0f, ii); }; - read_each(, / 15.0f); ) default: // TODO: add glSetError? @@ -632,9 +611,21 @@ bool quarter_pixel(const GLvoid *src[16], color[src_color->red] = pixel.r; color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; - *d = ((GLuint)(color[0] * 31) & 0x1f << 11) | - ((GLuint)(color[1] * 63) & 0x3f << 5) | - ((GLuint)(color[2] * 31) & 0x1f); + *d = (((GLuint)(color[0] * 31.0f) & 0x1f) << 11) | + (((GLuint)(color[1] * 63.0f) & 0x3f) << 5 ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) ); + ) + type_case(GL_UNSIGNED_SHORT_5_5_5_1, GLushort, + GLfloat color[4]; + color[src_color->red] = pixel.r; + color[src_color->green] = pixel.g; + color[src_color->blue] = pixel.b; + color[src_color->alpha] = pixel.a; + // TODO: can I macro this or something? it follows a pretty strict form. + *d = (((GLuint)(color[3] ) & 0x01) ) | + (((GLuint)(color[2] * 31.0f) & 0x1f) << 1 ) | + (((GLuint)(color[1] * 31.0f) & 0x1f) << 6 ) | + (((GLuint)(color[0] * 31.0f) & 0x1f) << 11); ) type_case(GL_UNSIGNED_SHORT_4_4_4_4, GLushort, GLfloat color[4]; @@ -642,10 +633,10 @@ bool quarter_pixel(const GLvoid *src[16], color[src_color->green] = pixel.g; color[src_color->blue] = pixel.b; color[src_color->alpha] = pixel.a; - *d = ((GLushort)(color[0] * 15.0) & 0x0f << 12) | - ((GLushort)(color[1] * 15.0) & 0x0f << 8) | - ((GLushort)(color[2] * 15.0) & 0x0f << 4) | - ((GLushort)(color[3] * 15.0) & 0x0f); + *d = (((GLushort)(color[0] * 15.0f) & 0x0f) << 12) | + (((GLushort)(color[1] * 15.0f) & 0x0f) << 8 ) | + (((GLushort)(color[2] * 15.0f) & 0x0f) << 4 ) | + (((GLushort)(color[3] * 15.0f) & 0x0f) ); ) default: printf("LIBGL: quarter_pixel Unsupported target data type: %s\n", PrintEnum(src_type)); @@ -1021,13 +1012,13 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height; - new_width = width / 2; if(new_width==0) new_width=1; - new_height = height / 2; if(new_height==0) new_height==1; + new_width = width / 2; if(!new_width) ++new_width; + new_height = height / 2; if(!new_height) ++new_height; /* if (new_width*2!=width || new_height*2!=height) { printf("LIBGL: halfscaling %ux%u failed\n", width, height); return false; }*/ -// printf("LIBGL: halfscaling %ux%u -> %ux%u\n", width, height, new_width, new_height); + //printf("LIBGL: halfscaling %ux%u -> %ux%u (%s / %s)\n", width, height, new_width, new_height, PrintEnum(format), PrintEnum(type)); const colorlayout_t *src_color; src_color = get_color_map(format); GLvoid *dst; @@ -1037,16 +1028,18 @@ bool pixel_halfscale(const GLvoid *old, GLvoid **new, dst = malloc(pixel_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dx = (width>1)?1:0; + const int dy = (height>1)?1:0; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { pix0 = src + ((x * 2) + (y * 2) * width) * pixel_size; - pix1 = src + ((x * 2 + 1) + + pix1 = src + ((x * 2 + dx) + (y * 2) * width) * pixel_size; pix2 = src + ((x * 2) + - (y * 2 + 1) * width) * pixel_size; - pix3 = src + ((x * 2 + 1) + - (y * 2 + 1) * width) * pixel_size; + (y * 2 + dy) * width) * pixel_size; + pix3 = src + ((x * 2 + dx) + + (y * 2 + dy) * width) * pixel_size; half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)pos, src_color, type); pos += pixel_size; } @@ -1059,8 +1052,8 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height, dest_size; - new_width = width / 2; - new_height = height / 2; + new_width = width / 2; if(!new_width) ++new_width; + new_height = height / 2; if(!new_height) ++new_height; if (new_width*2!=width || new_height*2!=height || format!=GL_RGBA || type!=GL_UNSIGNED_BYTE) { //printf("LIBGL: thirdscaling %ux%u failed\n", width, height); return false; @@ -1076,17 +1069,19 @@ bool pixel_thirdscale(const GLvoid *old, GLvoid **new, dst = malloc(dest_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dx = (width>1)?1:0; + const int dy = (height>1)?1:0; GLubyte tmp[4]; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { pix0 = src + ((x * 2) + (y * 2) * width) * pixel_size; - pix1 = src + ((x * 2 + 1) + + pix1 = src + ((x * 2 + dx) + (y * 2) * width) * pixel_size; pix2 = src + ((x * 2) + - (y * 2 + 1) * width) * pixel_size; - pix3 = src + ((x * 2 + 1) + - (y * 2 + 1) * width) * pixel_size; + (y * 2 + dy) * width) * pixel_size; + pix3 = src + ((x * 2 + dx) + + (y * 2 + dy) * width) * pixel_size; half_pixel((GLvoid *)pix0, (GLvoid *)pix1, (GLvoid *)pix2, (GLvoid *)pix3, (GLvoid *)tmp, src_color, type); *((GLushort*)pos) = (((GLushort)tmp[0])&0xf0)<<8 | (((GLushort)tmp[1])&0xf0)<<4 | (((GLushort)tmp[2])&0xf0) | (((GLushort)tmp[3])>>4); pos += dest_size; @@ -1100,8 +1095,8 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new, GLuint width, GLuint height, GLenum format, GLenum type) { GLuint pixel_size, new_width, new_height; - new_width = width / 4; - new_height = height / 4; + new_width = width / 4; if(!new_width) ++new_width; + new_height = height / 4; if(!new_height) ++new_height; /* if (new_width*4!=width || new_height*4!=height) { printf("LIBGL: quarterscaling %ux%u failed\n", width, height); return false; @@ -1116,12 +1111,14 @@ bool pixel_quarterscale(const GLvoid *old, GLvoid **new, dst = malloc(pixel_size * new_width * new_height); src = (uintptr_t)old; pos = (uintptr_t)dst; + const int dxs[4] = {0, width>1?1:0, width>2?2:0, width>3?3:width>1?1:0}; + const int dys[4] = {0, height>1?1:0, height>2?2:0, height>3?3:height>1?1:0}; for (int y = 0; y < new_height; y++) { for (int x = 0; x < new_width; x++) { for (int dx=0; dx<4; dx++) { for (int dy=0; dy<4; dy++) { - pix[dx+dy*4] = src + ((x * 4 + dx) + - (y * 4 + dy) * width) * pixel_size; + pix[dx+dy*4] = src + ((x * 4 + dxs[dx]) + + (y * 4 + dys[dy]) * width) * pixel_size; } } quarter_pixel((const GLvoid **)pix, (GLvoid *)pos, src_color, type); diff --git a/project/jni/gl4es/src/gl/state.h b/project/jni/gl4es/src/gl/state.h index d3a6489de..f148393bc 100755 --- a/project/jni/gl4es/src/gl/state.h +++ b/project/jni/gl4es/src/gl/state.h @@ -51,8 +51,6 @@ typedef struct { pack_skip_rows, pack_image_height; GLboolean pack_lsb_first; - // TODO: do we only need to worry about GL_TEXTURE_2D? - GLboolean rect_arb[MAX_TEX]; gltexture_t *bound[MAX_TEX][ENABLED_TEXTURE_LAST]; GLboolean pscoordreplace[MAX_TEX]; khash_t(tex) *list; diff --git a/project/jni/gl4es/src/gl/texture.c b/project/jni/gl4es/src/gl/texture.c index 1bde96aa6..4f6547de9 100755 --- a/project/jni/gl4es/src/gl/texture.c +++ b/project/jni/gl4es/src/gl/texture.c @@ -25,6 +25,12 @@ int npot(int n) { return i; } +static int inline nlevel(int size, int level) { + size>>=level; + if(!size) size=1; + return size; +} + // conversions for GL_ARB_texture_rectangle void tex_coord_rect_arb(GLfloat *tex, GLsizei len, GLsizei width, GLsizei height) { @@ -82,7 +88,7 @@ void tex_setup_texcoord(GLuint len, GLuint itarget) { // check if some changes are needed int changes = 0; - if ((glstate->texture.rect_arb[texunit]) + if ((itarget == ENABLED_TEXTURE_RECTANGLE) || (bound && ((bound->width!=bound->nwidth)||(bound->height!=bound->nheight) )) || !(globals4es.texmat || glstate->texture_matrix[texunit]->identity) ) @@ -96,7 +102,7 @@ void tex_setup_texcoord(GLuint len, GLuint itarget) { } copy_gl_pointer_tex_noalloc(tex[texunit], &glstate->vao->pointers.tex_coord[texunit], 4, 0, len); // Normalize if needed - if ((glstate->texture.rect_arb[texunit])) + if (itarget == ENABLED_TEXTURE_RECTANGLE) tex_coord_rect_arb(tex[texunit], len, bound->width, bound->height); // Apply transformation matrix if any if (!(globals4es.texmat || glstate->texture_matrix[texunit]->identity)) @@ -435,6 +441,86 @@ GLenum swizzle_internalformat(GLenum *internalformat) { return sret; } +static int get_shrinklevel(int width, int height, int level) { + int shrink = 0; + int mipwidth = width << level; + int mipheight = height << level; + switch(globals4es.texshrink) { + case 0: // nothing + break; + case 1: //everything / 2 + if ((mipwidth > 1) && (mipheight > 1)) { + shrink = 1; + } + break; + case 2: //only > 512 /2 + case 7: //only > 512 /2 , but not for empty texture + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 512) && (mipheight > 8)) || ((mipheight > 512) && (mipwidth > 8))) { + shrink = 1; + } + break; + case 3: //only > 256 /2 + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + shrink = 1; + } + break; + case 4: //only > 256 /2, >=1024 /4 + case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same) + if (((mipwidth%4==0) && (mipheight%4==0)) && + ((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + if ((mipwidth>=1024) || (mipheight>=1024)) { + shrink = 2; + } else { + shrink = 1; + } + } + break; + case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture + if (((mipwidth%2==0) && (mipheight%2==0)) && + ((mipwidth > 128) && (mipheight > 8)) || ((mipheight > 128) && (mipwidth > 8))) { + if (((mipwidth%2==0) && (mipheight%2==0)) && (mipwidth>=512) || (mipheight>=512)) { + while (((mipwidth > 256) && (mipheight > 8)) || ((mipheight > 256) && (mipwidth > 8))) { + width /= 2; + height /= 2; + mipwidth /= 2; + mipheight /= 2; + shrink+=1; + } + } else { + shrink = 1; + } + } + break; + case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 + if ((mipwidth>4096) || (mipheight>4096)) { + shrink=2; + } else + if ((mipwidth>2048) || (mipheight>2048)) { + shrink=1; + } + break; + case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture + if ((mipwidth>4096) || (mipheight>4096)) { + shrink=2; + } else + if ((mipwidth>512) || (mipheight>512)) { + shrink=1; + } + break; + case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture + if ((mipwidth>2048) || (mipheight>2048)) { + shrink=2; + } else + if ((mipwidth>512) || (mipheight>512)) { + shrink=1; + } + break; + } + return shrink; +} + static int default_tex_mipmap = 0; static int proxy_width = 0; @@ -487,6 +573,14 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, bound->orig_internal = internalformat; bound->internalformat = new_format; } + // shrink checking + int mipwidth = width << level; + int mipheight = height << level; + int shrink = 0; + if(bound) { + bound->shrink = shrink = get_shrinklevel(width, height, level); + } + if(width>>shrink==0 && height>>shrink==0) return; // nothing to do if (datab) { // implements GL_UNPACK_ROW_LENGTH @@ -511,13 +605,12 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, free(old); } - if (bound) { - bound->shrink = 0; - switch(globals4es.texshrink) { - case 0: // nothing + if (bound && bound->shrink!=0) { + switch(globals4es.texshrink) { + case 0: // nothing ??? break; case 1: //everything / 2 - if ((width > 1) && (height > 1)) { + if ((mipwidth > 1) && (mipheight > 1)) { GLvoid *out = pixels; GLfloat ratio = 0.5; pixel_scale(pixels, &out, width, height, ratio, format, type); @@ -529,163 +622,28 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, bound->shrink = 1; } break; - case 2: //only > 512 /2 - case 7: //only > 512 /2 , but not for empty texture - if (((width%2==0) && (height%2==0)) && - ((width > 512) && (height > 8)) || ((height > 512) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 3: //only > 256 /2 - if (((width%2==0) && (height%2==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 4: //only > 256 /2, >=1024 /4 - case 5: //every > 256 is downscaled to 256, but not for empty texture (as there is no downscale stronger than 4, there are the same) - if (((width%4==0) && (height%4==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - if ((width>=1024) || (height>=1024)) { + default: + while(shrink) { + if (shrink>1) { // quarterscale GLvoid *out = pixels; pixel_quarterscale(pixels, &out, width, height, format, type); if (out != pixels && pixels!=datab) free(pixels); pixels = out; - width /= 4; - height /= 4; - bound->shrink = 2; - } else { + width = nlevel(width, 2); + height = nlevel(height, 2); + shrink-=2; + } else { //halfscale GLvoid *out = pixels; pixel_halfscale(pixels, &out, width, height, format, type); if (out != pixels && pixels!=datab) free(pixels); pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; + width = nlevel(width, 1); + height = nlevel(height, 1); + shrink--; } } - break; - /*case 5: //every > 256 is downscaled to 256, but not for empty texture - while (((width%2==0) && (height%2==0)) && - ((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink+=1; - } - break;*/ - case 6: //only > 128 /2, >=512 is downscaled to 256, but not for empty texture - if (((width%2==0) && (height%2==0)) && - ((width > 128) && (height > 8)) || ((height > 128) && (width > 8))) { - if (((width%2==0) && (height%2==0)) && (width>=512) || (height>=512)) { - while (((width > 256) && (height > 8)) || ((height > 256) && (width > 8))) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - } else { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink = 1; - } - } - break; - case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 - if ((width>4096) || (height>4096)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>2048) || (height>2048)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; - case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture - if ((width>4096) || (height>4096)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>512) || (height>512)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; - case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture - if ((width>2048) || (height>2048)) { - GLvoid *out = pixels; - pixel_quarterscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 4; - height /= 4; - bound->shrink=2; - } else - if ((width>512) || (height>512)) { - GLvoid *out = pixels; - pixel_halfscale(pixels, &out, width, height, format, type); - if (out != pixels && pixels!=datab) - free(pixels); - pixels = out; - width /= 2; - height /= 2; - bound->shrink=1; - } - break; } } @@ -700,6 +658,7 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, ((internalformat==GL_RGB) || (internalformat==3) || (internalformat==GL_RGB8) || (internalformat==GL_BGR) || (internalformat==GL_RGB5)) || (globals4es.texstream==2) ) { bound->streamingID = AddStreamed(width, height, bound->texture); if (bound->streamingID>-1) { // success + bound->shrink = 0; // no shrink on Stream texture bound->streamed = true; ApplyFilterID(bound->streamingID, bound->min_filter, bound->mag_filter); GLboolean tmp = IS_TEX2D(glstate->enable.texture[glstate->texture.active]); @@ -716,62 +675,10 @@ void gl4es_glTexImage2D(GLenum target, GLint level, GLint internalformat, } #endif if (bound) { - bound->shrink = 0; if (!bound->streamed) swizzle_texture(width, height, &format, &type, internalformat, new_format, NULL); // convert format even if data is NULL - if ((globals4es.texshrink>0) && !bound->streamed) { - switch(globals4es.texshrink) { - case 1: //everything / 2 - width /= 2; - height /= 2; - bound->shrink = 1; - break; - case 2: //only > 512 /2 - if((width>512) || (height>512)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 3: //only > 256 /2 - if((width>256) || (height>256)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 4: //only > 256 /2, >=1024 /4 - if((width>1024) || (height>1024)) { - width /= 4; - height /= 4; - bound->shrink = 2; - } else if((width>256) || (height>256)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - case 5: //every > 256 is downscaled to 256, but not for empty texture - break; - case 6: //only > 128 /2, >=512 is downscaled to 256 ), but not for empty texture - break; - case 7: //only > 512 /2, but not for empty texture - break; - case 8: //advertise 8192 max texture size, but >2048 are shrinked to 2048 - case 9: //advertise 8192 max texture size, but >4096 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway) - case 10://advertise 8192 max texture size, but >2048 are quadshrinked and >512 are shrinked, but not for empty texture (but >2048 are not supported anyway) - if((width>4096) || (height>4096)) { - width /= 4; - height /= 4; - bound->shrink = 2; - } else if((width>2048) || (height>2048)) { - width /= 2; - height /= 2; - bound->shrink = 1; - } - break; - } - } + width = nlevel(width, bound->shrink); + height = nlevel(height, bound->shrink); } } @@ -1033,8 +940,8 @@ void gl4es_glTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoff errorGL(); } - if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3) && (!globals4es.texstream || (globals4es.texstream && !bound->streamed))) - gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE ); + /*if (bound && bound->mipmap_need && !bound->mipmap_auto && (globals4es.automipmap!=3) && (!globals4es.texstream || (globals4es.texstream && !bound->streamed))) + gles_glTexParameteri( target, GL_GENERATE_MIPMAP, GL_FALSE );*/ if ((target==GL_TEXTURE_2D) && globals4es.texcopydata && bound && ((globals4es.texstream && !bound->streamed) || !globals4es.texstream)) { //printf("*texcopy* glTexSubImage2D, xy=%i,%i, size=%i,%i=>%i,%i, format=%s, type=%s, tex=%u\n", xoffset, yoffset, width, height, bound->width, bound->height, PrintEnum(format), PrintEnum(type), bound->glname); @@ -1203,6 +1110,7 @@ gltexture_t* gl4es_getTexture(GLenum target, GLuint texture) { tex->type = GL_UNSIGNED_BYTE; tex->orig_internal = GL_RGBA; tex->internalformat = GL_RGBA; + tex->shrink = 0; tex->data = NULL; } else { tex = kh_value(list, k); @@ -1265,7 +1173,6 @@ tex_changed=1; // seems buggy, temporary disabling that... } #endif - glstate->texture.rect_arb[glstate->texture.active] = (target == GL_TEXTURE_RECTANGLE_ARB); target = map_tex_target(target); glstate->texture.bound[glstate->texture.active][itarget] = tex; @@ -1436,6 +1343,7 @@ void gl4es_glGenTextures(GLsizei n, GLuint * textures) { tex->min_filter = tex->mag_filter = GL_NEAREST; tex->format = GL_RGBA; tex->type = GL_UNSIGNED_BYTE; + tex->shrink = 0; tex->data = NULL; } else { tex = kh_value(list, k); @@ -1463,28 +1371,20 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL switch (pname) { case GL_TEXTURE_WIDTH: if (target==GL_PROXY_TEXTURE_2D) - (*params) = proxy_width>>level; - else - (*params) = ((bound)?bound->width:2048)>>level; - if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { - if (*params<4) // minimum size of a compressed block is 4 - *params = 0; - } else { - if (*params<=0) // 1 is the minimum, not 0 - *params = 1; + (*params) = nlevel(proxy_width,level); + else { + (*params) = nlevel((bound)?bound->width:2048,level); + if(level && (!bound || (bound && !(bound->mipmap_auto || bound->mipmap_need)))) + (*params) = 0; // Mipmap level not loaded } break; case GL_TEXTURE_HEIGHT: if (target==GL_PROXY_TEXTURE_2D) - (*params) = proxy_height>>level; - else - (*params) = ((bound)?bound->height:2048)>>level; - if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { - if (*params<4) // minimum size of a compressed block is 4 - *params = 0; - } else { - if (*params<=0) // 1 is the minimum, not 0, but only on uncompressed textures - *params = 1; + (*params) = nlevel(proxy_height,level); + else { + (*params) = nlevel((bound)?bound->height:2048,level); + if(level && (!bound || (bound && !(bound->mipmap_auto || bound->mipmap_need)))) + (*params) = 0; // Mipmap level not loaded } break; case GL_TEXTURE_INTERNAL_FORMAT: @@ -1492,7 +1392,7 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL (*params) = proxy_intformat; else { if (bound && bound->compressed) - (*params) = bound->format; + (*params) = bound->internalformat; else { if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { if(bound->orig_internal==GL_COMPRESSED_RGB) @@ -1535,9 +1435,9 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL break; case GL_TEXTURE_COMPRESSED_IMAGE_SIZE: if(bound && ((bound->orig_internal==GL_COMPRESSED_RGB) || (bound->orig_internal==GL_COMPRESSED_RGBA))) { - int w = bound->width>>level; - int h = bound->height>>level; - w = ((w>>2)+1) << 2; h = ((h>>2)+1) << 2; //DXT works on 4x4 blocks... + int w = nlevel((bound->width>>level),2); //DXT works on 4x4 blocks... + int h = nlevel((bound->height>>level),2); + w<<=2; h<<=2; if (bound->orig_internal==GL_COMPRESSED_RGB) //DXT1, 64bits (i.e. size=8) for a 4x4 block (*params) = (w*h)/2; else //DXT5, 64+64 (i.e. size = 16) for a 4x4 block @@ -1545,9 +1445,25 @@ void gl4es_glGetTexLevelParameteriv(GLenum target, GLint level, GLenum pname, GL } else (*params) = (bound)?(bound->width*bound->height*4):0; break; + case GL_TEXTURE_BORDER: + (*params) = 0; + break; + case GL_TEXTURE_INTENSITY_SIZE: + if(bound) + (*params) = 32; // is it correct ? GLES doesn't store Intensity... Shall I return 0 instead? Or fake it and return 8? + else + (*params) = 0; + break; + case GL_TEXTURE_LUMINANCE_SIZE: + if(bound) + (*params) = (bound->orig_internal==GL_LUMINANCE || bound->orig_internal==GL_LUMINANCE_ALPHA)?8:0; + else + (*params) = 0; + break; + break; default: errorShim(GL_INVALID_ENUM); //Wrong here... - printf("Stubbed glGetTexLevelParameteriv(%04x, %i, %04x, %p)\n", target, level, pname, params); + printf("Stubbed glGetTexLevelParameteriv(%s, %i, %s, %p)\n", PrintEnum(target), level, PrintEnum(pname), params); } } @@ -1582,8 +1498,8 @@ void gl4es_glGetTexImage(GLenum target, GLint level, GLenum format, GLenum type, pixel_halfscale(tmp, &tmp2, width, height, format, type); free(tmp); tmp = tmp2; - if(width>1) width>>=1; - if(height>1) height>>=1; + width = nlevel(width, 1); + height = nlevel(height, 1); } memcpy(img, tmp, width*height*pixel_sizeof(format, type)); free(tmp); @@ -2038,12 +1954,6 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor if (internalformat==GL_RGBA8) internalformat = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; // test if internalformat is not a compressed one - if (level != 0) { - noerrorShim(); - //TODO - //printf("STUBBED glCompressedTexImage2D with level=%i\n", level); - //return; - } if ((width<=0) || (height<=0)) { noerrorShim(); return; // nothing to do... @@ -2089,19 +1999,29 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor // automaticaly reduce the pixel size half=pixels; bound->alpha = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?false:true; - format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; - type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; - if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) - fact = 0; -// if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE)) -// fact = 1; - else { + if(globals4es.nodownsampling==1) { format = GL_RGBA; type = GL_UNSIGNED_BYTE; + } else { + format = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_RGB:GL_RGBA; +#ifdef PANDORA + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:(internalformat==GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_SHORT_4_4_4_4; +#else + type = (internalformat==GL_COMPRESSED_RGB_S3TC_DXT1_EXT)?GL_UNSIGNED_SHORT_5_6_5:GL_UNSIGNED_SHORT_4_4_4_4; +#endif + if (pixel_convert(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE, format, type, 0)) + fact = 0; +// if (pixel_thirdscale(pixels, &half, width, height, GL_RGBA, GL_UNSIGNED_BYTE)) +// fact = 1; + else { + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } } bound->format = format; //internalformat; bound->type = type; bound->compressed = true; + bound->internalformat = internalformat; } else { fact = 0; } @@ -2109,7 +2029,10 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor gl4es_glGetIntegerv(GL_UNPACK_ALIGNMENT, &oldalign); if (oldalign!=1) gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - gl4es_glTexImage2D(target, level, format, width>>fact, height>>fact, border, format, type, half); + gl4es_glTexImage2D(target, level, format==GL_RGBA?GL_COMPRESSED_RGBA:GL_COMPRESSED_RGB, nlevel(width,fact), nlevel(height,fact), border, format, type, half); + // re-update bounded texture info + bound->compressed = true; + bound->internalformat = internalformat; if (oldalign!=1) gl4es_glPixelStorei(GL_UNPACK_ALIGNMENT, oldalign); if (half!=pixels) @@ -2120,6 +2043,7 @@ void gl4es_glCompressedTexImage2D(GLenum target, GLint level, GLenum internalfor bound->alpha = true; bound->format = internalformat; bound->type = GL_UNSIGNED_BYTE; + bound->internalformat = internalformat; bound->compressed = true; gles_glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, datab); } @@ -2210,10 +2134,10 @@ void gl4es_glGetCompressedTexImage(GLenum target, GLint lod, GLvoid *img) { return; if(bound->orig_internal!=GL_COMPRESSED_RGB && bound->orig_internal!=GL_COMPRESSED_RGBA) return; - int width = bound->width>>lod; - int height = bound->height>>lod; - int w = ((width>>2)+1)<<2; - int h = ((height>>2)+1)<<2; + int width = nlevel(bound->width,lod); + int height = nlevel(bound->height,lod); + int w = nlevel(width,2); w<<=2; + int h = nlevel(height,2); h<<=2; int alpha = (bound->orig_internal==GL_COMPRESSED_RGBA)?1:0; diff --git a/project/jni/gl4es/src/gl/texture.h b/project/jni/gl4es/src/gl/texture.h index ea5bc615c..9ddcef64e 100755 --- a/project/jni/gl4es/src/gl/texture.h +++ b/project/jni/gl4es/src/gl/texture.h @@ -97,6 +97,7 @@ typedef enum { ENABLED_TEX1D = 0, ENABLED_TEX2D, ENABLED_TEX3D, + ENABLED_TEXTURE_RECTANGLE, ENABLED_CUBE_MAP, ENABLED_TEXTURE_LAST } texture_enabled_t; @@ -161,6 +162,7 @@ static inline GLuint what_target(GLenum target) { case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: return ENABLED_CUBE_MAP; case GL_TEXTURE_RECTANGLE_ARB: + return ENABLED_TEXTURE_RECTANGLE; case GL_TEXTURE_2D: default: return ENABLED_TEX2D; @@ -172,6 +174,8 @@ static inline GLenum to_target(GLuint itarget) { return GL_TEXTURE_1D; case ENABLED_TEX3D: return GL_TEXTURE_3D; + case ENABLED_TEXTURE_RECTANGLE: + return GL_TEXTURE_RECTANGLE_ARB; case ENABLED_CUBE_MAP: return GL_TEXTURE_CUBE_MAP; case ENABLED_TEX2D: diff --git a/project/jni/gl4es/src/glx/glx.c b/project/jni/gl4es/src/glx/glx.c index 9a1e95eea..17ee72938 100755 --- a/project/jni/gl4es/src/glx/glx.c +++ b/project/jni/gl4es/src/glx/glx.c @@ -388,34 +388,58 @@ void glx_init() { #endif } -#ifndef ANDROID +#ifndef ANDROID +static XVisualInfo *latest_visual = NULL; +static GLXFBConfig latest_glxfbconfig = NULL; + GLXContext gl4es_glXCreateContext(Display *display, XVisualInfo *visual, GLXContext shareList, Bool isDirect) { - DBG(printf("glXCreateContext(%p, %p, %p, %i)\n", display, visual, shareList, isDirect);) + DBG(printf("glXCreateContext(%p, %p, %p, %i), latest_visual=%p\n", display, visual, shareList, isDirect, latest_visual);) + + static struct __GLXFBConfigRec default_glxfbconfig; + GLXFBConfig glxfbconfig; + + if(visual==latest_visual) + glxfbconfig = latest_glxfbconfig; + else { + glxfbconfig = &default_glxfbconfig; + memset(glxfbconfig, 0, sizeof(struct __GLXFBConfigRec)); + default_glxfbconfig.redBits = (visual==0)?0:(visual->depth==16)?5:8; + default_glxfbconfig.greenBits = (visual==0)?0:(visual->depth==16)?6:8; + default_glxfbconfig.blueBits = (visual==0)?0:(visual->depth==16)?5:8; + default_glxfbconfig.alphaBits = (visual==0)?0:(visual->depth!=32)?0:8; + default_glxfbconfig.depthBits = 16; + default_glxfbconfig.stencilBits = 8; + } + EGLint configAttribs[] = { #ifdef PANDORA EGL_RED_SIZE, 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, #else - EGL_RED_SIZE, (visual==0)?0:(visual->depth==16)?5:8, - EGL_GREEN_SIZE, (visual==0)?0:(visual->depth==16)?6:8, - EGL_BLUE_SIZE, (visual==0)?0:(visual->depth==16)?5:8, - EGL_ALPHA_SIZE, (visual==0)?0:(visual->depth!=32)?0:8, + EGL_RED_SIZE, glxfbconfig->redBits, + EGL_GREEN_SIZE, glxfbconfig->greenBits, + EGL_BLUE_SIZE, glxfbconfig->blueBits, + EGL_ALPHA_SIZE, glxfbconfig->alphaBits, #endif EGL_DEPTH_SIZE, 16, #ifdef USE_ES2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else - EGL_BUFFER_SIZE, (visual==0)?16:visual->depth, - EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif + EGL_BUFFER_SIZE, glxfbconfig->depthBits, + EGL_STENCIL_SIZE, glxfbconfig->stencilBits, + + EGL_SAMPLE_BUFFERS, glxfbconfig->nMultiSampleBuffers, + EGL_SAMPLES, glxfbconfig->multiSampleSize, + + EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT, EGL_NONE }; - if (globals4es.usefb && fbcontext_count>0) { // don't create a new context, one FB is enough... fbcontext_count++; @@ -615,12 +639,14 @@ GLXContext gl4es_glXCreateContextAttribsARB(Display *display, GLXFBConfig config #endif EGL_DEPTH_SIZE, config->depthBits, EGL_STENCIL_SIZE, config->stencilBits, + EGL_SAMPLES, config->multiSampleSize, + EGL_SAMPLE_BUFFERS, config->nMultiSampleBuffers, #ifdef USE_ES2 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, #else - EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT), EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT, #endif + EGL_SURFACE_TYPE, (config->drawableType)==GLX_PIXMAP_BIT?EGL_PIXMAP_BIT:(EGL_WINDOW_BIT | EGL_PBUFFER_BIT), EGL_NONE }; @@ -785,6 +811,11 @@ XVisualInfo *gl4es_glXChooseVisual(Display *display, return NULL; } + // create and store the glxConfig that goes with thoses attributes + latest_visual = visual; + int count = 1; + latest_glxfbconfig = gl4es_glXChooseFBConfig(display, screen, attributes, &count)[0]; + return visual; } @@ -1124,6 +1155,7 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen, configs[0]->maxPbufferWidth = configs[0]->maxPbufferHeight = 2048; configs[0]->redBits = configs[0]->greenBits = configs[0]->blueBits = configs[0]->alphaBits = 0; configs[0]->nMultiSampleBuffers = 0; configs[0]->multiSampleSize = 0; + configs[0]->depthBits = 16; configs[0]->stencilBits = 8; if(attrib_list) { int i = 0; while(attrib_list[i]!=0) { @@ -1131,35 +1163,44 @@ GLXFBConfig *gl4es_glXChooseFBConfig(Display *display, int screen, case GLX_RED_SIZE: configs[0]->redBits = attrib_list[i++]; if(configs[0]->redBits==GLX_DONT_CARE) configs[0]->redBits = 0; + DBG(printf("FBConfig redBits=%d\n", configs[0]->redBits);) break; case GLX_GREEN_SIZE: configs[0]->greenBits = attrib_list[i++]; if(configs[0]->greenBits==GLX_DONT_CARE) configs[0]->greenBits = 0; + DBG(printf("FBConfig greenBits=%d\n", configs[0]->greenBits);) break; case GLX_BLUE_SIZE: configs[0]->blueBits = attrib_list[i++]; if(configs[0]->blueBits==GLX_DONT_CARE) configs[0]->blueBits = 0; + DBG(printf("FBConfig blueBits=%d\n", configs[0]->blueBits);) break; case GLX_ALPHA_SIZE: configs[0]->alphaBits = attrib_list[i++]; if(configs[0]->alphaBits==GLX_DONT_CARE) configs[0]->alphaBits = 0; + DBG(printf("FBConfig alphaBits=%d\n", configs[0]->alphaBits);) break; case GLX_DEPTH_SIZE: configs[0]->depthBits = attrib_list[i++]; if(configs[0]->depthBits==GLX_DONT_CARE) configs[0]->depthBits = 0; + DBG(printf("FBConfig depthBits=%d\n", configs[0]->depthBits);) break; case GLX_STENCIL_SIZE: configs[0]->stencilBits = attrib_list[i++]; if(configs[0]->stencilBits==GLX_DONT_CARE) configs[0]->stencilBits = 0; + DBG(printf("FBConfig stencilBits=%d\n", configs[0]->stencilBits);) break; case GLX_DRAWABLE_TYPE: configs[0]->drawableType = attrib_list[i++]; + DBG(printf("FBConfig drawableType=%d\n", configs[0]->drawableType);) break; case GLX_SAMPLE_BUFFERS: configs[0]->nMultiSampleBuffers = attrib_list[i++]; + DBG(printf("FBConfig multisampleBuffers=%d\n", configs[0]->nMultiSampleBuffers);) break; case GLX_SAMPLES: configs[0]->multiSampleSize = attrib_list[i++]; + DBG(printf("FBConfig multiSampleSize=%d\n", configs[0]->multiSampleSize);) break; default: ++i; diff --git a/project/jni/gl4es/src/glx/hardext.c b/project/jni/gl4es/src/glx/hardext.c index be6997a9c..177e3b52d 100755 --- a/project/jni/gl4es/src/glx/hardext.c +++ b/project/jni/gl4es/src/glx/hardext.c @@ -128,6 +128,7 @@ void GetHardwareExtensions(int notest) gles_glGetIntegerv(GL_MAX_TEXTURE_UNITS, &hardext.maxtex); gles_glGetIntegerv(GL_MAX_LIGHTS, &hardext.maxlights); if(hardext.maxtex>MAX_TEX) hardext.maxtex=MAX_TEX; // caping, as there are some fixed-sized array... + if(hardext.maxlights>MAX_LIGHT) hardext.maxlights=MAX_LIGHT; // caping lights too SHUT(LOGD("LIBGL: Texture Units: %d, Max lights: %d\n", hardext.maxtex, hardext.maxlights)); #ifndef PANDORA // The IMPLEMENTATION_COLOR_READ is pretty buggy on the Pandora, so disabling it (it's just use to blit PBuffer to Drawable in glx.c) diff --git a/project/jni/gl4es/version.h b/project/jni/gl4es/version.h index d72f1a932..422ec3521 100755 --- a/project/jni/gl4es/version.h +++ b/project/jni/gl4es/version.h @@ -3,6 +3,6 @@ #define MAJOR 0 #define MINOR 9 -#define REVISION 2 +#define REVISION 3 #endif //_GL4ES_VERSION_H \ No newline at end of file diff --git a/project/jni/sdl-1.2/include/SDL_android.h b/project/jni/sdl-1.2/include/SDL_android.h index 2a120e5b0..7cd48cf01 100644 --- a/project/jni/sdl-1.2/include/SDL_android.h +++ b/project/jni/sdl-1.2/include/SDL_android.h @@ -134,9 +134,23 @@ enum { /* TODO: more options, see Globals.java */ }; -/* Set SDL Android-specifc option, such as video depth or mouse emulation mode. Most options require restarting the app. */ +/* Set SDL Android-specifc option, and save it to SDL config file, such as video depth or mouse emulation mode. Most options require restarting the app. */ extern DECLSPEC void SDLCALL SDL_ANDROID_SetConfigOption(int option, int value); +/* Change mouse emulation mode, pass -1 to any option to keep the current value, this does not change SDL config file. + Currently only relativeMovement is processed, other options are ignored */ +extern DECLSPEC void SDLCALL SDL_ANDROID_SetMouseEmulationMode( + int relativeMovement, int relativeMovementSpeed, int relativeMovementAcceleration, + int leftClickMode, int leftClickKey, int leftClickTimeout, + int rightClickMode, int rightClickKey, int rightClickTimeout, + int moveMouseWithJoystick, int moveMouseWithJoystickSpeed, int moveMouseWithJoystickAcceleration, + int moveMouseWithGyroscope, int moveMouseWithGyroscopeSpeed, + int forceHardwareMouse, int showScreenUnderFinger, + int fingerHover, int fingerHoverJitterFilter, int generateSubframeTouchEvents +); + +extern DECLSPEC int SDLCALL SDL_ANDROID_GetMouseEmulationMode(); + #ifdef __cplusplus } #endif diff --git a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c index 1f1aaf18a..056183910 100644 --- a/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.2/src/video/android/SDL_androidinput.c @@ -1179,6 +1179,31 @@ JAVA_EXPORT_NAME(Settings_nativeSetMouseUsed) (JNIEnv* env, jobject thiz, } } +void SDLCALL SDL_ANDROID_SetMouseEmulationMode( + int _relativeMovement, int _relativeMovementSpeed, int _relativeMovementAcceleration, + int _leftClickMode, SDLKey _leftClickKey, int _leftClickTimeout, + int _rightClickMode, SDLKey _rightClickKey, int _rightClickTimeout, + int _moveMouseWithJoystick, int _moveMouseWithJoystickSpeed, int _moveMouseWithJoystickAcceleration, + int _moveMouseWithGyroscope, int _moveMouseWithGyroscopeSpeed, + int _forceHardwareMouse, int _showScreenUnderFinger, + int _fingerHover, int _fingerHoverJitterFilter, int _generateSubframeTouchEvents +) +{ + relativeMovement = _relativeMovement; + if (relativeMovement) + { + leftClickMethod = LEFT_CLICK_WITH_TAP_OR_TIMEOUT; + } + else + { + leftClickMethod = LEFT_CLICK_NORMAL; + } +} + +int SDLCALL SDL_ANDROID_GetMouseEmulationMode() { + return relativeMovement; +} + typedef struct { int leftClickMethod;