summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJens Arnold <amiconn@rockbox.org>2008-03-02 17:05:00 +0000
committerJens Arnold <amiconn@rockbox.org>2008-03-02 17:05:00 +0000
commit52e1f815994413aa6068b13367ca0d04d9246182 (patch)
treeebae13e1b8e1931eac2faf7920ccbd6d4f0690d1
parent1509faf618641a5dd1e8b33e0c1617dc521aa27c (diff)
downloadrockbox-52e1f815994413aa6068b13367ca0d04d9246182.tar.gz
rockbox-52e1f815994413aa6068b13367ca0d04d9246182.zip
Greyscale library: Assembler optimised update for coldfire, ~73% speedup when using IRAM, ~35% speedup without IRAM. Slight optimisation for other targets as well.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16482 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/plugins/lib/Makefile3
-rw-r--r--apps/plugins/lib/SOURCES3
-rwxr-xr-xapps/plugins/lib/grey_coldfire.S128
-rw-r--r--apps/plugins/lib/grey_draw.c19
4 files changed, 149 insertions, 4 deletions
diff --git a/apps/plugins/lib/Makefile b/apps/plugins/lib/Makefile
index 39f1743f7a..c75cca1be9 100644
--- a/apps/plugins/lib/Makefile
+++ b/apps/plugins/lib/Makefile
@@ -29,7 +29,8 @@ endif
29include $(TOOLSDIR)/makesrc.inc 29include $(TOOLSDIR)/makesrc.inc
30 30
31SOURCES = $(SRC) 31SOURCES = $(SRC)
32OBJS := $(SRC:%.c=$(OBJDIR)/%.o) 32OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
33OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
33DEPFILE = $(OBJDIR)/dep-pluginlib 34DEPFILE = $(OBJDIR)/dep-pluginlib
34DIRS = . 35DIRS = .
35 36
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index c1f5a483f2..b638740b0e 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -8,6 +8,9 @@ grey_core.c
8grey_draw.c 8grey_draw.c
9grey_parm.c 9grey_parm.c
10grey_scroll.c 10grey_scroll.c
11#ifdef CPU_COLDFIRE
12grey_coldfire.S
13#endif
11#endif 14#endif
12highscore.c 15highscore.c
13#ifndef SIMULATOR 16#ifndef SIMULATOR
diff --git a/apps/plugins/lib/grey_coldfire.S b/apps/plugins/lib/grey_coldfire.S
new file mode 100755
index 0000000000..cf66ca66b6
--- /dev/null
+++ b/apps/plugins/lib/grey_coldfire.S
@@ -0,0 +1,128 @@
1/***************************************************************************
2* __________ __ ___.
3* Open \______ \ ____ ____ | | _\_ |__ _______ ___
4* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7* \/ \/ \/ \/ \/
8* $Id: grey_draw.c 16080 2008-01-13 18:39:09Z amiconn $
9*
10* New greyscale framework
11* Coldfire assembler routines
12*
13* This is a generic framework to display 129 shades of grey on low-depth
14* bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins.
15*
16* Copyright (C) 2008 Jens Arnold
17*
18* All files in this archive are subject to the GNU General Public License.
19* See the file COPYING in the source tree root for full license agreement.
20*
21* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
22* KIND, either express or implied.
23*
24****************************************************************************/
25
26#include "config.h"
27/* Plugins should not normally do this, but we need to check a macro, and
28 * plugin.h would confuse the assembler. */
29
30 .text
31 .global _grey_line1
32 .type _grey_line1, @function
33
34#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2)
35
36/****************************************************************************
37 * void _grey_line1(int width,
38 * unsigned char *dst,
39 * const unsigned char *src,
40 * const unsigned char *lut);
41 */
42
43_grey_line1:
44 lea.l (-2*4, %sp), %sp
45 movem.l %d2/%a2, (%sp)
46 movem.l (2*4+4, %sp), %d2/%a0-%a2
47 clr.l %d0
48
49 move.l %a1, %d1
50 and.l #1, %d1
51 beq.s .p1_h_end
52
53 move.b (%a1)+, %d0
54 move.b (%d0.l, %a2), (%a0)
55 addq.l #4, %a0
56 subq.l #1, %d2
57.p1_h_end:
58
59 cmp.l #2, %d2
60 blo.s .p2_t_end
61 move.l %a1, %d1
62 and.l #2, %d1
63 beq.s .p2_h_end
64
65 move.w (%a1)+, %d1
66 move.w %d1, %d0
67 lsr.l #8, %d0
68 move.b (%d0.l, %a2), (%a0)
69 addq.l #4, %a0
70 move.b %d1, %d0
71 move.b (%d0.l, %a2), (%a0)
72 addq.l #4, %a0
73 subq.l #2, %d2
74.p2_h_end:
75
76 subq.l #4, %d2
77 blo.s .p4_end
78
79.p4_loop:
80 move.l (%a1)+, %d1
81 swap %d1
82 move.w %d1, %d0
83 lsr.l #8, %d0
84 move.b (%d0.l, %a2), (%a0)
85 addq.l #4, %a0
86 move.b %d1, %d0
87 move.b (%d0.l, %a2), (%a0)
88 addq.l #4, %a0
89 swap %d1
90 move.w %d1, %d0
91 lsr.l #8, %d0
92 move.b (%d0.l, %a2), (%a0)
93 addq.l #4, %a0
94 move.b %d1, %d0
95 move.b (%d0.l, %a2), (%a0)
96 addq.l #4, %a0
97 subq.l #4, %d2
98 bhs.s .p4_loop
99
100.p4_end:
101 addq.l #4, %d2
102 cmp.l #2, %d2
103 blo.s .p2_t_end
104
105 move.w (%a1)+, %d1
106 move.w %d1, %d0
107 lsr.l #8, %d0
108 move.b (%d0.l, %a2), (%a0)
109 addq.l #4, %a0
110 move.b %d1, %d0
111 move.b (%d0.l, %a2), (%a0)
112 addq.l #4, %a0
113 subq.l #2, %d2
114.p2_t_end:
115
116 tst.l %d2
117 beq.s .p1_t_end
118
119 move.b (%a1)+, %d0
120 move.b (%d0.l, %a2), (%a0)
121.p1_t_end:
122
123 movem.l (%sp), %d2/%a2
124 lea.l (2*4, %sp), %sp
125 rts
126 .size _grey_line1, . - _grey_line1
127
128#endif
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c
index 335d6d1b20..6df5556ec8 100644
--- a/apps/plugins/lib/grey_draw.c
+++ b/apps/plugins/lib/grey_draw.c
@@ -586,11 +586,17 @@ void grey_ub_clear_display(void)
586#endif 586#endif
587} 587}
588 588
589/* Assembler optimised helper function for copying a single line to the
590 * greyvalue buffer. */
591void _grey_line1(int width, unsigned char *dst, const unsigned char *src,
592 const unsigned char *lut);
593
589/* Draw a partial greyscale bitmap, canonical format */ 594/* Draw a partial greyscale bitmap, canonical format */
590void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y, 595void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
591 int stride, int x, int y, int width, int height) 596 int stride, int x, int y, int width, int height)
592{ 597{
593 int yc, ye; 598 int yc, ye;
599 unsigned char *dst;
594 600
595 /* nothing to draw? */ 601 /* nothing to draw? */
596 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width) 602 if ((width <= 0) || (height <= 0) || (x >= _grey_info.width)
@@ -618,16 +624,22 @@ void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
618 src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */ 624 src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */
619 yc = y; 625 yc = y;
620 ye = y + height; 626 ye = y + height;
627 dst = _grey_info.values + (x << _GREY_BSHIFT);
621 628
622 do 629 do
623 { 630 {
624#if LCD_PIXELFORMAT == HORIZONTAL_PACKING 631#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
625 int idx = _GREY_MULUQ(_grey_info.width, yc) + x; 632 int idx = _GREY_MULUQ(_grey_info.width, yc);
626#else 633#else
627 int idx = _GREY_MULUQ(_grey_info.width, yc & ~_GREY_BMASK) 634 int idx = _GREY_MULUQ(_grey_info.width, yc & ~_GREY_BMASK)
628 + (x << _GREY_BSHIFT) + (~yc & _GREY_BMASK); 635 + (~yc & _GREY_BMASK);
629#endif /* LCD_PIXELFORMAT */ 636#endif /* LCD_PIXELFORMAT */
630 unsigned char *dst_row = _grey_info.values + idx; 637
638#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2) \
639 && defined(CPU_COLDFIRE)
640 _grey_line1(width, dst + idx, src, _grey_info.gvalue);
641#else
642 unsigned char *dst_row = dst + idx;
631 const unsigned char *src_row = src; 643 const unsigned char *src_row = src;
632 const unsigned char *src_end = src + width; 644 const unsigned char *src_end = src + width;
633 645
@@ -637,6 +649,7 @@ void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
637 dst_row += _GREY_BSIZE; 649 dst_row += _GREY_BSIZE;
638 } 650 }
639 while (src_row < src_end); 651 while (src_row < src_end);
652#endif
640 653
641 src += stride; 654 src += stride;
642 } 655 }