summaryrefslogtreecommitdiff
path: root/firmware/target/hosted/android/lcd-android.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/hosted/android/lcd-android.c')
-rw-r--r--firmware/target/hosted/android/lcd-android.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/firmware/target/hosted/android/lcd-android.c b/firmware/target/hosted/android/lcd-android.c
new file mode 100644
index 0000000000..ef4004ef2a
--- /dev/null
+++ b/firmware/target/hosted/android/lcd-android.c
@@ -0,0 +1,291 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (c) 2010 Thomas Martitz
11 *
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.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22
23#include <jni.h>
24#include "config.h"
25#include "system.h"
26#include "lcd.h"
27
28extern JNIEnv *env_ptr;
29extern jclass RockboxActivity_class;
30extern jobject RockboxActivity_instance;
31
32static jobject Framebuffer_instance;
33static jmethodID java_lcd_update;
34
35void lcd_init_device(void)
36{
37 /* get the RockboxFramebuffer instance allocated by the activity */
38 jfieldID id = (*env_ptr)->GetFieldID(env_ptr,
39 RockboxActivity_class,
40 "fb",
41 "Lorg/rockbox/RockboxFramebuffer;");
42
43 Framebuffer_instance = (*env_ptr)->GetObjectField(env_ptr,
44 RockboxActivity_instance,
45 id);
46
47 jclass Framebuffer_class = (*env_ptr)->GetObjectClass(env_ptr,
48 Framebuffer_instance);
49
50 /* get the java init function and call it. it'll set up a bitmap
51 * based on LCD_WIDTH, LCD_HEIGHT and the ByteBuffer which directly maps
52 * our framebuffer */
53
54 jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr,
55 Framebuffer_class,
56 "java_lcd_init",
57 "(IILjava/nio/ByteBuffer;)V");
58 java_lcd_update = (*env_ptr)->GetMethodID(env_ptr,
59 Framebuffer_class,
60 "java_lcd_update",
61 "()V");
62
63 /* map the framebuffer to a ByteBuffer, this way lcd updates will
64 * be directly feched from the framebuffer */
65 jobject buf = (*env_ptr)->NewDirectByteBuffer(env_ptr,
66 lcd_framebuffer,
67 sizeof(lcd_framebuffer));
68
69 (*env_ptr)->CallVoidMethod(env_ptr,
70 Framebuffer_instance,
71 java_init_lcd,
72 LCD_WIDTH, LCD_HEIGHT, buf);
73}
74
75void lcd_update()
76{
77 /* tell the system we're ready for drawing */
78 (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update);
79}
80
81void lcd_update_rect(int x, int y, int height, int width)
82{
83 /* can't do partial updates yet */
84 (void)x; (void)y; (void)height; (void)width;
85 lcd_update();
86}
87
88/* below is a plain copy from lcd-sdl.c */
89
90/**
91 * |R| |1.000000 -0.000001 1.402000| |Y'|
92 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
93 * |B| |1.000000 1.772000 0.000000| |Pr|
94 * Scaled, normalized, rounded and tweaked to yield RGB 565:
95 * |R| |74 0 101| |Y' - 16| >> 9
96 * |G| = |74 -24 -51| |Cb - 128| >> 8
97 * |B| |74 128 0| |Cr - 128| >> 9
98 */
99#define YFAC (74)
100#define RVFAC (101)
101#define GUFAC (-24)
102#define GVFAC (-51)
103#define BUFAC (128)
104
105static inline int clamp(int val, int min, int max)
106{
107 if (val < min)
108 val = min;
109 else if (val > max)
110 val = max;
111 return val;
112}
113
114void lcd_yuv_set_options(unsigned options)
115{
116 (void)options;
117}
118
119/* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
120 in the core */
121void lcd_blit_yuv(unsigned char * const src[3],
122 int src_x, int src_y, int stride,
123 int x, int y, int width, int height)
124{
125 const unsigned char *ysrc, *usrc, *vsrc;
126 int linecounter;
127 fb_data *dst, *row_end;
128 long z;
129
130 /* width and height must be >= 2 and an even number */
131 width &= ~1;
132 linecounter = height >> 1;
133
134#if LCD_WIDTH >= LCD_HEIGHT
135 dst = &lcd_framebuffer[y][x];
136 row_end = dst + width;
137#else
138 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
139 row_end = dst + LCD_WIDTH * width;
140#endif
141
142 z = stride * src_y;
143 ysrc = src[0] + z + src_x;
144 usrc = src[1] + (z >> 2) + (src_x >> 1);
145 vsrc = src[2] + (usrc - src[1]);
146
147 /* stride => amount to jump from end of last row to start of next */
148 stride -= width;
149
150 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
151
152 do
153 {
154 do
155 {
156 int y, cb, cr, rv, guv, bu, r, g, b;
157
158 y = YFAC*(*ysrc++ - 16);
159 cb = *usrc++ - 128;
160 cr = *vsrc++ - 128;
161
162 rv = RVFAC*cr;
163 guv = GUFAC*cb + GVFAC*cr;
164 bu = BUFAC*cb;
165
166 r = y + rv;
167 g = y + guv;
168 b = y + bu;
169
170 if ((unsigned)(r | g | b) > 64*256-1)
171 {
172 r = clamp(r, 0, 64*256-1);
173 g = clamp(g, 0, 64*256-1);
174 b = clamp(b, 0, 64*256-1);
175 }
176
177 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
178
179#if LCD_WIDTH >= LCD_HEIGHT
180 dst++;
181#else
182 dst += LCD_WIDTH;
183#endif
184
185 y = YFAC*(*ysrc++ - 16);
186 r = y + rv;
187 g = y + guv;
188 b = y + bu;
189
190 if ((unsigned)(r | g | b) > 64*256-1)
191 {
192 r = clamp(r, 0, 64*256-1);
193 g = clamp(g, 0, 64*256-1);
194 b = clamp(b, 0, 64*256-1);
195 }
196
197 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
198
199#if LCD_WIDTH >= LCD_HEIGHT
200 dst++;
201#else
202 dst += LCD_WIDTH;
203#endif
204 }
205 while (dst < row_end);
206
207 ysrc += stride;
208 usrc -= width >> 1;
209 vsrc -= width >> 1;
210
211#if LCD_WIDTH >= LCD_HEIGHT
212 row_end += LCD_WIDTH;
213 dst += LCD_WIDTH - width;
214#else
215 row_end -= 1;
216 dst -= LCD_WIDTH*width + 1;
217#endif
218
219 do
220 {
221 int y, cb, cr, rv, guv, bu, r, g, b;
222
223 y = YFAC*(*ysrc++ - 16);
224 cb = *usrc++ - 128;
225 cr = *vsrc++ - 128;
226
227 rv = RVFAC*cr;
228 guv = GUFAC*cb + GVFAC*cr;
229 bu = BUFAC*cb;
230
231 r = y + rv;
232 g = y + guv;
233 b = y + bu;
234
235 if ((unsigned)(r | g | b) > 64*256-1)
236 {
237 r = clamp(r, 0, 64*256-1);
238 g = clamp(g, 0, 64*256-1);
239 b = clamp(b, 0, 64*256-1);
240 }
241
242 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
243
244#if LCD_WIDTH >= LCD_HEIGHT
245 dst++;
246#else
247 dst += LCD_WIDTH;
248#endif
249
250 y = YFAC*(*ysrc++ - 16);
251 r = y + rv;
252 g = y + guv;
253 b = y + bu;
254
255 if ((unsigned)(r | g | b) > 64*256-1)
256 {
257 r = clamp(r, 0, 64*256-1);
258 g = clamp(g, 0, 64*256-1);
259 b = clamp(b, 0, 64*256-1);
260 }
261
262 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
263
264#if LCD_WIDTH >= LCD_HEIGHT
265 dst++;
266#else
267 dst += LCD_WIDTH;
268#endif
269 }
270 while (dst < row_end);
271
272 ysrc += stride;
273 usrc += stride >> 1;
274 vsrc += stride >> 1;
275
276#if LCD_WIDTH >= LCD_HEIGHT
277 row_end += LCD_WIDTH;
278 dst += LCD_WIDTH - width;
279#else
280 row_end -= 1;
281 dst -= LCD_WIDTH*width + 1;
282#endif
283 }
284 while (--linecounter > 0);
285
286#if LCD_WIDTH >= LCD_HEIGHT
287 lcd_update_rect(x, y, width, height);
288#else
289 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
290#endif
291}