Skip to content

Commit ad3d0ff

Browse files
zelenskiCS107E BOT
authored andcommitted
Framebuffer lecture
commit 1535b7198074efb50134ab75cdd580f4a36a5156 Author: Julie Zelenski <[email protected]> Date: Fri Feb 14 03:03:30 2025 -0800 Framebuffer lecture
1 parent 8cf9c30 commit ad3d0ff

File tree

13 files changed

+296
-1
lines changed

13 files changed

+296
-1
lines changed

_data/unreleased.csv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ permalink,title,released
99
"/lectures/Arithmetic/","Number Representation and Arithmetic",false
1010
"/lectures/Ben/","Magic of Computer Systems",false
1111
"/lectures/FloatingPoint_Sound/","Floating Point and Sound",false
12-
"/lectures/Framebuffer/","Graphics and the framebuffer",false
1312
"/lectures/Interrupts1/","Interrupts",false
1413
"/lectures/Interrupts2/","Interrupts, cont'd",false
1514
"/lectures/OOP/","Object-oriented programming",false

lectures/Framebuffer/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
released: true
3+
permalink: /lectures/Framebuffer/
4+
title: Graphics and the framebuffer
5+
readings: |
6+
+ [cdecl](https://cdecl.org) for unraveling C types
7+
+ Documentation for Mango Pi [Display Engine](readings/Allwinner_DE2.0_Spec_V1.0.pdf)
8+
+ [HDMI spec](https://hdmi.org/spec/index)
9+
---
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
NAME = clear
2+
3+
ARCH = -march=rv64im -mabi=lp64
4+
ASFLAGS = $(ARCH)
5+
CFLAGS = $(ARCH) -g -Og -I$$CS107E/include -Wall -ffreestanding
6+
LDFLAGS = -nostdlib -L$$CS107E/lib -T memmap.ld
7+
LDLIBS = -lmango -lmango_gcc
8+
9+
all : $(NAME).bin
10+
11+
%.bin: %.elf
12+
riscv64-unknown-elf-objcopy $< -O binary $@
13+
14+
%.elf: %.o
15+
riscv64-unknown-elf-gcc $(LDFLAGS) $^ $(LDLIBS) -o $@
16+
17+
%.o: %.c
18+
riscv64-unknown-elf-gcc $(CFLAGS) -c $< -o $@
19+
20+
%.o: %.s
21+
riscv64-unknown-elf-as $(ASFLAGS) $< -o $@
22+
23+
run: $(NAME).bin
24+
mango-run $<
25+
26+
clean:
27+
rm -f *.o *.bin *.elf *.list *~
28+
29+
.PHONY: all clean run
30+
.PRECIOUS: %.elf %.o
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Show how to clear the framebuffer memory accessing using different array layout
2+
3+
- `clear_char_by_char`: access as 1D array of unsigned char's
4+
- `clear_int_by_int`: access a 1D array of unsigned int's
5+
- `clear_2d`: access a 2D array of unsigned int's
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include "fb.h"
2+
#include "de.h"
3+
#include "hdmi.h"
4+
#include "malloc.h"
5+
#include "printf.h"
6+
#include "uart.h"
7+
#include "strings.h"
8+
9+
// module-level variables
10+
static struct {
11+
int width; // count of horizontal pixels
12+
int height; // count of vertical pixels
13+
int depth; // num bytes per pixel
14+
void *framebuffer; // address of framebuffer memory
15+
} module;
16+
17+
18+
void fb_init(int width, int height, fb_mode_t mode) {
19+
module.width = width;
20+
module.height = height;
21+
module.depth = 4; // our pixels always 32-bit
22+
int nbytes = module.width * module.height * module.depth;
23+
module.framebuffer = malloc(nbytes);
24+
// what will be contents of newly malloc'ed memory block?
25+
26+
hdmi_resolution_id_t id = hdmi_best_match(width, height); // choose from available screen resolutions
27+
hdmi_init(id);
28+
de_init(width, height, hdmi_get_screen_width(), hdmi_get_screen_height());
29+
de_set_active_framebuffer(module.framebuffer);
30+
}
31+
32+
static void clear_char_by_char(void) {
33+
uint8_t *im = module.framebuffer;
34+
int total_bytes = module.width * module.height * module.depth;
35+
// write each byte in the framebuffer
36+
for (int i = 0; i < total_bytes; i++) {
37+
*im++ = 0xff; // white
38+
}
39+
}
40+
41+
static void clear_int_by_int_green(void) {
42+
unsigned int *im = module.framebuffer;
43+
int npixels = module.width * module.height;
44+
for (int i = 0; i < npixels; i++) {
45+
*im++ = 0xff00ff00; // green
46+
}
47+
}
48+
49+
static void clear_2d_purple(void) {
50+
unsigned int (*im)[module.width] = module.framebuffer;
51+
for (int y = 0; y < module.height; y++) {
52+
for (int x = 0; x < module.width; x++) {
53+
im[y][x] = 0xffff00ff; // purple
54+
}
55+
}
56+
}
57+
58+
static bool confirm(const char *msg) {
59+
printf("Next: %s. Hit any key when ready (q to quit): ", msg);
60+
int ch = uart_getchar();
61+
printf("%c\n", ch);
62+
return ch != 'q';
63+
}
64+
65+
void main(void) {
66+
uart_init();
67+
68+
fb_init(1600, 900, FB_SINGLEBUFFER);
69+
70+
printf("Screen size %d x %d\n", hdmi_get_screen_width(), hdmi_get_screen_height());
71+
printf("Framebuffer size %d x %d\n", module.width, module.height);
72+
clear_char_by_char();
73+
while (1) {
74+
if (!confirm("clear to white, char by char")) break;
75+
clear_char_by_char();
76+
77+
if (!confirm("clear to green, int by int")) break;
78+
clear_int_by_int_green();
79+
80+
if (!confirm("clear to purple, 2-D of int")) break;
81+
clear_2d_purple();
82+
}
83+
printf("Completed %s\n", __FILE__);
84+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
NAME = joshua
2+
3+
ARCH = -march=rv64im -mabi=lp64
4+
ASFLAGS = $(ARCH)
5+
CFLAGS = $(ARCH) -g -Og -I$$CS107E/include -Wall -ffreestanding
6+
LDFLAGS = -nostdlib -L$$CS107E/lib -T memmap.ld
7+
LDLIBS = -lmango -lmango_gcc
8+
9+
all : $(NAME).bin
10+
11+
%.bin: %.elf
12+
riscv64-unknown-elf-objcopy $< -O binary $@
13+
14+
%.elf: %.o
15+
riscv64-unknown-elf-gcc $(LDFLAGS) $^ $(LDLIBS) -o $@
16+
17+
%.o: %.c
18+
riscv64-unknown-elf-gcc $(CFLAGS) -c $< -o $@
19+
20+
%.o: %.s
21+
riscv64-unknown-elf-as $(ASFLAGS) $< -o $@
22+
23+
run: $(NAME).bin
24+
mango-run $<
25+
26+
clean:
27+
rm -f *.o *.bin *.elf *.list *~
28+
29+
.PHONY: all clean run
30+
.PRECIOUS: %.elf %.o
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "console.h"
2+
#include "timer.h"
3+
4+
void main(void)
5+
{
6+
console_init(12, 26, GL_GREEN, GL_BLACK);
7+
8+
console_printf("GREETINGS PROFESSOR FALKEN\n");
9+
console_printf("\n");
10+
timer_delay_ms(2000);
11+
console_printf("HELLO\n");
12+
console_printf("\n");
13+
timer_delay_ms(2000);
14+
console_printf("A STRANGE GAME\n");
15+
timer_delay_ms(2000);
16+
console_printf("THE ONLY WINNING MOVE IS\n");
17+
timer_delay_ms(2000);
18+
console_printf("NOT TO PLAY\n");
19+
console_printf("\n");
20+
timer_delay_ms(2000);
21+
console_printf("HOW ABOUT A NICE GAME OF CHESS?\n");
22+
timer_delay(10);
23+
}
24+
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
NAME = hello
2+
3+
ARCH = -march=rv64im -mabi=lp64
4+
ASFLAGS = $(ARCH)
5+
CFLAGS = $(ARCH) -g -Og -I$$CS107E/include -Wall -ffreestanding
6+
LDFLAGS = -nostdlib -L$$CS107E/lib -T memmap.ld
7+
LDLIBS = -lmango -lmango_gcc
8+
9+
all : $(NAME).bin
10+
11+
%.bin: %.elf
12+
riscv64-unknown-elf-objcopy $< -O binary $@
13+
14+
%.elf: %.o
15+
riscv64-unknown-elf-gcc $(LDFLAGS) $^ $(LDLIBS) -o $@
16+
17+
%.o: %.c
18+
riscv64-unknown-elf-gcc $(CFLAGS) -c $< -o $@
19+
20+
%.o: %.s
21+
riscv64-unknown-elf-as $(ASFLAGS) $< -o $@
22+
23+
run: $(NAME).bin
24+
mango-run $<
25+
26+
clean:
27+
rm -f *.o *.bin *.elf *.list *~
28+
29+
.PHONY: all clean run
30+
.PRECIOUS: %.elf %.o
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
When in single buffer mode, repeatedly clear and print string will produce
2+
a lot of jitter/tearing
3+
4+
Change to double buffer mode and there is smooth transition from
5+
one frame to another, neat!
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#include "gl.h"
2+
#include "printf.h"
3+
#include "uart.h"
4+
5+
void main(void) {
6+
uart_init();
7+
gl_init(400, 300, GL_SINGLEBUFFER); // change to GL_DOUBLEBUFFER instead
8+
9+
printf("Enter any key to exit: ");
10+
while (!uart_haschar()) {
11+
gl_clear(GL_BLACK);
12+
gl_draw_string(100, 100, "hello, world 0", GL_RED);
13+
gl_swap_buffer();
14+
15+
gl_clear(GL_BLACK);
16+
gl_draw_string(100, 100, "hello, world 1", GL_BLUE);
17+
gl_swap_buffer();
18+
}
19+
printf("%c\nExiting %s\n", uart_getchar(), __FILE__);
20+
}

0 commit comments

Comments
 (0)