Graphics and Framebuffers Baremetal on the Pi Raspberry Pi A+ ARM - - PowerPoint PPT Presentation

graphics and framebuffers baremetal on the pi
SMART_READER_LITE
LIVE PREVIEW

Graphics and Framebuffers Baremetal on the Pi Raspberry Pi A+ ARM - - PowerPoint PPT Presentation

Graphics and Framebuffers Baremetal on the Pi Raspberry Pi A+ ARM processor and memory Peripherals: GPIO, timers, UART (gpio, uart), keyboard Assembly and machine language (as) C and pointers (gcc) Functions and the stack (gdb) Serial


slide-1
SLIDE 1

Graphics and Framebuffers

slide-2
SLIDE 2

Baremetal on the Pi

Raspberry Pi A+ ARM processor and memory Peripherals: GPIO, timers, UART (gpio, uart), keyboard Assembly and machine language (as) C and pointers (gcc) Functions and the stack (gdb) Serial communication and strings (uart, printf) Linking and the memory map (ld, memmap, objcopy) Loading using the bootloader (rpi-install.py, bootloader) Starting (start.s, cstart.c) Memory managements Tools (git, bash, make, brew)

slide-3
SLIDE 3

The Force Awakens in You

slide-4
SLIDE 4
slide-5
SLIDE 5

gpio timer uart printf malloc keyboard fb gl console shell

slide-6
SLIDE 6
slide-7
SLIDE 7

HDMI

Clock Data 0 Data 1 Data 2 Control

Figure from High-Definition Multimedia Interface Specification Version 1.3a

slide-8
SLIDE 8

Displays

Pixels Displays Light

slide-9
SLIDE 9

The framebuffer is an image An image is a 2D array of pixels

slide-10
SLIDE 10

RGBA pixel (depth=32 bits) Red = 8 bits Green = 8 bits Blue = 8 bits Alpha = 8 bits

slide-11
SLIDE 11

Framebuffer Resolution read physical size read virtual size read pixel depth code/video

slide-12
SLIDE 12

Physical width Physical width Virtual width = 2 Virtual height = 2

2x2 image is interpolated to 1600x1200 to fill monitor

slide-13
SLIDE 13

FB Config Structure

40 bytes long, specifies 10 parameters

Field CPU GPU Description width write read Width of physical screen height write read Height of physical screen virtual_width write read Width of framebuffer virtual_height write read Height of framebuffer pitch read write Bytes/row of framebuffer depth write read Bits/pixel of framebuffer x_offset write read X offset of screen in framebuffer y_offset write read Y offset of screen in framebuffer pointer read write Pointer to framebuffer size read write Size of framebuffer in bytes

slide-14
SLIDE 14

Configure Framebuffer Resolution set physical size set virtual size set depth read pitch, size, fb pointer code/fb

slide-15
SLIDE 15

Shared Memory

frame buffer memory split between cpu & gpu

code/video

slide-16
SLIDE 16

GPU

(framebuffer)

CPU

0x020000000 0x100000000

4 GB Peripheral Registers

0x000000000

GPU 256MB CPU 256MB

slide-17
SLIDE 17

RGBA (BGRA) Pixel/Color

RGBA (BGRA) pixels are four bytes

00 00 ff ff 00 ff 00 ff ff 00 00 ff

B G R A Beware: blue is the first byte (lowest address) 0 1 2 3

slide-18
SLIDE 18

Array of unsigned char

The framebuffer is an array

unsigned char fb[2*2*4]; fb[0] = 0x00; // b fb[1] = 0x00; // g fb[2] = 0xff; // r fb[3] = 0xff; // a

00 00 ff ff

red

00 ff ff ff

yellow

ff 00 00 ff

blue

ff ff 00 ff

cyan Note: (0,0) is at the upper left corner of the monitor

slide-19
SLIDE 19

Array of unsigned char

The framebuffer is an array

unsigned char fb[2*2*4]; fb[bgra + 4*(x + 2*y)] = … bra = 0, 1, 2, or 3

00 00 ff ff

red

00 ff ff ff

yellow

ff 00 00 ff

blue

ff ff 00 ff

cyan

slide-20
SLIDE 20

Array of unsigned char

The display is a block of memory

#define DEPTH 2 #define WIDTH 2 #define HEIGHT 2 unsigned char fb[WIDTH*HEIGHT*DEPTH]; fb[bgra + DEPTH*(x + WIDTH*y)] = …

slide-21
SLIDE 21

Array of unsigned

The display is a block of memory

unsigned fb[WIDTH*HEIGHT]; fb[0] = 0xffff0000; // x=0, y=0 fb[1] = 0xffffff00; // x=1, y=0 fb[2] = 0xff0000ff; // x=0, y=1 fb[3] = 0xff00ffff; // x=1, y=1 #define DEPTH 2 #define WIDTH 2 #define HEIGHT 2 unsigned char fb[WIDTH*HEIGHT*DEPTH]; fb[rgba + DEPTH*(x + WIDTH*y)] = …

slide-22
SLIDE 22

Drawing code/clear

slide-23
SLIDE 23

2D Array of unsigned

The display is a block of memory

