From 3f1cfde0688018ca3afc60596171b0f049885c5a Mon Sep 17 00:00:00 2001 From: Tom Wai-Hong Tam Date: Wed, 12 Jan 2011 09:43:10 +0800 Subject: Speed up RLE8 bitmap decoding, each frame from 497ms to 87ms. - Aggregate the same code into one. - Sepearte critical code into functions, better locality. - Loop unrolling. BUG=chromium-os:10499 TEST=build, boot, and "bmp display BMP_ADDR" to render a RLE8 bitmap. Change-Id: I2ebab4f29ac41048afdfccb6f9d69292f1150c54 Review URL: http://codereview.chromium.org/6189004 --- common/lcd.c | 57 +++++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 12 deletions(-) (limited to 'common/lcd.c') diff --git a/common/lcd.c b/common/lcd.c index 9e18e7c28ed..82995ef3fa5 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -822,6 +822,38 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y) #define BMP_RLE8_EOBMP 1 #define BMP_RLE8_DELTA 2 +static void draw_unencoded_bitmap(ushort **fbp, uchar *bmap, ushort *cmap, + int cnt) +{ + while (cnt > 0) { + *(*fbp)++ = cmap[*bmap++]; + cnt--; + } +} + +static void draw_encoded_bitmap(ushort **fbp, ushort c, int cnt) +{ + ushort *fb = *fbp; + int cnt_8copy = cnt >> 3; + cnt -= cnt_8copy << 3; + while (cnt_8copy > 0) { + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + *fb++ = c; + cnt_8copy--; + } + while (cnt > 0) { + *fb++ = c; + cnt--; + } + (*fbp) = fb; +} + /* Do not call this function directly, must be called from * lcd_display_bitmap. */ @@ -830,7 +862,7 @@ static int lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, { uchar *bmap; ulong width, height; - ushort i, cnt, runlen; + ulong cnt, runlen; int x, y; int decode = 1; @@ -875,12 +907,9 @@ static int lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, cnt = width - x; else cnt = runlen; - for (i = 0; i < cnt; i++) { - *(ushort *)fb = - cmap[bmap[i]]; - /* move 2-byte */ - fb += 2; - } + draw_unencoded_bitmap( + (ushort **)&fb, + bmap, cmap, cnt); } x += runlen; } @@ -893,15 +922,19 @@ static int lcd_display_rle8_bitmap(bmp_image_t *bmp, ushort *cmap, uchar *fb, if (y < height) { runlen = bmap[0]; if (x < width) { + /* aggregate the same code */ + while (bmap[0] == 0xff && + bmap[2] != BMP_RLE8_ESCAPE && + bmap[1] == bmap[3]) { + runlen += bmap[2]; + bmap += 2; + } if (x + runlen > width) cnt = width - x; else cnt = runlen; - for (i = 0; i < cnt; i++) { - *(ushort *)fb = cmap[bmap[1]]; - /* move 2-byte */ - fb += 2; - } + draw_encoded_bitmap((ushort **)&fb, + cmap[bmap[1]], cnt); } x += runlen; } -- cgit v1.2.3