Create separate renderer and framebuffer modules
This commit is contained in:
112
renderer.c
Normal file
112
renderer.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "renderer.h"
|
||||
|
||||
#include "fb.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <xf86drm.h>
|
||||
|
||||
static int drm_fd;
|
||||
static drmModeConnector *conn;
|
||||
static drmModeCrtc *crtc;
|
||||
static uint32_t conn_id;
|
||||
|
||||
static fb_info_t fbs[2];
|
||||
static int front, back;
|
||||
|
||||
static uint32_t width, height;
|
||||
static void page_flip_handler(int, unsigned, unsigned, unsigned, void *)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
set_pixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b)
|
||||
{
|
||||
/* x %= width; */
|
||||
/* y %= height; */
|
||||
const uint32_t offset = y * (fbs[back].pitch / 4) + x;
|
||||
assert(offset < fbs[back].size);
|
||||
fbs[back].buf[offset] = (r << 16) | (g << 8) | b;
|
||||
}
|
||||
|
||||
renderer_params_t renderer_init()
|
||||
{
|
||||
drm_fd = open("/dev/dri/card1", O_RDWR | O_CLOEXEC);
|
||||
assert(drm_fd != -1);
|
||||
|
||||
drmModeRes *res = drmModeGetResources(drm_fd);
|
||||
assert(res != nullptr);
|
||||
conn = drmModeGetConnector(drm_fd, res->connectors[0]);
|
||||
assert(conn != nullptr);
|
||||
drmModeModeInfo mode = conn->modes[0];
|
||||
conn_id = conn->connector_id;
|
||||
|
||||
fbs[0] = fb_init(drm_fd, mode);
|
||||
fbs[1] = fb_init(drm_fd, mode);
|
||||
front = 0;
|
||||
back = 1;
|
||||
|
||||
const int err = drmModeSetCrtc(
|
||||
drm_fd, res->crtcs[0], fbs[front].id, 0, 0, &conn_id, 1, &mode);
|
||||
assert(err == 0);
|
||||
crtc = drmModeGetCrtc(drm_fd, res->crtcs[0]);
|
||||
assert(crtc != nullptr);
|
||||
|
||||
drmModeFreeResources(res);
|
||||
|
||||
width = mode.hdisplay;
|
||||
height = mode.vdisplay;
|
||||
|
||||
return (renderer_params_t) {
|
||||
.drm_fd = drm_fd,
|
||||
.aspect = (float)mode.hdisplay / (float)mode.vdisplay,
|
||||
};
|
||||
}
|
||||
|
||||
void renderer_cleanup()
|
||||
{
|
||||
drmModeSetCrtc(
|
||||
drm_fd, crtc->crtc_id, crtc->buffer_id, crtc->x, crtc->y, &conn_id,
|
||||
1, &crtc->mode);
|
||||
|
||||
fb_cleanup(drm_fd, fbs[0]);
|
||||
fb_cleanup(drm_fd, fbs[1]);
|
||||
drmModeFreeCrtc(crtc);
|
||||
drmModeFreeConnector(conn);
|
||||
close(drm_fd);
|
||||
}
|
||||
|
||||
void renderer_handle()
|
||||
{
|
||||
drmEventContext ev = {
|
||||
.version = DRM_EVENT_CONTEXT_VERSION,
|
||||
.page_flip_handler = page_flip_handler,
|
||||
};
|
||||
drmHandleEvent(drm_fd, &ev);
|
||||
}
|
||||
|
||||
void renderer_clear()
|
||||
{
|
||||
memset(fbs[back].buf, 0, fbs[back].size);
|
||||
}
|
||||
|
||||
void renderer_swap()
|
||||
{
|
||||
const int err = drmModePageFlip(
|
||||
drm_fd, crtc->crtc_id, fbs[back].id, DRM_MODE_PAGE_FLIP_EVENT,
|
||||
nullptr);
|
||||
assert(err == 0);
|
||||
|
||||
front = (front + 1) & 1;
|
||||
back = (back + 1) & 1;
|
||||
}
|
||||
|
||||
void renderer_draw()
|
||||
{
|
||||
for (unsigned y = 0; y < height; ++y) {
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
set_pixel(x, y, (x * 255) / width, (y * 255) / height, 128);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user