Double buffer framebuffer drawing

This commit is contained in:
Thomas Lovén 2022-01-10 10:28:26 +01:00
parent 8eaa8e6c8f
commit 27682a9fe1
3 changed files with 23 additions and 10 deletions

View File

@ -2,10 +2,9 @@
#include <memory.h> #include <memory.h>
#include <multiboot.h> #include <multiboot.h>
#include <framebuffer.h> #include <framebuffer.h>
#include <stdlib.h>
gfx_context kernel_fb; gfx_context kernel_fb;
gfx_context subcontext;
void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr) void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr)
{ {
@ -13,16 +12,24 @@ void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr)
uint64_t loc = \ uint64_t loc = \
y * ctx->pitch + \ y * ctx->pitch + \
x * ctx->bpp; x * ctx->bpp;
uint32_t *fb = incptr(P2V(ctx->addr), loc); uint32_t *fb = incptr(ctx->buffer, loc);
*fb = clr; *fb = clr;
} }
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),
ctx->width*ctx->bpp);
}
}
gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height) gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height)
{ {
gfx_context *out = &subcontext; gfx_context *out = malloc(sizeof(gfx_context));
uint64_t loc = \ uint64_t loc = \
y * ctx->pitch + \ y * ctx->pitch + \
x * ctx->bpp; x * ctx->bpp;
@ -33,6 +40,7 @@ gfx_context *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t
out->pitch = ctx->pitch; out->pitch = ctx->pitch;
out->addr = incptr(ctx->addr, loc); out->addr = incptr(ctx->addr, loc);
out->size = ctx->pitch * (height); out->size = ctx->pitch * (height);
out->buffer = calloc(1, out->size);
return out; return out;
} }
@ -43,11 +51,12 @@ void framebuffer_init(struct fbinfo *fbinfo)
kernel_fb.height = fbinfo->framebuffer_height; kernel_fb.height = fbinfo->framebuffer_height;
kernel_fb.bpp = fbinfo->framebuffer_bpp/8; kernel_fb.bpp = fbinfo->framebuffer_bpp/8;
kernel_fb.pitch = fbinfo->framebuffer_pitch; kernel_fb.pitch = fbinfo->framebuffer_pitch;
kernel_fb.addr = (void *)fbinfo->framebuffer_addr; kernel_fb.addr = P2V(fbinfo->framebuffer_addr);
kernel_fb.size = kernel_fb.pitch * (kernel_fb.height); kernel_fb.size = kernel_fb.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) for(uintptr_t p = (uintptr_t)kernel_fb.addr; p < ((uintptr_t)kernel_fb.addr + kernel_fb.size); p += PAGE_SIZE)
{ {
vmm_set_page(kernel_P4, (uint64_t)P2V(p), p, PAGE_WRITE | PAGE_PRESENT); vmm_set_page(kernel_P4, p, V2P(p), PAGE_WRITE | PAGE_PRESENT);
} }
} }

View File

@ -113,7 +113,7 @@ static void drawCharacter(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr
uint64_t loc = \ uint64_t loc = \
y * ctx->pitch + \ y * ctx->pitch + \
x * ctx->bpp; x * ctx->bpp;
uint32_t *fb = incptr(P2V(ctx->addr), loc); uint32_t *fb = incptr(ctx->buffer, loc);
for(int row = 0; row < 16; row++) for(int row = 0; row < 16; row++)
{ {
for(int col = 0; col < 8; col++) for(int col = 0; col < 8; col++)
@ -143,6 +143,7 @@ void fbterm_init(gfx_context *ctx)
{ {
term_fb = framebuffer_make_subcontext(ctx, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8); term_fb = framebuffer_make_subcontext(ctx, 20, 20, 8*VGA_COLS+8, 16*VGA_ROWS+8);
draw_border(term_fb, RGB(255, 0, 0)); draw_border(term_fb, RGB(255, 0, 0));
flip(term_fb);
term_fb = framebuffer_make_subcontext(ctx, 24, 24, 8*VGA_COLS, 16*VGA_ROWS); term_fb = framebuffer_make_subcontext(ctx, 24, 24, 8*VGA_COLS, 16*VGA_ROWS);
setup = 1; setup = 1;
} }
@ -163,4 +164,5 @@ void fbterm_flush(struct vga_cell *buffer)
drawCharacter(term_fb, col*8, row*16, 0xFFFFFF, 0, (char)buffer[i++].c); drawCharacter(term_fb, col*8, row*16, 0xFFFFFF, 0, (char)buffer[i++].c);
} }
} }
flip(term_fb);
} }

View File

@ -13,11 +13,13 @@ typedef struct {
size_t size; size_t size;
} gfx_context; } gfx_context;
// drivers/framebuffer.c
extern gfx_context kernel_fb; extern gfx_context kernel_fb;
#define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b))) #define RGB(r, g, b) (((uint32_t) (r<<16) + (g<<8) + (b)))
// drivers/framebuffer.c
void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr); void putpixel(gfx_context *ctx, uint64_t x, uint64_t y, uint32_t clr);
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 *framebuffer_make_subcontext(gfx_context *ctx, uint64_t x, uint64_t y, uint64_t width, uint64_t height);
void framebuffer_init(struct fbinfo *fbinfo); void framebuffer_init(struct fbinfo *fbinfo);