diff options
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/lcd-16bit-common.c | 445 |
1 files changed, 220 insertions, 225 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c index 27e6c23885..af1171b401 100644 --- a/firmware/drivers/lcd-16bit-common.c +++ b/firmware/drivers/lcd-16bit-common.c | |||
@@ -336,7 +336,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
336 | } | 336 | } |
337 | 337 | ||
338 | 338 | ||
339 | /* About Rockbox' internal alpha channel format (for ALPHA_COLOR_FONT_DEPTH == 2) | 339 | /* About Rockbox' internal alpha channel format (for ALPHA_BPP == 4) |
340 | * | 340 | * |
341 | * For each pixel, 4bit of alpha information is stored in a byte-stream, | 341 | * For each pixel, 4bit of alpha information is stored in a byte-stream, |
342 | * so two pixels are packed into one byte. | 342 | * so two pixels are packed into one byte. |
@@ -355,11 +355,15 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
355 | * so lcd_bmp() do expect even rows. | 355 | * so lcd_bmp() do expect even rows. |
356 | */ | 356 | */ |
357 | 357 | ||
358 | #define ALPHA_COLOR_FONT_DEPTH 2 | 358 | #define ALPHA_BPP 4 |
359 | #define ALPHA_COLOR_LOOKUP_SHIFT (1 << ALPHA_COLOR_FONT_DEPTH) | 359 | #define ALPHA_MASK ((1 << ALPHA_BPP) - 1) |
360 | #define ALPHA_COLOR_LOOKUP_SIZE ((1 << ALPHA_COLOR_LOOKUP_SHIFT) - 1) | 360 | #define ALPHA_PIXELS_PER_BYTE (CHAR_BIT / ALPHA_BPP) |
361 | #define ALPHA_COLOR_PIXEL_PER_BYTE (8 >> ALPHA_COLOR_FONT_DEPTH) | 361 | |
362 | #define ALPHA_COLOR_PIXEL_PER_WORD (32 >> ALPHA_COLOR_FONT_DEPTH) | 362 | #define ALPHA_WORD_T uint32_t |
363 | #define ALPHA_WORD_LOAD load_le32 | ||
364 | #define ALPHA_WORDSIZE sizeof(ALPHA_WORD_T) | ||
365 | #define ALPHA_PIXELS_PER_WORD (ALPHA_WORDSIZE * CHAR_BIT / ALPHA_BPP) | ||
366 | |||
363 | #ifdef CPU_ARM | 367 | #ifdef CPU_ARM |
364 | #define BLEND_INIT do {} while (0) | 368 | #define BLEND_INIT do {} while (0) |
365 | #define BLEND_FINISH do {} while(0) | 369 | #define BLEND_FINISH do {} while(0) |
@@ -368,6 +372,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
368 | #define BLEND_CONT(acc, color, alpha) \ | 372 | #define BLEND_CONT(acc, color, alpha) \ |
369 | asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha)) | 373 | asm volatile("mla %0, %1, %2, %0" : "+&r" (acc) : "r" (color), "r" (alpha)) |
370 | #define BLEND_OUT(acc) do {} while (0) | 374 | #define BLEND_OUT(acc) do {} while (0) |
375 | |||
371 | #elif defined(CPU_COLDFIRE) | 376 | #elif defined(CPU_COLDFIRE) |
372 | #define ALPHA_BITMAP_READ_WORDS | 377 | #define ALPHA_BITMAP_READ_WORDS |
373 | #define BLEND_INIT \ | 378 | #define BLEND_INIT \ |
@@ -379,6 +384,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
379 | asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha)) | 384 | asm volatile("mac.l %0, %1, %%acc0" :: "%d" (color), "d" (alpha)) |
380 | #define BLEND_CONT BLEND_START | 385 | #define BLEND_CONT BLEND_START |
381 | #define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc)) | 386 | #define BLEND_OUT(acc) asm volatile("movclr.l %%acc0, %0" : "=d" (acc)) |
387 | |||
382 | #else | 388 | #else |
383 | #define BLEND_INIT do {} while (0) | 389 | #define BLEND_INIT do {} while (0) |
384 | #define BLEND_FINISH do {} while(0) | 390 | #define BLEND_FINISH do {} while(0) |
@@ -390,7 +396,7 @@ void lcd_mono_bitmap(const unsigned char *src, int x, int y, int width, int heig | |||
390 | /* Blend the given two colors */ | 396 | /* Blend the given two colors */ |
391 | static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) | 397 | static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) |
392 | { | 398 | { |
393 | a += a >> (ALPHA_COLOR_LOOKUP_SHIFT - 1); | 399 | a += a >> (ALPHA_BPP - 1); |
394 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | 400 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) |
395 | c1 = swap16(c1); | 401 | c1 = swap16(c1); |
396 | c2 = swap16(c2); | 402 | c2 = swap16(c2); |
@@ -399,9 +405,9 @@ static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) | |||
399 | unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f; | 405 | unsigned c2l = (c2 | (c2 << 16)) & 0x07e0f81f; |
400 | unsigned p; | 406 | unsigned p; |
401 | BLEND_START(p, c1l, a); | 407 | BLEND_START(p, c1l, a); |
402 | BLEND_CONT(p, c2l, ALPHA_COLOR_LOOKUP_SIZE + 1 - a); | 408 | BLEND_CONT(p, c2l, ALPHA_MASK + 1 - a); |
403 | BLEND_OUT(p); | 409 | BLEND_OUT(p); |
404 | p = (p >> ALPHA_COLOR_LOOKUP_SHIFT) & 0x07e0f81f; | 410 | p = (p >> ALPHA_BPP) & 0x07e0f81f; |
405 | p |= (p >> 16); | 411 | p |= (p >> 16); |
406 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) | 412 | #if (LCD_PIXELFORMAT == RGB565SWAPPED) |
407 | return swap16(p); | 413 | return swap16(p); |
@@ -410,251 +416,240 @@ static inline unsigned blend_two_colors(unsigned c1, unsigned c2, unsigned a) | |||
410 | #endif | 416 | #endif |
411 | } | 417 | } |
412 | 418 | ||
413 | /* Blend an image with an alpha channel | 419 | static void ICODE_ATTR lcd_alpha_bitmap_part_mix( |
414 | * if image is NULL, drawing will happen according to the drawmode | 420 | const fb_data* image, const unsigned char *alpha, |
415 | * src is the alpha channel (4bit per pixel) */ | 421 | int src_x, int src_y, |
416 | static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image, | 422 | int x, int y, int width, int height, |
417 | const unsigned char *src, int src_x, | 423 | int stride_image, int stride_alpha) |
418 | int src_y, int x, int y, | ||
419 | int width, int height, | ||
420 | int stride_image, int stride_src) | ||
421 | { | 424 | { |
422 | struct viewport *vp = lcd_current_viewport; | 425 | struct viewport *vp = lcd_current_viewport; |
423 | fb_data *dst, *dst_row; | 426 | unsigned int dmask = 0; |
424 | unsigned dmask = 0x00000000; | ||
425 | int drmode = vp->drawmode; | 427 | int drmode = vp->drawmode; |
428 | fb_data *dst; | ||
429 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
430 | ALPHA_WORD_T alpha_data, *alpha_word; | ||
431 | size_t alpha_offset = 0, alpha_pixels; | ||
432 | #else | ||
433 | unsigned char alpha_data; | ||
434 | size_t alpha_pixels; | ||
435 | #endif | ||
426 | 436 | ||
427 | if (!clip_viewport_rect(vp, &x, &y, &width, &height, &src_x, &src_y)) | 437 | if (!clip_viewport_rect(vp, &x, &y, &width, &height, &src_x, &src_y)) |
428 | return; | 438 | return; |
429 | 439 | ||
430 | /* initialize blending */ | ||
431 | BLEND_INIT; | ||
432 | |||
433 | /* the following drawmode combinations are possible: | ||
434 | * 1) COMPLEMENT: just negates the framebuffer contents | ||
435 | * 2) BG and BG+backdrop: draws _only_ background pixels with either | ||
436 | * the background color or the backdrop (if any). The backdrop | ||
437 | * is an image in native lcd format | ||
438 | * 3) FG and FG+image: draws _only_ foreground pixels with either | ||
439 | * the foreground color or an image buffer. The image is in | ||
440 | * native lcd format | ||
441 | * 4) SOLID, SOLID+backdrop, SOLID+image, SOLID+backdrop+image, i.e. all | ||
442 | * possible combinations of 2) and 3). Draws both, fore- and background, | ||
443 | * pixels. The rules of 2) and 3) apply. | ||
444 | * | ||
445 | * INVERSEVID swaps fore- and background pixels, i.e. background pixels | ||
446 | * become foreground ones and vice versa. | ||
447 | */ | ||
448 | if (drmode & DRMODE_INVERSEVID) | 440 | if (drmode & DRMODE_INVERSEVID) |
449 | { | 441 | { |
450 | dmask = 0xffffffff; | 442 | dmask = 0xFFFFFFFFu; |
451 | drmode &= DRMODE_SOLID; /* mask out inversevid */ | 443 | drmode &= ~DRMODE_INVERSEVID; |
452 | } | 444 | } |
453 | 445 | ||
454 | /* Use extra bits to avoid if () in the switch-cases below */ | ||
455 | if (image != NULL) | 446 | if (image != NULL) |
456 | drmode |= DRMODE_INT_IMG; | 447 | drmode |= DRMODE_INT_IMG; |
457 | 448 | ||
458 | if ((drmode & DRMODE_BG) && lcd_backdrop) | 449 | if ((drmode & DRMODE_BG) && lcd_backdrop) |
459 | drmode |= DRMODE_INT_BD; | 450 | drmode |= DRMODE_INT_BD; |
460 | 451 | ||
461 | dst_row = FBADDR(x, y); | ||
462 | |||
463 | int col, row = height; | ||
464 | unsigned data, pixels; | ||
465 | unsigned skip_end = (stride_src - width); | ||
466 | unsigned skip_start = src_y * stride_src + src_x; | ||
467 | unsigned skip_start_image = STRIDE_MAIN(src_y * stride_image + src_x, | ||
468 | src_x * stride_image + src_y); | ||
469 | |||
470 | #ifdef ALPHA_BITMAP_READ_WORDS | 452 | #ifdef ALPHA_BITMAP_READ_WORDS |
471 | uint32_t *src_w = (uint32_t *)((uintptr_t)src & ~3); | 453 | #define INIT_ALPHA() \ |
472 | skip_start += ALPHA_COLOR_PIXEL_PER_BYTE * ((uintptr_t)src & 3); | 454 | do { \ |
473 | src_w += skip_start / ALPHA_COLOR_PIXEL_PER_WORD; | 455 | alpha_offset = src_y * stride_alpha + src_x; \ |
474 | data = letoh32(*src_w++) ^ dmask; | 456 | } while(0) |
475 | pixels = skip_start % ALPHA_COLOR_PIXEL_PER_WORD; | 457 | #define START_ALPHA() \ |
458 | do { \ | ||
459 | size_t __byteskip = (uintptr_t)alpha % ALPHA_WORDSIZE; \ | ||
460 | size_t __byteoff = alpha_offset / ALPHA_PIXELS_PER_BYTE; \ | ||
461 | alpha_word = (ALPHA_WORD_T *)ALIGN_DOWN(alpha + __byteoff, ALPHA_WORDSIZE); \ | ||
462 | alpha_data = ALPHA_WORD_LOAD(alpha_word++) ^ dmask; \ | ||
463 | alpha_pixels = ((__byteoff + __byteskip) % ALPHA_WORDSIZE) * ALPHA_PIXELS_PER_BYTE; \ | ||
464 | alpha_pixels += alpha_offset % ALPHA_PIXELS_PER_BYTE; \ | ||
465 | alpha_data >>= alpha_pixels * ALPHA_BPP; \ | ||
466 | alpha_pixels = ALPHA_PIXELS_PER_WORD - alpha_pixels; \ | ||
467 | } while(0) | ||
468 | #define END_ALPHA() \ | ||
469 | do { \ | ||
470 | alpha_offset += stride_alpha; \ | ||
471 | } while(0) | ||
472 | #define READ_ALPHA() \ | ||
473 | ({ \ | ||
474 | if (alpha_pixels == 0) { \ | ||
475 | alpha_data = ALPHA_WORD_LOAD(alpha_word++) ^ dmask; \ | ||
476 | alpha_pixels = ALPHA_PIXELS_PER_WORD; \ | ||
477 | } \ | ||
478 | ALPHA_WORD_T __ret = alpha_data & ALPHA_MASK; \ | ||
479 | alpha_data >>= ALPHA_BPP; \ | ||
480 | alpha_pixels--; \ | ||
481 | __ret; \ | ||
482 | }) | ||
483 | #elif ALPHA_BPP == 4 | ||
484 | #define INIT_ALPHA() \ | ||
485 | do { \ | ||
486 | alpha_pixels = src_y * stride_alpha + src_x; \ | ||
487 | stride_alpha = stride_alpha - width; \ | ||
488 | alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \ | ||
489 | alpha_pixels &= 1; \ | ||
490 | if (alpha_pixels) { \ | ||
491 | alpha_data = *alpha++ ^ dmask; \ | ||
492 | alpha_data >>= ALPHA_BPP; \ | ||
493 | } \ | ||
494 | } while(0) | ||
495 | #define START_ALPHA() do { } while(0) | ||
496 | #define END_ALPHA() \ | ||
497 | do { \ | ||
498 | if (stride_alpha) { \ | ||
499 | alpha_pixels = stride_alpha - alpha_pixels; \ | ||
500 | alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \ | ||
501 | alpha_data = *alpha++ ^ dmask; \ | ||
502 | alpha_pixels &= 1; \ | ||
503 | if (alpha_pixels) \ | ||
504 | alpha_data >>= ALPHA_BPP; \ | ||
505 | } \ | ||
506 | } while(0) | ||
507 | #define READ_ALPHA() \ | ||
508 | ({ \ | ||
509 | if (alpha_pixels == 0) \ | ||
510 | alpha_data = *alpha++ ^ dmask; \ | ||
511 | unsigned char __ret = alpha_data & ALPHA_MASK; \ | ||
512 | alpha_data >>= ALPHA_BPP; \ | ||
513 | alpha_pixels ^= 1; \ | ||
514 | __ret; \ | ||
515 | }) | ||
476 | #else | 516 | #else |
477 | src += skip_start / ALPHA_COLOR_PIXEL_PER_BYTE; | 517 | #define INIT_ALPHA() \ |
478 | data = *src ^ dmask; | 518 | do { \ |
479 | pixels = skip_start % ALPHA_COLOR_PIXEL_PER_BYTE; | 519 | alpha_pixels = src_y * stride_alpha + src_x; \ |
480 | #endif | 520 | stride_alpha = stride_alpha - width; \ |
481 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | 521 | alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \ |
482 | #ifdef ALPHA_BITMAP_READ_WORDS | 522 | alpha_data = *alpha++ ^ dmask; \ |
483 | pixels = 8 - pixels; | 523 | alpha_pixels %= ALPHA_PIXELS_PER_BYTE; \ |
524 | alpha_data >>= ALPHA_BPP * alpha_pixels; \ | ||
525 | alpha_pixels = ALPHA_PIXELS_PER_BYTE - alpha_pixels; \ | ||
526 | } while(0) | ||
527 | #define START_ALPHA() do { } while(0) | ||
528 | #define END_ALPHA() \ | ||
529 | do { \ | ||
530 | if ((size_t)stride_alpha <= alpha_pixels) \ | ||
531 | alpha_pixels -= stride_alpha; \ | ||
532 | else { \ | ||
533 | alpha_pixels = stride_alpha - alpha_pixels; \ | ||
534 | alpha += alpha_pixels / ALPHA_PIXELS_PER_BYTE; \ | ||
535 | alpha_data = *alpha++ ^ dmask; \ | ||
536 | alpha_pixels %= ALPHA_PIXELS_PER_BYTE; \ | ||
537 | alpha_data >>= ALPHA_BPP * alpha_pixels; \ | ||
538 | alpha_pixels = ALPHA_PIXELS_PER_BYTE - alpha_pixels; \ | ||
539 | } \ | ||
540 | } while(0) | ||
541 | #define READ_ALPHA() \ | ||
542 | ({ \ | ||
543 | if (alpha_pixels == 0) { \ | ||
544 | alpha_data = *alpha++ ^ dmask; \ | ||
545 | alpha_pixels = ALPHA_PIXELS_PER_BYTE; \ | ||
546 | } \ | ||
547 | unsigned char __ret = alpha_data & ALPHA_MASK; \ | ||
548 | alpha_data >>= ALPHA_BPP; \ | ||
549 | alpha_pixels--; \ | ||
550 | __ret; \ | ||
551 | }) | ||
484 | #endif | 552 | #endif |
485 | 553 | ||
486 | /* image is only accessed in DRMODE_INT_IMG cases, i.e. when non-NULL. | 554 | dst = FBADDR(x, y); |
487 | * Therefore NULL accesses are impossible and we can increment | 555 | image += STRIDE_MAIN(src_y * stride_image + src_x, |
488 | * unconditionally (applies for stride at the end of the loop as well) */ | 556 | src_x * stride_image + src_y); |
489 | image += skip_start_image; | 557 | |
490 | /* go through the rows and update each pixel */ | 558 | INIT_ALPHA(); |
559 | BLEND_INIT; | ||
560 | |||
491 | do | 561 | do |
492 | { | 562 | { |
493 | /* saving lcd_current_viewport->fg/bg_pattern and lcd_backdrop_offset into these | 563 | intptr_t bo, io; |
494 | * temp vars just before the loop helps gcc to opimize the loop better | 564 | unsigned int fg, bg; |
495 | * (testing showed ~15% speedup) */ | 565 | int col = width; |
496 | unsigned fg, bg; | 566 | fb_data *dst_row = dst; |
497 | ptrdiff_t bo, img_offset; | 567 | |
498 | col = width; | 568 | START_ALPHA(); |
499 | dst = dst_row; | ||
500 | dst_row += ROW_INC; | ||
501 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
502 | #define UPDATE_SRC_ALPHA do { \ | ||
503 | if (--pixels) \ | ||
504 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
505 | else \ | ||
506 | { \ | ||
507 | data = letoh32(*src_w++) ^ dmask; \ | ||
508 | pixels = ALPHA_COLOR_PIXEL_PER_WORD; \ | ||
509 | } \ | ||
510 | } while (0) | ||
511 | #elif ALPHA_COLOR_PIXEL_PER_BYTE == 2 | ||
512 | #define UPDATE_SRC_ALPHA do { \ | ||
513 | if (pixels ^= 1) \ | ||
514 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
515 | else \ | ||
516 | data = *(++src) ^ dmask; \ | ||
517 | } while (0) | ||
518 | #else | ||
519 | #define UPDATE_SRC_ALPHA do { \ | ||
520 | if (pixels = (++pixels % ALPHA_COLOR_PIXEL_PER_BYTE)) \ | ||
521 | data >>= ALPHA_COLOR_LOOKUP_SHIFT; \ | ||
522 | else \ | ||
523 | data = *(++src) ^ dmask; \ | ||
524 | } while (0) | ||
525 | #endif | ||
526 | 569 | ||
527 | switch (drmode) | 570 | switch (drmode) |
528 | { | 571 | { |
529 | case DRMODE_COMPLEMENT: | 572 | case DRMODE_COMPLEMENT: |
530 | do | 573 | do |
531 | { | 574 | { |
532 | *dst = blend_two_colors(*dst, ~(*dst), | 575 | *dst = blend_two_colors(*dst, ~(*dst), READ_ALPHA()); |
533 | data & ALPHA_COLOR_LOOKUP_SIZE ); | 576 | dst += COL_INC; |
534 | dst += COL_INC; | 577 | } while (--col); |
535 | UPDATE_SRC_ALPHA; | 578 | break; |
536 | } | 579 | case DRMODE_BG|DRMODE_INT_BD: |
537 | while (--col); | 580 | bo = lcd_backdrop_offset; |
538 | break; | 581 | do |
539 | case DRMODE_BG|DRMODE_INT_BD: | ||
540 | bo = lcd_backdrop_offset; | ||
541 | do | ||
542 | { | ||
543 | fb_data c = *(fb_data *)((uintptr_t)dst + bo); | ||
544 | *dst = blend_two_colors(c, *dst, data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
545 | dst += COL_INC; | ||
546 | image += STRIDE_MAIN(1, stride_image); | ||
547 | UPDATE_SRC_ALPHA; | ||
548 | } | ||
549 | while (--col); | ||
550 | break; | ||
551 | case DRMODE_BG: | ||
552 | bg = vp->bg_pattern; | ||
553 | do | ||
554 | { | ||
555 | *dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
556 | dst += COL_INC; | ||
557 | UPDATE_SRC_ALPHA; | ||
558 | } | ||
559 | while (--col); | ||
560 | break; | ||
561 | case DRMODE_FG|DRMODE_INT_IMG: | ||
562 | img_offset = image - dst; | ||
563 | do | ||
564 | { | ||
565 | *dst = blend_two_colors(*dst, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
566 | dst += COL_INC; | ||
567 | UPDATE_SRC_ALPHA; | ||
568 | } | ||
569 | while (--col); | ||
570 | break; | ||
571 | case DRMODE_FG: | ||
572 | fg = vp->fg_pattern; | ||
573 | do | ||
574 | { | ||
575 | *dst = blend_two_colors(*dst, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
576 | dst += COL_INC; | ||
577 | UPDATE_SRC_ALPHA; | ||
578 | } | ||
579 | while (--col); | ||
580 | break; | ||
581 | case DRMODE_SOLID|DRMODE_INT_BD: | ||
582 | bo = lcd_backdrop_offset; | ||
583 | fg = vp->fg_pattern; | ||
584 | do | ||
585 | { | ||
586 | fb_data *c = (fb_data *)((uintptr_t)dst + bo); | ||
587 | *dst = blend_two_colors(*c, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
588 | dst += COL_INC; | ||
589 | UPDATE_SRC_ALPHA; | ||
590 | } | ||
591 | while (--col); | ||
592 | break; | ||
593 | case DRMODE_SOLID|DRMODE_INT_IMG: | ||
594 | bg = vp->bg_pattern; | ||
595 | img_offset = image - dst; | ||
596 | do | ||
597 | { | ||
598 | *dst = blend_two_colors(bg, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
599 | dst += COL_INC; | ||
600 | UPDATE_SRC_ALPHA; | ||
601 | } | ||
602 | while (--col); | ||
603 | break; | ||
604 | case DRMODE_SOLID|DRMODE_INT_BD|DRMODE_INT_IMG: | ||
605 | bo = lcd_backdrop_offset; | ||
606 | img_offset = image - dst; | ||
607 | do | ||
608 | { | ||
609 | fb_data *c = (fb_data *)((uintptr_t)dst + bo); | ||
610 | *dst = blend_two_colors(*c, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
611 | dst += COL_INC; | ||
612 | UPDATE_SRC_ALPHA; | ||
613 | } | ||
614 | while (--col); | ||
615 | break; | ||
616 | case DRMODE_SOLID: | ||
617 | bg = vp->bg_pattern; | ||
618 | fg = vp->fg_pattern; | ||
619 | do | ||
620 | { | ||
621 | *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE ); | ||
622 | dst += COL_INC; | ||
623 | UPDATE_SRC_ALPHA; | ||
624 | } | ||
625 | while (--col); | ||
626 | break; | ||
627 | } | ||
628 | #ifdef ALPHA_BITMAP_READ_WORDS | ||
629 | if (skip_end < pixels) | ||
630 | { | ||
631 | pixels -= skip_end; | ||
632 | data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; | ||
633 | } else { | ||
634 | pixels = skip_end - pixels; | ||
635 | src_w += pixels / ALPHA_COLOR_PIXEL_PER_WORD; | ||
636 | pixels %= ALPHA_COLOR_PIXEL_PER_WORD; | ||
637 | data = letoh32(*src_w++) ^ dmask; | ||
638 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | ||
639 | pixels = 8 - pixels; | ||
640 | } | ||
641 | #else | ||
642 | if (skip_end) | ||
643 | { | ||
644 | pixels += skip_end; | ||
645 | if (pixels >= ALPHA_COLOR_PIXEL_PER_BYTE) | ||
646 | { | 582 | { |
647 | src += pixels / ALPHA_COLOR_PIXEL_PER_BYTE; | 583 | *dst = blend_two_colors(*PTR_ADD(dst, bo), *dst, READ_ALPHA()); |
648 | pixels %= ALPHA_COLOR_PIXEL_PER_BYTE; | 584 | dst += COL_INC; |
649 | data = *src ^ dmask; | 585 | } while (--col); |
650 | data >>= pixels * ALPHA_COLOR_LOOKUP_SHIFT; | 586 | break; |
651 | } else | 587 | case DRMODE_BG: |
652 | data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; | 588 | bg = vp->bg_pattern; |
589 | do | ||
590 | { | ||
591 | *dst = blend_two_colors(bg, *dst, READ_ALPHA()); | ||
592 | dst += COL_INC; | ||
593 | } while (--col); | ||
594 | break; | ||
595 | case DRMODE_FG|DRMODE_INT_IMG: | ||
596 | io = image - dst; | ||
597 | do | ||
598 | { | ||
599 | *dst = blend_two_colors(*dst, *(dst + io), READ_ALPHA()); | ||
600 | dst += COL_INC; | ||
601 | } while (--col); | ||
602 | break; | ||
603 | case DRMODE_FG: | ||
604 | fg = vp->fg_pattern; | ||
605 | do | ||
606 | { | ||
607 | *dst = blend_two_colors(*dst, fg, READ_ALPHA()); | ||
608 | dst += COL_INC; | ||
609 | } while (--col); | ||
610 | break; | ||
611 | case DRMODE_SOLID|DRMODE_INT_BD: | ||
612 | fg = vp->fg_pattern; | ||
613 | bo = lcd_backdrop_offset; | ||
614 | do | ||
615 | { | ||
616 | *dst = blend_two_colors(*PTR_ADD(dst, bo), fg, READ_ALPHA()); | ||
617 | dst += COL_INC; | ||
618 | } while (--col); | ||
619 | break; | ||
620 | case DRMODE_SOLID|DRMODE_INT_IMG: | ||
621 | bg = vp->bg_pattern; | ||
622 | io = image - dst; | ||
623 | do | ||
624 | { | ||
625 | *dst = blend_two_colors(bg, *(dst + io), READ_ALPHA()); | ||
626 | dst += COL_INC; | ||
627 | } while (--col); | ||
628 | break; | ||
629 | case DRMODE_SOLID|DRMODE_INT_BD|DRMODE_INT_IMG: | ||
630 | bo = lcd_backdrop_offset; | ||
631 | io = image - dst; | ||
632 | do | ||
633 | { | ||
634 | *dst = blend_two_colors(*PTR_ADD(dst, bo), *(dst + io), READ_ALPHA()); | ||
635 | dst += COL_INC; | ||
636 | } while (--col); | ||
637 | break; | ||
638 | case DRMODE_SOLID: | ||
639 | fg = vp->fg_pattern; | ||
640 | bg = vp->bg_pattern; | ||
641 | do | ||
642 | { | ||
643 | *dst = blend_two_colors(bg, fg, READ_ALPHA()); | ||
644 | dst += COL_INC; | ||
645 | } while (--col); | ||
646 | break; | ||
653 | } | 647 | } |
654 | #endif | ||
655 | 648 | ||
656 | image += STRIDE_MAIN(stride_image,1); | 649 | END_ALPHA(); |
657 | } while (--row); | 650 | image += STRIDE_MAIN(stride_image, 1); |
651 | dst = dst_row + ROW_INC; | ||
652 | } while (--height); | ||
658 | 653 | ||
659 | BLEND_FINISH; | 654 | BLEND_FINISH; |
660 | } | 655 | } |