summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2009-06-01 21:28:03 +0000
committerJens Arnold <amiconn@rockbox.org>2009-06-01 21:28:03 +0000
commitc1d27d105c3333b5df67c97d88885efa2a49bc9a (patch)
tree143ea17a46fe2a4bc86386ffa381d9c9f8249029
parentaa7d43f7a61998080be228f94aa3d26b5c1dfbc5 (diff)
downloadrockbox-c1d27d105c3333b5df67c97d88885efa2a49bc9a.tar.gz
rockbox-c1d27d105c3333b5df67c97d88885efa2a49bc9a.zip
Speed up mono bitmap drawing on horizontally packed greyscale targets (greyscale iPods). Average speedup is 80% on PP5002, and 55% on PP502x. * Simplify mono bitmap drawing in the 16 bit driver and the greylib a bit, also giving a slight speedup (3% on PP502x, 1.5% on coldfire).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21163 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/lib/grey_draw.c3
-rw-r--r--firmware/drivers/lcd-16bit.c3
-rw-r--r--firmware/drivers/lcd-2bit-horz.c148
3 files changed, 124 insertions, 30 deletions
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c
index c1e6376cfe..3b81694426 100644
--- a/apps/plugins/lib/grey_draw.c
+++ b/apps/plugins/lib/grey_draw.c
@@ -447,6 +447,7 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
447 src_end = src + width; 447 src_end = src + width;
448 dwidth = _grey_info.width; 448 dwidth = _grey_info.width;
449 dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x]; 449 dst = &_grey_info.buffer[_GREY_MULUQ(dwidth, y) + x];
450 dst_end = dst + _GREY_MULUQ(dwidth, height);
450 451
451 if (drmode & DRMODE_INVERSEVID) 452 if (drmode & DRMODE_INVERSEVID)
452 { 453 {
@@ -461,8 +462,6 @@ void grey_mono_bitmap_part(const unsigned char *src, int src_x, int src_y,
461 unsigned data = (*src_col ^ dmask) >> src_y; 462 unsigned data = (*src_col ^ dmask) >> src_y;
462 int fg, bg; 463 int fg, bg;
463 464
464 dst_end = dst_col + _GREY_MULUQ(dwidth, height);
465
466#define UPDATE_SRC do { \ 465#define UPDATE_SRC do { \
467 data >>= 1; \ 466 data >>= 1; \
468 if (data == 0x001) { \ 467 if (data == 0x001) { \
diff --git a/firmware/drivers/lcd-16bit.c b/firmware/drivers/lcd-16bit.c
index 0aa62f66b4..ef0865fc8c 100644
--- a/firmware/drivers/lcd-16bit.c
+++ b/firmware/drivers/lcd-16bit.c
@@ -752,6 +752,7 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
752 src_y &= 7; 752 src_y &= 7;
753 src_end = src + width; 753 src_end = src + width;
754 dst = LCDADDR(current_vp->x + x, current_vp->y + y); 754 dst = LCDADDR(current_vp->x + x, current_vp->y + y);
755 dst_end = dst + height * LCD_WIDTH;
755 756
756 if (drmode & DRMODE_INVERSEVID) 757 if (drmode & DRMODE_INVERSEVID)
757 { 758 {
@@ -767,8 +768,6 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
767 int fg, bg; 768 int fg, bg;
768 long bo; 769 long bo;
769 770
770 dst_end = dst_col + height * LCD_WIDTH;
771
772#define UPDATE_SRC do { \ 771#define UPDATE_SRC do { \
773 data >>= 1; \ 772 data >>= 1; \
774 if (data == 0x001) { \ 773 if (data == 0x001) { \
diff --git a/firmware/drivers/lcd-2bit-horz.c b/firmware/drivers/lcd-2bit-horz.c
index 4dc82deae0..70f7261e35 100644
--- a/firmware/drivers/lcd-2bit-horz.c
+++ b/firmware/drivers/lcd-2bit-horz.c
@@ -690,10 +690,11 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
690 int src_y, int stride, int x, int y, 690 int src_y, int stride, int x, int y,
691 int width, int height) 691 int width, int height)
692{ 692{
693 int ny, nx, ymax; 693 const unsigned char *src_end;
694 const unsigned char * src_end; 694 fb_data *dst, *dst_end;
695 lcd_pixelfunc_type* fgfunc; 695 unsigned dmask = 0x100; /* bit 8 == sentinel */
696 lcd_pixelfunc_type* bgfunc; 696 unsigned dst_mask;
697 int drmode = current_vp->drawmode;
697 698
698 /* nothing to draw? */ 699 /* nothing to draw? */
699 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) || 700 if ((width <= 0) || (height <= 0) || (x >= current_vp->width) ||
@@ -718,42 +719,137 @@ void ICODE_ATTR lcd_mono_bitmap_part(const unsigned char *src, int src_x,
718 if (y + height > current_vp->height) 719 if (y + height > current_vp->height)
719 height = current_vp->height - y; 720 height = current_vp->height - y;
720 721
721 /* adjust for viewport */
722 x += current_vp->x;
723 y += current_vp->y;
724
725 src += stride * (src_y >> 3) + src_x; /* move starting point */ 722 src += stride * (src_y >> 3) + src_x; /* move starting point */
726 src_y &= 7; 723 src_y &= 7;
727 src_end = src + width; 724 src_end = src + width;
725 x += current_vp->x; /* adjust for viewport */
726 dst = &lcd_framebuffer[current_vp->y + y][x >> 2];
727 dst_end = dst + height * LCD_FBWIDTH;
728 dst_mask = pixmask[x & 3];
729
730 if (drmode & DRMODE_INVERSEVID)
731 {
732 dmask = 0x1ff; /* bit 8 == sentinel */
733 drmode &= DRMODE_SOLID; /* mask out inversevid */
734 }
728 735
729 fgfunc = lcd_pixelfuncs[current_vp->drawmode];
730 bgfunc = lcd_pixelfuncs[current_vp->drawmode ^ DRMODE_INVERSEVID];
731 nx = x;
732 do 736 do
733 { 737 {
734 const unsigned char *src_col = src++; 738 const unsigned char *src_col = src++;
735 unsigned data = (*src_col | 0x100) >> src_y; /* bit 8 == sentinel */ 739 unsigned data = (*src_col ^ dmask) >> src_y;
736 740 fb_data *dst_col = dst;
737 ymax = y + height; 741 int fg, bg;
738 ny = y; 742 long bo;
739 do 743
744#define UPDATE_SRC do { \
745 data >>= 1; \
746 if (data == 0x001) { \
747 src_col += stride; \
748 data = *src_col ^ dmask; \
749 } \
750 } while (0)
751
752 switch (drmode)
740 { 753 {
741 if (data & 0x01) 754 case DRMODE_COMPLEMENT:
742 fgfunc(nx,ny); 755 do
756 {
757 if (data & 0x01)
758 *dst_col ^= dst_mask;
759
760 dst_col += LCD_FBWIDTH;
761 UPDATE_SRC;
762 }
763 while (dst_col < dst_end);
764 break;
765
766 case DRMODE_BG:
767 if (lcd_backdrop)
768 {
769 bo = lcd_backdrop_offset;
770 do
771 {
772 if (!(data & 0x01))
773 {
774 unsigned block = *dst_col;
775 *dst_col = block
776 ^ ((block ^ *(dst_col + bo)) & dst_mask);
777 }
778 dst_col += LCD_FBWIDTH;
779 UPDATE_SRC;
780 }
781 while (dst_col < dst_end);
782 }
743 else 783 else
744 bgfunc(nx,ny); 784 {
785 bg = bg_pattern;
786 do
787 {
788 if (!(data & 0x01))
789 {
790 unsigned block = *dst_col;
791 *dst_col = block ^ ((block ^ bg) & dst_mask);
792 }
793 dst_col += LCD_FBWIDTH;
794 UPDATE_SRC;
795 }
796 while (dst_col < dst_end);
797 }
798 break;
745 799
746 ny++; 800 case DRMODE_FG:
801 fg = fg_pattern;
802 do
803 {
804 if (data & 0x01)
805 {
806 unsigned block = *dst_col;
807 *dst_col = block ^ ((block ^ fg) & dst_mask);
808 }
809 dst_col += LCD_FBWIDTH;
810 UPDATE_SRC;
811 }
812 while (dst_col < dst_end);
813 break;
747 814
748 data >>= 1; 815 case DRMODE_SOLID:
749 if (data == 0x001) 816 fg = fg_pattern;
817 if (lcd_backdrop)
818 {
819 bo = lcd_backdrop_offset;
820 do
821 {
822 unsigned block = *dst_col;
823 *dst_col = block ^ ((block ^ ((data & 0x01) ?
824 fg : *(dst_col + bo))) & dst_mask);
825
826 dst_col += LCD_FBWIDTH;
827 UPDATE_SRC;
828 }
829 while (dst_col < dst_end);
830 }
831 else
750 { 832 {
751 src_col += stride; 833 bg = bg_pattern;
752 data = *src_col | 0x100; 834 do
835 {
836 unsigned block = *dst_col;
837 *dst_col = block ^ ((block ^ ((data & 0x01) ?
838 fg : bg)) & dst_mask);
839
840 dst_col += LCD_FBWIDTH;
841 UPDATE_SRC;
842 }
843 while (dst_col < dst_end);
753 } 844 }
845 break;
846 }
847 dst_mask >>= 2;
848 if (dst_mask == 0)
849 {
850 dst++;
851 dst_mask = 0xC0;
754 } 852 }
755 while (ny < ymax);
756 nx++;
757 } 853 }
758 while (src < src_end); 854 while (src < src_end);
759} 855}