From 7d9a744cf23edb3f20215e96a2ef0604d71901e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Fri, 14 Jan 2022 14:59:54 +0100 Subject: [PATCH] Some drawing performance improvements --- src/kernel/boot/TEMP-test_scheduler.c | 1 - src/kernel/drivers/terminal/fbterm.c | 26 +++------- src/libmittos/graphics/graphics.c | 70 +++++++++++++++++---------- src/libmittos/include/graphics.h | 1 + 4 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/kernel/boot/TEMP-test_scheduler.c b/src/kernel/boot/TEMP-test_scheduler.c index 3cef0c2..d427010 100644 --- a/src/kernel/boot/TEMP-test_scheduler.c +++ b/src/kernel/boot/TEMP-test_scheduler.c @@ -25,7 +25,6 @@ void thread2() int a = 0; while(1) { putCharacter(term_fb, 10, 10, RGB(0,255,255), RGB(0,0,0), 'A'+(a++%10)); - draw_rect(term_fb, 10, 10, 200, 300, RGB((uint8_t)(a%256), 0, 255-(uint8_t)(a%256))); flip(term_fb); sched_yield(); diff --git a/src/kernel/drivers/terminal/fbterm.c b/src/kernel/drivers/terminal/fbterm.c index 6adf09c..f2c45a8 100644 --- a/src/kernel/drivers/terminal/fbterm.c +++ b/src/kernel/drivers/terminal/fbterm.c @@ -7,20 +7,6 @@ gfx_context kernel_fb; gfx_context *term_fb; static int setup = 0; -static void draw_border(gfx_context *ctx, uint32_t clr) -{ - for(uint64_t x = 0; x < ctx->width; x++) - { - putpixel(ctx, x, 0, clr); - putpixel(ctx, x, ctx->height-1, clr); - } - for(uint64_t y = 0; y < ctx->height; y++) - { - putpixel(ctx, 0, y, clr); - putpixel(ctx, ctx->width-1, y, clr); - } -} - void fbterm_movecursor(unsigned int cursor) { (void) cursor; @@ -34,7 +20,7 @@ void fbterm_flush(struct vga_cell *buffer) { for(int col=0; col < VGA_COLS; col++) { - putCharacter(term_fb, col*8, row*16, 0xFFFFFF, 0, (char)buffer[i++].c); + putCharacter(term_fb, col*8, row*16, 0xebdbb2, 0x282828, (char)buffer[i++].c); } } flip(term_fb); @@ -45,9 +31,9 @@ void fbterm_init(struct fbinfo *fbinfo) kernel_fb.width = fbinfo->framebuffer_width; kernel_fb.height = fbinfo->framebuffer_height; kernel_fb.bpp = fbinfo->framebuffer_bpp/8; - kernel_fb.pitch = fbinfo->framebuffer_pitch; + kernel_fb.pitch = fbinfo->framebuffer_pitch/kernel_fb.bpp; kernel_fb.addr = P2V(fbinfo->framebuffer_addr); - kernel_fb.size = kernel_fb.pitch * (kernel_fb.height); + kernel_fb.size = fbinfo->framebuffer_pitch * (kernel_fb.height); kernel_fb.buffer = calloc(1, kernel_fb.size); for(uintptr_t p = (uintptr_t)kernel_fb.addr; p < ((uintptr_t)kernel_fb.addr + kernel_fb.size); p += PAGE_SIZE) @@ -55,10 +41,10 @@ void fbterm_init(struct fbinfo *fbinfo) vmm_set_page(kernel_P4, p, V2P(p), PAGE_WRITE | PAGE_PRESENT); } - term_fb = framebuffer_make_subcontext(&kernel_fb, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8); - draw_border(term_fb, RGB(255, 0, 0)); - flip(term_fb); + draw_rect(&kernel_fb, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8, RGB(255, 0, 0)); + flip(&kernel_fb); term_fb = framebuffer_make_subcontext(&kernel_fb, 24, 24, 8*VGA_COLS, 16*VGA_ROWS); + flip(term_fb); setup = 1; draw_line(&kernel_fb, 750, 850, 120, 120, RGB(255,0,0)); diff --git a/src/libmittos/graphics/graphics.c b/src/libmittos/graphics/graphics.c index 6550dfc..a649050 100644 --- a/src/libmittos/graphics/graphics.c +++ b/src/libmittos/graphics/graphics.c @@ -7,14 +7,15 @@ #include "u_vga16.termfont.inc" +#define PXL(ctx, x, y) ((y) * ctx->pitch + (x)) +#define STEP_X(ctx) 1 +#define STEP_Y(ctx) (ctx)->pitch + void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) { if(x >= ctx->width || y >= ctx->height) return; - uint64_t loc = \ - y * ctx->pitch + \ - x * ctx->bpp; - uint32_t *fb = incptr(ctx->buffer, loc); - *fb = clr; + uint32_t *fb = (uint32_t *)ctx->buffer; + fb[PXL(ctx, x, y)] = clr; } void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t y1, uint32_t clr) @@ -25,9 +26,10 @@ void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t int sy = y1 > y0 ? 1 : -1; uint64_t x = x0, y = y0; int64_t diff = dx - dy; + uint32_t *fb = (uint32_t *)ctx->buffer; while(1) { - putpixel(ctx, x, y, clr); + fb[PXL(ctx, x, y)] = clr; if(x == x1 && y == y1) break; if((2*diff) > -dy) { @@ -42,34 +44,52 @@ void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t void draw_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr) { - for(uint64_t _x = x; _x <= x+width; _x++) + uint32_t *fb = (uint32_t *)ctx->buffer; + uint64_t l1 = PXL(ctx, x, y); + uint64_t l2 = PXL(ctx, x, y + height); + for(uint64_t _x = 0; _x <= width; _x++) { - putpixel(ctx, _x, y, clr); - putpixel(ctx, _x, y+height, clr); + fb[l1] = fb[l2] = clr; + l1 += STEP_X(ctx); + l2 += STEP_X(ctx); } - for(uint64_t _y = y; _y <= y+height; _y++) + l1 = PXL(ctx, x, y); + l2 = PXL(ctx, x + width, y); + for(uint64_t _y = 0; _y <= height; _y++) { - putpixel(ctx, x, _y, clr); - putpixel(ctx, x+width, _y, clr); + fb[l1] = fb[l2] = clr; + l1 += STEP_Y(ctx); + l2 += STEP_Y(ctx); + } +} + +void fill_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr) +{ + uint32_t *fb = (uint32_t *)ctx->buffer; + uint64_t loc = PXL(ctx, x, y); + for(uint64_t _y = 0; _y <= height; _y++) + { + for(uint64_t _x = 0; _x <= width; _x += STEP_X(ctx)) + { + fb[loc + _x] = clr; + } + loc += STEP_Y(ctx); } - } void putCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c) { unsigned char *chr = c ? font[(int)c-0x20]: font[0]; if(x >= ctx->width || y >= ctx->height) return; - uint64_t loc = \ - y * ctx->pitch + \ - x * ctx->bpp; - uint32_t *fb = incptr(ctx->buffer, loc); + uint32_t *fb = (uint32_t *)ctx->buffer; + uint64_t loc = y * ctx->pitch + x; for(int row = 0; row < 16; row++) { for(int col = 0; col < 8; col++) { - fb[col] = ((chr[row]>>(7-col))&0x1) ? clr_fg : clr_bg; + fb[loc+col] = ((chr[row]>>(7-col))&0x1) ? clr_fg : clr_bg; } - fb = incptr(fb, ctx->pitch); + loc += ctx->pitch; } } @@ -78,8 +98,8 @@ void flip(gfx_context *ctx) for(uint64_t y = 0; y < ctx->height; y++) { memcpy( - incptr(ctx->addr, y*ctx->pitch), - incptr(ctx->buffer, y*ctx->pitch), + incptr(ctx->addr, y*ctx->pitch*ctx->bpp), + incptr(ctx->buffer, y*ctx->pitch*ctx->bpp), ctx->width*ctx->bpp); } } @@ -87,16 +107,14 @@ void flip(gfx_context *ctx) gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) { gfx_context *out = malloc(sizeof(gfx_context)); - uint64_t loc = \ - y * ctx->pitch + \ - x * ctx->bpp; + uint64_t loc = y * ctx->pitch + x; out->width = width; out->height = height; out->bpp = ctx->bpp; out->pitch = ctx->pitch; - out->addr = incptr(ctx->addr, loc); - out->size = ctx->pitch * (height); + out->addr = incptr(ctx->addr, loc*ctx->bpp); + out->size = ctx->pitch * height * ctx->bpp; out->buffer = calloc(1, out->size); return out; diff --git a/src/libmittos/include/graphics.h b/src/libmittos/include/graphics.h index 7087874..ca7a987 100644 --- a/src/libmittos/include/graphics.h +++ b/src/libmittos/include/graphics.h @@ -16,6 +16,7 @@ typedef struct { void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr); void draw_line(gfx_context *ctx, uint64_t x0, uint64_t x1, uint64_t y0, uint64_t y1, uint32_t clr); void draw_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr); +void fill_rect(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height, uint32_t clr); void putCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr_fg, uint32_t clr_bg, char c); void flip(gfx_context *ctx); gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height); \ No newline at end of file