summaryrefslogtreecommitdiff
path: root/apps/plugins/lib
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 /apps/plugins/lib
parent1509faf618641a5dd1e8b33e0c1617dc521aa27c (diff)
downloadrockbox-52e1f815994413aa6068b13367ca0d04d9246182.zip
rockbox-52e1f815994413aa6068b13367ca0d04d9246182.tar.gz
rockbox-52e1f815994413aa6068b13367ca0d04d9246182.tar.bz2
rockbox-52e1f815994413aa6068b13367ca0d04d9246182.tar.xz
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
Diffstat (limited to 'apps/plugins/lib')
-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 39f1743..c75cca1 100644
--- a/apps/plugins/lib/Makefile
+++ b/apps/plugins/lib/Makefile
@@ -29,7 +29,8 @@ endif
include $(TOOLSDIR)/makesrc.inc
SOURCES = $(SRC)
-OBJS := $(SRC:%.c=$(OBJDIR)/%.o)
+OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o)
+OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2))
DEPFILE = $(OBJDIR)/dep-pluginlib
DIRS = .
diff --git a/apps/plugins/lib/SOURCES b/apps/plugins/lib/SOURCES
index c1f5a48..b638740 100644
--- a/apps/plugins/lib/SOURCES
+++ b/apps/plugins/lib/SOURCES
@@ -8,6 +8,9 @@ grey_core.c
grey_draw.c
grey_parm.c
grey_scroll.c
+#ifdef CPU_COLDFIRE
+grey_coldfire.S
+#endif
#endif
highscore.c
#ifndef SIMULATOR
diff --git a/apps/plugins/lib/grey_coldfire.S b/apps/plugins/lib/grey_coldfire.S
new file mode 100755
index 0000000..cf66ca6
--- /dev/null
+++ b/apps/plugins/lib/grey_coldfire.S
@@ -0,0 +1,128 @@
+/***************************************************************************
+* __________ __ ___.
+* Open \______ \ ____ ____ | | _\_ |__ _______ ___
+* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+* \/ \/ \/ \/ \/
+* $Id: grey_draw.c 16080 2008-01-13 18:39:09Z amiconn $
+*
+* New greyscale framework
+* Coldfire assembler routines
+*
+* This is a generic framework to display 129 shades of grey on low-depth
+* bitmap LCDs (Archos b&w, Iriver & Ipod 4-grey) within plugins.
+*
+* Copyright (C) 2008 Jens Arnold
+*
+* All files in this archive are subject to the GNU General Public License.
+* See the file COPYING in the source tree root for full license agreement.
+*
+* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+* KIND, either express or implied.
+*
+****************************************************************************/
+
+#include "config.h"
+/* Plugins should not normally do this, but we need to check a macro, and
+ * plugin.h would confuse the assembler. */
+
+ .text
+ .global _grey_line1
+ .type _grey_line1, @function
+
+#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2)
+
+/****************************************************************************
+ * void _grey_line1(int width,
+ * unsigned char *dst,
+ * const unsigned char *src,
+ * const unsigned char *lut);
+ */
+
+_grey_line1:
+ lea.l (-2*4, %sp), %sp
+ movem.l %d2/%a2, (%sp)
+ movem.l (2*4+4, %sp), %d2/%a0-%a2
+ clr.l %d0
+
+ move.l %a1, %d1
+ and.l #1, %d1
+ beq.s .p1_h_end
+
+ move.b (%a1)+, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ subq.l #1, %d2
+.p1_h_end:
+
+ cmp.l #2, %d2
+ blo.s .p2_t_end
+ move.l %a1, %d1
+ and.l #2, %d1
+ beq.s .p2_h_end
+
+ move.w (%a1)+, %d1
+ move.w %d1, %d0
+ lsr.l #8, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ move.b %d1, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ subq.l #2, %d2
+.p2_h_end:
+
+ subq.l #4, %d2
+ blo.s .p4_end
+
+.p4_loop:
+ move.l (%a1)+, %d1
+ swap %d1
+ move.w %d1, %d0
+ lsr.l #8, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ move.b %d1, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ swap %d1
+ move.w %d1, %d0
+ lsr.l #8, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ move.b %d1, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ subq.l #4, %d2
+ bhs.s .p4_loop
+
+.p4_end:
+ addq.l #4, %d2
+ cmp.l #2, %d2
+ blo.s .p2_t_end
+
+ move.w (%a1)+, %d1
+ move.w %d1, %d0
+ lsr.l #8, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ move.b %d1, %d0
+ move.b (%d0.l, %a2), (%a0)
+ addq.l #4, %a0
+ subq.l #2, %d2
+.p2_t_end:
+
+ tst.l %d2
+ beq.s .p1_t_end
+
+ move.b (%a1)+, %d0
+ move.b (%d0.l, %a2), (%a0)
+.p1_t_end:
+
+ movem.l (%sp), %d2/%a2
+ lea.l (2*4, %sp), %sp
+ rts
+ .size _grey_line1, . - _grey_line1
+
+#endif
diff --git a/apps/plugins/lib/grey_draw.c b/apps/plugins/lib/grey_draw.c
index 335d6d1..6df5556 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)
#endif
}
+/* Assembler optimised helper function for copying a single line to the
+ * greyvalue buffer. */
+void _grey_line1(int width, unsigned char *dst, const unsigned char *src,
+ const unsigned char *lut);
+
/* Draw a partial greyscale bitmap, canonical format */
void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
int stride, int x, int y, int width, int height)
{
int yc, ye;
+ unsigned char *dst;
/* nothing to draw? */
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,
src += _GREY_MULUQ(stride, src_y) + src_x; /* move starting point */
yc = y;
ye = y + height;
+ dst = _grey_info.values + (x << _GREY_BSHIFT);
do
{
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
- int idx = _GREY_MULUQ(_grey_info.width, yc) + x;
+ int idx = _GREY_MULUQ(_grey_info.width, yc);
#else
int idx = _GREY_MULUQ(_grey_info.width, yc & ~_GREY_BMASK)
- + (x << _GREY_BSHIFT) + (~yc & _GREY_BMASK);
+ + (~yc & _GREY_BMASK);
#endif /* LCD_PIXELFORMAT */
- unsigned char *dst_row = _grey_info.values + idx;
+
+#if (LCD_PIXELFORMAT == VERTICAL_PACKING) && (LCD_DEPTH == 2) \
+ && defined(CPU_COLDFIRE)
+ _grey_line1(width, dst + idx, src, _grey_info.gvalue);
+#else
+ unsigned char *dst_row = dst + idx;
const unsigned char *src_row = src;
const unsigned char *src_end = src + width;
@@ -637,6 +649,7 @@ void grey_ub_gray_bitmap_part(const unsigned char *src, int src_x, int src_y,
dst_row += _GREY_BSIZE;
}
while (src_row < src_end);
+#endif
src += stride;
}