From 52e1f815994413aa6068b13367ca0d04d9246182 Mon Sep 17 00:00:00 2001 From: Jens Arnold Date: Sun, 2 Mar 2008 17:05:00 +0000 Subject: 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 --- apps/plugins/lib/Makefile | 3 +- apps/plugins/lib/SOURCES | 3 + apps/plugins/lib/grey_coldfire.S | 128 +++++++++++++++++++++++++++++++++++++++ apps/plugins/lib/grey_draw.c | 19 +++++- 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100755 apps/plugins/lib/grey_coldfire.S 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 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 c1f5a483f2..b638740b0e 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 0000000000..cf66ca66b6 --- /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 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) #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; } -- cgit v1.2.3