feature (kernel): Implemented layer system and string rendering

This commit is contained in:
antifallobst 2023-02-21 15:58:04 +01:00
parent 65b2ba08f4
commit d025ccaff2
3 changed files with 119 additions and 59 deletions

View File

@ -17,11 +17,19 @@
#define NOX_RENDERER_H #define NOX_RENDERER_H
#include "utils/stdtypes.h" #include "utils/stdtypes.h"
#include "utils/string.h"
#include "drivers/graphics/color.h" #include "drivers/graphics/color.h"
#include "drivers/graphics/font.h" #include "drivers/graphics/font.h"
#include "drivers/graphics/framebuffer.h" #include "drivers/graphics/framebuffer.h"
#include "boot/boot_info.h" #include "boot/boot_info.h"
typedef enum {
GRAPHICS_BUFFER_STANDARD,
GRAPHICS_BUFFER_OVERLAY,
GRAPHICS_BUFFER_ENUM_MAX
} graphics_buffer_layer_E;
typedef struct graphics_buffer_T graphics_buffer_T; typedef struct graphics_buffer_T graphics_buffer_T;
struct graphics_buffer_T { struct graphics_buffer_T {
color_argb_T* buffer; color_argb_T* buffer;
@ -29,6 +37,8 @@ struct graphics_buffer_T {
uint32_t height; uint32_t height;
uint32_t pos_x; uint32_t pos_x;
uint32_t pos_y; uint32_t pos_y;
bool blocked;
graphics_buffer_layer_E layer;
graphics_buffer_T* prev; graphics_buffer_T* prev;
graphics_buffer_T* next; graphics_buffer_T* next;
}; };
@ -37,19 +47,21 @@ typedef struct {
framebuffer_T framebuffer; framebuffer_T framebuffer;
uint32_t* back_buffer; uint32_t* back_buffer;
uint64_t buffer_size; uint64_t buffer_size;
graphics_buffer_T* graphics_buffers; graphics_buffer_T** graphics_buffer_layers;
font_T font; font_T font;
bool initialized;
} graphics_renderer_T; } graphics_renderer_T;
graphics_buffer_T* graphics_buffer_request (uint32_t pos_x, uint32_t pos_y, uint32_t width, uint32_t height); graphics_buffer_T* graphics_buffer_request (uint32_t pos_x, uint32_t pos_y, uint32_t width, uint32_t height, graphics_buffer_layer_E layer);
void graphics_buffer_destruct (graphics_buffer_T* graphics_buffer); void graphics_buffer_destruct (graphics_buffer_T* graphics_buffer);
void graphics_buffer_set_pixel (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color); void graphics_buffer_set_pixel (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color);
color_argb_T graphics_buffer_get_pixel (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y); color_argb_T graphics_buffer_get_pixel (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y);
void graphics_buffer_draw_char (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, char chr); void graphics_buffer_draw_char (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, char chr);
void graphics_buffer_draw_string (graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, string_t string);
void graphics_renderer_init (boot_info_T* boot_info); void graphics_renderer_init (boot_info_T* boot_info);
void graphics_renderer_update (); void graphics_renderer_update ();
graphics_buffer_T* graphics_renderer_get_top_buffer (); graphics_buffer_T* graphics_renderer_get_top_buffer (graphics_buffer_layer_E layer);
uint32_t graphics_renderer_get_width (); uint32_t graphics_renderer_get_width ();
uint32_t graphics_renderer_get_height (); uint32_t graphics_renderer_get_height ();

View File

