mirror of
https://github.com/limine-bootloader/limine
synced 2024-12-23 22:36:48 +03:00
gterm: Speed up terminal greatly by caching an alpha blent canvas of the background instead of alpha blending every pixel of the background every time
This commit is contained in:
parent
21ec72f1b7
commit
05c60bac51
@ -51,11 +51,11 @@ Some keys take *URIs* as values; these are described in the next section.
|
||||
*Globally assignable* keys are:
|
||||
* `TIMEOUT` - Specifies the timeout in seconds before the first *entry* is automatically booted. If set to `no`, disable automatic boot. If set to `0`, boots default entry instantly (see `DEFAULT_ENTRY` key).
|
||||
* `DEFAULT_ENTRY` - 1-based entry index of the entry which will be automatically selected at startup. If unspecified, it is `1`.
|
||||
* `GRAPHICS` - If set to `yes`, do use graphical VESA framebuffer for the boot menu, else use text mode.
|
||||
* `GRAPHICS` - If set to `yes`, do use graphical VESA framebuffer for the boot menu, else use text mode. Ignored with Limine UEFI.
|
||||
* `MENU_RESOLUTION` - Specify screen resolution to be used by the Limine menu in the form `<width>x<height>`. This will *only* affect the menu, not any booted OS. If not specified, Limine will pick a resolution automatically. If the resolution is not available, Limine will pick another one automatically. Ignored if `GRAPHICS` is not `yes`.
|
||||
* `MENU_BRANDING` - A string that will be displayed on top of the Limine menu.
|
||||
* `MENU_FONT` - URI path to a font file to be used instead of the default one for the menu. The font file must be a code page 437 character set comprised of 256 consecutive 8x16 glyphs bitmaps (4096 byte font file). Each glyph's bitmap must be expressed left to right (1 byte per row), and top to bottom (16 bytes per whole glyph).
|
||||
* `THEME_COLOURS` - Specifies the colour palette used by the terminal (AARRGGBB). It is a `;` separated array of 8 colours: black, red, green, brown, blue, magenta, cyan, and gray, respectively. Ignored if `GRAPHICS` is not `yes`.
|
||||
* `THEME_COLOURS` - Specifies the colour palette used by the terminal (AARRGGBB). It is a `;` separated array of 10 colours: black, red, green, brown, blue, magenta, cyan, gray, background, and foreground respectively. While an alpha transparency value can be specified for every colour, it is ignored for all but background. Ignored if `GRAPHICS` is not `yes`.
|
||||
* `THEME_COLORS` - Alias of `THEME_COLOURS`.
|
||||
* `THEME_MARGIN` - Set the amount of margin around the terminal. Ignored if `GRAPHICS` is not `yes`.
|
||||
* `THEME_MARGIN_GRADIENT` - Set the thickness in pixel for the gradient around the terminal. Ignored if `GRAPHICS` is not `yes`.
|
||||
|
@ -157,7 +157,7 @@ void text_set_cursor_pos(int x, int y) {
|
||||
draw_cursor();
|
||||
}
|
||||
|
||||
static uint8_t ansi_colours[] = { 0, 4, 2, 0x0e, 1, 5, 3, 7 };
|
||||
static uint8_t ansi_colours[] = { 0, 4, 2, 0x0e, 1, 5, 3, 7, 0, 7 };
|
||||
|
||||
void text_set_text_fg(int fg) {
|
||||
text_palette = (text_palette & 0xf0) | ansi_colours[fg];
|
||||
|
@ -40,7 +40,9 @@ EFI_STATUS EFIAPI efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
|
||||
0x000000aa, // blue
|
||||
0x00aa00aa, // magenta
|
||||
0x0000aaaa, // cyan
|
||||
0x00aaaaaa // grey
|
||||
0x00aaaaaa, // grey
|
||||
0x00000000, // background (black)
|
||||
0x00aaaaaa // foreground (white)
|
||||
};
|
||||
|
||||
term_vbe(colourscheme, 64, 0, NULL);
|
||||
|
@ -26,7 +26,7 @@ extern symbol _binary_font_bin_start;
|
||||
|
||||
static uint8_t *vga_font = NULL;
|
||||
|
||||
static uint32_t ansi_colours[8];
|
||||
static uint32_t ansi_colours[10];
|
||||
|
||||
static int frame_height, frame_width;
|
||||
|
||||
@ -35,6 +35,8 @@ static struct image *background;
|
||||
static struct gterm_char *grid = NULL;
|
||||
static struct gterm_char *front_grid = NULL;
|
||||
|
||||
static uint32_t *bg_canvas = NULL;
|
||||
|
||||
static bool double_buffer_enabled = false;
|
||||
|
||||
static bool cursor_status = true;
|
||||
@ -42,11 +44,6 @@ static bool cursor_status = true;
|
||||
static int cursor_x;
|
||||
static int cursor_y;
|
||||
|
||||
static uint32_t cursor_fg = 0x00000000;
|
||||
static uint32_t cursor_bg = 0x00ffffff;
|
||||
static uint32_t text_fg;
|
||||
static uint32_t text_bg;
|
||||
|
||||
static int rows;
|
||||
static int cols;
|
||||
static int margin_gradient;
|
||||
@ -74,16 +71,10 @@ void gterm_plot_px(int x, int y, uint32_t hex) {
|
||||
gterm_framebuffer[fb_i] = hex;
|
||||
}
|
||||
|
||||
static void _gterm_plot_bg_blent_px(int x, int y, uint32_t hex) {
|
||||
gterm_plot_px(x, y, colour_blend(hex, background->get_pixel(background, x, y)));
|
||||
}
|
||||
|
||||
void (*gterm_plot_bg_blent_px)(int x, int y, uint32_t hex) = gterm_plot_px;
|
||||
|
||||
static uint32_t blend_gradient_from_box(int x, int y, uint32_t hex) {
|
||||
if (x >= frame_width && x < frame_width + VGA_FONT_WIDTH * cols
|
||||
&& y >= frame_height && y < frame_height + VGA_FONT_HEIGHT * rows) {
|
||||
return hex;
|
||||
return colour_blend(hex, background->get_pixel(background, x, y));
|
||||
}
|
||||
|
||||
uint32_t bg_px = background->get_pixel(background, x, y);
|
||||
@ -121,53 +112,43 @@ static uint32_t blend_gradient_from_box(int x, int y, uint32_t hex) {
|
||||
return colour_blend((hex & 0xffffff) | (new_alpha << 24), bg_px);
|
||||
}
|
||||
|
||||
void gterm_plot_background(int x, int y, int width, int height) {
|
||||
void gterm_generate_canvas(void) {
|
||||
if (background) {
|
||||
for (int yy = 0; yy < height; yy++) {
|
||||
for (int xx = 0; xx < width; xx++) {
|
||||
gterm_plot_px(x + xx, y + yy, blend_gradient_from_box(xx, yy, text_bg));
|
||||
for (int y = 0; y < gterm_height; y++) {
|
||||
for (int x = 0; x < gterm_width; x++) {
|
||||
bg_canvas[y * gterm_width + x] = blend_gradient_from_box(x, y, ansi_colours[8]);
|
||||
gterm_plot_px(x, y, bg_canvas[y * gterm_width + x]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int yy = 0; yy < height; yy++) {
|
||||
for (int xx = 0; xx < width; xx++) {
|
||||
gterm_plot_px(x + xx, y + yy, text_bg);
|
||||
for (int y = 0; y < gterm_height; y++) {
|
||||
for (int x = 0; x < gterm_width; x++) {
|
||||
bg_canvas[y * gterm_width + x] = ansi_colours[8];
|
||||
gterm_plot_px(x, y, ansi_colours[8]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gterm_plot_rect(int x, int y, int width, int height, uint32_t hex) {
|
||||
for (int yy = 0; yy < height; yy++) {
|
||||
for (int xx = 0; xx < width; xx++) {
|
||||
gterm_plot_px(x + xx, y + yy, hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gterm_plot_bg_blent_rect(int x, int y, int width, int height, uint32_t hex) {
|
||||
for (int yy = 0; yy < height; yy++) {
|
||||
for (int xx = 0; xx < width; xx++) {
|
||||
gterm_plot_bg_blent_px(x + xx, y + yy, hex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct gterm_char {
|
||||
uint32_t c;
|
||||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
int fg;
|
||||
int bg;
|
||||
};
|
||||
|
||||
void gterm_plot_char(struct gterm_char *c, int x, int y) {
|
||||
uint8_t *glyph = &vga_font[(size_t)c->c * VGA_FONT_HEIGHT];
|
||||
|
||||
gterm_plot_bg_blent_rect(x, y, VGA_FONT_WIDTH, VGA_FONT_HEIGHT, c->bg);
|
||||
|
||||
for (int i = 0; i < VGA_FONT_HEIGHT; i++) {
|
||||
for (int j = 0; j < VGA_FONT_WIDTH; j++) {
|
||||
if ((glyph[i] & (0x80 >> j)))
|
||||
gterm_plot_bg_blent_px(x + j, y + i, c->fg);
|
||||
if ((glyph[i] & (0x80 >> j))) {
|
||||
gterm_plot_px(x + j, y + i, ansi_colours[c->fg]);
|
||||
} else {
|
||||
if (c->bg == 8)
|
||||
gterm_plot_px(x + j, y + i, bg_canvas[(y + i) * gterm_width + (x + j)]);
|
||||
else
|
||||
gterm_plot_px(x + j, y + i, ansi_colours[c->bg]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,16 +163,16 @@ static void plot_char_grid(struct gterm_char *c, int x, int y) {
|
||||
|
||||
static void clear_cursor(void) {
|
||||
struct gterm_char c = grid[cursor_x + cursor_y * cols];
|
||||
c.fg = text_fg;
|
||||
c.bg = text_bg;
|
||||
c.fg = 9;
|
||||
c.bg = 8;
|
||||
plot_char_grid(&c, cursor_x, cursor_y);
|
||||
}
|
||||
|
||||
static void draw_cursor(void) {
|
||||
if (cursor_status) {
|
||||
struct gterm_char c = grid[cursor_x + cursor_y * cols];
|
||||
c.fg = cursor_fg;
|
||||
c.bg = cursor_bg;
|
||||
c.fg = 0;
|
||||
c.bg = 7;
|
||||
plot_char_grid(&c, cursor_x, cursor_y);
|
||||
}
|
||||
}
|
||||
@ -206,8 +187,8 @@ static void scroll(void) {
|
||||
// Clear the last line of the screen.
|
||||
struct gterm_char empty;
|
||||
empty.c = ' ';
|
||||
empty.fg = text_fg;
|
||||
empty.bg = text_bg;
|
||||
empty.fg = 9;
|
||||
empty.bg = 8;
|
||||
for (int i = rows * cols - cols; i < rows * cols; i++) {
|
||||
plot_char_grid(&empty, i % cols, i / cols);
|
||||
}
|
||||
@ -220,8 +201,8 @@ void gterm_clear(bool move) {
|
||||
|
||||
struct gterm_char empty;
|
||||
empty.c = ' ';
|
||||
empty.fg = text_fg;
|
||||
empty.bg = text_bg;
|
||||
empty.fg = 9;
|
||||
empty.bg = 8;
|
||||
for (int i = 0; i < rows * cols; i++) {
|
||||
plot_char_grid(&empty, i % cols, i / cols);
|
||||
}
|
||||
@ -256,12 +237,14 @@ void gterm_get_cursor_pos(int *x, int *y) {
|
||||
*y = cursor_y;
|
||||
}
|
||||
|
||||
static int text_fg = 9, text_bg = 8;
|
||||
|
||||
void gterm_set_text_fg(int fg) {
|
||||
text_fg = ansi_colours[fg];
|
||||
text_fg = fg;
|
||||
}
|
||||
|
||||
void gterm_set_text_bg(int bg) {
|
||||
text_bg = ansi_colours[bg];
|
||||
text_bg = bg;
|
||||
}
|
||||
|
||||
void gterm_double_buffer_flush(void) {
|
||||
@ -395,19 +378,17 @@ bool gterm_init(int *_rows, int *_cols, uint32_t *_colours, int _margin, int _ma
|
||||
front_grid = ext_mem_alloc(rows * cols * sizeof(struct gterm_char));
|
||||
background = _background;
|
||||
|
||||
if (background)
|
||||
gterm_plot_bg_blent_px = _gterm_plot_bg_blent_px;
|
||||
|
||||
memcpy(ansi_colours, _colours, sizeof(ansi_colours));
|
||||
text_bg = ansi_colours[0];
|
||||
text_fg = ansi_colours[7];
|
||||
|
||||
margin_gradient = _margin_gradient;
|
||||
|
||||
frame_height = gterm_height / 2 - (VGA_FONT_HEIGHT * rows) / 2;
|
||||
frame_width = gterm_width / 2 - (VGA_FONT_WIDTH * cols) / 2;
|
||||
|
||||
gterm_plot_background(0, 0, gterm_width, gterm_height);
|
||||
if (bg_canvas == NULL)
|
||||
bg_canvas = ext_mem_alloc(gterm_width * gterm_height * sizeof(uint32_t));
|
||||
|
||||
gterm_generate_canvas();
|
||||
gterm_clear(true);
|
||||
|
||||
return true;
|
||||
|
@ -101,8 +101,8 @@ static void term_putchar(uint8_t c) {
|
||||
|
||||
static void sgr(void) {
|
||||
if (esc_value0 == 0){
|
||||
set_text_bg(0);
|
||||
set_text_fg(7);
|
||||
set_text_bg(8);
|
||||
set_text_fg(9);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -379,7 +379,9 @@ char *menu(char **cmdline) {
|
||||
0x000000aa, // blue
|
||||
0x00aa00aa, // magenta
|
||||
0x0000aaaa, // cyan
|
||||
0x00aaaaaa // grey
|
||||
0x00aaaaaa, // grey
|
||||
0x00000000, // background (black)
|
||||
0x00aaaaaa // foreground (grey)
|
||||
};
|
||||
|
||||
char *colours = config_get_value(NULL, 0, "THEME_COLOURS");
|
||||
@ -387,7 +389,7 @@ char *menu(char **cmdline) {
|
||||
colours = config_get_value(NULL, 0, "THEME_COLORS");
|
||||
if (colours != NULL) {
|
||||
const char *first = colours;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
for (int i = 0; i < 10; i++) {
|
||||
const char *last;
|
||||
uint32_t col = strtoui(first, &last, 16);
|
||||
if (first == last)
|
||||
|
@ -3,7 +3,7 @@ TIMEOUT=3
|
||||
GRAPHICS=yes
|
||||
MENU_FONT=boot:///boot/font.bin
|
||||
|
||||
THEME_COLOURS=60000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa
|
||||
THEME_COLOURS=000000;aa0000;00aaff;aa5500;0000aa;aa00aa;9076de;aaaaaa;60000000;aaaaaa
|
||||
THEME_MARGIN=64
|
||||
|
||||
BACKGROUND_PATH=boot:///boot/bg.bmp
|
||||
|
Loading…
Reference in New Issue
Block a user