diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2019-11-14 21:35:25 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2019-11-14 21:44:15 -0800 |
commit | aeb6fc5986757b0186634f7106d32861dbf55c54 (patch) | |
tree | 9780f85688a6c94ea2ca5763e1bc8c433e1d997f | |
parent | 3f260bcbcd9d29457d9dbd4f27a913c8d2e5d555 (diff) |
rtv: implement "Rototiller TV" renderer
This is sort of a meta renderer, as it simply renders other
modules in its prepare_frame() stage. They're still threaded
as the newly public rototiller_module_render() utilizes the
threading machinery, it just needs to be called from the serial
phase @ prepare_frame().
I'm pretty sure this module will leak memory every time it changes
modules, since the existing cleanup paths for the modules hasn't
needed to be thorough in the least. So that's something to fix
in a later commit, go through all the modules and make sure their
destroy_context() entrypoints actually cleans everything up.
See the source for some rtv-specific TODOs.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/Makefile.am | 2 | ||||
-rw-r--r-- | src/modules/rtv/Makefile.am | 3 | ||||
-rw-r--r-- | src/modules/rtv/rtv.c | 114 | ||||
-rw-r--r-- | src/rototiller.c | 2 |
6 files changed, 122 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac index 20be6cf..d9232b8 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,7 @@ AC_CONFIG_FILES([ src/modules/plasma/Makefile src/modules/ray/Makefile src/modules/roto/Makefile + src/modules/rtv/Makefile src/modules/sparkler/Makefile src/modules/stars/Makefile src/modules/submit/Makefile diff --git a/src/Makefile.am b/src/Makefile.am index d2a6e75..f6b4b92 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -4,4 +4,4 @@ rototiller_SOURCES = fb.c fb.h fps.c fps.h rototiller.c rototiller.h sdl_fb.c se if ENABLE_DRM rototiller_SOURCES += drm_fb.c endif -rototiller_LDADD = modules/flui2d/libflui2d.a modules/julia/libjulia.a modules/pixbounce/libpixbounce.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/sparkler/libsparkler.a modules/stars/libstars.a modules/submit/libsubmit.a libs/grid/libgrid.a libs/ray/libray.a -lm +rototiller_LDADD = modules/flui2d/libflui2d.a modules/julia/libjulia.a modules/pixbounce/libpixbounce.a modules/plasma/libplasma.a modules/ray/libray.a modules/roto/libroto.a modules/rtv/librtv.a modules/sparkler/libsparkler.a modules/stars/libstars.a modules/submit/libsubmit.a libs/grid/libgrid.a libs/ray/libray.a -lm diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am index 83c4ac6..fa4e852 100644 --- a/src/modules/Makefile.am +++ b/src/modules/Makefile.am @@ -1 +1 @@ -SUBDIRS = flui2d julia pixbounce plasma ray roto sparkler stars submit +SUBDIRS = flui2d julia pixbounce plasma ray roto rtv sparkler stars submit diff --git a/src/modules/rtv/Makefile.am b/src/modules/rtv/Makefile.am new file mode 100644 index 0000000..c301257 --- /dev/null +++ b/src/modules/rtv/Makefile.am @@ -0,0 +1,3 @@ +noinst_LIBRARIES = librtv.a +librtv_a_SOURCES = rtv.c +librtv_a_CPPFLAGS = -I@top_srcdir@/src diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c new file mode 100644 index 0000000..da6ae52 --- /dev/null +++ b/src/modules/rtv/rtv.c @@ -0,0 +1,114 @@ +#include <stdlib.h> +#include <time.h> + +#include "fb.h" +#include "rototiller.h" +#include "util.h" + +/* Copyright (C) 2019 - Vito Caputo <vcaputo@pengaru.com> */ + +/* This implements an MTV-inspired random slideshow of rototiller modules. + * + * Eventually it'd be nice to have it show a caption every time a new + * module starts overlaying the name, author, license, etc. + * + * Some TODO items: + * - show captions (need text rendering) + * - optionally persist module contexts so they resume rather than restart + * - runtime-configurable duration + * - randomize runtime settings of shown modules + * - redo the next module selection from random to + * walking the list and randomizing the list every + * time it completes a cycle. The current dumb + * random technique will happily keep showing you the + * same thing over and over. + */ + +#define RTV_DURATION_SECS 15 + +typedef struct rtv_context_t { + const rototiller_module_t **modules; + size_t n_modules; + + time_t last_switch; + const rototiller_module_t *module; + void *module_ctxt; +} rtv_context_t; + +static void setup_next_module(rtv_context_t *ctxt); +static void * rtv_create_context(void); +static void rtv_destroy_context(void *context); +static void rtv_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter); +static void rtv_finish_frame(void *context, fb_fragment_t *fragment); + + +rototiller_module_t rtv_module = { + .create_context = rtv_create_context, + .destroy_context = rtv_destroy_context, + .prepare_frame = rtv_prepare_frame, + .finish_frame = rtv_finish_frame, + .name = "rtv", + .description = "Rototiller TV", + .author = "Vito Caputo <vcaputo@pengaru.com>", + .license = "GPLv2", +}; + + +static void setup_next_module(rtv_context_t *ctxt) +{ + int i; + + /* TODO: most of this module stuff should probably be + * in rototiller.c helpers, but it's harmless for now. + */ + if (ctxt->module) { + if (ctxt->module->destroy_context) + ctxt->module->destroy_context(ctxt->module_ctxt); + + ctxt->module_ctxt = NULL; + } + + do { + i = rand() % ctxt->n_modules; + } while (ctxt->modules[i] == &rtv_module || ctxt->modules[i] == ctxt->module); + + ctxt->module = ctxt->modules[i]; + if (ctxt->module->create_context) + ctxt->module_ctxt = ctxt->module->create_context(); + + ctxt->last_switch = time(NULL); +} + + +static void * rtv_create_context(void) +{ + rtv_context_t *ctxt = calloc(1, sizeof(rtv_context_t)); + + rototiller_get_modules(&ctxt->modules, &ctxt->n_modules); + setup_next_module(ctxt); + + return ctxt; +} + + +static void rtv_destroy_context(void *context) +{ + free(context); +} + + +static void rtv_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter) +{ + rtv_context_t *ctxt = context; + + if (!ctxt->last_switch || time(NULL) - ctxt->last_switch > RTV_DURATION_SECS) + setup_next_module(ctxt); + + rototiller_module_render(ctxt->module, ctxt->module_ctxt, fragment); +} + + +static void rtv_finish_frame(void *context, fb_fragment_t *fragment) +{ + /* TODO: this is stubbed here for drawing the caption overlay */ +} diff --git a/src/rototiller.c b/src/rototiller.c index eb6a57f..51704a5 100644 --- a/src/rototiller.c +++ b/src/rototiller.c @@ -37,6 +37,7 @@ extern rototiller_module_t pixbounce_module; extern rototiller_module_t plasma_module; extern rototiller_module_t roto_module; extern rototiller_module_t ray_module; +extern rototiller_module_t rtv_module; extern rototiller_module_t sparkler_module; extern rototiller_module_t stars_module; extern rototiller_module_t submit_module; @@ -51,6 +52,7 @@ static const rototiller_module_t *modules[] = { &submit_module, &flui2d_module, &pixbounce_module, + &rtv_module, }; typedef struct rototiller_t { |