aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-10-12 12:10:26 +0200
committerBad Diode <bd@badd10de.dev>2022-10-12 12:10:26 +0200
commitb9d7ed276d73f671f482ca88958ac38d618f2644 (patch)
tree8bce3d9ded5a6e92d5fdfb01dbbdd5c5a20b9fa4
parente146eb61450f5c09ed81fe421eb6b8f1ca153296 (diff)
downloaduxnfb-b9d7ed276d73f671f482ca88958ac38d618f2644.tar.gz
uxnfb-b9d7ed276d73f671f482ca88958ac38d618f2644.zip
[WIP] Update screen update/refresh to avoid forking
-rw-r--r--src/main.c127
-rw-r--r--src/ppu.c46
2 files changed, 46 insertions, 127 deletions
diff --git a/src/main.c b/src/main.c
index 53aa5c3..f2d373b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -523,7 +523,8 @@ main(int argc, char *argv[]) {
523 523
524 // Main loop. 524 // Main loop.
525 Time frame_time = time_now(); 525 Time frame_time = time_now();
526 size_t frames = 0; 526 size_t frames_update = 0;
527 size_t frames_refresh = 0;
527 while (true) { 528 while (true) {
528 poll_input(); 529 poll_input();
529 size_t elapsed = time_elapsed(frame_time); 530 size_t elapsed = time_elapsed(frame_time);
@@ -535,26 +536,18 @@ main(int argc, char *argv[]) {
535 536
536 // Blit ppu.pixels to the framebuffer. 537 // Blit ppu.pixels to the framebuffer.
537 blit_framebuffer(); 538 blit_framebuffer();
538 if (++frames > 5) { 539 // TODO: make update frames and refresh frames as parameters instead
539 // memset(framebuffer, 0xFF, screen_width * screen_height * bpp); 540 // of hardcoded
540 // system("echo 0 > /dev/graphics/fb0"); 541 if (++frames_update > 5) {
541 // redraw_screen(); 542 write(fb_file, "0", 0);
542 // blit_framebuffer(); 543 frames_update = 0;
543 544 }
544 // FIXME: Thre HAS to be a better way to refresh the display lol. 545 // NOTE: Maybe this should happen on blit_framebuffer depending on
545 system("echo 0 > /dev/graphics/fb0"); 546 // the number of actual updates (uxn applications that don't modify
546 547 // the framebuffer shouldn't have to blink).
547 // Time t = time_now(); 548 if (++frames_refresh > 360) {
548 // while (time_elapsed(t) < 16666666 * 2) { 549 write(refresh_file, "1", 1);
549 // // nop wait X frames for the refresh? 550 frames_refresh = 0;
550 // }
551 // wait(ret);
552 // memset(framebuffer, 0xFF, screen_width * screen_height * bpp);
553 // redraw_screen();
554 // memset(framebuffer, 0x00, screen_width * screen_height * bpp);
555 // redraw_screen();
556
557 frames = 0;
558 } 551 }
559 frame_time = time_now(); 552 frame_time = time_now();
560 } 553 }
@@ -562,95 +555,3 @@ main(int argc, char *argv[]) {
562 555
563 return 0; 556 return 0;
564} 557}
565
566// int
567// main(int argc, char *argv[]) {
568// // FIXME: Experimental
569// int fb = open("/dev/graphics/fb0", O_RDWR);
570// if (fb <= 0) {
571// fprintf(stderr, "error: couldn't open the framebuffer\n");
572// exit(EXIT_FAILURE);
573// }
574// struct fb_var_screeninfo info;
575// if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) {
576// fprintf(stderr, "error: couldn't get the framebuffer size\n");
577// exit(EXIT_FAILURE);
578// }
579// size_t screen_width = info.xres;
580// size_t screen_height = info.yres;
581// size_t bpp = info.bits_per_pixel / 8;
582// size_t len = bpp * screen_width * screen_height;
583// u8 *framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0);
584// if (framebuffer == MAP_FAILED) {
585// fprintf(stderr, "error: couldn't mmap the framebuffer\n");
586// exit(EXIT_FAILURE);
587// }
588
589// // Print all relevant elements from the fb_var_screeninfo struct
590// printf("> xres: %d\n"
591// "> yres: %d\n"
592// "> xres_virtual: %d\n"
593// "> yres_virtual: %d\n"
594// "> xoffset: %d\n"
595// "> yoffset: %d\n"
596// "> bits_per_pixel: %d\n"
597// "> grayscale: %d\n"
598// "> activate: %d\n"
599// "> height: %d\n"
600// "> width: %d\n"
601// "> hsync_len: %d\n"
602// "> vsync_len: %d\n"
603// "> sync: %d\n"
604// "> vmode: %d\n"
605// "> rotate: %d\n"
606// "> len: %d\n",
607// info.xres,
608// info.yres,
609// info.xres_virtual,
610// info.yres_virtual,
611// info.xoffset,
612// info.yoffset,
613// info.bits_per_pixel,
614// info.grayscale,
615// info.activate,
616// info.height,
617// info.width,
618// info.hsync_len,
619// info.vsync_len,
620// info.sync,
621// info.vmode,
622// info.rotate,
623// len);
624
625
626// // Clean screen
627// // memset(framebuffer, 0x00, screen_width * screen_height * 2); // black
628// memset(framebuffer, 0xFF, len); // white
629// for (size_t i = 0, k = 0; i < (screen_width * screen_height) / 2; i++) {
630// for (size_t b = 0; b < bpp; b++) {
631// framebuffer[k++] = 0xF0;
632// }
633// // p[i] = 0xF0F0;
634// // framebuffer[k++] = 0xFF;
635// // framebuffer[k++] = 0x00;
636// }
637
638// // Main loop.
639// Time frame_time = time_now();
640// size_t frames = 0;
641// while (true) {
642// size_t elapsed = time_elapsed(frame_time);
643// if (elapsed >= 16666666) {
644
645// // FIXME: Thre HAS to be a better way lol.
646// frame_time = time_now();
647// frames++;
648// if (frames > 10) {
649// system("echo 0 > /dev/graphics/fb0");
650// frames = 0;
651// }
652// }
653// }
654
655// return 0;
656// }
diff --git a/src/ppu.c b/src/ppu.c
index 175b2a7..3afa533 100644
--- a/src/ppu.c
+++ b/src/ppu.c
@@ -25,6 +25,8 @@
25static size_t screen_width = 0; 25static size_t screen_width = 0;
26static size_t screen_height = 0; 26static size_t screen_height = 0;
27static size_t bpp = 0; 27static size_t bpp = 0;
28static int fb_file = 0;
29static int refresh_file = 0;
28 30
29static u8 *framebuffer = 0; 31static u8 *framebuffer = 0;
30 32
@@ -45,10 +47,13 @@ static u8 blending[5][16] = {
45 47
46u16 48u16
47rgb565(u32 rgba) { 49rgb565(u32 rgba) {
48 u16 r = rgba >> 16 & 0xFF; 50 u16 r = (rgba >> 16 & 0xFF);
49 u16 g = rgba >> 8 & 0xFF; 51 u16 g = (rgba >> 8 & 0xFF);
50 u16 b = rgba >> 0 & 0xFF; 52 u16 b = (rgba >> 0 & 0xFF);
51 return (r << 8) | (g << 3) | (b >> 3); 53 r = r >> 3;
54 g = g >> 2;
55 b = b >> 3;
56 return (r << 11) | (g << 5) | b;
52} 57}
53 58
54void 59void
@@ -142,13 +147,20 @@ set_tty(bool graphics) {
142int 147int
143ppu_init(void) { 148ppu_init(void) {
144 // Open frambuffer and get the size. 149 // Open frambuffer and get the size.
145 int fb = open("/dev/graphics/fb0", O_RDWR); 150 fb_file = open("/dev/graphics/fb0", O_RDWR);
146 if (fb <= 0) { 151 if (fb_file <= 0) {
147 fprintf(stderr, "error: couldn't open the framebuffer\n"); 152 fprintf(stderr, "error: couldn't open the framebuffer\n");
148 exit(EXIT_FAILURE); 153 exit(EXIT_FAILURE);
149 } 154 }
155
156 refresh_file = open("/sys/class/graphics/fb0/epd_refresh", O_RDWR);
157 if (refresh_file == 0) {
158 fprintf(stderr, "error: couldn't open the refresh file\n");
159 exit(EXIT_FAILURE);
160 }
161
150 struct fb_var_screeninfo info; 162 struct fb_var_screeninfo info;
151 if (ioctl(fb, FBIOGET_VSCREENINFO, &info) != 0) { 163 if (ioctl(fb_file, FBIOGET_VSCREENINFO, &info) != 0) {
152 fprintf(stderr, "error: couldn't get the framebuffer size\n"); 164 fprintf(stderr, "error: couldn't get the framebuffer size\n");
153 exit(EXIT_FAILURE); 165 exit(EXIT_FAILURE);
154 } 166 }
@@ -156,9 +168,9 @@ ppu_init(void) {
156 // Mmap the framebuffer to a buffer object. 168 // Mmap the framebuffer to a buffer object.
157 screen_width = info.xres; 169 screen_width = info.xres;
158 screen_height = info.yres; 170 screen_height = info.yres;
159 bpp = info.bits_per_pixel / 8; 171 bpp = info.bits_per_pixel;
160 size_t len = bpp * screen_width * screen_height; 172 size_t len = bpp / 8 * screen_width * screen_height;
161 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0); 173 framebuffer = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fb_file, 0);
162 if (framebuffer == MAP_FAILED) { 174 if (framebuffer == MAP_FAILED) {
163 fprintf(stderr, "error: couldn't mmap the framebuffer\n"); 175 fprintf(stderr, "error: couldn't mmap the framebuffer\n");
164 exit(EXIT_FAILURE); 176 exit(EXIT_FAILURE);
@@ -208,10 +220,16 @@ blit_framebuffer(void) {
208 if (dirty_lines[j] != 0) { 220 if (dirty_lines[j] != 0) {
209 for (size_t i = 0; i < screen_width; i++) { 221 for (size_t i = 0; i < screen_width; i++) {
210 size_t idx = i + j * screen_width; 222 size_t idx = i + j * screen_width;
211 u16 *p = framebuffer; 223 if (bpp == 16) {
212 p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]); 224 u16 *p = framebuffer;
213 // FIXME: can we generalize this to use bpp instead of having 225 p[idx] = rgb565(palette[pixels_fg[idx] << 2 | pixels_bg[idx]]);
214 // a version for 32/16 bit color? 226 } else if (bpp == 32) {
227 u32 *p = framebuffer;
228 p[idx] = palette[pixels_fg[idx] << 2 | pixels_bg[idx]];
229 } else {
230 fprintf(stderr, "error: wrong bits per pixel (expected 16 or 32)\n");
231 exit(EXIT_FAILURE);
232 }
215 } 233 }
216 } 234 }
217 dirty_lines[j] = 0; 235 dirty_lines[j] = 0;