diff options
author | Jens Arnold <amiconn@rockbox.org> | 2009-03-08 17:22:17 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2009-03-08 17:22:17 +0000 |
commit | 9eeead922ad958cae62015eec8156e47ca47fc58 (patch) | |
tree | f920b48878aae27cf77f301396eb811d9e8a187a /apps | |
parent | 87d1744e91e016b650a3c7826a93cd6afcaf0383 (diff) | |
download | rockbox-9eeead922ad958cae62015eec8156e47ca47fc58.tar.gz rockbox-9eeead922ad958cae62015eec8156e47ca47fc58.zip |
Optimize hline, fillrect and mono bitmap drawing for chunky displays (16 bit colour and greylib). Speeds up text rendering by 20..45% on colour coldfire, by 30..50% on colour ARM, and is noticeable in archos pictureflow.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20242 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/lib/grey_draw.c | 160 |
1 files changed, 106 insertions, 54 deletions
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c index 286cae06a4..65f2211b7f 100644 --- a/apps/plugins/lib/grey_draw.c +++ b/apps/plugins/lib/grey_draw.c | |||
@@ -155,8 +155,7 @@ void grey_hline(int x1, int x2, int y) | |||
155 | int value = 0; | 155 | int value = 0; |
156 | unsigned char *dst; | 156 | unsigned char *dst; |
157 | bool fillopt = false; | 157 | bool fillopt = false; |
158 | void (*pfunc)(unsigned char *address); | 158 | |
159 | |||
160 | /* direction flip */ | 159 | /* direction flip */ |
161 | if (x2 < x1) | 160 | if (x2 < x1) |
162 | { | 161 | { |
@@ -170,12 +169,7 @@ void grey_hline(int x1, int x2, int y) | |||
170 | || (x1 >= _grey_info.width) || (x2 < 0)) | 169 | || (x1 >= _grey_info.width) || (x2 < 0)) |
171 | return; | 170 | return; |
172 | 171 | ||
173 | /* clipping */ | 172 | /* drawmode and optimisation */ |
174 | if (x1 < 0) | ||
175 | x1 = 0; | ||
176 | if (x2 >= _grey_info.width) | ||
177 | x2 = _grey_info.width - 1; | ||
178 | |||
179 | if (_grey_info.drawmode & DRMODE_INVERSEVID) | 173 | if (_grey_info.drawmode & DRMODE_INVERSEVID) |
180 | { | 174 | { |
181 | if (_grey_info.drawmode & DRMODE_BG) | 175 | if (_grey_info.drawmode & DRMODE_BG) |
@@ -192,17 +186,25 @@ void grey_hline(int x1, int x2, int y) | |||
192 | value = _grey_info.fg_brightness; | 186 | value = _grey_info.fg_brightness; |
193 | } | 187 | } |
194 | } | 188 | } |
195 | pfunc = _grey_pixelfuncs[_grey_info.drawmode]; | 189 | if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT) |
190 | return; | ||
191 | |||
192 | /* clipping */ | ||
193 | if (x1 < 0) | ||
194 | x1 = 0; | ||
195 | if (x2 >= _grey_info.width) | ||
196 | x2 = _grey_info.width - 1; | ||
197 | |||
196 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1]; | 198 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x1]; |
197 | 199 | ||
198 | if (fillopt) | 200 | if (fillopt) |
199 | rb->memset(dst, value, x2 - x1 + 1); | 201 | rb->memset(dst, value, x2 - x1 + 1); |
200 | else | 202 | else /* DRMODE_COMPLEMENT */ |
201 | { | 203 | { |
202 | unsigned char *dst_end = dst + x2 - x1; | 204 | unsigned char *dst_end = dst + x2 - x1; |
203 | do | 205 | do |
204 | pfunc(dst++); | 206 | *dst = ~(*dst); |
205 | while (dst <= dst_end); | 207 | while (++dst <= dst_end); |
206 | } | 208 | } |
207 | } | 209 | } |
208 | 210 | ||
@@ -335,29 +337,13 @@ void grey_fillrect(int x, int y, int width, int height) | |||
335 | int value = 0; | 337 | int value = 0; |
336 | unsigned char *dst, *dst_end; | 338 | unsigned char *dst, *dst_end; |
337 | bool fillopt = false; | 339 | bool fillopt = false; |
338 | void (*pfunc)(unsigned char *address); | ||
339 | 340 | ||
340 | /* nothing to draw? */ | 341 | /* nothing to draw? */ |
341 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | 342 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) |
342 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | 343 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) |
343 | return; | 344 | return; |
344 | 345 | ||
345 | /* clipping */ | 346 | /* drawmode and optimisation */ |
346 | if (x < 0) | ||
347 | { | ||
348 | width += x; | ||
349 | x = 0; | ||
350 | } | ||
351 | if (y < 0) | ||
352 | { | ||
353 | height += y; | ||
354 | y = 0; | ||
355 | } | ||
356 | if (x + width > _grey_info.width) | ||
357 | width = _grey_info.width - x; | ||
358 | if (y + height > _grey_info.height) | ||
359 | height = _grey_info.height - y; | ||
360 | |||
361 | if (_grey_info.drawmode & DRMODE_INVERSEVID) | 347 | if (_grey_info.drawmode & DRMODE_INVERSEVID) |
362 | { | 348 | { |
363 | if (_grey_info.drawmode & DRMODE_BG) | 349 | if (_grey_info.drawmode & DRMODE_BG) |
@@ -374,7 +360,25 @@ void grey_fillrect(int x, int y, int width, int height) | |||
374 | value = _grey_info.fg_brightness; | 360 | value = _grey_info.fg_brightness; |
375 | } | 361 | } |
376 | } | 362 | } |
377 | pfunc = _grey_pixelfuncs[_grey_info.drawmode]; | 363 | if (!fillopt && _grey_info.drawmode != DRMODE_COMPLEMENT) |
364 | return; | ||
365 | |||
366 | /* clipping */ | ||
367 | if (x < 0) | ||
368 | { | ||
369 | width += x; | ||
370 | x = 0; | ||
371 | } | ||
372 | if (y < 0) | ||
373 | { | ||
374 | height += y; | ||
375 | y = 0; | ||
376 | } | ||
377 | if (x + width > _grey_info.width) | ||
378 | width = _grey_info.width - x; | ||
379 | if (y + height > _grey_info.height) | ||
380 | height = _grey_info.height - y; | ||
381 | |||
378 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; | 382 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; |
379 | dst_end = dst + _GREY_MULUQ(_grey_info.width, height); | 383 | dst_end = dst + _GREY_MULUQ(_grey_info.width, height); |
380 | 384 | ||
@@ -382,14 +386,14 @@ void grey_fillrect(int x, int y, int width, int height) | |||
382 | { | 386 | { |
383 | if (fillopt) | 387 | if (fillopt) |
384 | rb->memset(dst, value, width); | 388 | rb->memset(dst, value, width); |
385 | else | 389 | else /* DRMODE_COMPLEMENT */ |
386 | { | 390 | { |
387 | unsigned char *dst_row = dst; | 391 | unsigned char *dst_row = dst; |
388 | unsigned char *row_end = dst_row + width; | 392 | unsigned char *row_end = dst_row + width; |
389 | 393 | ||
390 | do | 394 | do |
391 | pfunc(dst_row++); | 395 | *dst_row = ~(*dst_row); |
392 | while (dst_row < row_end); | 396 | while (++dst_row < row_end); |
393 | } | 397 | } |
394 | dst += _grey_info.width; | 398 | dst += _grey_info.width; |
395 | } | 399 | } |
@@ -411,8 +415,9 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
411 | { | 415 | { |
412 | const unsigned char *src_end; | 416 | const unsigned char *src_end; |
413 | unsigned char *dst, *dst_end; | 417 | unsigned char *dst, *dst_end; |
414 | void (*fgfunc)(unsigned char *address); | 418 | unsigned dmask = 0x100; /* bit 8 == sentinel */ |
415 | void (*bgfunc)(unsigned char *address); | 419 | int drmode = _grey_info.drawmode; |
420 | int dwidth; | ||
416 | 421 | ||
417 | /* nothing to draw? */ | 422 | /* nothing to draw? */ |
418 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | 423 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) |
@@ -440,37 +445,84 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
440 | src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */ | 445 | src += _GREY_MULUQ(stride, src_y >> 3) + src_x; /* move starting point */ |
441 | src_y &= 7; | 446 | src_y &= 7; |
442 | src_end = src + width; | 447 | src_end = src + width; |
448 | dwidth = _grey_info.width; | ||
449 | dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x]; | ||
443 | 450 | ||
444 | fgfunc = _grey_pixelfuncs[_grey_info.drawmode]; | 451 | if (drmode & DRMODE_INVERSEVID) |
445 | bgfunc = _grey_pixelfuncs[_grey_info.drawmode ^ DRMODE_INVERSEVID]; | 452 | { |
446 | dst = &_grey_info.buffer[_GREY_MULUQ(_grey_info.width, y) + x]; | 453 | dmask = 0x1ff; /* bit 8 == sentinel */ |
454 | drmode &= DRMODE_SOLID; /* mask out inversevid */ | ||
455 | } | ||
447 | 456 | ||
448 | do | 457 | do |
449 | { | 458 | { |
450 | const unsigned char *src_col = src++; | 459 | const unsigned char *src_col = src++; |
451 | unsigned char *dst_col = dst++; | 460 | unsigned char *dst_col = dst++; |
452 | unsigned data = *src_col >> src_y; | 461 | unsigned data = (*src_col ^ dmask) >> src_y; |
453 | int numbits = 8 - src_y; | 462 | int fg, bg; |
463 | |||
464 | dst_end = dst_col + _GREY_MULUQ(dwidth, height); | ||
454 | 465 | ||
455 | dst_end = dst_col + _GREY_MULUQ(_grey_info.width, height); | 466 | #define UPDATE_SRC do { \ |
456 | do | 467 | data >>= 1; \ |
468 | if (data == 0x001) { \ | ||
469 | src_col += stride; \ | ||
470 | data = *src_col ^ dmask; \ | ||
471 | } \ | ||
472 | } while (0) | ||
473 | |||
474 | switch (drmode) | ||
457 | { | 475 | { |
458 | if (data & 0x01) | 476 | case DRMODE_COMPLEMENT: |
459 | fgfunc(dst_col); | 477 | do |
460 | else | 478 | { |
461 | bgfunc(dst_col); | 479 | if (data & 0x01) |
480 | *dst_col = ~(*dst_col); | ||
462 | 481 | ||
463 | dst_col += _grey_info.width; | 482 | dst_col += dwidth; |
483 | UPDATE_SRC; | ||
484 | } | ||
485 | while (dst_col < dst_end); | ||
486 | break; | ||
464 | 487 | ||
465 | data >>= 1; | 488 | case DRMODE_BG: |
466 | if (--numbits == 0) | 489 | bg = _grey_info.bg_brightness; |
490 | do | ||
467 | { | 491 | { |
468 | src_col += stride; | 492 | if (!(data & 0x01)) |
469 | data = *src_col; | 493 | *dst_col = bg; |
470 | numbits = 8; | 494 | |
495 | dst_col += dwidth; | ||
496 | UPDATE_SRC; | ||
471 | } | 497 | } |
498 | while (dst_col < dst_end); | ||
499 | break; | ||
500 | |||
501 | case DRMODE_FG: | ||
502 | fg = _grey_info.fg_brightness; | ||
503 | do | ||
504 | { | ||
505 | if (data & 0x01) | ||
506 | *dst_col = fg; | ||
507 | |||
508 | dst_col += dwidth; | ||
509 | UPDATE_SRC; | ||
510 | } | ||
511 | while (dst_col < dst_end); | ||
512 | break; | ||
513 | |||
514 | case DRMODE_SOLID: | ||
515 | fg = _grey_info.fg_brightness; | ||
516 | bg = _grey_info.bg_brightness; | ||
517 | do | ||
518 | { | ||
519 | *dst_col = (data & 0x01) ? fg : bg; | ||
520 | dst_col += dwidth; | ||
521 | UPDATE_SRC; | ||
522 | } | ||
523 | while (dst_col < dst_end); | ||
524 | break; | ||
472 | } | 525 | } |
473 | while (dst_col < dst_end); | ||
474 | } | 526 | } |
475 | while (src < src_end); | 527 | while (src < src_end); |
476 | } | 528 | } |
@@ -491,7 +543,7 @@ void grey_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, | |||
491 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) | 543 | if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) |
492 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) | 544 | || (y >= _grey_info.height) || (x + width <= 0) || (y + height <= 0)) |
493 | return; | 545 | return; |
494 | 546 | ||
495 | /* clipping */ | 547 | /* clipping */ |
496 | if (x < 0) | 548 | if (x < 0) |
497 | { | 549 | { |