diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/main.c | 7 | ||||
-rw-r--r-- | src/mem_fb.c | 166 |
3 files changed, 174 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 65b7626..89120ad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,7 +7,7 @@ libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la m if ENABLE_ROTOTILLER bin_PROGRAMS = rototiller -rototiller_SOURCES = fps.c fps.h main.c setup.h setup.c til.h til_fb.c til_fb.h til_knobs.h til_settings.c til_settings.h til_threads.c til_threads.h til_util.c til_util.h +rototiller_SOURCES = fps.c fps.h main.c mem_fb.c setup.h setup.c til.h til_fb.c til_fb.h til_knobs.h til_settings.c til_settings.h til_threads.c til_threads.h til_util.c til_util.h if ENABLE_SDL rototiller_SOURCES += sdl_fb.c endif @@ -34,6 +34,7 @@ #endif extern til_fb_ops_t drm_fb_ops; +extern til_fb_ops_t mem_fb_ops; extern til_fb_ops_t sdl_fb_ops; static til_fb_ops_t *fb_ops; @@ -74,6 +75,7 @@ static int setup_video(til_settings_t *settings, til_setting_t **res_setting, co #ifdef HAVE_DRM "drm", #endif + "mem", #ifdef HAVE_SDL "sdl", #endif @@ -106,6 +108,11 @@ static int setup_video(til_settings_t *settings, til_setting_t **res_setting, co return drm_fb_ops.setup(settings, res_setting, res_desc, res_setup); } #endif + if (!strcasecmp(video, "mem")) { + fb_ops = &mem_fb_ops; + + return mem_fb_ops.setup(settings, res_setting, res_desc, res_setup); + } #ifdef HAVE_SDL if (!strcasecmp(video, "sdl")) { fb_ops = &sdl_fb_ops; diff --git a/src/mem_fb.c b/src/mem_fb.c new file mode 100644 index 0000000..a564c1f --- /dev/null +++ b/src/mem_fb.c @@ -0,0 +1,166 @@ +#include <assert.h> +#include <stdlib.h> + +#include "til_fb.h" +#include "til_settings.h" +#include "til_util.h" + +/* dummy mem_fb backend; render to anonymous memory */ +/* useful for testing/debugging, and benchmarking systems even if headless */ + +typedef struct mem_fb_page_t mem_fb_page_t; + +struct mem_fb_page_t { + void *unused; + uint32_t buf[]; +}; + +typedef struct mem_fb_setup_t { + til_setup_t til_setup; + unsigned width, height; +} mem_fb_setup_t; + +typedef struct mem_fb_t { + mem_fb_setup_t setup; +} mem_fb_t; + + +static int mem_fb_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup) +{ + const char *size; + int r; + + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Virtual window size", + .key = "size", + .regex = "[1-9][0-9]*[xX][1-9][0-9]*", + .preferred = "640x480", + .values = NULL, + .annotations = NULL + }, + &size, + res_setting, + res_desc); + if (r) + return r; + + if (res_setup) { + mem_fb_setup_t *setup; + + setup = til_setup_new(sizeof(*setup), (void(*)(til_setup_t *))free); + if (!setup) + return -ENOMEM; + + /* TODO FIXME: parse errors */ + sscanf(size, "%ux%u", &setup->width, &setup->height); + + *res_setup = &setup->til_setup; + } + + return 0; +} + + +static int mem_fb_init(const til_setup_t *setup, void **res_context) +{ + mem_fb_t *c; + int r; + + assert(setup); + assert(res_context); + + c = calloc(1, sizeof(mem_fb_t)); + if (!c) { + r = -ENOMEM; + goto _err; + } + + c->setup = *(mem_fb_setup_t *)setup; + + *res_context = c; + + return 0; + +_err: + return r; +} + + +static void mem_fb_shutdown(til_fb_t *fb, void *context) +{ + mem_fb_t *c = context; + + assert(c); + + free(c); +} + + +static int mem_fb_acquire(til_fb_t *fb, void *context, void *page) +{ + mem_fb_t *c = context; + mem_fb_page_t *p = page; + + return 0; +} + + +static void mem_fb_release(til_fb_t *fb, void *context) +{ +} + + +static void * mem_fb_page_alloc(til_fb_t *fb, void *context, til_fb_page_t *res_page) +{ + mem_fb_t *c = context; + mem_fb_page_t *p; + + p = calloc(1, sizeof(mem_fb_page_t) + c->setup.width * c->setup.height * sizeof(uint32_t)); + if (!p) + return NULL; + + *res_page = (til_fb_page_t){ + .fragment.buf = p->buf, + .fragment.width = c->setup.width, + .fragment.frame_width = c->setup.width, + .fragment.height = c->setup.height, + .fragment.frame_height = c->setup.height, + .fragment.pitch = c->setup.width, + }; + + return p; +} + + +static int mem_fb_page_free(til_fb_t *fb, void *context, void *page) +{ + mem_fb_t *c = context; + mem_fb_page_t *p = page; + + free(p); + + return 0; +} + + +static int mem_fb_page_flip(til_fb_t *fb, void *context, void *page) +{ + mem_fb_t *c = context; + mem_fb_page_t *p = page; + + /* TODO: add a timer for supporting an fps setting? */ + return 0; +} + + +til_fb_ops_t mem_fb_ops = { + .setup = mem_fb_setup, + .init = mem_fb_init, + .shutdown = mem_fb_shutdown, + .acquire = mem_fb_acquire, + .release = mem_fb_release, + .page_alloc = mem_fb_page_alloc, + .page_free = mem_fb_page_free, + .page_flip = mem_fb_page_flip +}; |