gol: Use memory-mapped IO
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
b5d146b492
commit
bfcca3a220
35
apps/gol.cpp
35
apps/gol.cpp
@ -6,6 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
@ -24,6 +25,7 @@ static int g_fb_height;
|
|||||||
static int g_fd;
|
static int g_fd;
|
||||||
|
|
||||||
static Cell* g_cells;
|
static Cell* g_cells;
|
||||||
|
static char* g_fb;
|
||||||
|
|
||||||
static Result<void> fill_cells()
|
static Result<void> fill_cells()
|
||||||
{
|
{
|
||||||
@ -47,27 +49,29 @@ static Cell& find_cell(int row, int column)
|
|||||||
|
|
||||||
static constexpr int BYTES_PER_PIXEL = 4;
|
static constexpr int BYTES_PER_PIXEL = 4;
|
||||||
|
|
||||||
static char* g_buf;
|
|
||||||
|
|
||||||
static void draw_cells()
|
static void draw_cells()
|
||||||
{
|
{
|
||||||
lseek(g_fd, 0, SEEK_SET);
|
|
||||||
|
|
||||||
const int CELL_WIDTH = g_fb_width / g_num_columns;
|
const int CELL_WIDTH = g_fb_width / g_num_columns;
|
||||||
const int CELL_HEIGHT = g_fb_height / g_num_rows;
|
const int CELL_HEIGHT = g_fb_height / g_num_rows;
|
||||||
|
|
||||||
for (int i = 0; i < g_num_rows; i++)
|
for (int i = 0; i < g_num_rows; i++)
|
||||||
{
|
{
|
||||||
memset(g_buf, 0, g_fb_width * BYTES_PER_PIXEL);
|
|
||||||
|
|
||||||
for (int j = 0; j < g_num_columns; j++)
|
for (int j = 0; j < g_num_columns; j++)
|
||||||
{
|
{
|
||||||
auto& cell = find_cell(i, j);
|
char* buf = g_fb + (i * g_fb_width * CELL_HEIGHT * BYTES_PER_PIXEL);
|
||||||
if (cell.state) memset(g_buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), 0xff, CELL_WIDTH * BYTES_PER_PIXEL);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int j = 0; j < CELL_HEIGHT; j++) { write(g_fd, g_buf, g_fb_width * BYTES_PER_PIXEL); }
|
auto& cell = find_cell(i, j);
|
||||||
|
u8 color = cell.state ? 0xff : 0x00;
|
||||||
|
for (int k = 0; k < CELL_HEIGHT; k++)
|
||||||
|
{
|
||||||
|
memset(buf + (j * CELL_WIDTH * BYTES_PER_PIXEL), color, CELL_WIDTH * BYTES_PER_PIXEL);
|
||||||
|
buf += g_fb_width * BYTES_PER_PIXEL;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
msync(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL, MS_SYNC);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int find_neighbors(int row, int column)
|
static int find_neighbors(int row, int column)
|
||||||
@ -137,7 +141,7 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
else
|
else
|
||||||
srand((unsigned)time(NULL));
|
srand((unsigned)time(NULL));
|
||||||
|
|
||||||
g_fd = open("/dev/fb0", O_WRONLY);
|
g_fd = open("/dev/fb0", O_RDWR);
|
||||||
if (g_fd < 0)
|
if (g_fd < 0)
|
||||||
{
|
{
|
||||||
perror("gol: cannot open framebuffer for writing");
|
perror("gol: cannot open framebuffer for writing");
|
||||||
@ -149,7 +153,13 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
TRY(fill_cells());
|
TRY(fill_cells());
|
||||||
|
|
||||||
g_buf = (char*)TRY(calloc_impl(g_fb_width, BYTES_PER_PIXEL));
|
g_fb =
|
||||||
|
(char*)mmap(nullptr, g_fb_height * g_fb_width * BYTES_PER_PIXEL, PROT_READ | PROT_WRITE, MAP_SHARED, g_fd, 0);
|
||||||
|
if (g_fb == MAP_FAILED)
|
||||||
|
{
|
||||||
|
perror("gol: cannot map framebuffer into memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
draw_cells();
|
draw_cells();
|
||||||
|
|
||||||
@ -162,5 +172,8 @@ Result<int> luna_main(int argc, char** argv)
|
|||||||
|
|
||||||
usleep(delay_at_end * 1000);
|
usleep(delay_at_end * 1000);
|
||||||
|
|
||||||
|
munmap(g_fb, g_fb_height * g_fb_width * BYTES_PER_PIXEL);
|
||||||
|
free(g_cells);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user