diff options
author | Thomas Martitz <kugel@rockbox.org> | 2010-12-02 23:50:50 +0000 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2010-12-02 23:50:50 +0000 |
commit | 55b58a3f30270ce8df7c1b51720bb777e7972c7f (patch) | |
tree | 46a3be432fd4e75b5604905338800e66a70d0ce5 /firmware | |
parent | 1d425bf1e6c0346db02f03be496ecef749b49c22 (diff) | |
download | rockbox-55b58a3f30270ce8df7c1b51720bb777e7972c7f.tar.gz rockbox-55b58a3f30270ce8df7c1b51720bb777e7972c7f.zip |
Android: Make lcd updates synchronous, doesn't make it faster but smoother (no updates are skipped) and guaranteed to be glitch free.
test_fps can also now report reasonable numbers: ~62 fps for both 1/1 and 1/4 updates (was 300-400 previously).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@28728 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/hosted/android/lcd-android.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index f4ef7b5e75..2bc6d04b9e 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c @@ -23,6 +23,7 @@ #include <jni.h> #include "config.h" #include "system.h" +#include "kernel.h" #include "lcd.h" extern JNIEnv *env_ptr; @@ -31,16 +32,18 @@ extern jobject RockboxService_instance; static jclass RockboxFramebuffer_class; static jobject RockboxFramebuffer_instance; -static jmethodID java_lcd_update; -static jmethodID java_lcd_update_rect; +static jmethodID postInvalidate1; +static jmethodID postInvalidate2; static bool display_on; static int dpi; static int scroll_threshold; +static struct wakeup lcd_wakeup; void lcd_init_device(void) { JNIEnv e = *env_ptr; + wakeup_init(&lcd_wakeup); RockboxFramebuffer_class = e->FindClass(env_ptr, "org/rockbox/RockboxFramebuffer"); /* instantiate a RockboxFramebuffer instance @@ -71,13 +74,13 @@ void lcd_init_device(void) buf); /* cache update functions */ - java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, + postInvalidate1 = (*env_ptr)->GetMethodID(env_ptr, RockboxFramebuffer_class, - "java_lcd_update", + "postInvalidate", "()V"); - java_lcd_update_rect = (*env_ptr)->GetMethodID(env_ptr, + postInvalidate2 = (*env_ptr)->GetMethodID(env_ptr, RockboxFramebuffer_class, - "java_lcd_update_rect", + "postInvalidate", "(IIII)V"); jmethodID get_dpi = e->GetMethodID(env_ptr, @@ -96,22 +99,44 @@ void lcd_init_device(void) display_on = true; } +/* the update mechanism is asynchronous since + * onDraw() must be called from the UI thread + * + * The Rockbox thread calling lcd_update() has to wait + * for the update to complete, so that it's synchronous, + * and we need to notify it (we could wait in the java layer, but + * that'd block the other Rockbox threads too) + * + * That should give more smoonth animations + */ void lcd_update(void) { /* tell the system we're ready for drawing */ if (display_on) - (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, java_lcd_update); + { + (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate1); + wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); + } } -void lcd_update_rect(int x, int y, int height, int width) +void lcd_update_rect(int x, int y, int width, int height) { if (display_on) { - (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, java_lcd_update_rect, - x, y, height, width); + (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate2, + (jint)x, (jint)y, (jint)x+width, (jint)y+height); + wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); } } +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_post_1update_1done(JNIEnv *e, jobject this) +{ + (void)e; + (void)this; + wakeup_signal(&lcd_wakeup); +} + bool lcd_active(void) { return display_on; |