From aeb6fc5986757b0186634f7106d32861dbf55c54 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Thu, 14 Nov 2019 21:35:25 -0800 Subject: 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. --- src/Makefile.am | 2 +- src/modules/Makefile.am | 2 +- src/modules/rtv/Makefile.am | 3 ++ src/modules/rtv/rtv.c | 114 ++++++++++++++++++++++++++++++++++++++++++++ src/rototiller.c | 2 + 5 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 src/modules/rtv/Makefile.am create mode 100644 src/modules/rtv/rtv.c (limited to 'src') 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 +#include + +#include "fb.h" +#include "rototiller.h" +#include "util.h" + +/* Copyright (C) 2019 - Vito Caputo */ + +/* 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 ", + .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 { -- cgit v1.2.3