1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
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
);
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
;
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
77 static inline int clamp(int val
, int min
, int max
)
86 void lcd_yuv_set_options(unsigned options
)
91 /* Draw a partial YUV colour bitmap - similiar behavior to lcd_blit_yuv
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
;
99 fb_data
*dst
, *row_end
;
102 /* width and height must be >= 2 and an even number */
104 linecounter
= height
>> 1;
106 #if LCD_WIDTH >= LCD_HEIGHT
107 dst
= &lcd_framebuffer
[y
][x
];
108 row_end
= dst
+ width
;
110 dst
= &lcd_framebuffer
[x
][LCD_WIDTH
- y
- 1];
111 row_end
= dst
+ LCD_WIDTH
* width
;
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 */
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);
135 guv
= GUFAC
*cb
+ GVFAC
*cr
;
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
157 y
= YFAC
*(*ysrc
++ - 16);
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
177 while (dst
< row_end
);
183 #if LCD_WIDTH >= LCD_HEIGHT
184 row_end
+= LCD_WIDTH
;
185 dst
+= LCD_WIDTH
- width
;
188 dst
-= LCD_WIDTH
*width
+ 1;
193 int y
, cb
, cr
, rv
, guv
, bu
, r
, g
, b
;
195 y
= YFAC
*(*ysrc
++ - 16);
200 guv
= GUFAC
*cb
+ GVFAC
*cr
;
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
222 y
= YFAC
*(*ysrc
++ - 16);
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
242 while (dst
< row_end
);
248 #if LCD_WIDTH >= LCD_HEIGHT
249 row_end
+= LCD_WIDTH
;
250 dst
+= LCD_WIDTH
- width
;
253 dst
-= LCD_WIDTH
*width
+ 1;
256 while (--linecounter
> 0);
258 #if LCD_WIDTH >= LCD_HEIGHT
259 lcd_update_rect(x
, y
, width
, height
);
261 lcd_update_rect(LCD_WIDTH
- y
- height
, x
, height
, width
);