summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2010-08-04 01:03:25 +0000
committerThomas Martitz <kugel@rockbox.org>2010-08-04 01:03:25 +0000
commit594110e962831b0d8ae2ded7efc49d48e4a6c3eb (patch)
treeb167636938ed249fb61ccd62e9873ef5481ee8af
parentf66a233bdbbf5c772903a744938d7333da1b53bf (diff)
downloadrockbox-594110e962831b0d8ae2ded7efc49d48e4a6c3eb.tar.gz
rockbox-594110e962831b0d8ae2ded7efc49d48e4a6c3eb.tar.bz2
rockbox-594110e962831b0d8ae2ded7efc49d48e4a6c3eb.zip
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
-rw-r--r--android/src/org/rockbox/RockboxActivity.java23
-rw-r--r--android/src/org/rockbox/RockboxFramebuffer.java35
-rw-r--r--firmware/export/config/application.h4
-rw-r--r--firmware/target/hosted/android/lcd-android.c60
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 */
/**