diff options
author | Greg White <gwhite@rockbox.org> | 2007-01-15 13:07:47 +0000 |
---|---|---|
committer | Greg White <gwhite@rockbox.org> | 2007-01-15 13:07:47 +0000 |
commit | 69bb4362239e566d7232854ab65df3d0a5758179 (patch) | |
tree | a5abc6ff74e93d369dab5de0409dcc4bcfda5116 /firmware/target | |
parent | 724641268ea5154ee2d403252fa5ae13a78d46ca (diff) | |
download | rockbox-69bb4362239e566d7232854ab65df3d0a5758179.tar.gz rockbox-69bb4362239e566d7232854ab65df3d0a5758179.zip |
Optimize transparent blit; optimize DRMODE_SOLID for mono bitmaps
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@12015 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c index 3ecd7df4e8..f323dda1e1 100644 --- a/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c +++ b/firmware/target/arm/gigabeat/meg-fx/lcd-meg-fx.c | |||
@@ -8,7 +8,11 @@ | |||
8 | #include <stdlib.h> | 8 | #include <stdlib.h> |
9 | #include "memory.h" | 9 | #include "memory.h" |
10 | #include "lcd-target.h" | 10 | #include "lcd-target.h" |
11 | #include "font.h" | ||
12 | #include "rbunicode.h" | ||
13 | #include "bidi.h" | ||
11 | 14 | ||
15 | #define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) | ||
12 | /* | 16 | /* |
13 | ** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups | 17 | ** We prepare foreground and background fills ahead of time - DMA fills in 16 byte groups |
14 | */ | 18 | */ |
@@ -235,6 +239,159 @@ void lcd_update(void) | |||
235 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); | 239 | lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT); |
236 | } | 240 | } |
237 | 241 | ||
242 | void lcd_bitmap_transparent_part(const fb_data *src, int src_x, int src_y, | ||
243 | int stride, int x, int y, int width, | ||
244 | int height) | ||
245 | { | ||
246 | fb_data *dst, *dst_end; | ||
247 | unsigned int transcolor; | ||
248 | |||
249 | /* nothing to draw? */ | ||
250 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
251 | || (x + width <= 0) || (y + height <= 0)) | ||
252 | return; | ||
253 | |||
254 | /* clipping */ | ||
255 | if (x < 0) | ||
256 | { | ||
257 | width += x; | ||
258 | src_x -= x; | ||
259 | x = 0; | ||
260 | } | ||
261 | if (y < 0) | ||
262 | { | ||
263 | height += y; | ||
264 | src_y -= y; | ||
265 | y = 0; | ||
266 | } | ||
267 | if (x + width > LCD_WIDTH) | ||
268 | width = LCD_WIDTH - x; | ||
269 | if (y + height > LCD_HEIGHT) | ||
270 | height = LCD_HEIGHT - y; | ||
271 | |||
272 | src += stride * src_y + src_x; /* move starting point */ | ||
273 | dst = &lcd_framebuffer[(y)][(x)]; | ||
274 | dst_end = dst + height * LCD_WIDTH; | ||
275 | width *= 2; | ||
276 | stride *= 2; | ||
277 | transcolor = TRANSPARENT_COLOR; | ||
278 | asm volatile( | ||
279 | "rowstart: \n" | ||
280 | "mov r0, #0 \n" | ||
281 | "nextpixel: \n" | ||
282 | "ldrh r1, [%0, r0] \n" /* Load word src+r0 */ | ||
283 | "cmp r1, %5 \n" /* Compare to transparent color */ | ||
284 | "strneh r1, [%1, r0] \n" /* Store dst+r0 if not transparent */ | ||
285 | "add r0, r0, #2 \n" | ||
286 | "cmp r0, %2 \n" /* r0 == width? */ | ||
287 | "bne nextpixel \n" /* More in this row? */ | ||
288 | "add %0, %0, %4 \n" /* src += stride */ | ||
289 | "add %1, %1, #480 \n" /* dst += LCD_WIDTH (x2) */ | ||
290 | "cmp %1, %3 \n" | ||
291 | "bne rowstart \n" /* if(dst != dst_end), keep going */ | ||
292 | : : "r" (src), "r" (dst), "r" (width), "r" (dst_end), "r" (stride), "r" (transcolor) : "r0", "r1" ); | ||
293 | } | ||
294 | |||
295 | void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
296 | int stride, int x, int y, int width, int height) | ||
297 | ICODE_ATTR; | ||
298 | void lcd_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | ||
299 | int stride, int x, int y, int width, int height) | ||
300 | { | ||
301 | const unsigned char *src_end; | ||
302 | fb_data *dst, *dst_end; | ||
303 | |||
304 | /* nothing to draw? */ | ||
305 | if ((width <= 0) || (height <= 0) || (x >= LCD_WIDTH) || (y >= LCD_HEIGHT) | ||
306 | || (x + width <= 0) || (y + height <= 0)) | ||
307 | return; | ||
308 | |||
309 | /* clipping */ | ||
310 | if (x < 0) | ||
311 | { | ||
312 | width += x; | ||
313 | src_x -= x; | ||
314 | x = 0; | ||
315 | } | ||
316 | if (y < 0) | ||
317 | { | ||
318 | height += y; | ||
319 | src_y -= y; | ||
320 | y = 0; | ||
321 | } | ||
322 | if (x + width > LCD_WIDTH) | ||
323 | width = LCD_WIDTH - x; | ||
324 | if (y + height > LCD_HEIGHT) | ||
325 | height = LCD_HEIGHT - y; | ||
326 | |||
327 | src += stride * (src_y >> 3) + src_x; /* move starting point */ | ||
328 | src_y &= 7; | ||
329 | src_end = src + width; | ||
330 | |||
331 | dst = LCDADDR(x, y); | ||
332 | int drawmode = lcd_get_drawmode(); | ||
333 | if(drawmode == DRMODE_SOLID) { | ||
334 | do | ||
335 | { | ||
336 | const unsigned char *src_col = src++; | ||
337 | unsigned data = *src_col >> src_y; | ||
338 | fb_data *dst_col = dst++; | ||
339 | int numbits = 8 - src_y; | ||
340 | |||
341 | dst_end = dst_col + height * LCD_WIDTH; | ||
342 | asm volatile( | ||
343 | "transrowstart: \n" | ||
344 | "tst %0, #1 \n" /* Test data bit 1 */ | ||
345 | "strneh %6, [%1] \n" /* If it is set, set pixel */ | ||
346 | "add %1, %1, #480 \n" /* dst_col += LCD_WIDTH (x2) */ | ||
347 | "sub %7, %7, #1 \n" /* numbits-- */ | ||
348 | "cmp %7, #0 \n" | ||
349 | "movne %0, %0, LSR #1 \n" /* Shift data */ | ||
350 | "bne transrowstart \n" /* if(numbits != 0) goto transrowstart */ | ||
351 | "add %5, %5, %4 \n" /* src_col += stride */ | ||
352 | "ldrb %0, [%5] \n" /* data = *srccol */ | ||
353 | "mov %7, #8 \n" /* numbits = 8; */ | ||
354 | "cmp %1, %3 \n" /* if(dst_col < dst_end */ | ||
355 | "blt transrowstart \n" /* Keep going */ | ||
356 | : : "r" (data), "r" (dst_col), "r" (numbits), "r" (dst_end), "r" (stride), "r" (src_col), "r" (fg_pattern), "r" (numbits) ); | ||
357 | } | ||
358 | while (src < src_end); | ||
359 | } | ||
360 | else { | ||
361 | lcd_fastpixelfunc_type *fgfunc = lcd_fastpixelfuncs[drawmode];; | ||
362 | lcd_fastpixelfunc_type *bgfunc = lcd_fastpixelfuncs[drawmode ^ DRMODE_INVERSEVID];; | ||
363 | do | ||
364 | { | ||
365 | const unsigned char *src_col = src++; | ||
366 | unsigned data = *src_col >> src_y; | ||
367 | fb_data *dst_col = dst++; | ||
368 | int numbits = 8 - src_y; | ||
369 | |||
370 | dst_end = dst_col + height * LCD_WIDTH; | ||
371 | do | ||
372 | { | ||
373 | if (data & 0x01) | ||
374 | fgfunc(dst_col); | ||
375 | else | ||
376 | bgfunc(dst_col); | ||
377 | |||
378 | dst_col += LCD_WIDTH; | ||
379 | |||
380 | data >>= 1; | ||
381 | if (--numbits == 0) | ||
382 | { | ||
383 | src_col += stride; | ||
384 | data = *src_col; | ||
385 | numbits = 8; | ||
386 | } | ||
387 | } | ||
388 | while (dst_col < dst_end); | ||
389 | } | ||
390 | while (src < src_end); | ||
391 | } | ||
392 | } | ||
393 | |||
394 | |||
238 | #define CSUB_X 2 | 395 | #define CSUB_X 2 |
239 | #define CSUB_Y 2 | 396 | #define CSUB_Y 2 |
240 | 397 | ||