diff options
author | Rich Felker <dalias@aerifal.cx> | 2006-10-03 05:28:28 +0000 |
---|---|---|
committer | Rich Felker <dalias@aerifal.cx> | 2006-10-03 05:28:28 +0000 |
commit | c5f4506b9a65948f8385113718493a86d970e8fe (patch) | |
tree | ab2e4180f429a89f94455b0d780588e36569df63 | |
parent | 7197e4e7d54104233ca1b6881a8e19e1f49ab104 (diff) |
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.
-rw-r--r-- | dblbuf.c | 140 | ||||
-rw-r--r-- | dblbuf.h | 4 | ||||
-rw-r--r-- | refresh.c | 2 |
3 files changed, 29 insertions, 117 deletions
@@ -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) @@ -4,7 +4,7 @@ struct slice { int y; - unsigned char *colors; + unsigned long *colors; unsigned char *bitmap; }; @@ -23,7 +23,7 @@ struct dblbuf }; #define SLICE_BUF_SIZE(w, h, cs, ch) \ - ( (h)*(sizeof(struct slice) + (w)*(1 + (cs)*(ch))) ) + ( (h)*(sizeof(struct slice) + (w)*(2*sizeof(long) + (cs)*(ch))) ) struct slice *dblbuf_setup_buf(int, int, int, int, unsigned char *); @@ -37,7 +37,7 @@ void uuterm_refresh_row(struct uudisp *d, struct uurow *row, int x1, int x2) extract_cell(ch[(x+1)&3], &row->cells[x+1]); for (i=0; i<sizeof(ch[0]) && ch[x&3][i]; i++) { const void *glyph = lookup_glyph(ch[x&3], i, ch[(x+3)&3], ch[(x+1)&3]); - uudisp_draw_glyph(d, row->idx, x, glyph, row->cells[x].a); + uudisp_draw_glyph(d, row->idx, x, glyph, row->cells[x].a & 0xff); } } } |