From 594110e962831b0d8ae2ded7efc49d48e4a6c3eb Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Wed, 4 Aug 2010 01:03:25 +0000 Subject: Implement HAVE_LCD_ENABLE and lcd_update_rect(). When Rockbox runs in the background this greatly reduces CPU load. lcd_update_rect shoves a bit as well. CPU usage with Rockbox in background is between 3% (with a 200kbps vbr mp3) and 12% (320kbps cbr mp3), so it's low but still dependent on codecs and even particular files. Driving a WPS with peakmeter, e.g. the builtin one, adds about 30% cpu usage. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27689 a1c6a512-1295-4272-9138-f99709370657 --- android/src/org/rockbox/RockboxActivity.java | 23 ++++++++++ android/src/org/rockbox/RockboxFramebuffer.java | 35 ++++++++++----- firmware/export/config/application.h | 4 ++ firmware/target/hosted/android/lcd-android.c | 60 ++++++++++++++++++++----- 4 files changed, 98 insertions(+), 24 deletions(-) diff --git a/android/src/org/rockbox/RockboxActivity.java b/android/src/org/rockbox/RockboxActivity.java index 38bfec16ef..2bafb6688d 100644 --- a/android/src/org/rockbox/RockboxActivity.java +++ b/android/src/org/rockbox/RockboxActivity.java @@ -78,6 +78,7 @@ public class RockboxActivity extends Activity { public void onResume() { super.onResume(); + if (RockboxService.fb != null) { try { @@ -91,8 +92,30 @@ public class RockboxActivity extends Activity { } catch (Exception e) { LOG(e.toString()); } + RockboxService.fb.resume(); } } + + /* this is also called when the backlight goes off, + * which is nice + */ + @Override + protected void onPause() { + super.onPause(); + RockboxService.fb.suspend(); + } + + @Override + protected void onStop() { + super.onStop(); + RockboxService.fb.suspend(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + RockboxService.fb.suspend(); + } private void LOG(CharSequence text) { diff --git a/android/src/org/rockbox/RockboxFramebuffer.java b/android/src/org/rockbox/RockboxFramebuffer.java index f947806bb4..ca11de090c 100644 --- a/android/src/org/rockbox/RockboxFramebuffer.java +++ b/android/src/org/rockbox/RockboxFramebuffer.java @@ -34,21 +34,11 @@ public class RockboxFramebuffer extends View { private Bitmap btm; private ByteBuffer native_buf; - private Handler update_handler; - private Runnable cb; public RockboxFramebuffer(Context c) { super(c); - update_handler = new Handler(); - cb = new Runnable() { - public void run() - { - btm.copyPixelsFromBuffer(native_buf); - invalidate(); - } - }; btm = null; } @@ -66,12 +56,21 @@ public class RockboxFramebuffer extends View public void java_lcd_update() { - update_handler.post(cb); + + btm.copyPixelsFromBuffer(native_buf); + postInvalidate(); + } + + public void java_lcd_update_rect(int x, int y, int w, int h) + { + /* can't copy a partial buffer */ + btm.copyPixelsFromBuffer(native_buf); + postInvalidate(x, y, x+w, y+h); } private void LOG(CharSequence text) { - Log.d("RockboxBootloader", (String) text); + Log.d("RockboxBootloader", (String) text); } public boolean onTouchEvent(MotionEvent me) @@ -93,6 +92,18 @@ public class RockboxFramebuffer extends View return true; } + /* the two below should only be called from the activity thread */ + public void suspend() + { /* suspend, Rockbox will not make any lcd updates */ + set_lcd_active(0); + } + public void resume() + { /* make updates again, the underlying function will + * send an event */ + set_lcd_active(1); + } + + public native void set_lcd_active(int active); public native void pixelHandler(int x, int y); public native void touchHandler(int down); } diff --git a/firmware/export/config/application.h b/firmware/export/config/application.h index 988f0d51ac..71ee62356b 100644 --- a/firmware/export/config/application.h +++ b/firmware/export/config/application.h @@ -53,6 +53,10 @@ #define LCD_DEPTH 16 #define LCD_PIXELFORMAT 565 +#if (CONFIG_PLATFORM & PLATFORM_ANDROID) +#define HAVE_LCD_ENABLE +#endif + /* define this to indicate your device's keypad */ #define HAVE_TOUCHSCREEN #define HAVE_BUTTON_DATA diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c index efe68cdd71..1043dfa35c 100644 --- a/firmware/target/hosted/android/lcd-android.c +++ b/firmware/target/hosted/android/lcd-android.c @@ -31,6 +31,9 @@ extern jobject RockboxService_instance; static jobject Framebuffer_instance; static jmethodID java_lcd_update; +static jmethodID java_lcd_update_rect; + +static bool display_on; void lcd_init_device(void) { @@ -52,13 +55,17 @@ void lcd_init_device(void) * our framebuffer */ jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr, - Framebuffer_class, - "java_lcd_init", - "(IILjava/nio/ByteBuffer;)V"); - java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, - Framebuffer_class, - "java_lcd_update", - "()V"); + Framebuffer_class, + "java_lcd_init", + "(IILjava/nio/ByteBuffer;)V"); + java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_update", + "()V"); + java_lcd_update_rect = (*env_ptr)->GetMethodID(env_ptr, + Framebuffer_class, + "java_lcd_update_rect", + "(IIII)V"); /* map the framebuffer to a ByteBuffer, this way lcd updates will * be directly feched from the framebuffer */ @@ -70,21 +77,50 @@ void lcd_init_device(void) Framebuffer_instance, java_init_lcd, LCD_WIDTH, LCD_HEIGHT, buf); + display_on = true; } -void lcd_update() +void lcd_update(void) { /* tell the system we're ready for drawing */ - (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update); + if (display_on) + (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update); } void lcd_update_rect(int x, int y, int height, int width) { - /* can't do partial updates yet */ - (void)x; (void)y; (void)height; (void)width; - lcd_update(); + if (display_on) + { + (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update_rect, + x, y, height, width); + } +} + +bool lcd_active(void) +{ + return display_on; } +/* + * (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 */ /** -- cgit v1.2.3