summaryrefslogtreecommitdiff
path: root/firmware/drivers
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2013-12-28 14:27:18 +0100
committerThomas Martitz <kugel@rockbox.org>2014-01-05 19:35:23 +0100
commita17a7038c265d3bd6b5399f77c4caa4edfc67df7 (patch)
tree9adf8a2713a24b7bba68fe5a0cd5de3ed9204471 /firmware/drivers
parent17a1867c9ca8f22c5e2f2bb6b8228cad273527a9 (diff)
downloadrockbox-a17a7038c265d3bd6b5399f77c4caa4edfc67df7.tar.gz
rockbox-a17a7038c265d3bd6b5399f77c4caa4edfc67df7.zip
lcd: Fix certain drawmode combinations.
Some seldomly used drawmode combinations did not work in conjunction with alpha bitmaps and backdrops. Now all should work (see comment added) by using more bits. Change-Id: I2bc96ecf471fa8c1a608a321a235b9c8527b3dc5
Diffstat (limited to 'firmware/drivers')
-rw-r--r--firmware/drivers/lcd-16bit-common.c96
1 files changed, 62 insertions, 34 deletions
diff --git a/firmware/drivers/lcd-16bit-common.c b/firmware/drivers/lcd-16bit-common.c
index dffc1cf075..99cbe489fc 100644
--- a/firmware/drivers/lcd-16bit-common.c
+++ b/firmware/drivers/lcd-16bit-common.c
@@ -623,7 +623,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
623 623
624 /* Use extra bit to avoid if () in the switch-cases below */ 624 /* Use extra bit to avoid if () in the switch-cases below */
625 if ((drmode & DRMODE_BG) && lcd_backdrop) 625 if ((drmode & DRMODE_BG) && lcd_backdrop)
626 drmode |= DRMODE_INT_MOD; 626 drmode |= DRMODE_INT_BD;
627 627
628 /* go through each column and update each pixel */ 628 /* go through each column and update each pixel */
629 do 629 do
@@ -659,7 +659,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
659 while (--row); 659 while (--row);
660 break; 660 break;
661 661
662 case DRMODE_BG|DRMODE_INT_MOD: 662 case DRMODE_BG|DRMODE_INT_BD:
663 bo = lcd_backdrop_offset; 663 bo = lcd_backdrop_offset;
664 do 664 do
665 { 665 {
@@ -698,7 +698,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
698 while (--row); 698 while (--row);
699 break; 699 break;
700 700
701 case DRMODE_SOLID|DRMODE_INT_MOD: 701 case DRMODE_SOLID|DRMODE_INT_BD:
702 fg = current_vp->fg_pattern; 702 fg = current_vp->fg_pattern;
703 bo = lcd_backdrop_offset; 703 bo = lcd_backdrop_offset;
704 do 704 do
@@ -817,7 +817,6 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
817 int stride_image, int stride_src) 817 int stride_image, int stride_src)
818{ 818{
819 fb_data *dst, *dst_row; 819 fb_data *dst, *dst_row;
820 const fb_data *image_row;
821 unsigned dmask = 0x00000000; 820 unsigned dmask = 0x00000000;
822 int drmode = current_vp->drawmode; 821 int drmode = current_vp->drawmode;
823 /* nothing to draw? */ 822 /* nothing to draw? */
@@ -878,21 +877,33 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
878 height = LCD_HEIGHT - y; 877 height = LCD_HEIGHT - y;
879#endif 878#endif
880 879
880 /* the following drawmode combinations are possible:
881 * 1) COMPLEMENT: just negates the framebuffer contents
882 * 2) BG and BG+backdrop: draws _only_ background pixels with either
883 * the background color or the backdrop (if any). The backdrop
884 * is an image in native lcd format
885 * 3) FG and FG+image: draws _only_ foreground pixels with either
886 * the foreground color or an image buffer. The image is in
887 * native lcd format
888 * 4) SOLID, SOLID+backdrop, SOLID+image, SOLID+backdrop+image, i.e. all
889 * possible combinations of 2) and 3). Draws both, fore- and background,
890 * pixels. The rules of 2) and 3) apply.
891 *
892 * INVERSEVID swaps fore- and background pixels, i.e. background pixels
893 * become foreground ones and vice versa.
894 */
881 if (drmode & DRMODE_INVERSEVID) 895 if (drmode & DRMODE_INVERSEVID)
882 { 896 {
883 dmask = 0xffffffff; 897 dmask = 0xffffffff;
884 drmode &= DRMODE_SOLID; /* mask out inversevid */ 898 drmode &= DRMODE_SOLID; /* mask out inversevid */
885 } 899 }
886 if (drmode == DRMODE_BG) 900
887 dmask = ~dmask; 901 /* Use extra bits to avoid if () in the switch-cases below */
888 /* If drawmode is FG use a separate special case that blends the image
889 * onto the current framebuffer contents. Otherwise BG is forced that
890 * blends the image with the backdrop (if any, otherwise background color )*/
891 if (image != NULL) 902 if (image != NULL)
892 drmode = (drmode == DRMODE_FG) ? DRMODE_FG|DRMODE_INT_MOD : DRMODE_BG; 903 drmode |= DRMODE_INT_IMG;
893 /* Use extra bit to avoid if () in the switch-cases below */ 904
894 if ((drmode & DRMODE_BG) && lcd_backdrop) 905 if ((drmode & DRMODE_BG) && lcd_backdrop)
895 drmode |= DRMODE_INT_MOD; 906 drmode |= DRMODE_INT_BD;
896 907
897 dst_row = FBADDR(x, y); 908 dst_row = FBADDR(x, y);
898 909
@@ -918,10 +929,11 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
918#ifdef ALPHA_BITMAP_READ_WORDS 929#ifdef ALPHA_BITMAP_READ_WORDS
919 pixels = 8 - pixels; 930 pixels = 8 - pixels;
920#endif 931#endif
921 if (image)
922 image += skip_start_image;
923 image_row = image;
924 932
933 /* image is only accessed in DRMODE_INT_IMG cases, i.e. when non-NULL.
934 * Therefore NULL accesses are impossible and we can increment
935 * unconditionally (applies for stride at the end of the loop as well) */
936 image += skip_start_image;
925 /* go through the rows and update each pixel */ 937 /* go through the rows and update each pixel */
926 do 938 do
927 { 939 {
@@ -929,16 +941,10 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
929 * temp vars just before the loop helps gcc to opimize the loop better 941 * temp vars just before the loop helps gcc to opimize the loop better
930 * (testing showed ~15% speedup) */ 942 * (testing showed ~15% speedup) */
931 unsigned fg, bg; 943 unsigned fg, bg;
932 uintptr_t bo; 944 ptrdiff_t bo, img_offset;
933 col = width; 945 col = width;
934 dst = dst_row; 946 dst = dst_row;
935 dst_row += ROW_INC; 947 dst_row += ROW_INC;
936 if (image_row) {
937 image = image_row;
938 image_row += STRIDE_MAIN(stride_image,1);
939 }
940 else
941 image = dst;
942#ifdef ALPHA_BITMAP_READ_WORDS 948#ifdef ALPHA_BITMAP_READ_WORDS
943#define UPDATE_SRC_ALPHA do { \ 949#define UPDATE_SRC_ALPHA do { \
944 if (--pixels) \ 950 if (--pixels) \
@@ -964,8 +970,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
964 data = *(++src) ^ dmask; \ 970 data = *(++src) ^ dmask; \
965 } while (0) 971 } while (0)
966#endif 972#endif
967 /* we don't want to have this in our inner 973
968 * loop and the codesize increase is minimal */
969 switch (drmode) 974 switch (drmode)
970 { 975 {
971 case DRMODE_COMPLEMENT: 976 case DRMODE_COMPLEMENT:
@@ -978,12 +983,12 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
978 } 983 }
979 while (--col); 984 while (--col);
980 break; 985 break;
981 case DRMODE_BG|DRMODE_INT_MOD: 986 case DRMODE_BG|DRMODE_INT_BD:
982 bo = lcd_backdrop_offset; 987 bo = lcd_backdrop_offset;
983 do 988 do
984 { 989 {
985 fb_data c = *(fb_data *)((uintptr_t)dst + bo); 990 fb_data c = *(fb_data *)((uintptr_t)dst + bo);
986 *dst = blend_two_colors(c, *image, data & ALPHA_COLOR_LOOKUP_SIZE ); 991 *dst = blend_two_colors(c, *dst, data & ALPHA_COLOR_LOOKUP_SIZE );
987 dst += COL_INC; 992 dst += COL_INC;
988 image += STRIDE_MAIN(1, stride_image); 993 image += STRIDE_MAIN(1, stride_image);
989 UPDATE_SRC_ALPHA; 994 UPDATE_SRC_ALPHA;
@@ -994,19 +999,18 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
994 bg = current_vp->bg_pattern; 999 bg = current_vp->bg_pattern;
995 do 1000 do
996 { 1001 {
997 *dst = blend_two_colors(bg, *image, data & ALPHA_COLOR_LOOKUP_SIZE ); 1002 *dst = blend_two_colors(bg, *dst, data & ALPHA_COLOR_LOOKUP_SIZE );
998 dst += COL_INC; 1003 dst += COL_INC;
999 image += STRIDE_MAIN(1, stride_image);
1000 UPDATE_SRC_ALPHA; 1004 UPDATE_SRC_ALPHA;
1001 } 1005 }
1002 while (--col); 1006 while (--col);
1003 break; 1007 break;
1004 case DRMODE_FG|DRMODE_INT_MOD: 1008 case DRMODE_FG|DRMODE_INT_IMG:
1009 img_offset = image - dst;
1005 do 1010 do
1006 { 1011 {
1007 *dst = blend_two_colors(*dst, *image, data & ALPHA_COLOR_LOOKUP_SIZE ); 1012 *dst = blend_two_colors(*dst, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
1008 dst += COL_INC; 1013 dst += COL_INC;
1009 image += STRIDE_MAIN(1, stride_image);
1010 UPDATE_SRC_ALPHA; 1014 UPDATE_SRC_ALPHA;
1011 } 1015 }
1012 while (--col); 1016 while (--col);
@@ -1021,7 +1025,7 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
1021 } 1025 }
1022 while (--col); 1026 while (--col);
1023 break; 1027 break;
1024 case DRMODE_SOLID|DRMODE_INT_MOD: 1028 case DRMODE_SOLID|DRMODE_INT_BD:
1025 bo = lcd_backdrop_offset; 1029 bo = lcd_backdrop_offset;
1026 fg = current_vp->fg_pattern; 1030 fg = current_vp->fg_pattern;
1027 do 1031 do
@@ -1033,13 +1037,35 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
1033 } 1037 }
1034 while (--col); 1038 while (--col);
1035 break; 1039 break;
1040 case DRMODE_SOLID|DRMODE_INT_IMG:
1041 bg = current_vp->bg_pattern;
1042 img_offset = image - dst;
1043 do
1044 {
1045 *dst = blend_two_colors(bg, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
1046 dst += COL_INC;
1047 UPDATE_SRC_ALPHA;
1048 }
1049 while (--col);
1050 break;
1051 case DRMODE_SOLID|DRMODE_INT_BD|DRMODE_INT_IMG:
1052 bo = lcd_backdrop_offset;
1053 img_offset = image - dst;
1054 do
1055 {
1056 fb_data *c = (fb_data *)((uintptr_t)dst + bo);
1057 *dst = blend_two_colors(*c, *(dst + img_offset), data & ALPHA_COLOR_LOOKUP_SIZE );
1058 dst += COL_INC;
1059 UPDATE_SRC_ALPHA;
1060 }
1061 while (--col);
1062 break;
1036 case DRMODE_SOLID: 1063 case DRMODE_SOLID:
1037 bg = current_vp->bg_pattern; 1064 bg = current_vp->bg_pattern;
1038 fg = current_vp->fg_pattern; 1065 fg = current_vp->fg_pattern;
1039 do 1066 do
1040 { 1067 {
1041 *dst = blend_two_colors(bg, fg, 1068 *dst = blend_two_colors(bg, fg, data & ALPHA_COLOR_LOOKUP_SIZE );
1042 data & ALPHA_COLOR_LOOKUP_SIZE );
1043 dst += COL_INC; 1069 dst += COL_INC;
1044 UPDATE_SRC_ALPHA; 1070 UPDATE_SRC_ALPHA;
1045 } 1071 }
@@ -1073,6 +1099,8 @@ static void ICODE_ATTR lcd_alpha_bitmap_part_mix(const fb_data* image,
1073 data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT; 1099 data >>= skip_end * ALPHA_COLOR_LOOKUP_SHIFT;
1074 } 1100 }
1075#endif 1101#endif
1102
1103 image += STRIDE_MAIN(stride_image,1);
1076 } while (--row); 1104 } while (--row);
1077 1105
1078 BLEND_FINISH; 1106 BLEND_FINISH;