Monorepo for Aesthetic.Computer
aesthetic.computer
1#ifndef AC_DRM_DISPLAY_H
2#define AC_DRM_DISPLAY_H
3
4#include <stdint.h>
5#include <xf86drm.h>
6#include <xf86drmMode.h>
7#include "framebuffer.h"
8#include "graph.h"
9
10// SDL3 loaded via dlopen at runtime — no header dependency
11
12typedef struct {
13 int fd; // DRM or fbdev device fd
14 uint32_t connector_id;
15 uint32_t crtc_id;
16 uint32_t encoder_id;
17 drmModeModeInfo mode; // Display mode (resolution, refresh)
18 int width, height;
19
20 // Double buffering
21 struct {
22 uint32_t handle;
23 uint32_t fb_id;
24 uint32_t pitch;
25 uint32_t size;
26 uint32_t *map; // mmap'd pixel buffer
27 } buffers[2];
28 int front; // Currently displayed buffer index
29
30 // Saved CRTC for cleanup
31 drmModeCrtc *saved_crtc;
32
33 // fbdev fallback
34 int is_fbdev; // 1 if using /dev/fb0 instead of DRM
35 uint32_t *fbdev_map; // fbdev mmap
36 uint32_t fbdev_size; // fbdev map size
37 int fbdev_stride; // fbdev line length in pixels
38 int fbdev_swap_rb; // 1 if need to swap R and B channels (BGR format)
39
40 // SDL3 GPU-accelerated display (loaded via dlopen — void* to avoid header dep)
41 int is_sdl; // 1 if using SDL3 backend
42 void *sdl_window;
43 void *sdl_renderer;
44 void *sdl_texture;
45 int sdl_tex_w, sdl_tex_h; // texture dimensions (matches small framebuffer)
46 char sdl_renderer_name[32]; // renderer driver name (e.g. "opengl", "vulkan")
47} ACDisplay;
48
49// Get display driver name ("sdl3:opengl", "drm", "fbdev", "wayland")
50const char *drm_display_driver(ACDisplay *d);
51
52// Initialize display (tries SDL3 GPU first if available, then DRM, then fbdev)
53ACDisplay *drm_init(void);
54
55// Present the small framebuffer scaled up to the display
56// This is the primary display function — handles GPU texture upload or CPU scaling
57void display_present(ACDisplay *d, ACFramebuffer *screen, int scale);
58
59// Flip to the back buffer (makes it visible) — used by non-SDL3 paths
60void drm_flip(ACDisplay *d);
61
62// Get pointer to the back buffer (the one to draw into)
63uint32_t *drm_back_buffer(ACDisplay *d);
64int drm_back_stride(ACDisplay *d);
65
66// Get pointer to the front buffer (currently displayed — writes are immediate)
67uint32_t *drm_front_buffer(ACDisplay *d);
68int drm_front_stride(ACDisplay *d);
69
70// Secondary display (HDMI out) — double-buffered, low-res internal render
71typedef struct {
72 int active;
73 int fd;
74 uint32_t connector_id;
75 uint32_t crtc_id;
76 drmModeModeInfo mode;
77 int width, height;
78 struct {
79 uint32_t handle, fb_id, pitch, size;
80 uint32_t *map;
81 } bufs[2]; // Double buffers (back/front)
82 int buf_front; // Which buffer is currently displayed
83 drmModeCrtc *saved_crtc;
84 ACFramebuffer *small_fb; // 1/8-scale internal render target (fast)
85} ACSecondaryDisplay;
86
87// Initialize secondary HDMI display (call after drm_init, returns NULL if no HDMI)
88ACSecondaryDisplay *drm_init_secondary(ACDisplay *primary);
89
90// Check if an HDMI/DP connector (other than primary) is connected
91int drm_secondary_is_connected(ACDisplay *primary);
92
93// Render waveform + resolution text to HDMI back buffer and flip
94void drm_secondary_present_waveform(ACSecondaryDisplay *s, ACGraph *g,
95 float *waveform, int wf_size, int wf_pos);
96
97// Fill secondary display with solid color (legacy)
98void drm_secondary_fill(ACSecondaryDisplay *s, uint8_t r, uint8_t g, uint8_t b);
99
100// Cleanup secondary display
101void drm_secondary_destroy(ACSecondaryDisplay *s);
102
103// Cleanup
104void drm_destroy(ACDisplay *d);
105
106#endif