From c5f4506b9a65948f8385113718493a86d970e8fe Mon Sep 17 00:00:00 2001 From: Rich Felker Date: Tue, 3 Oct 2006 05:28:28 +0000 Subject: 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. --- dblbuf.c | 140 ++++++++++++-------------------------------------------------- dblbuf.h | 4 +- refresh.c | 2 +- 3 files changed, 29 insertions(+), 117 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 + #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>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> 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> 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; icell_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; icells[x+1]); for (i=0; iidx, x, glyph, row->cells[x].a); + uudisp_draw_glyph(d, row->idx, x, glyph, row->cells[x].a & 0xff); } } } -- cgit v1.2.3