summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2020-01-25 17:26:54 -0800
committerVito Caputo <vcaputo@pengaru.com>2020-01-25 17:38:27 -0800
commit6385931985fa6fa8dd7ed69c20785d6b8d9cf37a (patch)
tree8fd19a7f72e60202367b417827112f7a57c0f24e /src
parent792d0a60dd05035435574633c4a13a666fe6ce5d (diff)
rototiller: introduce ticks and wire up to modules
Most modules find themselves wanting some kind of "t" value increasing with time or frames rendered. It's common for them to create and maintain this variable locally, incrementing it with every frame rendered. It may be interesting to introduce a global notion of ticks since rototiller started, and have all modules derive their "t" value from this instead of having their own private versions of it. In future modules and general innovations it seems likely that playing with time, like jumping it forwards and backwards to achieve some visual effects, will be desirable. This isn't applicable to all modules, but for many their entire visible state is derived from their "t" value, making them entirely reversible. This commit doesn't change any modules functionally, it only adds the plumbing to pull a ticks value down to the modules from the core. A ticks offset has also been introduced in preparation for supporting dynamic shifting of the ticks value, though no API is added for doing so yet. It also seems likely an API will be needed for disabling the time-based ticks advancement, with functions for explicitly setting its value. If modules are created for incorporating external sequencers and music coordination, they will almost certainly need to manage the ticks value explicitly. When a sequencer jumps forwards/backwards in the creative process, the module glue responsible will need to keep ticks synchronized with the sequencer/editor tool. Before any of this can happen, we need ticks as a first-class core thing shared by all modules. Future commits will have to modify existing modules to use the ticks appropriately, replacing their bespoke variants.
Diffstat (limited to 'src')
-rw-r--r--src/modules/drizzle/drizzle.c6
-rw-r--r--src/modules/flui2d/flui2d.c6
-rw-r--r--src/modules/julia/julia.c6
-rw-r--r--src/modules/meta2d/meta2d.c6
-rw-r--r--src/modules/montage/montage.c18
-rw-r--r--src/modules/pixbounce/pixbounce.c4
-rw-r--r--src/modules/plasma/plasma.c6
-rw-r--r--src/modules/ray/ray.c8
-rw-r--r--src/modules/roto/roto.c6
-rw-r--r--src/modules/rtv/rtv.c24
-rw-r--r--src/modules/snow/snow.c6
-rw-r--r--src/modules/sparkler/sparkler.c6
-rw-r--r--src/modules/spiro/spiro.c4
-rw-r--r--src/modules/stars/stars.c4
-rw-r--r--src/modules/submit/submit.c6
-rw-r--r--src/modules/swab/swab.c6
-rw-r--r--src/rototiller.c38
-rw-r--r--src/rototiller.h10
-rw-r--r--src/threads.c8
-rw-r--r--src/threads.h2
20 files changed, 101 insertions, 79 deletions
diff --git a/src/modules/drizzle/drizzle.c b/src/modules/drizzle/drizzle.c
index 436c347..bc04456 100644
--- a/src/modules/drizzle/drizzle.c
+++ b/src/modules/drizzle/drizzle.c
@@ -63,7 +63,7 @@ static inline uint32_t color_to_uint32(v3f_t color) {
}
-static void * drizzle_create_context(unsigned num_cpus)
+static void * drizzle_create_context(unsigned ticks, unsigned num_cpus)
{
drizzle_context_t *ctxt;
@@ -100,7 +100,7 @@ static int drizzle_fragmenter(void *context, const fb_fragment_t *fragment, unsi
}
-static void drizzle_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void drizzle_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
drizzle_context_t *ctxt = context;
@@ -124,7 +124,7 @@ static void drizzle_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t
}
-static void drizzle_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void drizzle_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
drizzle_context_t *ctxt = context;
float xf = 2.f / (float)fragment->frame_width;
diff --git a/src/modules/flui2d/flui2d.c b/src/modules/flui2d/flui2d.c
index d0106ee..62dbbec 100644
--- a/src/modules/flui2d/flui2d.c
+++ b/src/modules/flui2d/flui2d.c
@@ -187,7 +187,7 @@ typedef struct flui2d_context_t {
} flui2d_context_t;
-static void * flui2d_create_context(unsigned num_cpus)
+static void * flui2d_create_context(unsigned ticks, unsigned num_cpus)
{
flui2d_context_t *ctxt;
@@ -215,7 +215,7 @@ static int flui2d_fragmenter(void *context, const fb_fragment_t *fragment, unsig
/* Prepare a frame for concurrent drawing of fragment using multiple fragments */
-static void flui2d_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void flui2d_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
flui2d_context_t *ctxt = context;
static float r;
@@ -247,7 +247,7 @@ static void flui2d_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *
/* Draw a the flui2d densities */
-static void flui2d_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void flui2d_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
flui2d_context_t *ctxt = context;
diff --git a/src/modules/julia/julia.c b/src/modules/julia/julia.c
index 22a79fd..61515bd 100644
--- a/src/modules/julia/julia.c
+++ b/src/modules/julia/julia.c
@@ -66,7 +66,7 @@ static uint32_t colors[] = {
};
-static void * julia_create_context(unsigned num_cpus)
+static void * julia_create_context(unsigned ticks, unsigned num_cpus)
{
return calloc(1, sizeof(julia_context_t));
}
@@ -111,7 +111,7 @@ static int julia_fragmenter(void *context, const fb_fragment_t *fragment, unsign
/* Prepare a frame for concurrent drawing of fragment using multiple fragments */
-static void julia_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void julia_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
julia_context_t *ctxt = context;
@@ -139,7 +139,7 @@ static void julia_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *f
/* Draw a morphing Julia set */
-static void julia_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void julia_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
julia_context_t *ctxt = context;
unsigned x, y;
diff --git a/src/modules/meta2d/meta2d.c b/src/modules/meta2d/meta2d.c
index 08cd15a..56f9b25 100644
--- a/src/modules/meta2d/meta2d.c
+++ b/src/modules/meta2d/meta2d.c
@@ -65,7 +65,7 @@ static inline uint32_t color_to_uint32(v3f_t color) {
}
-static void * meta2d_create_context(unsigned num_cpus)
+static void * meta2d_create_context(unsigned ticks, unsigned num_cpus)
{
meta2d_context_t *ctxt;
@@ -108,7 +108,7 @@ static int meta2d_fragmenter(void *context, const fb_fragment_t *fragment, unsig
}
-static void meta2d_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void meta2d_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
meta2d_context_t *ctxt = context;
@@ -185,7 +185,7 @@ static void meta2d_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *
}
-static void meta2d_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void meta2d_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
meta2d_context_t *ctxt = context;
float xf = 2.f / (float)fragment->frame_width;
diff --git a/src/modules/montage/montage.c b/src/modules/montage/montage.c
index f064e5c..d7dd55f 100644
--- a/src/modules/montage/montage.c
+++ b/src/modules/montage/montage.c
@@ -17,10 +17,10 @@ typedef struct montage_context_t {
} montage_context_t;
static void setup_next_module(montage_context_t *ctxt);
-static void * montage_create_context(unsigned num_cpus);
+static void * montage_create_context(unsigned ticks, unsigned num_cpus);
static void montage_destroy_context(void *context);
-static void montage_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
-static void montage_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment);
+static void montage_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
+static void montage_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment);
rototiller_module_t montage_module = {
@@ -35,7 +35,7 @@ rototiller_module_t montage_module = {
};
-static void * montage_create_context(unsigned num_cpus)
+static void * montage_create_context(unsigned ticks, unsigned num_cpus)
{
const rototiller_module_t **modules, *rtv_module, *pixbounce_module, *stars_module;
size_t n_modules;
@@ -81,7 +81,7 @@ static void * montage_create_context(unsigned num_cpus)
const rototiller_module_t *module = ctxt->modules[i];
if (module->create_context) /* FIXME errors */
- ctxt->contexts[i] = module->create_context(num_cpus);
+ ctxt->contexts[i] = module->create_context(ticks, num_cpus);
}
return ctxt;
@@ -175,7 +175,7 @@ static int montage_fragmenter(void *context, const fb_fragment_t *fragment, unsi
-static void montage_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void montage_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
montage_context_t *ctxt = context;
@@ -183,7 +183,7 @@ static void montage_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t
}
-static void montage_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void montage_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
montage_context_t *ctxt = context;
const rototiller_module_t *module = ctxt->modules[fragment->number];
@@ -211,10 +211,10 @@ static void montage_render_fragment(void *context, unsigned cpu, fb_fragment_t *
* sensitive to this aspect of the API and it skips itself.
*/
- module->prepare_frame(ctxt->contexts[fragment->number], 1, fragment, &unused);
+ module->prepare_frame(ctxt->contexts[fragment->number], ticks, 1, fragment, &unused);
}
if (module->render_fragment)
- module->render_fragment(ctxt->contexts[fragment->number], 0, fragment);
+ module->render_fragment(ctxt->contexts[fragment->number], ticks, 0, fragment);
}
diff --git a/src/modules/pixbounce/pixbounce.c b/src/modules/pixbounce/pixbounce.c
index c5697cc..a59efbe 100644
--- a/src/modules/pixbounce/pixbounce.c
+++ b/src/modules/pixbounce/pixbounce.c
@@ -109,7 +109,7 @@ static int pick_pix(int num_pics, int last_pic)
return pix_num;
}
-static void * pixbounce_create_context(unsigned num_cpus)
+static void * pixbounce_create_context(unsigned ticks, unsigned num_cpus)
{
pixbounce_context_t *ctxt;
@@ -135,7 +135,7 @@ static void pixbounce_destroy_context(void *context)
free(context);
}
-static void pixbounce_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void pixbounce_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
pixbounce_context_t *ctxt = context;
diff --git a/src/modules/plasma/plasma.c b/src/modules/plasma/plasma.c
index ba34054..20dc942 100644
--- a/src/modules/plasma/plasma.c
+++ b/src/modules/plasma/plasma.c
@@ -47,7 +47,7 @@ static void init_plasma(int32_t *costab, int32_t *sintab)
}
-static void * plasma_create_context(unsigned num_cpus)
+static void * plasma_create_context(unsigned ticks, unsigned num_cpus)
{
return calloc(1, sizeof(plasma_context_t));
}
@@ -68,7 +68,7 @@ static int plasma_fragmenter(void *context, const fb_fragment_t *fragment, unsig
/* Prepare a frame for concurrent drawing of fragment using multiple fragments */
-static void plasma_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void plasma_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
plasma_context_t *ctxt = context;
static int initialized;
@@ -86,7 +86,7 @@ static void plasma_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *
/* Draw a plasma effect */
-static void plasma_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void plasma_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
plasma_context_t *ctxt = context;
unsigned width = fragment->width, height = fragment->height;
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index a9d78c4..636e834 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -130,7 +130,7 @@ typedef struct ray_context_t {
} ray_context_t;
-static void * ray_create_context(unsigned num_cpus)
+static void * ray_create_context(unsigned ticks, unsigned num_cpus)
{
return calloc(1, sizeof(ray_context_t));
}
@@ -149,7 +149,7 @@ static int ray_fragmenter(void *context, const fb_fragment_t *fragment, unsigned
/* prepare a frame for concurrent rendering */
-static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void ray_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
ray_context_t *ctxt = context;
@@ -181,7 +181,7 @@ static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fra
/* ray trace a simple scene into the fragment */
-static void ray_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void ray_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
ray_context_t *ctxt = context;
@@ -189,7 +189,7 @@ static void ray_render_fragment(void *context, unsigned cpu, fb_fragment_t *frag
}
-static void ray_finish_frame(void *context, fb_fragment_t *fragment)
+static void ray_finish_frame(void *context, unsigned ticks, fb_fragment_t *fragment)
{
ray_context_t *ctxt = context;
diff --git a/src/modules/roto/roto.c b/src/modules/roto/roto.c
index 56ca08a..c72301b 100644
--- a/src/modules/roto/roto.c
+++ b/src/modules/roto/roto.c
@@ -32,7 +32,7 @@ static int32_t costab[FIXED_TRIG_LUT_SIZE], sintab[FIXED_TRIG_LUT_SIZE];
static uint8_t texture[256][256];
static color_t palette[2];
-static void * roto_create_context(unsigned num_cpus)
+static void * roto_create_context(unsigned ticks, unsigned num_cpus)
{
return calloc(1, sizeof(roto_context_t));
}
@@ -178,7 +178,7 @@ static int roto_fragmenter(void *context, const fb_fragment_t *fragment, unsigne
/* prepare a frame for concurrent rendering */
-static void roto_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void roto_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
roto_context_t *ctxt = context;
static int initialized;
@@ -199,7 +199,7 @@ static void roto_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fr
/* Draw a rotating checkered 256x256 texture into fragment. */
-static void roto_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void roto_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
roto_context_t *ctxt = context;
int y_cos_r, y_sin_r, x_cos_r, x_sin_r, x_cos_r_init, x_sin_r_init, cos_r, sin_r;
diff --git a/src/modules/rtv/rtv.c b/src/modules/rtv/rtv.c
index 196bbfb..6961a4f 100644
--- a/src/modules/rtv/rtv.c
+++ b/src/modules/rtv/rtv.c
@@ -42,11 +42,11 @@ typedef struct rtv_context_t {
rtv_module_t modules[];
} rtv_context_t;
-static void setup_next_module(rtv_context_t *ctxt);
-static void * rtv_create_context(unsigned num_cpus);
+static void setup_next_module(rtv_context_t *ctxt, unsigned ticks);
+static void * rtv_create_context(unsigned ticks, unsigned num_cpus);
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);
+static void rtv_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
+static void rtv_finish_frame(void *context, unsigned ticks, fb_fragment_t *fragment);
rototiller_module_t rtv_module = {
@@ -126,7 +126,7 @@ static char * randomize_module_setup(const rototiller_module_t *module)
}
-static void setup_next_module(rtv_context_t *ctxt)
+static void setup_next_module(rtv_context_t *ctxt, unsigned ticks)
{
time_t now = time(NULL);
@@ -181,11 +181,11 @@ static void setup_next_module(rtv_context_t *ctxt)
}
if (ctxt->module->create_context)
- ctxt->module_ctxt = ctxt->module->create_context(ctxt->n_cpus);
+ ctxt->module_ctxt = ctxt->module->create_context(ticks, ctxt->n_cpus);
}
-static void * rtv_create_context(unsigned num_cpus)
+static void * rtv_create_context(unsigned ticks, unsigned num_cpus)
{
rtv_context_t *ctxt;
const rototiller_module_t **modules;
@@ -208,7 +208,7 @@ static void * rtv_create_context(unsigned num_cpus)
ctxt->modules[ctxt->n_modules++].module = modules[i];
}
- setup_next_module(ctxt);
+ setup_next_module(ctxt, ticks);
return ctxt;
}
@@ -220,22 +220,22 @@ 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_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
rtv_context_t *ctxt = context;
time_t now = time(NULL);
if (now >= ctxt->next_switch)
- setup_next_module(ctxt);
+ setup_next_module(ctxt, ticks);
if (now >= ctxt->next_hide_caption)
ctxt->caption = txt_free(ctxt->caption);
- rototiller_module_render(ctxt->module, ctxt->module_ctxt, fragment);
+ rototiller_module_render(ctxt->module, ctxt->module_ctxt, ticks, fragment);
}
-static void rtv_finish_frame(void *context, fb_fragment_t *fragment)
+static void rtv_finish_frame(void *context, unsigned ticks, fb_fragment_t *fragment)
{
rtv_context_t *ctxt = context;
diff --git a/src/modules/snow/snow.c b/src/modules/snow/snow.c
index 2de4d76..af96285 100644
--- a/src/modules/snow/snow.c
+++ b/src/modules/snow/snow.c
@@ -20,7 +20,7 @@ typedef struct snow_context_t {
} snow_context_t;
-static void * snow_create_context(unsigned n_cpus)
+static void * snow_create_context(unsigned ticks, unsigned n_cpus)
{
snow_context_t *ctxt;
@@ -51,13 +51,13 @@ static int snow_fragmenter(void *context, const fb_fragment_t *fragment, unsigne
}
-static void snow_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void snow_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
*res_fragmenter = snow_fragmenter;
}
-static void snow_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void snow_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
snow_context_t *ctxt = context;
int *seed = &ctxt->seeds[cpu].seed;
diff --git a/src/modules/sparkler/sparkler.c b/src/modules/sparkler/sparkler.c
index b2de5ee..7c1c2f1 100644
--- a/src/modules/sparkler/sparkler.c
+++ b/src/modules/sparkler/sparkler.c
@@ -24,7 +24,7 @@ typedef struct sparkler_context_t {
extern particle_ops_t simple_ops;
-static void * sparkler_create_context(unsigned num_cpus)
+static void * sparkler_create_context(unsigned ticks, unsigned num_cpus)
{
static int initialized;
sparkler_context_t *ctxt;
@@ -66,7 +66,7 @@ static int sparkler_fragmenter(void *context, const fb_fragment_t *fragment, uns
return fb_fragment_slice_single(fragment, ctxt->n_cpus, number, res_fragment);
}
-static void sparkler_prepare_frame(void *context, unsigned ncpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void sparkler_prepare_frame(void *context, unsigned ticks, unsigned ncpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
sparkler_context_t *ctxt = context;
@@ -80,7 +80,7 @@ static void sparkler_prepare_frame(void *context, unsigned ncpus, fb_fragment_t
/* Render a 3D particle system */
-static void sparkler_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void sparkler_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
sparkler_context_t *ctxt = context;
diff --git a/src/modules/spiro/spiro.c b/src/modules/spiro/spiro.c
index f6aeddc..b404c75 100644
--- a/src/modules/spiro/spiro.c
+++ b/src/modules/spiro/spiro.c
@@ -28,7 +28,7 @@ typedef struct spiro_context_t {
} spiro_context_t;
-static void * spiro_create_context(unsigned num_cpus)
+static void * spiro_create_context(unsigned ticks, unsigned num_cpus)
{
spiro_context_t *ctxt;
float z;
@@ -60,7 +60,7 @@ static void spiro_destroy_context(void *context)
}
-static void spiro_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void spiro_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
spiro_context_t *ctxt = context;
diff --git a/src/modules/stars/stars.c b/src/modules/stars/stars.c
index df5dc3a..a50a099 100644
--- a/src/modules/stars/stars.c
+++ b/src/modules/stars/stars.c
@@ -40,7 +40,7 @@ float get_random_unit_coord() {
}
-static void * stars_create_context(unsigned num_cpus)
+static void * stars_create_context(unsigned ticks, unsigned num_cpus)
{
stars_context_t *ctxt;
float z;
@@ -94,7 +94,7 @@ static void stars_destroy_context(void *context)
}
-static void stars_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void stars_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
stars_context_t *ctxt = context;
struct points* iterator;
diff --git a/src/modules/submit/submit.c b/src/modules/submit/submit.c
index 7035a3a..7b4fd91 100644
--- a/src/modules/submit/submit.c
+++ b/src/modules/submit/submit.c
@@ -261,7 +261,7 @@ static void setup_grid(submit_context_t *ctxt)
}
-static void * submit_create_context(unsigned num_cpus)
+static void * submit_create_context(unsigned ticks, unsigned num_cpus)
{
submit_context_t *ctxt;
@@ -290,7 +290,7 @@ static int submit_fragmenter(void *context, const fb_fragment_t *fragment, unsig
}
-static void submit_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void submit_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
submit_context_t *ctxt = context;
@@ -311,7 +311,7 @@ static void submit_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *
}
-static void submit_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void submit_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
submit_context_t *ctxt = context;
diff --git a/src/modules/swab/swab.c b/src/modules/swab/swab.c
index 2b80d95..a8db372 100644
--- a/src/modules/swab/swab.c
+++ b/src/modules/swab/swab.c
@@ -65,7 +65,7 @@ static inline uint32_t color_to_uint32(color_t color) {
}
-static void * swab_create_context(unsigned num_cpus)
+static void * swab_create_context(unsigned ticks, unsigned num_cpus)
{
swab_context_t *ctxt;
@@ -100,7 +100,7 @@ static int swab_fragmenter(void *context, const fb_fragment_t *fragment, unsigne
}
-static void swab_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
+static void swab_prepare_frame(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter)
{
swab_context_t *ctxt = context;
@@ -111,7 +111,7 @@ static void swab_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fr
}
-static void swab_render_fragment(void *context, unsigned cpu, fb_fragment_t *fragment)
+static void swab_render_fragment(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment)
{
swab_context_t *ctxt = context;
float cos_r = cos(ctxt->r);
diff --git a/src/rototiller.c b/src/rototiller.c
index 2477d4b..d2dce75 100644
--- a/src/rototiller.c
+++ b/src/rototiller.c
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
+#include <sys/time.h>
#include <unistd.h>
#include "settings.h"
@@ -74,6 +75,8 @@ typedef struct rototiller_t {
threads_t *threads;
pthread_t thread;
fb_t *fb;
+ struct timeval start_tv;
+ unsigned t_offset;
} rototiller_t;
static rototiller_t rototiller;
@@ -102,32 +105,32 @@ void rototiller_get_modules(const rototiller_module_t ***res_modules, size_t *re
}
-static void module_render_fragment(const rototiller_module_t *module, void *context, threads_t *threads, fb_fragment_t *fragment)
+static void module_render_fragment(const rototiller_module_t *module, void *context, threads_t *threads, unsigned ticks, fb_fragment_t *fragment)
{
if (module->prepare_frame) {
rototiller_fragmenter_t fragmenter;
- module->prepare_frame(context, threads_num_threads(threads), fragment, &fragmenter);
+ module->prepare_frame(context, ticks, threads_num_threads(threads), fragment, &fragmenter);
if (module->render_fragment) {
- threads_frame_submit(threads, fragment, fragmenter, module->render_fragment, context);
+ threads_frame_submit(threads, fragment, fragmenter, module->render_fragment, context, ticks);
threads_wait_idle(threads);
}
} else if (module->render_fragment)
- module->render_fragment(context, 0, fragment);
+ module->render_fragment(context, ticks, 0, fragment);
if (module->finish_frame)
- module->finish_frame(context, fragment);
+ module->finish_frame(context, ticks, fragment);
}
/* This is a public interface to the threaded module rendering intended for use by
* modules that wish to get the output of other modules for their own use.
*/
-void rototiller_module_render(const rototiller_module_t *module, void *context, fb_fragment_t *fragment)
+void rototiller_module_render(const rototiller_module_t *module, void *context, unsigned ticks, fb_fragment_t *fragment)
{
- module_render_fragment(module, context, rototiller.threads, fragment);
+ module_render_fragment(module, context, rototiller.threads, ticks, fragment);
}
@@ -375,15 +378,28 @@ static int print_help(void)
}
+static unsigned get_ticks(const struct timeval *start, const struct timeval *now, unsigned offset)
+{
+ return (unsigned)((now->tv_sec - start->tv_sec) * 1000 + (now->tv_usec - start->tv_usec) / 1000) + offset;
+}
+
+
static void * rototiller_thread(void *_rt)
{
rototiller_t *rt = _rt;
+ struct timeval now;
for (;;) {
fb_page_t *page;
+ unsigned ticks;
page = fb_page_get(rt->fb);
- module_render_fragment(rt->module, rt->module_context, rt->threads, &page->fragment);
+
+ gettimeofday(&now, NULL);
+ ticks = get_ticks(&rt->start_tv, &now, rt->t_offset);
+
+ module_render_fragment(rt->module, rt->module_context, rt->threads, ticks, &page->fragment);
+
fb_page_put(rt->fb, page);
}
@@ -428,7 +444,11 @@ int main(int argc, const char *argv[])
"unable to create rendering threads");
exit_if(rototiller.module->create_context &&
- !(rototiller.module_context = rototiller.module->create_context(threads_num_threads(rototiller.threads))),
+ !(rototiller.module_context = rototiller.module->create_context(
+ get_ticks(&rototiller.start_tv,
+ &rototiller.start_tv,
+ rototiller.t_offset),
+ threads_num_threads(rototiller.threads))),
"unable to create module context");
pexit_if(pthread_create(&rototiller.thread, NULL, rototiller_thread, &rototiller) != 0,
diff --git a/src/rototiller.h b/src/rototiller.h
index 70b9ef2..4561ae5 100644
--- a/src/rototiller.h
+++ b/src/rototiller.h
@@ -11,11 +11,11 @@ typedef struct settings_t settings;
typedef struct setting_desc_t setting_desc_t;
typedef struct rototiller_module_t {
- void * (*create_context)(unsigned n_cpus);
+ void * (*create_context)(unsigned ticks, unsigned n_cpus);
void (*destroy_context)(void *context);
- void (*prepare_frame)(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
- void (*render_fragment)(void *context, unsigned cpu, fb_fragment_t *fragment);
- void (*finish_frame)(void *context, fb_fragment_t *fragment);
+ void (*prepare_frame)(void *context, unsigned ticks, unsigned n_cpus, fb_fragment_t *fragment, rototiller_fragmenter_t *res_fragmenter);
+ void (*render_fragment)(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment);
+ void (*finish_frame)(void *context, unsigned ticks, fb_fragment_t *fragment);
char *name;
char *description;
char *author;
@@ -25,6 +25,6 @@ typedef struct rototiller_module_t {
const rototiller_module_t * rototiller_lookup_module(const char *name);
void rototiller_get_modules(const rototiller_module_t ***res_modules, size_t *res_n_modules);
-void rototiller_module_render(const rototiller_module_t *module, void *context, fb_fragment_t *fragment);
+void rototiller_module_render(const rototiller_module_t *module, void *context, unsigned ticks, fb_fragment_t *fragment);
#endif
diff --git a/src/threads.c b/src/threads.c
index 0a68861..3cd69d3 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -22,10 +22,11 @@ typedef struct threads_t {
pthread_mutex_t frame_mutex;
pthread_cond_t frame_cond;
- void (*render_fragment_func)(void *context, unsigned cpu, fb_fragment_t *fragment);
+ void (*render_fragment_func)(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment);
void *context;
fb_fragment_t *fragment;
rototiller_fragmenter_t fragmenter;
+ unsigned ticks;
unsigned next_fragment;
unsigned frame_num;
@@ -63,7 +64,7 @@ static void * thread_func(void *_thread)
if (!threads->fragmenter(threads->context, threads->fragment, frag_num, &fragment))
break;
- threads->render_fragment_func(threads->context, thread->id, &fragment);
+ threads->render_fragment_func(threads->context, threads->ticks, thread->id, &fragment);
}
/* report as idle */
@@ -90,7 +91,7 @@ void threads_wait_idle(threads_t *threads)
/* submit a frame's fragments to the threads */
-void threads_frame_submit(threads_t *threads, fb_fragment_t *fragment, rototiller_fragmenter_t fragmenter, void (*render_fragment_func)(void *context, unsigned cpu, fb_fragment_t *fragment), void *context)
+void threads_frame_submit(threads_t *threads, fb_fragment_t *fragment, rototiller_fragmenter_t fragmenter, void (*render_fragment_func)(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment), void *context, unsigned ticks)
{
threads_wait_idle(threads); /* XXX: likely non-blocking; already happens pre page flip */
@@ -99,6 +100,7 @@ void threads_frame_submit(threads_t *threads, fb_fragment_t *fragment, rototille
threads->fragmenter = fragmenter;
threads->render_fragment_func = render_fragment_func;
threads->context = context;
+ threads->ticks = ticks;
threads->frame_num++;
threads->n_idle = threads->next_fragment = 0;
pthread_cond_broadcast(&threads->frame_cond);
diff --git a/src/threads.h b/src/threads.h
index 7080537..f0ffe6f 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -8,7 +8,7 @@ typedef struct threads_t threads_t;
threads_t * threads_create();
void threads_destroy(threads_t *threads);
-void threads_frame_submit(threads_t *threads, fb_fragment_t *fragment, rototiller_fragmenter_t fragmenter, void (*render_fragment_func)(void *context, unsigned cpu, fb_fragment_t *fragment), void *context);
+void threads_frame_submit(threads_t *threads, fb_fragment_t *fragment, rototiller_fragmenter_t fragmenter, void (*render_fragment_func)(void *context, unsigned ticks, unsigned cpu, fb_fragment_t *fragment), void *context, unsigned ticks);
void threads_wait_idle(threads_t *threads);
unsigned threads_num_threads(threads_t *threads);
© All Rights Reserved