summaryrefslogtreecommitdiff
path: root/src/framebuffer.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-10-15 19:32:21 -0700
committer3gg <3gg@shellblade.net>2025-10-15 19:32:21 -0700
commit55bcdf37342d782c723166de54ff031d09b1281f (patch)
tree11a95bfb390ba6f73e122a17fe0a00312f25dc78 /src/framebuffer.c
parentc099bcb7402421985e6e8c025e8cde591eaa073a (diff)
Clear framebuffer to pink
Diffstat (limited to 'src/framebuffer.c')
-rw-r--r--src/framebuffer.c84
1 files changed, 50 insertions, 34 deletions
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 @@
1#include <framebuffer.h> 1#include <framebuffer.h>
2 2
3#include <mailbox.h> 3#include <mailbox.h>
4#include <string.h>
4 5
5#include <stddef.h> 6#include <stddef.h>
6#include <stdint.h> 7#include <stdint.h>
7 8
8#define WIDTH 640 9#define WIDTH 640
9#define HEIGHT 480 10#define HEIGHT 480
10#define DEPTH 32 11#define DEPTH 24
11#define ALIGNMENT 16 // Framebuffer byte alignment. 12#define ALIGNMENT 16 // Framebuffer byte alignment.
12 13
13typedef struct Framebuffer {
14 volatile void* pixels;
15 size_t size;
16} Framebuffer;
17
18static Framebuffer framebuffer = {}; 14static Framebuffer framebuffer = {};
19 15
20bool framebuffer_init(uint32_t* error) { 16bool framebuffer_init(uint32_t* error) {
21 MAIL_T uint32_t ConfigureScreen[20] = { 17 // TODO: We can combine both messages, this one and the one below, into a
22 80, // Size in bytes, aligned to MAIL_ALIGN. 18 // single array and make a single call to mbox_write().
23 MAILBOX_REQUEST, 19 MAIL_T uint32_t InitFramebuffer[24] = {
24 TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, 20 /*00*/96, // Size in bytes, aligned to MAIL_ALIGN.
25 TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT, 21 /*01*/MAILBOX_REQUEST,
26 TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH, 22 /*02*/TAG_FRAMEBUFFER_SET_PHYSICAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT,
27 TAG_END, 23 /*07*/TAG_FRAMEBUFFER_SET_VIRTUAL_SCREEN_SIZE, 8, MAILBOX_REQUEST, WIDTH, HEIGHT,
28 0, 0, 0 // Padding. 24 /*12*/TAG_FRAMEBUFFER_SET_DEPTH, 4, MAILBOX_REQUEST, DEPTH,
29 }; 25 /*16*/TAG_FRAMEBUFFER_ALLOCATE, 8, MAILBOX_REQUEST, ALIGNMENT, 0,
30 mbox_write(PROPERTY_CHANNEL, ConfigureScreen); 26 /*21*/TAG_END,
31 const Mail* response = mbox_read(PROPERTY_CHANNEL); 27 /*22*/0, 0 // Padding.
32 if (response->code != MAILBOX_SUCCESS) {
33 goto end;
34 }
35
36 MAIL_T uint32_t InitFramebuffer[8] = {
37 32, // Size in bytes, aligned to MAIL_ALIGN.
38 MAILBOX_REQUEST,
39 TAG_FRAMEBUFFER_ALLOCATE, 8, MAILBOX_REQUEST, ALIGNMENT, 0,
40 TAG_END
41 }; 28 };
42 mbox_write(PROPERTY_CHANNEL, InitFramebuffer); 29 const uint32_t result = mbox_write(PROPERTY_CHANNEL, InitFramebuffer);
43 response = mbox_read(PROPERTY_CHANNEL); 30 if (result != MAILBOX_SUCCESS) {
44 if (response->code != MAILBOX_SUCCESS) {
45 goto end; 31 goto end;
46 } 32 }
47 33
48 // The input mail is overwritten with the response. 34 // The input mail is overwritten with the response.
35 //
36 // TAG_FRAMEBUFFER_ALLOCATE response:
49 // u32 fb base address 37 // u32 fb base address
50 // u32 fb size 38 // u32 fb size
51 framebuffer.pixels = (void*)(uintptr_t)InitFramebuffer[5]; 39 // TODO: Do we need & 0x3FFFFFFF? Something about converting GPU address space
52 framebuffer.size = InitFramebuffer[6]; 40 // to ARM address space.
53 41 // TODO: Should we read back the pitch, or does pitch match width?
42 framebuffer = (Framebuffer) {
43 .pixels = (Pixel*)((uintptr_t)InitFramebuffer[19] & 0x3FFFFFFF),
44 .size = InitFramebuffer[20],
45 .width = InitFramebuffer[5],
46 .height = InitFramebuffer[6],
47 .depth = InitFramebuffer[15]
48 };
49
54end: 50end:
55 *error = response->code; 51 *error = result;
56 return response->code == MAILBOX_SUCCESS; 52 return result == MAILBOX_SUCCESS;
53}
54
55const Framebuffer* framebuffer_get() {
56 return &framebuffer;
57}
58
59void framebuffer_present(const Pixel* pixels) {
60 memcpy(framebuffer.pixels, pixels, framebuffer.size);
61}
62
63void framebuffer_clear(Pixel colour) {
64 const uint32_t num_channels = framebuffer.depth / 8;
65 const uint32_t num_pixels = framebuffer.size / num_channels;
66 volatile Pixel* fb = framebuffer.pixels;
67 for (size_t i = 0; i < num_pixels; i++) {
68 fb->r = colour.r;
69 fb->g = colour.g;
70 fb->b = colour.b;
71 fb++;
72 }
57} 73}
58 74