Fix red caused by incorrect includes.
[maemo-rb.git] / firmware / target / hosted / android / lcd-android.c
blob92e8f5b96fad47f499b5656519d0e3d101fdf63c
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (c) 2010 Thomas Martitz
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
23 #include <jni.h>
24 #include "config.h"
25 #include "system.h"
26 #include "kernel.h"
27 #include "lcd.h"
29 extern JNIEnv *env_ptr;
30 extern jclass RockboxService_class;
31 extern jobject RockboxService_instance;
33 static jclass RockboxFramebuffer_class;
34 static jobject RockboxFramebuffer_instance;
35 static jmethodID postInvalidate1;
36 static jmethodID postInvalidate2;
38 static bool display_on;
39 static int dpi;
40 static int scroll_threshold;
41 static struct wakeup lcd_wakeup;
42 static struct mutex lcd_mtx;
44 void lcd_init_device(void)
46 JNIEnv e = *env_ptr;
47 wakeup_init(&lcd_wakeup);
48 mutex_init(&lcd_mtx);
49 RockboxFramebuffer_class = e->FindClass(env_ptr,
50 "org/rockbox/RockboxFramebuffer");
51 /* instantiate a RockboxFramebuffer instance
53 * Pass lcd width and height and our framebuffer so the java layer
54 * can create a Bitmap which directly maps to it
55 **/
57 /* map the framebuffer to a ByteBuffer, this way lcd updates will
58 * be directly feched from the framebuffer */
59 jobject buf = e->NewDirectByteBuffer(env_ptr,
60 lcd_framebuffer,
61 (jlong)sizeof(lcd_framebuffer));
63 jmethodID constructor = e->GetMethodID(env_ptr,
64 RockboxFramebuffer_class,
65 "<init>",
66 "(Landroid/content/Context;" /* Service */
67 "II" /* lcd width/height */
68 "Ljava/nio/ByteBuffer;)V"); /* ByteBuffer */
70 RockboxFramebuffer_instance = e->NewObject(env_ptr,
71 RockboxFramebuffer_class,
72 constructor,
73 RockboxService_instance,
74 (jint)LCD_WIDTH,
75 (jint)LCD_HEIGHT,
76 buf);
78 /* cache update functions */
79 postInvalidate1 = (*env_ptr)->GetMethodID(env_ptr,
80 RockboxFramebuffer_class,
81 "postInvalidate",
82 "()V");
83 postInvalidate2 = (*env_ptr)->GetMethodID(env_ptr,
84 RockboxFramebuffer_class,
85 "postInvalidate",
86 "(IIII)V");
88 jmethodID get_dpi = e->GetMethodID(env_ptr,
89 RockboxFramebuffer_class,
90 "getDpi", "()I");
92 jmethodID get_scroll_threshold
93 = e->GetMethodID(env_ptr,
94 RockboxFramebuffer_class,
95 "getScrollThreshold", "()I");
97 dpi = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance,
98 get_dpi);
99 scroll_threshold = e->CallIntMethod(env_ptr, RockboxFramebuffer_instance,
100 get_scroll_threshold);
101 display_on = true;
104 /* the update mechanism is asynchronous since
105 * onDraw() must be called from the UI thread
107 * The Rockbox thread calling lcd_update() has to wait
108 * for the update to complete, so that it's synchronous,
109 * and we need to notify it (we could wait in the java layer, but
110 * that'd block the other Rockbox threads too)
112 * That should give more smoonth animations
114 void lcd_update(void)
116 /* tell the system we're ready for drawing */
117 if (display_on)
119 mutex_lock(&lcd_mtx);
120 (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate1);
121 wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
122 mutex_unlock(&lcd_mtx);
126 void lcd_update_rect(int x, int y, int width, int height)
128 if (display_on)
130 mutex_lock(&lcd_mtx);
131 (*env_ptr)->CallVoidMethod(env_ptr, RockboxFramebuffer_instance, postInvalidate2,
132 (jint)x, (jint)y, (jint)x+width, (jint)y+height);
133 wakeup_wait(&lcd_wakeup, TIMEOUT_BLOCK);
134 mutex_unlock(&lcd_mtx);
138 JNIEXPORT void JNICALL
139 Java_org_rockbox_RockboxFramebuffer_post_1update_1done(JNIEnv *e, jobject this)
141 (void)e;
142 (void)this;
143 wakeup_signal(&lcd_wakeup);
146 bool lcd_active(void)
148 return display_on;
151 int lcd_get_dpi(void)
153 return dpi;
156 int touchscreen_get_scroll_threshold(void)
158 return scroll_threshold;
162 * (un)block lcd updates.
164 * Notice: This is called from the activity thread, so take it
165 * as interrupt context and take care what the event callback does
166 * (it shouldn't block in particular
168 * the 1s are needed due to strange naming conventions...
170 JNIEXPORT void JNICALL
171 Java_org_rockbox_RockboxFramebuffer_set_1lcd_1active(JNIEnv *e,
172 jobject this,
173 jint active)
175 (void)e;
176 (void)this;
177 display_on = active != 0;
178 if (active)
179 send_event(LCD_EVENT_ACTIVATION, NULL);
181 /* below is a plain copy from lcd-sdl.c */
184 * |R| |1.000000 -0.000001 1.402000| |Y'|
185 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
186 * |B| |1.000000 1.772000 0.000000| |Pr|
187 * Scaled, normalized, rounded and tweaked to yield RGB 565:
188 * |R| |74 0 101| |Y' - 16| >> 9
189 * |G| = |74 -24 -51| |Cb - 128| >> 8
190 * |B| |74 128 0| |Cr - 128| >> 9
192 #define YFAC (74)
193 #define RVFAC (101)
194 #define GUFAC (-24)
195 #define GVFAC (-51)
196 #define BUFAC (128)
198 static inline int clamp(int val, int min, int max)
200 if (val < min)
201 val = min;
202 else if (val > max)
203 val = max;
204 return val;
207 void lcd_yuv_set_options(unsigned options)
209 (void)options;
212 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
213 in the core */
214 void lcd_blit_yuv(unsigned char * const src[3],
215 int src_x, int src_y, int stride,
216 int x, int y, int width, int height)
218 const unsigned char *ysrc, *usrc, *vsrc;
219 int linecounter;
220 fb_data *dst, *row_end;
221 long z;
223 /* width and height must be >= 2 and an even number */
224 width &= ~1;
225 linecounter = height >> 1;
227 #if LCD_WIDTH >= LCD_HEIGHT
228 dst = &lcd_framebuffer[y][x];
229 row_end = dst + width;
230 #else
231 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
232 row_end = dst + LCD_WIDTH * width;
233 #endif
235 z = stride * src_y;
236 ysrc = src[0] + z + src_x;
237 usrc = src[1] + (z >> 2) + (src_x >> 1);
238 vsrc = src[2] + (usrc - src[1]);
240 /* stride => amount to jump from end of last row to start of next */
241 stride -= width;
243 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
249 int y, cb, cr, rv, guv, bu, r, g, b;
251 y = YFAC*(*ysrc++ - 16);
252 cb = *usrc++ - 128;
253 cr = *vsrc++ - 128;
255 rv = RVFAC*cr;
256 guv = GUFAC*cb + GVFAC*cr;
257 bu = BUFAC*cb;
259 r = y + rv;
260 g = y + guv;
261 b = y + bu;
263 if ((unsigned)(r | g | b) > 64*256-1)
265 r = clamp(r, 0, 64*256-1);
266 g = clamp(g, 0, 64*256-1);
267 b = clamp(b, 0, 64*256-1);
270 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
272 #if LCD_WIDTH >= LCD_HEIGHT
273 dst++;
274 #else
275 dst += LCD_WIDTH;
276 #endif
278 y = YFAC*(*ysrc++ - 16);
279 r = y + rv;
280 g = y + guv;
281 b = y + bu;
283 if ((unsigned)(r | g | b) > 64*256-1)
285 r = clamp(r, 0, 64*256-1);
286 g = clamp(g, 0, 64*256-1);
287 b = clamp(b, 0, 64*256-1);
290 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
292 #if LCD_WIDTH >= LCD_HEIGHT
293 dst++;
294 #else
295 dst += LCD_WIDTH;
296 #endif
298 while (dst < row_end);
300 ysrc += stride;
301 usrc -= width >> 1;
302 vsrc -= width >> 1;
304 #if LCD_WIDTH >= LCD_HEIGHT
305 row_end += LCD_WIDTH;
306 dst += LCD_WIDTH - width;
307 #else
308 row_end -= 1;
309 dst -= LCD_WIDTH*width + 1;
310 #endif
314 int y, cb, cr, rv, guv, bu, r, g, b;
316 y = YFAC*(*ysrc++ - 16);
317 cb = *usrc++ - 128;
318 cr = *vsrc++ - 128;
320 rv = RVFAC*cr;
321 guv = GUFAC*cb + GVFAC*cr;
322 bu = BUFAC*cb;
324 r = y + rv;
325 g = y + guv;
326 b = y + bu;
328 if ((unsigned)(r | g | b) > 64*256-1)
330 r = clamp(r, 0, 64*256-1);
331 g = clamp(g, 0, 64*256-1);
332 b = clamp(b, 0, 64*256-1);
335 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
337 #if LCD_WIDTH >= LCD_HEIGHT
338 dst++;
339 #else
340 dst += LCD_WIDTH;
341 #endif
343 y = YFAC*(*ysrc++ - 16);
344 r = y + rv;
345 g = y + guv;
346 b = y + bu;
348 if ((unsigned)(r | g | b) > 64*256-1)
350 r = clamp(r, 0, 64*256-1);
351 g = clamp(g, 0, 64*256-1);
352 b = clamp(b, 0, 64*256-1);
355 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
357 #if LCD_WIDTH >= LCD_HEIGHT
358 dst++;
359 #else
360 dst += LCD_WIDTH;
361 #endif
363 while (dst < row_end);
365 ysrc += stride;
366 usrc += stride >> 1;
367 vsrc += stride >> 1;
369 #if LCD_WIDTH >= LCD_HEIGHT
370 row_end += LCD_WIDTH;
371 dst += LCD_WIDTH - width;
372 #else
373 row_end -= 1;
374 dst -= LCD_WIDTH*width + 1;
375 #endif
377 while (--linecounter > 0);
379 #if LCD_WIDTH >= LCD_HEIGHT
380 lcd_update_rect(x, y, width, height);
381 #else
382 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
383 #endif