unsigned (*fb)[2] = (unsigned (*)[2])frame; fb[0][0] = 0xffff0000; // x=0, y=0 fb[1][0] = 0xffffff00; // x=1, y=0 fb[0][1] = 0xff0000ff; // x=0, y=1 fb[1][1] = 0xff00ffff; // x=1, y=1

What is unsigned *fb[2], (*fb)[2]?

#define DEPTH 2 #define WIDTH 2 #define HEIGHT 2 unsigned char fb[WIDTH*HEIGHT*DEPTH]; fb[rgba + DEPTH*(x + WIDTH*y)] = …

cdecl.org

slide-24
SLIDE 24

Demo draw a grid

slide-25
SLIDE 25

Double-Buffering

slide-26
SLIDE 26

Double Buffering

Writing directly to screen can cause flickering Solution: Double buffering

  • Two buffers: back-buffer and front-buffer
  • Front-buffer is being display
  • Draw into back-buffer
  • Swap buffers to update display
slide-27
SLIDE 27

Single Buffer

Virtual Width Virtual Height

Drawing directly to framebuffer lets you see the graphics as it is draw (good for debugging!) Normally we just show the result. Don't see the drawing process Double buffering: display "front- buffer" while drawing into "back"-

  • buffer. Swap buffers when you are

done drawing. Which arrangement is better?

  • r
slide-28
SLIDE 28

Double Buffer

Virtual Width Virtual Height

Double buffering:

  • Display the "front"-buffer
  • Draw into the "back"-buffer
  • Swap front and back when you are

done drawing

  • Requires 2 frame buffers
slide-29
SLIDE 29

Display Top Buffer

Virtual Width 2 * Virtual Height

x_offset = 0; y_offset = 0;

Double buffering:

  • Display the "front"-buffer
  • Draw into the "back"-buffer
  • Swap front and back when you are

done drawing

  • Requires 2 frame buffers
slide-30
SLIDE 30

Display Bottom Buffer

Virtual Width 2 * Virtual Height

x_offset = 0; y_offset = vheight;

Double buffering:

  • Display the "front"-buffer
  • Draw into the "back"-buffer
  • Swap front and back when you are

done drawing

  • Requires 2 frame buffers
slide-31
SLIDE 31

code/singlebuffer code/doublebuffer

slide-32
SLIDE 32

Drawing Text

Fonts: monospaced vs. proportional Font a set of "glyphs"

x,y x+w,y x+2w,y x+3w,y x+4w,y x+5w,y

slide-33
SLIDE 33

Mailbox

slide-34
SLIDE 34

GPU

(framebuffer)

CPU

0x020000000 0x100000000

4 GB Peripheral Registers

0x000000000

GPU 256MB CPU 256MB

slide-35
SLIDE 35

RPi Memory Map

slide-36
SLIDE 36

Coordinating CPU+GPU

CPU and GPU need to communicate

  • CPU code wants to set/change screen settings
  • GPU and CPU need to agree where frame buffer is

Danger: reading incomplete/partial data

  • They are two processors, running at different speeds, C

compiler has no knowledge of this

  • Need a simple handshake that depends on a single bit
  • "I've set this bit, which means I have sent some data to you."
  • "I've cleared the bit, which means I've read the data."
slide-37
SLIDE 37

Mailbox

CPU GPU

Memory

Mailbox

0x2000B880

code/clear/mailbox.c

slide-38
SLIDE 38

CPU "Mails" Message to GPU

CPU GPU

Memory

Mailbox

0x2000B880

code/fb/mailbox.c

slide-39
SLIDE 39

GPU Mails Reply to CPU

code/fb/mailbox.c

CPU GPU

Memory

Mailbox

0x2000B880

slide-40
SLIDE 40

Mailbox Format

Register Offset R/W Use Read 0x00 R Destructively read value Peek 0x10 R Read without removing data Sender 0x14 R Sender ID (bottom 2 bits) Status 0x18 R Status bits Configuration 0x1C RW Configuration bits Write 0x20 W Address to write data (GPU addr) F E undocumented/unused? F = Full
 E = Empty

code/fb/mailbox.c

slide-41
SLIDE 41

Mailbox Format

code/fb/mailbox.c

#define MAILBOX_BASE 0x2000B880 #define MAILBOX_FULL (1<<31) #define MAILBOX_EMPTY (1<<30) typedef struct { unsigned int read; unsigned int padding[3]; // note padding to skip 3 words unsigned int peek; unsigned int sender; unsigned int status; unsigned int configuration; unsigned int write; } mailbox_t; void mailbox_write(unsigned channel, unsigned addr) { if (channel >= MAILBOX_MAXCHANNEL) {return;} if (addr & 0xF) {return;} volatile mailbox_t *mailbox = (volatile mailbox_t *)MAILBOX_BASE; while (mailbox->status & MAILBOX_FULL) ; mailbox->write = addr + channel; }

slide-42
SLIDE 42

Framebuffer Overview

GPU refreshes the display using a framebuffer The size of the image sent to the monitor is called the physical size The size of the framebuffer image in memory is called the virtual size The CPU and GPU share the memory, and hence the frame buffer The CPU and GPU exchange messages using a mailbox

slide-43
SLIDE 43

Put It All Together graphical shell

slide-44
SLIDE 44