@ -16,25 +16,27 @@
#include "drivers/graphics/renderer.h" #include "drivers/graphics/renderer.h"
#include "utils/memory.h" #include "utils/memory.h"
#include "utils/math.h" #include "utils/math.h"
#include "utils/logger.h" #include "utils/core.h"
graphics_renderer_T g_renderer; graphics_renderer_T g_renderer;
graphics_buffer_T* graphics_buffer_request(uint32_t pos_x, uint32_t pos_y, uint32_t width, uint32_t height) { graphics_buffer_T* graphics_buffer_request(uint32_t pos_x, uint32_t pos_y, uint32_t width, uint32_t height, graphics_buffer_layer_E layer) {
graphics_buffer_T* graphics_buffer = memory_allocate(sizeof(graphics_buffer_T)); graphics_buffer_T* graphics_buffer = memory_allocate(sizeof(graphics_buffer_T));
graphics_buffer->pos_x = pos_x; graphics_buffer->pos_x = pos_x;
graphics_buffer->pos_y = pos_y; graphics_buffer->pos_y = pos_y;
graphics_buffer->width = width; graphics_buffer->width = width;
graphics_buffer->height = height; graphics_buffer->height = height;
graphics_buffer->blocked = false;
graphics_buffer->layer = layer;
graphics_buffer->buffer = memory_allocate(width * height * sizeof(color_argb_T)); graphics_buffer->buffer = memory_allocate(width * height * sizeof(color_argb_T));
memory_set(graphics_buffer->buffer, 0, width * height * sizeof(color_argb_T)); memory_set(graphics_buffer->buffer, 0, width * height * sizeof(color_argb_T));
graphics_buffer_T* top_buffer = graphics_renderer_get_top_buffer(); graphics_buffer_T* top_buffer = graphics_renderer_get_top_buffer(layer);
graphics_buffer->prev = top_buffer; graphics_buffer->prev = top_buffer;
graphics_buffer->next = NULL; graphics_buffer->next = NULL;
if (top_buffer == NULL) { if (top_buffer == NULL) {
g_renderer.graphics_buffers = graphics_buffer; g_renderer.graphics_buffer_layers[layer] = graphics_buffer;
} else { } else {
top_buffer->next = graphics_buffer; top_buffer->next = graphics_buffer;
} }
@ -46,7 +48,7 @@ void graphics_buffer_destruct(graphics_buffer_T* graphics_buffer) {
if (graphics_buffer->prev != NULL) { if (graphics_buffer->prev != NULL) {
graphics_buffer->prev->next = graphics_buffer->next; graphics_buffer->prev->next = graphics_buffer->next;
} else { } else {
g_renderer.graphics_buffers = graphics_buffer->next; g_renderer.graphics_buffer_layers[graphics_buffer->layer] = graphics_buffer->next;
} }
if (graphics_buffer->next != NULL) { if (graphics_buffer->next != NULL) {
graphics_buffer->next->prev = graphics_buffer->prev; graphics_buffer->next->prev = graphics_buffer->prev;
@ -64,8 +66,8 @@ color_argb_T graphics_buffer_get_pixel(graphics_buffer_T* graphics_buffer, uint3
return graphics_buffer->buffer[y * graphics_buffer->width + x]; return graphics_buffer->buffer[y * graphics_buffer->width + x];
} }
// this function is not thread safe, consider using `graphics_buffer_draw_string` instead
void graphics_buffer_draw_char(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, char chr) { void graphics_buffer_draw_char(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, char chr) {
uint8_t* glyph = &g_renderer.font.buffer[g_renderer.font.glyph_size * chr]; uint8_t* glyph = &g_renderer.font.buffer[g_renderer.font.glyph_size * chr];
for (int y_pos = 0; y_pos < g_renderer.font.height; y_pos++){ for (int y_pos = 0; y_pos < g_renderer.font.height; y_pos++){
@ -80,6 +82,38 @@ void graphics_buffer_draw_char(graphics_buffer_T* graphics_buffer, uint32_t x, u
} }
} }
void graphics_buffer_draw_string(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, string_t string) {
CORE_HALT_WHILE(graphics_buffer->blocked)
graphics_buffer->blocked = true;
uint64_t strlen = string_length(string);
for (int i = 0; i < strlen; i++) {
switch (string[i]) {
case '\n': {
x = 0;
y += g_renderer.font.height;
break;
}
case '\r': {
x = 0;
break;
}
default: {
if (x + g_renderer.font.width >= graphics_buffer->width) {
x = 0;
y += g_renderer.font.height;
}
graphics_buffer_draw_char(graphics_buffer, x, y, color, string[i]);
x += g_renderer.font.width;
break;
}
}
}
graphics_buffer->blocked = false;
}
void graphics_renderer_init(boot_info_T* boot_info_T) { void graphics_renderer_init(boot_info_T* boot_info_T) {
struct limine_framebuffer* framebuffer = boot_info_T->framebuffer->framebuffers[0]; struct limine_framebuffer* framebuffer = boot_info_T->framebuffer->framebuffers[0];
@ -95,16 +129,20 @@ void graphics_renderer_init(boot_info_T* boot_info_T) {
g_renderer.buffer_size = g_renderer.framebuffer.width * g_renderer.framebuffer.height * g_renderer.framebuffer.bytes_per_pixel; g_renderer.buffer_size = g_renderer.framebuffer.width * g_renderer.framebuffer.height * g_renderer.framebuffer.bytes_per_pixel;
g_renderer.back_buffer = memory_allocate(g_renderer.buffer_size); g_renderer.back_buffer = memory_allocate(g_renderer.buffer_size);
g_renderer.graphics_buffers = NULL; g_renderer.graphics_buffer_layers = memory_allocate(GRAPHICS_BUFFER_ENUM_MAX * sizeof(graphics_buffer_T*));
g_renderer.font = g_font; g_renderer.font = g_font;
memory_set(g_renderer.graphics_buffer_layers, 0, GRAPHICS_BUFFER_ENUM_MAX * sizeof(graphics_buffer_T*));
memory_set(g_renderer.back_buffer, 0, g_renderer.buffer_size); memory_set(g_renderer.back_buffer, 0, g_renderer.buffer_size);
g_renderer.initialized = true;
} }
void graphics_renderer_update() { bool graphics_renderer_is_initialized() {
graphics_buffer_T* graphics_buffer = g_renderer.graphics_buffers; return g_renderer.initialized;
while (graphics_buffer != NULL) { }
void graphics_renderer_update_graphics_buffer(graphics_buffer_T* graphics_buffer) {
uint32_t size_x = MIN(graphics_buffer->pos_x + graphics_buffer->width, g_renderer.framebuffer.width); uint32_t size_x = MIN(graphics_buffer->pos_x + graphics_buffer->width, g_renderer.framebuffer.width);
uint32_t size_y = MIN(graphics_buffer->pos_y + graphics_buffer->height, g_renderer.framebuffer.height); uint32_t size_y = MIN(graphics_buffer->pos_y + graphics_buffer->height, g_renderer.framebuffer.height);
@ -127,7 +165,19 @@ void graphics_renderer_update() {
(color.blue << g_renderer.framebuffer.shift_blue); (color.blue << g_renderer.framebuffer.shift_blue);
} }
} }
}
void graphics_renderer_update() {
graphics_buffer_T* graphics_buffer = g_renderer.graphics_buffer_layers[GRAPHICS_BUFFER_STANDARD];
while (graphics_buffer != NULL) {
graphics_renderer_update_graphics_buffer(graphics_buffer);
graphics_buffer = graphics_buffer->next;
}
graphics_buffer = g_renderer.graphics_buffer_layers[GRAPHICS_BUFFER_OVERLAY];
while (graphics_buffer != NULL) {
graphics_renderer_update_graphics_buffer(graphics_buffer);
graphics_buffer = graphics_buffer->next; graphics_buffer = graphics_buffer->next;
} }
@ -135,12 +185,13 @@ void graphics_renderer_update() {
memory_copy(g_renderer.back_buffer, g_renderer.framebuffer.address, g_renderer.buffer_size); memory_copy(g_renderer.back_buffer, g_renderer.framebuffer.address, g_renderer.buffer_size);
} }
graphics_buffer_T* graphics_renderer_get_top_buffer() { graphics_buffer_T* graphics_renderer_get_top_buffer(graphics_buffer_layer_E layer) {
if (g_renderer.graphics_buffers == NULL) { if (g_renderer.graphics_buffer_layers[layer] == NULL) {
return NULL; return NULL;
} }
graphics_buffer_T* graphics_buffer = g_renderer.graphics_buffers; graphics_buffer_T* graphics_buffer = g_renderer.graphics_buffer_layers[layer];
while (graphics_buffer->next != NULL) { while (graphics_buffer->next != NULL) {
graphics_buffer = graphics_buffer->next; graphics_buffer = graphics_buffer->next;
} }

View File

@ -74,19 +74,16 @@ void kmain(boot_info_T boot_info) {
limine_terminal_print(&boot_info, "Kernel initialized\n"); limine_terminal_print(&boot_info, "Kernel initialized\n");
log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n"); log(LOG_INFO, "!=====[ Kernel Initialized ]=====!\n");
graphics_buffer_T* buffer = graphics_buffer_request(0, 0, 50, 50); graphics_buffer_T* buffer = graphics_buffer_request(0, 0, graphics_renderer_get_width() / 2, graphics_renderer_get_height(), GRAPHICS_BUFFER_OVERLAY);
graphics_buffer_T* buffer2 = graphics_buffer_request(0, 0, 50, 50); // graphics_buffer_T* buffer2 = graphics_buffer_request(0, 0, 50, 50);
for (int x = 0; x < 50; x++) { // for (int x = 0; x < 50; x++) {
for (int y = 0; y < 50; y++) { // for (int y = 0; y < 50; y++) {
graphics_buffer_set_pixel(buffer2, x, y, (color_argb_T){0x80, 0xca, 0xca, 0xca}); // graphics_buffer_set_pixel(buffer2, x, y, (color_argb_T){0x80, 0xca, 0xca, 0xca});
} // }
} // }
graphics_buffer_draw_char(buffer, 0, 0, (color_argb_T){0xFF, 0xFF, 0, 0}, 'R');
graphics_buffer_draw_char(buffer, 8, 0, (color_argb_T){0xFF, 0, 0xFF, 0}, 'G');
graphics_buffer_draw_char(buffer, 16, 0, (color_argb_T){0xFF, 0, 0, 0xFF}, 'B');
graphics_buffer_draw_string(buffer, 0, 0, (color_argb_T){0xFF, 0xFF, 0, 0}, "test string\n");
graphics_renderer_update(); graphics_renderer_update();
CORE_HALT_FOREVER CORE_HALT_FOREVER