feat: expand Intel GPU display management

This commit is contained in:
2026-07-30 17:12:08 +01:00
parent 86de3400a9
commit 471903bafb
25 changed files with 1715 additions and 16 deletions
+39 -5
View File
@@ -161,24 +161,58 @@ struct Canvas {
// ---- Text ----
void text_bitmap(int x, int y, const char* str, Color c, int scale = 1) {
if (!str || !font_data || scale <= 0) return;
uint32_t pixel = c.to_pixel();
int cx = x;
for (int i = 0; str[i]; i++, cx += FONT_WIDTH * scale) {
const uint8_t* glyph =
&font_data[(unsigned char)str[i] * FONT_HEIGHT];
for (int row = 0; row < FONT_HEIGHT; row++) {
uint8_t bits = glyph[row];
if (!bits) continue;
for (int col = 0; col < FONT_WIDTH; col++) {
if (!(bits & (0x80 >> col))) continue;
int px = cx + col * scale;
int py = y + row * scale;
for (int sy = 0; sy < scale; sy++) {
int dy = py + sy;
if (dy < 0 || dy >= h) continue;
for (int sx = 0; sx < scale; sx++) {
int dx = px + sx;
if (dx >= 0 && dx < w) pixels[dy * w + dx] = pixel;
}
}
}
}
}
}
void text(int x, int y, const char* str, Color c) {
if (fonts::system_font && fonts::system_font->valid) {
fonts::system_font->draw_to_buffer(pixels, w, h, x, y, str, c, fonts::UI_SIZE);
if (fonts::system_font->draw_to_buffer(
pixels, w, h, x, y, str, c, fonts::UI_SIZE))
return;
}
text_bitmap(x, y, str, c);
}
void text_2x(int x, int y, const char* str, Color c) {
if (fonts::system_font && fonts::system_font->valid) {
fonts::system_font->draw_to_buffer(pixels, w, h, x, y, str, c, fonts::LARGE_SIZE);
if (fonts::system_font->draw_to_buffer(
pixels, w, h, x, y, str, c, fonts::LARGE_SIZE))
return;
}
text_bitmap(x, y, str, c, 2);
}
void text_mono(int x, int y, const char* str, Color c) {
if (fonts::mono && fonts::mono->valid) {
fonts::mono->draw_to_buffer(pixels, w, h, x, y, str, c, fonts::TERM_SIZE);
return;
if (fonts::mono->draw_to_buffer(
pixels, w, h, x, y, str, c, fonts::TERM_SIZE))
return;
}
text(x, y, str, c);
text_bitmap(x, y, str, c);
}
// ---- Icons ----
+4 -2
View File
@@ -14,8 +14,10 @@ namespace gui {
static constexpr int FONT_WIDTH = 8;
static constexpr int FONT_HEIGHT = 16;
// Defined in font_data.cpp
extern const uint8_t font_data[256 * 16];
// Defined by programs that ship the built-in VGA fallback. Keep the symbol
// weak so Canvas remains usable by small apps that intentionally rely only on
// TrueType fonts, while login/desktop can recover when TrueType setup fails.
extern const uint8_t font_data[256 * 16] __attribute__((weak));
// Dynamic font height: TTF line height or 16 (bitmap fallback)
inline int system_font_height() {
+17 -1
View File
@@ -8,6 +8,7 @@
#include <cstdint>
#include <montauk/syscall.h>
#include <montauk/string.h>
#include <montauk/config.h>
#include "gui/gui.hpp"
namespace gui {
@@ -61,6 +62,20 @@ class Framebuffer {
return 0xFF000000 | (rr << 16) | (gg << 8) | bb;
}
static bool prefer_hardware_page_flip() {
char user[64] = {};
if (montauk::getuser(user, sizeof(user)) > 0 && user[0]) {
auto doc = montauk::config::load_user(user, "display");
bool enabled = doc.get_bool("graphics.tear_free", true);
doc.destroy();
return enabled;
}
auto doc = montauk::config::load("display");
bool enabled = doc.get_bool("graphics.tear_free", true);
doc.destroy();
return enabled;
}
public:
Framebuffer() : hw_fb(nullptr), hw_fb2(nullptr), back_buf(nullptr),
fb_width(0), fb_height(0), fb_pitch(0), hw_next(1) {
@@ -76,7 +91,8 @@ public:
// Hardware page flipping: fb_map() maps the second scanout buffer
// directly after the first when the kernel supports flipping.
if (hw_fb && montauk::fb_flip(-1, 0) == 1) {
if (hw_fb && prefer_hardware_page_flip()
&& montauk::fb_flip(-1, 0) == 1) {
uint64_t pages = ((uint64_t)fb_height * fb_pitch + 0xFFF) / 0x1000;
hw_fb2 = (uint32_t*)((uint8_t*)hw_fb + pages * 0x1000);
}
+5 -2
View File
@@ -311,13 +311,14 @@ struct TrueTypeFont {
draw(fb, x, y, text, fg, pixel_size);
}
void draw_to_buffer(uint32_t* pixels, int buf_w, int buf_h,
bool draw_to_buffer(uint32_t* pixels, int buf_w, int buf_h,
int x, int y, const char* text,
Color color, int pixel_size) {
if (!valid) return;
if (!valid) return false;
GlyphCache* gc = get_cache(pixel_size);
int cx = x;
int baseline = y + gc->ascent;
bool drew_pixel = false;
for (int i = 0; text[i]; i++) {
CachedGlyph* g = get_glyph(gc, (unsigned char)text[i]);
@@ -334,6 +335,7 @@ struct TrueTypeFont {
if (dx < 0 || dx >= buf_w) continue;
uint8_t alpha = g->bitmap[row * g->width + col];
if (alpha == 0) continue;
drew_pixel = true;
if (alpha == 255) {
pixels[dy * buf_w + dx] =
@@ -356,6 +358,7 @@ struct TrueTypeFont {
}
cx += g->advance;
}
return drew_pixel;
}
// Draw text to buffer with clip rectangle (pixels outside clip_x..clip_x+clip_w are not drawn)