1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Thomas Martitz 2010-08-04 01:03:25 +00:00
parent f66a233bdb
commit 594110e962
4 changed files with 98 additions and 24 deletions

View file

@ -78,6 +78,7 @@ public class RockboxActivity extends Activity {
public void onResume() public void onResume()
{ {
super.onResume(); super.onResume();
if (RockboxService.fb != null) if (RockboxService.fb != null)
{ {
try { try {
@ -91,8 +92,30 @@ public class RockboxActivity extends Activity {
} catch (Exception e) { } catch (Exception e) {
LOG(e.toString()); 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) private void LOG(CharSequence text)
{ {

View file

@ -34,21 +34,11 @@ public class RockboxFramebuffer extends View
{ {
private Bitmap btm; private Bitmap btm;
private ByteBuffer native_buf; private ByteBuffer native_buf;
private Handler update_handler;
private Runnable cb;
public RockboxFramebuffer(Context c) public RockboxFramebuffer(Context c)
{ {
super(c); super(c);
update_handler = new Handler();
cb = new Runnable() {
public void run()
{
btm.copyPixelsFromBuffer(native_buf);
invalidate();
}
};
btm = null; btm = null;
} }
@ -66,12 +56,21 @@ public class RockboxFramebuffer extends View
public void java_lcd_update() 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) private void LOG(CharSequence text)
{ {
Log.d("RockboxBootloader", (String) text); Log.d("RockboxBootloader", (String) text);
} }
public boolean onTouchEvent(MotionEvent me) public boolean onTouchEvent(MotionEvent me)
@ -93,6 +92,18 @@ public class RockboxFramebuffer extends View
return true; 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 pixelHandler(int x, int y);
public native void touchHandler(int down); public native void touchHandler(int down);
} }

View file

@ -53,6 +53,10 @@
#define LCD_DEPTH 16 #define LCD_DEPTH 16
#define LCD_PIXELFORMAT 565 #define LCD_PIXELFORMAT 565
#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
#define HAVE_LCD_ENABLE
#endif
/* define this to indicate your device's keypad */ /* define this to indicate your device's keypad */
#define HAVE_TOUCHSCREEN #define HAVE_TOUCHSCREEN
#define HAVE_BUTTON_DATA #define HAVE_BUTTON_DATA

View file

@ -31,6 +31,9 @@ extern jobject RockboxService_instance;
static jobject Framebuffer_instance; static jobject Framebuffer_instance;
static jmethodID java_lcd_update; static jmethodID java_lcd_update;
static jmethodID java_lcd_update_rect;
static bool display_on;
void lcd_init_device(void) void lcd_init_device(void)
{ {
@ -52,13 +55,17 @@ void lcd_init_device(void)
* our framebuffer */ * our framebuffer */
jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr, jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr,
Framebuffer_class, Framebuffer_class,
"java_lcd_init", "java_lcd_init",
"(IILjava/nio/ByteBuffer;)V"); "(IILjava/nio/ByteBuffer;)V");
java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, java_lcd_update = (*env_ptr)->GetMethodID(env_ptr,
Framebuffer_class, Framebuffer_class,
"java_lcd_update", "java_lcd_update",
"()V"); "()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 /* map the framebuffer to a ByteBuffer, this way lcd updates will
* be directly feched from the framebuffer */ * be directly feched from the framebuffer */
@ -70,21 +77,50 @@ void lcd_init_device(void)
Framebuffer_instance, Framebuffer_instance,
java_init_lcd, java_init_lcd,
LCD_WIDTH, LCD_HEIGHT, buf); LCD_WIDTH, LCD_HEIGHT, buf);
display_on = true;
} }
void lcd_update() void lcd_update(void)
{ {
/* tell the system we're ready for drawing */ /* 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) void lcd_update_rect(int x, int y, int height, int width)
{ {
/* can't do partial updates yet */ if (display_on)
(void)x; (void)y; (void)height; (void)width; {
lcd_update(); (*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 */ /* below is a plain copy from lcd-sdl.c */
/** /**