diff options
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/hosted/android/app/button-target.h | 2 | ||||
-rw-r--r-- | firmware/target/hosted/android/lcd-android.c | 140 |
2 files changed, 61 insertions, 81 deletions
diff --git a/firmware/target/hosted/android/app/button-target.h b/firmware/target/hosted/android/app/button-target.h index 6106b612f9..3b6028739c 100644 --- a/firmware/target/hosted/android/app/button-target.h +++ b/firmware/target/hosted/android/app/button-target.h @@ -58,6 +58,8 @@ void android_ignore_back_button(bool yes); #define BUTTON_BOTTOMMIDDLE 0x00080000 #define BUTTON_BOTTOMRIGHT 0x00100000 +#define BUTTON_FORCE_REDRAW 0x00200000 + /* No remote */ #define BUTTON_REMOTE 0 diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index 92e8f5b96f..f719329819 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c @@ -21,10 +21,12 @@ #include <jni.h> +#include <string.h> #include "config.h" #include "system.h" #include "kernel.h" #include "lcd.h" +#include "button.h" extern JNIEnv *env_ptr; extern jclass RockboxService_class; @@ -32,57 +34,48 @@ extern jobject RockboxService_instance; static jclass RockboxFramebuffer_class; static jobject RockboxFramebuffer_instance; -static jmethodID postInvalidate1; -static jmethodID postInvalidate2; +static jmethodID java_lcd_update; +static jmethodID java_lcd_update_rect; -static bool display_on; static int dpi; static int scroll_threshold; -static struct wakeup lcd_wakeup; -static struct mutex lcd_mtx; +static bool display_on; void lcd_init_device(void) { JNIEnv e = *env_ptr; - wakeup_init(&lcd_wakeup); - mutex_init(&lcd_mtx); - RockboxFramebuffer_class = e->FindClass(env_ptr, - "org/rockbox/RockboxFramebuffer"); - /* instantiate a RockboxFramebuffer instance - * - * Pass lcd width and height and our framebuffer so the java layer - * can create a Bitmap which directly maps to it - **/ - - /* map the framebuffer to a ByteBuffer, this way lcd updates will - * be directly feched from the framebuffer */ + /* get existing instance from the Service */ + jmethodID get_fb = e->GetMethodID(env_ptr, RockboxService_class, "get_fb", + "()Lorg/rockbox/RockboxFramebuffer;"); + RockboxFramebuffer_instance = e->CallObjectMethod(env_ptr, + RockboxService_instance, + get_fb); + RockboxFramebuffer_class = (*env_ptr)->GetObjectClass(env_ptr, + RockboxFramebuffer_instance); + + /* Get init function and set up what's left from the constructor */ + jmethodID java_lcd_init = (*env_ptr)->GetMethodID(env_ptr, + RockboxFramebuffer_class, + "java_lcd_init", + "(IILjava/nio/ByteBuffer;)V"); + jobject buf = e->NewDirectByteBuffer(env_ptr, lcd_framebuffer, (jlong)sizeof(lcd_framebuffer)); - jmethodID constructor = e->GetMethodID(env_ptr, - RockboxFramebuffer_class, - "<init>", - "(Landroid/content/Context;" /* Service */ - "II" /* lcd width/height */ - "Ljava/nio/ByteBuffer;)V"); /* ByteBuffer */ - - RockboxFramebuffer_instance = e->NewObject(env_ptr, - RockboxFramebuffer_class, - constructor, - RockboxService_instance, + e->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, java_lcd_init, (jint)LCD_WIDTH, (jint)LCD_HEIGHT, buf); /* cache update functions */ - postInvalidate1 = (*env_ptr)->GetMethodID(env_ptr, + java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, RockboxFramebuffer_class, - "postInvalidate", + "java_lcd_update", "()V"); - postInvalidate2 = (*env_ptr)->GetMethodID(env_ptr, + java_lcd_update_rect = (*env_ptr)->GetMethodID(env_ptr, RockboxFramebuffer_class, - "postInvalidate", + "java_lcd_update_rect", "(IIII)V"); jmethodID get_dpi = e->GetMethodID(env_ptr, @@ -98,49 +91,54 @@ void lcd_init_device(void) get_dpi); scroll_threshold = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance, get_scroll_threshold); - display_on = true; + /* must not draw until surface is created */ + display_on = false; } -/* 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) - { - mutex_lock(&lcd_mtx); - (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate1); - wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); - mutex_unlock(&lcd_mtx); - } + (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, + java_lcd_update); } void lcd_update_rect(int x, int y, int width, int height) { if (display_on) - { - mutex_lock(&lcd_mtx); - (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate2, - (jint)x, (jint)y, (jint)x+width, (jint)y+height); - wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK); - mutex_unlock(&lcd_mtx); - } + (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, + java_lcd_update_rect, x, y, width, height); +} + +/* + * this is called when the surface is created, which called is everytime + * the activity is brought in front and the RockboxFramebuffer gains focus + * + * Note this is considered interrupt context + */ +JNIEXPORT void JNICALL +Java_org_rockbox_RockboxFramebuffer_surfaceCreated(JNIEnv *e, jobject this, + jobject surfaceholder) +{ + (void)e; (void)this; (void)surfaceholder; + + display_on = true; + send_event(LCD_EVENT_ACTIVATION, NULL); + /* Force an update, since the newly created surface is initially black + * waiting for the next normal update results in a longish black screen */ + queue_post(&button_queue, BUTTON_FORCE_REDRAW, 0); } +/* + * the surface is destroyed everytime the RockboxFramebuffer loses focus and + * goes invisible + */ JNIEXPORT void JNICALL -Java_org_rockbox_RockboxFramebuffer_post_1update_1done(JNIEnv *e, jobject this) +Java_org_rockbox_RockboxFramebuffer_surfaceDestroyed(JNIEnv *e, jobject this, + jobject surfaceholder) { - (void)e; - (void)this; - wakeup_signal(&lcd_wakeup); + (void)e; (void)this; (void)surfaceholder; + + display_on = false; } bool lcd_active(void) @@ -158,26 +156,6 @@ int touchscreen_get_scroll_threshold(void) return scroll_threshold; } -/* - * (un)block lcd updates. - * - * Notice: This is called from the activity thread, so take it - * as interrupt context and take care what the event callback does - * (it shouldn't block in particular - * - * the 1s are needed due to strange naming conventions... - **/ -JNIEXPORT void JNICALL -Java_org_rockbox_RockboxFramebuffer_set_1lcd_1active(JNIEnv *e, - jobject this, - jint active) -{ - (void)e; - (void)this; - display_on = active != 0; - if (active) - send_event(LCD_EVENT_ACTIVATION, NULL); -} /* below is a plain copy from lcd-sdl.c */ /** |