From 7c66610c1319a26a3a615f34498622ea2f241449 Mon Sep 17 00:00:00 2001 From: pyao12 Date: Fri, 5 Jun 2026 18:03:13 +0800 Subject: [PATCH] [fix] Draw effect target --- Makefile | 2 +- graphics/context.cpp | 22 ++++++++++++++ graphics/draw.cpp | 32 ++++++++++++++++++-- graphics/rect.cpp | 61 -------------------------------------- include/graphics/context.h | 14 +++++++-- include/graphics/draw.h | 8 ++++- include/graphics/rect.h | 13 -------- kernel/graphics/layer.cpp | 6 ++-- kernel/main.cpp | 30 +++++++------------ 9 files changed, 85 insertions(+), 103 deletions(-) delete mode 100644 graphics/rect.cpp delete mode 100644 include/graphics/rect.h diff --git a/Makefile b/Makefile index 30d3d10..9852364 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ KERNEL_CPP = kernel/entry.cpp kernel/main.cpp kernel/serial.cpp kernel/fs.cpp \ kernel/interrupt/gdt.cpp kernel/interrupt/idt.cpp \ kernel/interrupt/pic.cpp kernel/interrupt/pit.cpp \ kernel/graphics/layer.cpp \ - graphics/context.cpp graphics/draw.cpp graphics/rect.cpp \ + graphics/context.cpp graphics/draw.cpp \ fonts/pixel_font.cpp KERNEL_ASM = kernel/scheduler/context_switch.S kernel/interrupt/isr.S kernel/interrupt/idt_helpers.S KERNEL_OBJ = $(KERNEL_CPP:%.cpp=build/%.o) $(KERNEL_ASM:%.S=build/%.o) diff --git a/graphics/context.cpp b/graphics/context.cpp index c90894a..f3b9c04 100644 --- a/graphics/context.cpp +++ b/graphics/context.cpp @@ -1,15 +1,37 @@ +// GFX 存在的意义是什么? +// 每一次想要draw pixel,都需要传入GOP的各种参数, +// 加入 GFX 后,GOP 的context就是全局的,可以直接用 +// 而不用显示传递参数到draw的函数里 + #include gfx_context g_gfx; +draw_target g_draw_target; void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP) { g_gfx.GOP = GOP; g_gfx.hr = GOP->Mode->Info->HorizontalResolution; g_gfx.vr = GOP->Mode->Info->VerticalResolution; g_gfx.base = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) GOP->Mode->FrameBufferBase; + + g_draw_target.buf = g_gfx.base; + g_draw_target.w = g_gfx.hr; + g_draw_target.h = g_gfx.vr; } void gfx_clear(void) { EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0}; g_gfx.GOP->Blt(g_gfx.GOP, &black, EfiBltVideoFill, 0, 0, 0, 0, g_gfx.hr, g_gfx.vr, 0); +} + +void draw_set_target(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, unsigned int w, unsigned int h) { + g_draw_target.buf = buf; + g_draw_target.w = w; + g_draw_target.h = h; +} + +void draw_set_default_target(void) { + g_draw_target.buf = g_gfx.base; + g_draw_target.w = g_gfx.hr; + g_draw_target.h = g_gfx.vr; } \ No newline at end of file diff --git a/graphics/draw.cpp b/graphics/draw.cpp index 0fa9a20..d2e7e08 100644 --- a/graphics/draw.cpp +++ b/graphics/draw.cpp @@ -1,10 +1,36 @@ #include -void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_gfx.base + (g_gfx.hr * y) + x; +// --- Global (framebuffer) --- +void global_draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_gfx.base + (g_gfx.hr * y) + x; p->Blue = color.Blue; p->Green = color.Green; p->Red = color.Red; p->Reserved = color.Reserved; -} \ No newline at end of file +} + +void global_draw_rect(unsigned int bx, unsigned int by, unsigned int ex, unsigned int ey, + EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { + for (unsigned int x = bx; x <= ex; x++) + for (unsigned int y = by; y <= ey; y++) + global_draw_pixel(x, y, color); +} + +// --- Current target buffer --- + +void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { + if (x >= g_draw_target.w || y >= g_draw_target.h) return; + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *p = g_draw_target.buf + (g_draw_target.w * y) + x; + p->Blue = color.Blue; + p->Green = color.Green; + p->Red = color.Red; + p->Reserved = color.Reserved; +} + +void draw_rect(unsigned int bx, unsigned int by, unsigned int ex, unsigned int ey, + EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { + for (unsigned int x = bx; x <= ex; x++) + for (unsigned int y = by; y <= ey; y++) + draw_pixel(x, y, color); +} diff --git a/graphics/rect.cpp b/graphics/rect.cpp deleted file mode 100644 index 08d1e98..0000000 --- a/graphics/rect.cpp +++ /dev/null @@ -1,61 +0,0 @@ -#include - -void gfx_fill_rect(EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf, - UINT32 buf_w, UINT32 buf_h, - UINT32 x, UINT32 y, UINT32 w, UINT32 h, - EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { - if (x >= buf_w || y >= buf_h) return; - - UINT32 x2 = x + w; - UINT32 y2 = y + h; - if (x2 > buf_w) x2 = buf_w; - if (y2 > buf_h) y2 = buf_h; - - for (UINT32 row = y; row < y2; row++) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = buf + (buf_w * row) + x; - for (UINT32 col = x; col < x2; col++) { - p->Blue = color.Blue; - p->Green = color.Green; - p->Red = color.Red; - p->Reserved = color.Reserved; - p++; - } - } -} - -void gfx_draw_rect(EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf, - UINT32 buf_w, UINT32 buf_h, - UINT32 x, UINT32 y, UINT32 w, UINT32 h, - EFI_GRAPHICS_OUTPUT_BLT_PIXEL color) { - if (x >= buf_w || y >= buf_h) return; - - UINT32 x2 = x + w; - UINT32 y2 = y + h; - if (x2 > buf_w) x2 = buf_w; - if (y2 > buf_h) y2 = buf_h; - - // Top edge - for (UINT32 col = x; col < x2; col++) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = buf + (buf_w * y) + col; - p->Blue = color.Blue; p->Green = color.Green; p->Red = color.Red; p->Reserved = color.Reserved; - } - // Bottom edge - if (y2 - 1 < buf_h) { - for (UINT32 col = x; col < x2; col++) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = buf + (buf_w * (y2 - 1)) + col; - p->Blue = color.Blue; p->Green = color.Green; p->Red = color.Red; p->Reserved = color.Reserved; - } - } - // Left edge - for (UINT32 row = y; row < y2; row++) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = buf + (buf_w * row) + x; - p->Blue = color.Blue; p->Green = color.Green; p->Red = color.Red; p->Reserved = color.Reserved; - } - // Right edge - if (x2 - 1 < buf_w) { - for (UINT32 row = y; row < y2; row++) { - EFI_GRAPHICS_OUTPUT_BLT_PIXEL* p = buf + (buf_w * row) + (x2 - 1); - p->Blue = color.Blue; p->Green = color.Green; p->Red = color.Red; p->Reserved = color.Reserved; - } - } -} diff --git a/include/graphics/context.h b/include/graphics/context.h index 90166c7..3ed58e8 100644 --- a/include/graphics/context.h +++ b/include/graphics/context.h @@ -13,5 +13,15 @@ struct gfx_context { extern gfx_context g_gfx; -void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP); // 初始化 GFX -void gfx_clear(void); // 清空 GFX(相当于重置) \ No newline at end of file +struct draw_target { + EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf; + unsigned int w; + unsigned int h; +}; + +extern draw_target g_draw_target; + +void gfx_init(EFI_GRAPHICS_OUTPUT_PROTOCOL *GOP); +void gfx_clear(void); +void draw_set_target(EFI_GRAPHICS_OUTPUT_BLT_PIXEL *buf, unsigned int w, unsigned int h); +void draw_set_default_target(void); \ No newline at end of file diff --git a/include/graphics/draw.h b/include/graphics/draw.h index 5b08c9e..df9a3af 100644 --- a/include/graphics/draw.h +++ b/include/graphics/draw.h @@ -3,4 +3,10 @@ #include #include -void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); // 画像素 \ No newline at end of file +void global_draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); +void global_draw_rect(unsigned int bx, unsigned int by, unsigned int ex, unsigned int ey, + EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); + +void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); +void draw_rect(unsigned int bx, unsigned int by, unsigned int ex, unsigned int ey, + EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); diff --git a/include/graphics/rect.h b/include/graphics/rect.h deleted file mode 100644 index 1a05016..0000000 --- a/include/graphics/rect.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include - -void gfx_fill_rect(EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf, - UINT32 buf_w, UINT32 buf_h, - UINT32 x, UINT32 y, UINT32 w, UINT32 h, - EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); - -void gfx_draw_rect(EFI_GRAPHICS_OUTPUT_BLT_PIXEL* buf, - UINT32 buf_w, UINT32 buf_h, - UINT32 x, UINT32 y, UINT32 w, UINT32 h, - EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); diff --git a/kernel/graphics/layer.cpp b/kernel/graphics/layer.cpp index 084c697..995a29e 100644 --- a/kernel/graphics/layer.cpp +++ b/kernel/graphics/layer.cpp @@ -1,5 +1,5 @@ #include -#include +#include #include #include #include @@ -273,7 +273,9 @@ void layer_compositor_task(void) { // Clear back buffer EFI_GRAPHICS_OUTPUT_BLT_PIXEL black = {0, 0, 0, 0}; - gfx_fill_rect(g_back_buffer, hr, vr, 0, 0, hr, vr, black); + draw_set_target(g_back_buffer, hr, vr); + draw_rect(0, 0, hr, vr, black); + draw_set_default_target(); // Composite layers from lowest z to highest layer_t* cur = g_layer_list; diff --git a/kernel/main.cpp b/kernel/main.cpp index 7561cb0..8277794 100644 --- a/kernel/main.cpp +++ b/kernel/main.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include #include #include @@ -164,9 +163,10 @@ extern "C" void kernel_main() { layer_t* desktop = layer_create("desktop", LAYER_TYPE_DESKTOP, g_gfx.hr, g_gfx.vr); if (desktop) { layer_set_z(desktop, 0); - // Fill with dark blue - EFI_GRAPHICS_OUTPUT_BLT_PIXEL bg = {180, 80, 40, 0}; // BGRA: dark blue - gfx_fill_rect(desktop->buffer, g_gfx.hr, g_gfx.vr, 0, 0, g_gfx.hr, g_gfx.vr, bg); + EFI_GRAPHICS_OUTPUT_BLT_PIXEL bg = {180, 80, 40, 0}; + draw_set_target(desktop->buffer, g_gfx.hr, g_gfx.vr); + draw_rect(0, 0, g_gfx.hr, g_gfx.vr, bg); + draw_set_default_target(); layer_set_pos(desktop, 0, 0); } @@ -175,15 +175,10 @@ extern "C" void kernel_main() { if (win1) { layer_set_pos(win1, (int)(g_gfx.hr / 2) - 150, (int)(g_gfx.vr / 2) - 100); layer_set_z(win1, 1); - // Fill with gray EFI_GRAPHICS_OUTPUT_BLT_PIXEL win_color = {200, 200, 200, 0}; - gfx_fill_rect(win1->buffer, 300, 200, 0, 0, 300, 200, win_color); - // White border - EFI_GRAPHICS_OUTPUT_BLT_PIXEL border = {255, 255, 255, 0}; - gfx_draw_rect(win1->buffer, 300, 200, 0, 0, 300, 200, border); - // Title bar (blue strip at top) - EFI_GRAPHICS_OUTPUT_BLT_PIXEL title_bar = {180, 100, 30, 0}; - gfx_fill_rect(win1->buffer, 300, 200, 0, 0, 300, 30, title_bar); + draw_set_target(win1->buffer, 300, 200); + draw_rect(0, 0, 299, 199, win_color); + draw_set_default_target(); } // Create window 2 (offset from center) @@ -191,15 +186,10 @@ extern "C" void kernel_main() { if (win2) { layer_set_pos(win2, (int)(g_gfx.hr / 2) - 50, (int)(g_gfx.vr / 2) - 40); layer_set_z(win2, 2); - // Fill with light green EFI_GRAPHICS_OUTPUT_BLT_PIXEL win2_color = {180, 220, 140, 0}; - gfx_fill_rect(win2->buffer, 250, 180, 0, 0, 250, 180, win2_color); - // Dark border - EFI_GRAPHICS_OUTPUT_BLT_PIXEL border2 = {50, 50, 50, 0}; - gfx_draw_rect(win2->buffer, 250, 180, 0, 0, 250, 180, border2); - // Title bar - EFI_GRAPHICS_OUTPUT_BLT_PIXEL title2 = {160, 180, 100, 0}; - gfx_fill_rect(win2->buffer, 250, 180, 0, 0, 250, 28, title2); + draw_set_target(win2->buffer, 250, 180); + draw_rect(0, 0, 249, 179, win2_color); + draw_set_default_target(); } // Compositor task (replaces the old demo tasks)