feat: vsync and double buffer for framebuffer
This commit is contained in:
parent
4041117faf
commit
1676583d3b
|
@ -49,6 +49,8 @@ struct swwApp
|
|||
{
|
||||
struct termios term;
|
||||
|
||||
uint8_t* fb;
|
||||
|
||||
int fbfd;
|
||||
int xres;
|
||||
int yres;
|
||||
|
@ -68,12 +70,15 @@ struct swwWindow
|
|||
{
|
||||
swwImage* surface;
|
||||
|
||||
/* Poistion on display(framebuffer) */
|
||||
uint32_t x, y;
|
||||
|
||||
/* common data */
|
||||
swwWindowCallback callback;
|
||||
void* userdata;
|
||||
};
|
||||
|
||||
swwApp g_app = {{0}, 0, 0, 0, 0, 0, NULL, {-1}, 0, {0}, {0}};
|
||||
swwApp g_app = {{0}, NULL, 0, 0, 0, 0, 0, NULL, {-1}, 0, {0}, {0}};
|
||||
|
||||
/* Signal Handler */
|
||||
typedef enum
|
||||
|
@ -291,8 +296,6 @@ void swwApp_Initialize()
|
|||
// EnableRawMode();
|
||||
struct fb_var_screeninfo vinfo;
|
||||
struct fb_fix_screeninfo finfo;
|
||||
long int screensize = 0;
|
||||
char* fbp = 0;
|
||||
|
||||
g_app.fbfd = open("/dev/fb0", O_RDWR);
|
||||
if (g_app.fbfd == -1) {
|
||||
|
@ -315,6 +318,13 @@ void swwApp_Initialize()
|
|||
exit(4);
|
||||
}
|
||||
|
||||
g_app.fb = (uint8_t*)mmap(0, g_app.xres * g_app.yres * 4, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
g_app.fbfd, 0);
|
||||
if (g_app.fb == (void*)-1) {
|
||||
perror("Error: failed to map framebuffer device to memory");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
g_app.xres = vinfo.xres;
|
||||
g_app.yres = vinfo.yres;
|
||||
|
||||
|
@ -354,6 +364,8 @@ void swwApp_Cleanup()
|
|||
close(g_app.event_source[i].fd);
|
||||
}
|
||||
}
|
||||
|
||||
munmap(g_app.fb, g_app.xres * g_app.yres * 4);
|
||||
close(g_app.fbfd);
|
||||
// DisableRawMode();
|
||||
}
|
||||
|
@ -391,22 +403,11 @@ swwWindow* swwWindow_Create(const char* title, uint32_t width, uint32_t height)
|
|||
|
||||
assert(width > 0 && height > 0 && width < g_app.xres && height < g_app.yres);
|
||||
|
||||
int screensize = g_app.xres * g_app.yres * 4;
|
||||
|
||||
uint8_t* fbp = (uint8_t*)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, g_app.fbfd, 0);
|
||||
if (fbp == (void*)-1) {
|
||||
perror("Error: failed to map framebuffer device to memory");
|
||||
exit(5);
|
||||
}
|
||||
|
||||
o = (swwWindow*)malloc(sizeof(swwWindow));
|
||||
memset(o, 0, sizeof(swwWindow));
|
||||
o->surface = swwImage_Create(10, 10, 4);
|
||||
// NOTE(donkey): An guly patch, the buffer will be allocated by mmap
|
||||
free(o->surface->buffer);
|
||||
o->surface->buffer = fbp;
|
||||
o->surface->width = g_app.xres;
|
||||
o->surface->height = g_app.yres;
|
||||
o->surface = swwImage_Create(width, height, 4);
|
||||
o->x = (g_app.xres - width) >> 1; // divided by 2
|
||||
o->y = (g_app.yres - height) >> 1; // divided by 2
|
||||
|
||||
g_app.window = o;
|
||||
++g_app.window_count;
|
||||
|
@ -417,15 +418,34 @@ swwWindow* swwWindow_Create(const char* title, uint32_t width, uint32_t height)
|
|||
void swwWindow_Destroy(swwWindow* o)
|
||||
{
|
||||
if (o != NULL) {
|
||||
munmap(o->surface->buffer, o->surface->width * o->surface->height * 4);
|
||||
swwImage_Destroy(o->surface);
|
||||
free(o);
|
||||
--g_app.window_count;
|
||||
g_app.window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void swwWindow_Present(swwWindow* window)
|
||||
{}
|
||||
void swwWindow_Present(swwWindow* o)
|
||||
{
|
||||
int i = 0;
|
||||
/* Start position: <fb4pixels>[y][x] */
|
||||
uint8_t* start = g_app.fb + (((o->y * g_app.xres) + o->x) << 2);
|
||||
uint8_t* buf = o->surface->buffer;
|
||||
size_t line_size = o->o->surface->width << 2;
|
||||
|
||||
// VSYNC
|
||||
int zero = 0;
|
||||
int ret = ioctl(g_app.fbfd, FBIO_WAITFORVSYNC, &zero);
|
||||
|
||||
if (ret != 0) {
|
||||
perror("Failed to do VSYNC!");
|
||||
}
|
||||
|
||||
/* Copy the window buffer to framebuffer line by line */
|
||||
for (; i < o->height; ++i, start += (g_app.xres << 2), buf += line_size) {
|
||||
memcpy(start, buf, line_size);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t* swwWindow_LockBuffer(swwWindow* o)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue