[fix] Draw effect target

This commit is contained in:
2026-06-05 18:03:13 +08:00
Unverified
parent 5a31effcf1
commit 7c66610c13
9 changed files with 85 additions and 103 deletions
+1 -1
View File
@@ -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)
+22
View File
@@ -1,15 +1,37 @@
// GFX 存在的意义是什么?
// 每一次想要draw pixel,都需要传入GOP的各种参数,
// 加入 GFX 后,GOP 的context就是全局的,可以直接用
// 而不用显示传递参数到draw的函数里
#include <graphics/context.h>
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;
}
+29 -3
View File
@@ -1,10 +1,36 @@
#include <graphics/draw.h>
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;
}
}
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);
}
-61
View File
@@ -1,61 +0,0 @@
#include <graphics/rect.h>
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;
}
}
}
+12 -2
View File
@@ -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(相当于重置)
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);
+7 -1
View File
@@ -3,4 +3,10 @@
#include <efi.h>
#include <graphics/context.h>
void draw_pixel(unsigned int x, unsigned int y, EFI_GRAPHICS_OUTPUT_BLT_PIXEL color); // 画像素
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);
-13
View File
@@ -1,13 +0,0 @@
#pragma once
#include <efi.h>
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);
+4 -2
View File
@@ -1,5 +1,5 @@
#include <graphics/layer.h>
#include <graphics/rect.h>
#include <graphics/draw.h>
#include <graphics/context.h>
#include <memory/heap.h>
#include <memory/pmm.h>
@@ -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;
+10 -20
View File
@@ -1,7 +1,6 @@
#include <efi.h>
#include <graphics/context.h>
#include <graphics/draw.h>
#include <graphics/rect.h>
#include <graphics/layer.h>
#include <fonts/pixel_font.h>
#include <serial.h>
@@ -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)