RockboxBootloader => Rockbox
[kugel-rb.git] / firmware / target / hosted / android / lcd-android.c
blob5d694d4c9f9b17bceaba55e709f83248dfba8d9b
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 "lcd.h"
28 jclass Framebuffer_class;
29 jobject Framebuffer_instance;
30 extern JNIEnv *env_ptr;
31 extern jclass RbBl_class;
32 extern jobject RbBl_instance;
34 jmethodID java_lcd_update;
36 void lcd_init_device(void)
38 LOG("%s(): Hello", __func__);
39 jfieldID id = (*env_ptr)->GetFieldID(env_ptr, RbBl_class, "fb", "Lorg/rockbox/RockboxFramebuffer;");
40 Framebuffer_instance = (*env_ptr)->GetObjectField(env_ptr, RbBl_instance, id);
41 Framebuffer_class = (*env_ptr)->GetObjectClass(env_ptr, Framebuffer_instance);
43 jmethodID java_init_lcd = (*env_ptr)->GetMethodID(env_ptr, Framebuffer_class, "java_lcd_init", "(IILjava/nio/ByteBuffer;)V");
44 java_lcd_update = (*env_ptr)->GetMethodID(env_ptr, Framebuffer_class, "java_lcd_update", "()V");
46 jobject buf = (*env_ptr)->NewDirectByteBuffer(env_ptr, lcd_framebuffer, sizeof(lcd_framebuffer));
48 (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_init_lcd, LCD_WIDTH, LCD_HEIGHT, buf);
51 void lcd_update()
53 (*env_ptr)->CallVoidMethod(env_ptr, Framebuffer_instance, java_lcd_update);
56 void lcd_update_rect(int x, int y, int height, int width)
58 (void)x; (void)y; (void)height; (void)width;
59 lcd_update();
62 /**
63 * |R| |1.000000 -0.000001 1.402000| |Y'|
64 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
65 * |B| |1.000000 1.772000 0.000000| |Pr|
66 * Scaled, normalized, rounded and tweaked to yield RGB 565:
67 * |R| |74 0 101| |Y' - 16| >> 9
68 * |G| = |74 -24 -51| |Cb - 128| >> 8
69 * |B| |74 128 0| |Cr - 128| >> 9
71 #define YFAC (74)
72 #define RVFAC (101)
73 #define GUFAC (-24)
74 #define GVFAC (-51)
75 #define BUFAC (128)
77 static inline int clamp(int val, int min, int max)
79 if (val < min)
80 val = min;
81 else if (val > max)
82 val = max;
83 return val;
86 void lcd_yuv_set_options(unsigned options)
88 (void)options;
91 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
92 in the core */
93 void lcd_blit_yuv(unsigned char * const src[3],
94 int src_x, int src_y, int stride,
95 int x, int y, int width, int height)
97 const unsigned char *ysrc, *usrc, *vsrc;
98 int linecounter;
99 fb_data *dst, *row_end;
100 long z;
102 /* width and height must be >= 2 and an even number */
103 width &= ~1;
104 linecounter = height >> 1;
106 #if LCD_WIDTH >= LCD_HEIGHT
107 dst = &lcd_framebuffer[y][x];
108 row_end = dst + width;
109 #else
110 dst = &lcd_framebuffer[x][LCD_WIDTH - y - 1];
111 row_end = dst + LCD_WIDTH * width;
112 #endif
114 z = stride * src_y;
115 ysrc = src[0] + z + src_x;
116 usrc = src[1] + (z >> 2) + (src_x >> 1);
117 vsrc = src[2] + (usrc - src[1]);
119 /* stride => amount to jump from end of last row to start of next */
120 stride -= width;
122 /* upsampling, YUV->RGB conversion and reduction to RGB565 in one go */
128 int y, cb, cr, rv, guv, bu, r, g, b;
130 y = YFAC*(*ysrc++ - 16);
131 cb = *usrc++ - 128;
132 cr = *vsrc++ - 128;
134 rv = RVFAC*cr;
135 guv = GUFAC*cb + GVFAC*cr;
136 bu = BUFAC*cb;
138 r = y + rv;
139 g = y + guv;
140 b = y + bu;
142 if ((unsigned)(r | g | b) > 64*256-1)
144 r = clamp(r, 0, 64*256-1);
145 g = clamp(g, 0, 64*256-1);
146 b = clamp(b, 0, 64*256-1);
149 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
151 #if LCD_WIDTH >= LCD_HEIGHT
152 dst++;
153 #else
154 dst += LCD_WIDTH;
155 #endif
157 y = YFAC*(*ysrc++ - 16);
158 r = y + rv;
159 g = y + guv;
160 b = y + bu;
162 if ((unsigned)(r | g | b) > 64*256-1)
164 r = clamp(r, 0, 64*256-1);
165 g = clamp(g, 0, 64*256-1);
166 b = clamp(b, 0, 64*256-1);
169 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
171 #if LCD_WIDTH >= LCD_HEIGHT
172 dst++;
173 #else
174 dst += LCD_WIDTH;
175 #endif
177 while (dst < row_end);
179 ysrc += stride;
180 usrc -= width >> 1;
181 vsrc -= width >> 1;
183 #if LCD_WIDTH >= LCD_HEIGHT
184 row_end += LCD_WIDTH;
185 dst += LCD_WIDTH - width;
186 #else
187 row_end -= 1;
188 dst -= LCD_WIDTH*width + 1;
189 #endif
193 int y, cb, cr, rv, guv, bu, r, g, b;
195 y = YFAC*(*ysrc++ - 16);
196 cb = *usrc++ - 128;
197 cr = *vsrc++ - 128;
199 rv = RVFAC*cr;
200 guv = GUFAC*cb + GVFAC*cr;
201 bu = BUFAC*cb;
203 r = y + rv;
204 g = y + guv;
205 b = y + bu;
207 if ((unsigned)(r | g | b) > 64*256-1)
209 r = clamp(r, 0, 64*256-1);
210 g = clamp(g, 0, 64*256-1);
211 b = clamp(b, 0, 64*256-1);
214 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
216 #if LCD_WIDTH >= LCD_HEIGHT
217 dst++;
218 #else
219 dst += LCD_WIDTH;
220 #endif
222 y = YFAC*(*ysrc++ - 16);
223 r = y + rv;
224 g = y + guv;
225 b = y + bu;
227 if ((unsigned)(r | g | b) > 64*256-1)
229 r = clamp(r, 0, 64*256-1);
230 g = clamp(g, 0, 64*256-1);
231 b = clamp(b, 0, 64*256-1);
234 *dst = LCD_RGBPACK_LCD(r >> 9, g >> 8, b >> 9);
236 #if LCD_WIDTH >= LCD_HEIGHT
237 dst++;
238 #else
239 dst += LCD_WIDTH;
240 #endif
242 while (dst < row_end);
244 ysrc += stride;
245 usrc += stride >> 1;
246 vsrc += stride >> 1;
248 #if LCD_WIDTH >= LCD_HEIGHT
249 row_end += LCD_WIDTH;
250 dst += LCD_WIDTH - width;
251 #else
252 row_end -= 1;
253 dst -= LCD_WIDTH*width + 1;
254 #endif
256 while (--linecounter > 0);
258 #if LCD_WIDTH >= LCD_HEIGHT
259 lcd_update_rect(x, y, width, height);
260 #else
261 lcd_update_rect(LCD_WIDTH - y - height, x, height, width);
262 #endif