summaryrefslogtreecommitdiff
path: root/common/lcd.c
diff options
context:
space:
mode:
authorTom Wai-Hong Tam <waihong@google.com>2011-01-12 09:43:10 +0800
committerSimon Glass <sjg@chromium.org>2011-08-24 10:00:13 -0700
commit3f1cfde0688018ca3afc60596171b0f049885c5a (patch)
tree05d7822f81f1941be63bc2dc9c165eac89bb8653 /common/lcd.c
parentb34a32df2631d506fbab8381d1a84fdb3a535d95 (diff)
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
Diffstat (limited to 'common/lcd.c')
-rw-r--r--common/lcd.c57
1 files changed, 45 insertions, 12 deletions
diff --git a/common/lcd.c b/common/lcd.c
index 9e18e7c28e..82995ef3fa 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;
}