PatchworkOS
Loading...
Searching...
No Matches
screen.c
Go to the documentation of this file.
1#include "screen.h"
2
3#include "region.h"
4#include "surface.h"
5
6#include <errno.h>
7#include <stdio.h>
8#include <stdlib.h>
9#include <string.h>
10#include <sys/fb.h>
11#include <sys/io.h>
12#include <sys/proc.h>
13
15static void* frontbuffer;
16static void* backbuffer;
17
20
21static void frontbuffer_init(void)
22{
23 if (readfile("/dev/fb/0/info", &info, sizeof(fb_info_t), 0) == ERR)
24 {
25 printf("dwm: failed to read framebuffer info (%s)\n", strerror(errno));
26 abort();
27 }
28
29 printf("dwm: using framebuffer '%s' width=%lu height=%lu stride=%lu format=%u\n", info.name, info.width,
31
32 fd_t fbBuffer = open("/dev/fb/0/buffer");
33 if (fbBuffer == ERR)
34 {
35 printf("dwm: failed to open framebuffer device (%s)\n", strerror(errno));
36 abort();
37 }
38
39 switch (info.format)
40 {
41 case FB_ARGB32:
42 {
44 if (frontbuffer == NULL)
45 {
46 printf("dwm: failed to map framebuffer memory (%s)\n", strerror(errno));
47 abort();
48 }
50 }
51 break;
52 default:
53 {
54 printf("dwm: unsupported framebuffer format\n");
55 abort();
56 }
57 }
58
59 close(fbBuffer);
60}
61
62static void backbuffer_init(void)
63{
65 if (backbuffer == NULL)
66 {
67 printf("dwm: failed to allocate backbuffer memory\n");
68 abort();
69 }
70}
71
72static void screen_invalidate(const rect_t* rect)
73{
74 rect_t fitRect = *rect;
75 RECT_FIT(&fitRect, &screenRect);
76 region_add(&invalidRegion, &fitRect);
77}
78
86
87void screen_deinit(void)
88{
91}
92
93void screen_transfer(surface_t* surface, const rect_t* rect)
94{
95 rect_t fitRect = *rect;
96 RECT_FIT(&fitRect, &screenRect);
97
98 point_t srcPoint = {
99 .x = MAX(fitRect.left - surface->pos.x, 0),
100 .y = MAX(fitRect.top - surface->pos.y, 0),
101 };
102 int64_t width = RECT_WIDTH(&fitRect);
103 int64_t height = RECT_HEIGHT(&fitRect);
104 for (int64_t y = 0; y < height; y++)
105 {
106 memcpy(&((pixel_t*)backbuffer)[(fitRect.left) + (fitRect.top + y) * info.stride],
107 &surface->buffer[(srcPoint.x) + (srcPoint.y + y) * surface->width], width * sizeof(pixel_t));
108 }
109 screen_invalidate(rect);
110}
111
112void screen_transfer_blend(surface_t* surface, const rect_t* rect)
113{
114 rect_t fitRect = *rect;
115 RECT_FIT(&fitRect, &screenRect);
116
117 point_t srcPoint = {
118 .x = MAX(fitRect.left - surface->pos.x, 0),
119 .y = MAX(fitRect.top - surface->pos.y, 0),
120 };
121 int64_t width = RECT_WIDTH(&fitRect);
122 int64_t height = RECT_HEIGHT(&fitRect);
123 for (int64_t y = 0; y < height; y++)
124 {
125 for (int64_t x = 0; x < width; x++)
126 {
127 pixel_t* pixel = &surface->buffer[(srcPoint.x + x) + (srcPoint.y + y) * surface->width];
128 pixel_t* out = &((pixel_t*)backbuffer)[(fitRect.left + x) + (fitRect.top + y) * info.stride];
129 PIXEL_BLEND(out, pixel);
130 }
131 }
132 screen_invalidate(&fitRect);
133}
134
136{
137 rect_t fitRect = *rect;
138 RECT_FIT(&fitRect, &screenRect);
139
140 point_t srcPoint = {
141 .x = MAX(fitRect.left - surface->pos.x, 0),
142 .y = MAX(fitRect.top - surface->pos.y, 0),
143 };
144 switch (info.format)
145 {
146 case FB_ARGB32:
147 {
148 for (int64_t y = 0; y < RECT_HEIGHT(&fitRect); y++)
149 {
150 memcpy(&((uint32_t*)frontbuffer)[(fitRect.left) + (fitRect.top + y) * info.stride],
151 &surface->buffer[(srcPoint.x) + (srcPoint.y + y) * surface->width],
152 RECT_WIDTH(&fitRect) * sizeof(uint32_t));
153 }
154 }
155 break;
156 default:
157 {
158 printf("dwm: unsupported framebuffer format\n");
159 abort();
160 }
161 }
162
164}
165
166void screen_swap(void)
167{
168 switch (info.format)
169 {
170 case FB_ARGB32:
171 {
172 for (uint64_t i = 0; i < invalidRegion.count; i++)
173 {
174 rect_t* rect = &invalidRegion.rects[i];
175 for (int64_t y = 0; y < RECT_HEIGHT(rect); y++)
176 {
177 memcpy(&((uint32_t*)frontbuffer)[(rect->left) + (rect->top + y) * info.stride],
178 &((pixel_t*)backbuffer)[(rect->left) + (rect->top + y) * info.stride],
179 RECT_WIDTH(rect) * sizeof(uint32_t));
180 }
181 }
182 }
183 break;
184 default:
185 {
186 printf("dwm: unsupported framebuffer format\n");
187 abort();
188 }
189 }
190
192}
193
195{
196 return info.width;
197}
198
200{
201 return info.height;
202}
203
205{
206 *rect = screenRect;
207}
#define errno
Error number variable.
Definition errno.h:27
@ FB_ARGB32
Definition fb.h:29
fd_t open(const char *path)
System call for opening files.
Definition open.c:9
uint64_t close(fd_t fd)
System call for closing files.
Definition close.c:9
uint64_t readfile(const char *path, void *buffer, uint64_t count, uint64_t offset)
Wrapper for reading a file directly using a path.
Definition readfile.c:3
#define MAX(x, y)
Definition math.h:15
void * mmap(fd_t fd, void *address, uint64_t length, prot_t prot)
System call to map memory from a file.
Definition mmap.c:6
uint64_t munmap(void *address, uint64_t length)
System call to unmap mapped memory.
Definition munmap.c:6
@ PROT_READ
Memory can be read from.
Definition proc.h:172
@ PROT_WRITE
Memory can be written to.
Definition proc.h:173
#define NULL
Pointer error value.
Definition NULL.h:23
#define ERR
Integer error value.
Definition ERR.h:17
__UINT64_TYPE__ fd_t
A file descriptor.
Definition fd_t.h:12
#define PIXEL_BLEND(dest, src)
Definition pixel.h:20
uint32_t pixel_t
Definition pixel.h:11
int64_t x
Definition main.c:152
int64_t y
Definition main.c:153
#define RECT_FIT(rect, parent)
Definition rect.h:73
#define RECT_INIT_DIM(x, y, width, height)
Definition rect.h:32
#define RECT_HEIGHT(rect)
Definition rect.h:39
#define RECT_WIDTH(rect)
Definition rect.h:38
static void region_add(region_t *region, const rect_t *rect)
Definition region.h:32
static void region_init(region_t *region)
Definition region.h:17
static void region_clear(region_t *region)
Definition region.h:22
static void * frontbuffer
Definition screen.c:15
void screen_swap(void)
Definition screen.c:166
void screen_transfer(surface_t *surface, const rect_t *rect)
Definition screen.c:93
static void screen_invalidate(const rect_t *rect)
Definition screen.c:72
void screen_deinit(void)
Definition screen.c:87
uint64_t screen_height(void)
Definition screen.c:199
void screen_transfer_blend(surface_t *surface, const rect_t *rect)
Definition screen.c:112
void screen_rect(rect_t *rect)
Definition screen.c:204
static region_t invalidRegion
Definition screen.c:19
void screen_transfer_frontbuffer(surface_t *surface, const rect_t *rect)
Definition screen.c:135
static void * backbuffer
Definition screen.c:16
static fb_info_t info
Definition screen.c:14
uint64_t screen_width(void)
Definition screen.c:194
void screen_init(void)
Definition screen.c:79
static void frontbuffer_init(void)
Definition screen.c:21
static rect_t screenRect
Definition screen.c:18
static void backbuffer_init(void)
Definition screen.c:62
__UINT32_TYPE__ uint32_t
Definition stdint.h:15
__UINT64_TYPE__ uint64_t
Definition stdint.h:17
__INT64_TYPE__ int64_t
Definition stdint.h:16
_PUBLIC int printf(const char *_RESTRICT format,...)
Definition printf.c:5
_PUBLIC void * malloc(size_t size)
Definition malloc.c:5
_PUBLIC _NORETURN void abort(void)
Definition abort.c:7
_PUBLIC void free(void *ptr)
Definition free.c:11
_PUBLIC char * strerror(int errnum)
Definition strerror.c:6
_PUBLIC void * memcpy(void *_RESTRICT s1, const void *_RESTRICT s2, size_t n)
Definition memcpy.c:4
_PUBLIC void * memset(void *s, int c, size_t n)
Definition memset.c:4
Framebuffer info struct.
Definition fb.h:39
uint64_t width
Definition fb.h:40
fb_format_t format
Definition fb.h:43
uint64_t stride
Definition fb.h:42
char name[MAX_NAME]
Definition fb.h:44
uint64_t height
Definition fb.h:41
int64_t y
Definition point.h:14
int64_t x
Definition point.h:13
Definition rect.h:13
int32_t top
Definition rect.h:15
int32_t left
Definition rect.h:14
rect_t rects[MAX_REGION_RECTS]
Definition region.h:11
uint64_t count
Definition region.h:12
pixel_t * buffer
Definition surface.h:27
uint32_t width
Definition surface.h:28
point_t pos
Definition surface.h:25