summaryrefslogtreecommitdiff
path: root/dblbuf.c
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2006-10-03 05:28:28 +0000
committerRich Felker <dalias@aerifal.cx>2006-10-03 05:28:28 +0000
commitc5f4506b9a65948f8385113718493a86d970e8fe (patch)
treeab2e4180f429a89f94455b0d780588e36569df63 /dblbuf.c
parent7197e4e7d54104233ca1b6881a8e19e1f49ab104 (diff)
downloaduuterm-c5f4506b9a65948f8385113718493a86d970e8fe.tar.gz
rework the dblbuf framebuffer module's blutter heavily, based on work
by loren merritt. roughly 3-4 times as fast as the old code with slightly increased memory usage. still only supports 8bpp and font width of 8, for now, but the new design is more easily extended to 16bpp and 32bpp than the old one.
Diffstat (limited to 'dblbuf.c')
-rw-r--r--dblbuf.c140
1 files changed, 26 insertions, 114 deletions
diff --git a/dblbuf.c b/dblbuf.c
index ad70576..8de52ea 100644
--- a/dblbuf.c
+++ b/dblbuf.c
@@ -1,117 +1,27 @@
/* uuterm, Copyright (C) 2006 Rich Felker; licensed under GNU GPL v2 only */
+#include <inttypes.h>
+
#include "uuterm.h"
#include "dblbuf.h"
-#if 0
-static void blitline8_crap(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw)
-{
- int cs = (cw+7)>>3;
- int skip = (-cw)&7;
- int x, i, j;
- signed char b;
- for (x=0; x<w; x++) {
- j=skip;
- b=*src++<<skip;
- for (i=0; ; i++) {
- for (; j<8; j++, b<<=1)
- //*dest++ = 7 & (b>>7);
- *dest++ = (*colors&15&(b>>7)) | (*colors>>4&~(b>>7));
- if (i >= cs) break;
- b=*src++;
- j=0;
- }
- colors++;
- }
-}
-
-static void blitline8_2(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw)
-{
- int cs = (cw+7)>>3;
- int skip = (-cw)&7;
- int x, i, j;
- signed char b;
- unsigned char fg, bg;
-
- for (x=0; x<w; x++) {
- j=skip;
- b=*src++<<skip;
- fg = *colors & 15;
- bg = *colors++ >> 4;
- for (i=0; ; i++) {
- for (; j<8; j++, b<<=1)
- *dest++ = (fg&(b>>7)) | (bg&~(b>>7));
- if (i >= cs) break;
- b=*src++;
- j=0;
- }
- }
-}
-#endif
-
-#ifdef HAVE_I386_ASM
-
-#define BLIT_PIXEL_8 \
- "add %%al,%%al \n\t" \
- "sbb %%dl,%%dl \n\t" \
- "and %%bh,%%dl \n\t" \
- "mov %%bl,%%dh \n\t" \
- "add %%dl,%%dh \n\t" \
- "mov %%dh,(%%edi) \n\t" \
- "inc %%edi \n\t" \
-
-static void blitline8(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw)
-{
- __asm__ __volatile__(
- "push %%ebp \n\t"
- "mov %%ebx, %%ebp \n\t"
- "\n1: \n\t"
- "mov (%%esi), %%al \n\t"
- "inc %%esi \n\t"
- "mov (%%ecx), %%bl \n\t"
- "inc %%ecx \n\t"
- "mov %%bl, %%bh \n\t"
- "shr $4, %%bl \n\t"
- "and $15, %%bh \n\t"
- "sub %%bl, %%bh \n\t"
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- BLIT_PIXEL_8
- "dec %%ebp \n\t"
- "jnz 1b \n\t"
- "pop %%ebp \n\t"
- : "=S"(src), "=D"(dest), "=c"(colors), "=b"(w)
- : "S"(src), "D"(dest), "c"(colors), "b"(w)
- : "memory" );
-}
-#else
-static void blitline8(unsigned char *dest, unsigned char *src, unsigned char *colors, int w, int cw)
+static void blitline8(unsigned char *dest, unsigned char *src, unsigned long *colors, int w)
{
- int x;
- unsigned char b;
- unsigned char c[2];
-
- for (x=0; x<w; x++) {
- b=*src++;
- c[1] = *colors & 15;
- c[0] = *colors++ >> 4;
- dest[0] = c[b>>7]; b<<=1;
- dest[1] = c[b>>7]; b<<=1;
- dest[2] = c[b>>7]; b<<=1;
- dest[3] = c[b>>7]; b<<=1;
- dest[4] = c[b>>7]; b<<=1;
- dest[5] = c[b>>7]; b<<=1;
- dest[6] = c[b>>7]; b<<=1;
- dest[7] = c[b>>7]; b<<=1;
- dest += 8;
+#define T(x) ~((x&8)*0xff>>3 | (x&4)*0xff<<6 | (x&2)*0xff<<15 | (x&1)*0xff<<24)
+ static const uint32_t tab[16] = {
+ T(0), T(1), T(2), T(3), T(4), T(5), T(6), T(7),
+ T(8), T(9), T(10), T(11), T(12), T(13), T(14), T(15)
+ };
+#undef T
+ uint32_t *dest4 = (uint32_t*)dest;
+ for(; w--; dest4+=2, colors+=2) {
+ int s = *src++;
+ int t0 = tab[s>>4];
+ int t1 = tab[s&15];
+ dest4[0] = colors[0] ^ (colors[1] & t0);
+ dest4[1] = colors[0] ^ (colors[1] & t1);
}
}
-#endif
static void blit_slice(struct uudisp *d, int idx, int x1, int x2)
{
@@ -125,10 +35,10 @@ static void blit_slice(struct uudisp *d, int idx, int x1, int x2)
unsigned char *dest = b->vidmem + y*b->row_stride
+ x1*d->cell_w*b->bytes_per_pixel;
unsigned char *src = b->slices[idx].bitmap + x1*cs;
- unsigned char *colors = b->slices[idx].colors + x1;
+ unsigned long *colors = b->slices[idx].colors + 2*x1;
for (i=0; i<d->cell_h; i++) {
- blitline8(dest, src, colors, w, d->cell_w);
+ blitline8(dest, src, colors, w);
dest += b->line_stride;
src += s;
}
@@ -143,7 +53,7 @@ void clear_cells(struct uudisp *d, int idx, int x1, int x2)
int stride = d->w * cs;
unsigned char *dest = b->slices[idx].bitmap + x1 * cs;
- memset(b->slices[idx].colors + x1, 0, x2-x1+1);
+ memset(b->slices[idx].colors + 2*x1, 0, (x2-x1+1)*2*sizeof(long));
for (i=d->cell_h; i; i--, dest += stride)
memset(dest, 0, cnt);
}
@@ -157,7 +67,9 @@ void uudisp_draw_glyph(struct uudisp *d, int idx, int x, const void *glyph, int
unsigned char *src = (void *)glyph;
unsigned char *dest = b->slices[idx].bitmap + cs * x;
- b->slices[idx].colors[x] = color;
+ b->slices[idx].colors[2*x] = (color&15)*(unsigned long)0x0101010101010101;
+ b->slices[idx].colors[2*x+1] = b->slices[idx].colors[2*x]
+ ^ (color>>4)*(unsigned long)0x0101010101010101;
for (i=d->cell_h; i; i--, dest += stride)
*dest |= *src++;
}
@@ -192,9 +104,9 @@ void uudisp_refresh(struct uudisp *d, struct uuterm *t)
if (d->blink & 1) {
int idx = t->rows[t->y]->idx;
- b->slices[idx].colors[t->x] ^= 0xff;
+ b->slices[idx].colors[2*t->x] ^= (unsigned long)0x0f0f0f0f0f0f0f0f;
blit_slice(d, idx, t->x, t->x);
- b->slices[idx].colors[t->x] ^= 0xff;
+ b->slices[idx].colors[2*t->x] ^= (unsigned long)0x0f0f0f0f0f0f0f0f;
}
b->curs_x = t->x;
b->curs_y = t->y;
@@ -208,9 +120,9 @@ struct slice *dblbuf_setup_buf(int w, int h, int cs, int ch, unsigned char *mem)
mem += sizeof(slices[0]) * h;
- for (i=0; i<h; i++, mem += w) {
+ for (i=0; i<h; i++, mem += w*2*sizeof(long)) {
slices[i].y = -1;
- slices[i].colors = mem;
+ slices[i].colors = (unsigned long *)mem;
}
w *= cs * ch;
for (i=0; i<h; i++, mem += w)