From 55bcdf37342d782c723166de54ff031d09b1281f Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Wed, 15 Oct 2025 19:32:21 -0700 Subject: Clear framebuffer to pink --- src/framebuffer.c | 84 +++++++++++++++++++++++++++++++++---------------------- 1 file changed, 50 insertions(+), 34 deletions(-) (limited to 'src/framebuffer.c') diff --git a/src/framebuffer.c b/src/framebuffer.c index c3845b1..6505ace 100644 --- a/src/framebuffer.c +++ b/src/framebuffer.c @@ -1,58 +1,74 @@ #include #include +#include #include #include #define WIDTH 640 #define HEIGHT 480 -#define DEPTH 32 +#define DEPTH 24 #define ALIGNMENT 16 // Framebuffer byte alignment. -typedef struct Framebuffer { - volatile void* pixels; - size_t size; -} Framebuffer; - static Framebuffer framebuffer = {}; bool framebuffer_init(uint32_t* error) { - MAIL_T uint32_t ConfigureScreen[20] = { - 80, // Size in bytes, aligned to MAIL_ALIGN. - MAILBOX_REQUEST, - TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, - TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, - TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH, - TAG_END, - 0, 0, 0 // Padding. - }; - mbox_write(PROPERTY_CHANNEL, ConfigureScreen); - const Mail* response = mbox_read(PROPERTY_CHANNEL); - if (response->code != MAILBOX_SUCCESS) { - goto end; - } - - MAIL_T uint32_t InitFramebuffer[8] = { - 32, // Size in bytes, aligned to MAIL_ALIGN. - MAILBOX_REQUEST, - TAG_FRAMEBUFFER_ALLOCATE, 8, MAILBOX_REQUEST, ALIGNMENT, 0, - TAG_END + // TODO: We can combine both messages, this one and the one below, into a + // single array and make a single call to mbox_write(). + MAIL_T uint32_t InitFramebuffer[24] = { + /*00*/96, // Size in bytes, aligned to MAIL_ALIGN. + /*01*/MAILBOX_REQUEST, + /*02*/TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, + /*07*/TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, + /*12*/TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH, + /*16*/TAG_FRAMEBUFFER_ALLOCATE, 8, MAILBOX_REQUEST, ALIGNMENT, 0, + /*21*/TAG_END, + /*22*/0, 0 // Padding. }; - mbox_write(PROPERTY_CHANNEL, InitFramebuffer); - response = mbox_read(PROPERTY_CHANNEL); - if (response->code != MAILBOX_SUCCESS) { + const uint32_t result = mbox_write(PROPERTY_CHANNEL, InitFramebuffer); + if (result != MAILBOX_SUCCESS) { goto end; } // The input mail is overwritten with the response. + // + // TAG_FRAMEBUFFER_ALLOCATE response: // u32 fb base address // u32 fb size - framebuffer.pixels = (void*)(uintptr_t)InitFramebuffer[5]; - framebuffer.size = InitFramebuffer[6]; - + // TODO: Do we need & 0x3FFFFFFF? Something about converting GPU address space + // to ARM address space. + // TODO: Should we read back the pitch, or does pitch match width? + framebuffer = (Framebuffer) { + .pixels = (Pixel*)((uintptr_t)InitFramebuffer[19] & 0x3FFFFFFF), + .size = InitFramebuffer[20], + .width = InitFramebuffer[5], + .height = InitFramebuffer[6], + .depth = InitFramebuffer[15] + }; + end: - *error = response->code; - return response->code == MAILBOX_SUCCESS; + *error = result; + return result == MAILBOX_SUCCESS; +} + +const Framebuffer* framebuffer_get() { + return &framebuffer; +} + +void framebuffer_present(const Pixel* pixels) { + memcpy(framebuffer.pixels, pixels, framebuffer.size); +} + +void framebuffer_clear(Pixel colour) { + const uint32_t num_channels = framebuffer.depth / 8; + const uint32_t num_pixels = framebuffer.size / num_channels; + volatile Pixel* fb = framebuffer.pixels; + for (size_t i = 0; i < num_pixels; i++) { + fb->r = colour.r; + fb->g = colour.g; + fb->b = colour.b; + fb++; + } } -- cgit v1.2.3