diff --git a/kernel/src/drivers/graphics/renderer.c b/kernel/src/drivers/graphics/renderer.c index 2dda84e..62344a9 100644 --- a/kernel/src/drivers/graphics/renderer.c +++ b/kernel/src/drivers/graphics/renderer.c @@ -27,224 +27,3 @@ 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_layer_E layer) { - graphics_buffer_T* graphics_buffer = memory_allocate(sizeof(graphics_buffer_T)); - - graphics_buffer->pos_x = pos_x; - graphics_buffer->pos_y = pos_y; - graphics_buffer->width = width; - graphics_buffer->height = height; - graphics_buffer->blocked = false; - graphics_buffer->render = true; - graphics_buffer->layer = layer; - graphics_buffer->buffer = memory_allocate(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(layer); - graphics_buffer->prev = top_buffer; - graphics_buffer->next = NULL; - if (top_buffer == NULL) { - g_renderer.graphics_buffer_layers[layer] = graphics_buffer; - } else { - top_buffer->next = graphics_buffer; - } - - return graphics_buffer; -} - -void graphics_buffer_show (graphics_buffer_T* graphics_buffer) { - graphics_buffer->render = true; -} - -void graphics_buffer_hide (graphics_buffer_T* graphics_buffer) { - graphics_buffer->render = false; -} - -void graphics_buffer_destruct(graphics_buffer_T* graphics_buffer) { - if (graphics_buffer->prev != NULL) { - graphics_buffer->prev->next = graphics_buffer->next; - } else { - g_renderer.graphics_buffer_layers[graphics_buffer->layer] = graphics_buffer->next; - } - if (graphics_buffer->next != NULL) { - graphics_buffer->next->prev = graphics_buffer->prev; - } - - memory_free(graphics_buffer->buffer); - memory_free(graphics_buffer); -} - -void graphics_buffer_shift_up(graphics_buffer_T* graphics_buffer, uint16_t shift) { - memory_copy(&graphics_buffer->buffer[graphics_buffer->width * shift], - graphics_buffer->buffer, - graphics_buffer->width * (graphics_buffer->height - shift) * sizeof(color_argb_T)); - - memory_set(&graphics_buffer->buffer[graphics_buffer->width * (graphics_buffer->height - shift)], - 0, - graphics_buffer->width * shift * sizeof(color_argb_T)); -} - -void graphics_buffer_set_pixel(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color) { - graphics_buffer->buffer[y * graphics_buffer->width + x] = color; -} - -color_argb_T graphics_buffer_get_pixel(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y) { - 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) { - 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 x_pos = 0; x_pos < g_renderer.font.width; x_pos++){ - if (*glyph & (1 << x_pos)) { - graphics_buffer_set_pixel(graphics_buffer, x + x_pos, y + y_pos, color); - } else { - graphics_buffer_set_pixel(graphics_buffer, x + x_pos, y + y_pos, (color_argb_T){0x00, 0x00, 0x00, 0x00}); - } - } - glyph++; - } -} - -position_T graphics_buffer_draw_string(graphics_buffer_T* graphics_buffer, uint32_t x, uint32_t y, color_argb_T color, string_t string) { - CORE_INTERRUPTABLE_HALT_WHILE(graphics_buffer->blocked) - graphics_buffer->blocked = true; - - position_T pos = (position_T){x, y}; - uint64_t strlen = string_length(string); - for (int i = 0; i < strlen; i++) { - switch (string[i]) { - case '\n': { - pos.x = 0; - pos.y += g_renderer.font.height; - break; - } - case '\r': { - pos.x = 0; - break; - } - - default: { - if (pos.x + g_renderer.font.width >= graphics_buffer->width) { - pos.x = 0; - pos.y += g_renderer.font.height; - } - if (pos.y + g_renderer.font.height >= graphics_buffer->height) { - pos.y -= g_renderer.font.height; - graphics_buffer_shift_up(graphics_buffer, g_renderer.font.height); - } - graphics_buffer_draw_char(graphics_buffer, pos.x, pos.y, color, string[i]); - pos.x += g_renderer.font.width; - break; - } - } - } - - graphics_buffer->blocked = false; - return pos; -} - -void graphics_renderer_init(boot_info_T* boot_info_T) { - struct limine_framebuffer* framebuffer = boot_info_T->framebuffer->framebuffers[0]; - - g_renderer.framebuffer.address = framebuffer->address; - g_renderer.framebuffer.width = framebuffer->width; - g_renderer.framebuffer.height = framebuffer->height; - g_renderer.framebuffer.pitch = framebuffer->pitch; - g_renderer.framebuffer.bits_per_pixel = framebuffer->bpp; - g_renderer.framebuffer.bytes_per_pixel = CEIL_TO(framebuffer->bpp, 8) / 8; - g_renderer.framebuffer.shift_red = framebuffer->red_mask_shift; - g_renderer.framebuffer.shift_green = framebuffer->green_mask_shift; - g_renderer.framebuffer.shift_blue = framebuffer->blue_mask_shift; - - 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.graphics_buffer_layers = memory_allocate(GRAPHICS_BUFFER_ENUM_MAX * sizeof(graphics_buffer_T*)); - g_renderer.font = g_font; - g_renderer.blocked = false; - - 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); - - g_renderer.initialized = true; -} - -bool graphics_renderer_is_initialized() { - return g_renderer.initialized; -} - -void graphics_renderer_update_graphics_buffer(graphics_buffer_T* graphics_buffer) { - if (!graphics_buffer->render) { return; } - - 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); - - for (uint32_t y = graphics_buffer->pos_y; y < size_y; y++) { - for (uint32_t x = graphics_buffer->pos_x; x < size_x; x++) { - color_argb_T color = graphics_buffer->buffer[(y - graphics_buffer->pos_y) * graphics_buffer->width + (x - graphics_buffer->pos_x)]; - - color_argb_T original; - original.alpha = 0xFF; - original.red = (g_renderer.back_buffer[y * g_renderer.framebuffer.width + x] >> g_renderer.framebuffer.shift_red) & 0xFF; - original.green = (g_renderer.back_buffer[y * g_renderer.framebuffer.width + x] >> g_renderer.framebuffer.shift_green) & 0xFF; - original.blue = (g_renderer.back_buffer[y * g_renderer.framebuffer.width + x] >> g_renderer.framebuffer.shift_blue) & 0xFF; - - // apply transparency - color = color_argb_blend_alpha(original, color); - - // write into back_buffer - g_renderer.back_buffer[y * g_renderer.framebuffer.width + x] = (color.red << g_renderer.framebuffer.shift_red) | - (color.green << g_renderer.framebuffer.shift_green) | - (color.blue << g_renderer.framebuffer.shift_blue); - } - } -} - -void graphics_renderer_update() { - CORE_INTERRUPTABLE_HALT_WHILE(g_renderer.blocked) - g_renderer.blocked = true; - - memory_set(g_renderer.back_buffer, 0, g_renderer.buffer_size); - - 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; - } - - // swap back_buffer into framebuffer - memory_copy(g_renderer.back_buffer, g_renderer.framebuffer.address, g_renderer.buffer_size); - - g_renderer.blocked = false; -} - -graphics_buffer_T* graphics_renderer_get_top_buffer(graphics_buffer_layer_E layer) { - if (g_renderer.graphics_buffer_layers[layer] == NULL) { - return NULL; - } - - graphics_buffer_T* graphics_buffer = g_renderer.graphics_buffer_layers[layer]; - - while (graphics_buffer->next != NULL) { - graphics_buffer = graphics_buffer->next; - } - - return graphics_buffer; -} - -uint32_t graphics_renderer_get_width() { - return g_renderer.framebuffer.width; -} - -uint32_t graphics_renderer_get_height() { - return g_renderer.framebuffer.height; -} \ No newline at end of file