summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-04-22 15:29:49 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-04-22 15:29:49 -0700
commitd28ceb85a6b43a503c608116798945baab0e060f (patch)
tree1a96ae21cbab1ef8fdf831d588fd2c9477fb3f92
parent1ff4632e895202c4485818f6e748e773b6fd2859 (diff)
*: add module context machinery
introduces create_context() and destroy_context() methods, and adds a 'void *context' first parameter to the module methods. If a module doesn't supply create_context() then NULL is simply passed around as the context, so trivial modules can continue to only implement render_fragment(). A subsequent commit will update the modules to encapsulate their global state in module-specific contexts.
-rw-r--r--src/modules/julia/julia.c4
-rw-r--r--src/modules/plasma/plasma.c4
-rw-r--r--src/modules/ray/ray.c4
-rw-r--r--src/modules/roto/roto.c6
-rw-r--r--src/modules/sparkler/sparkler.c2
-rw-r--r--src/modules/stars/stars.c2
-rw-r--r--src/rototiller.c23
-rw-r--r--src/rototiller.h6
-rw-r--r--src/threads.c12
-rw-r--r--src/threads.h2
10 files changed, 39 insertions, 26 deletions
diff --git a/src/modules/julia/julia.c b/src/modules/julia/julia.c
index 69d1022..3811d0d 100644
--- a/src/modules/julia/julia.c
+++ b/src/modules/julia/julia.c
@@ -42,7 +42,7 @@ static inline unsigned julia_iter(float real, float imag, float creal, float cim
/* Prepare a frame for concurrent drawing of fragment using multiple fragments */
-static void julia_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
+static void julia_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
{
res_frame->n_fragments = n_cpus;
fb_fragment_divide(fragment, n_cpus, res_frame->fragments);
@@ -59,7 +59,7 @@ static void julia_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototi
/* Draw a morphing Julia set */
-static void julia_render_fragment(fb_fragment_t *fragment)
+static void julia_render_fragment(void *context, fb_fragment_t *fragment)
{
static uint32_t colors[] = {
/* this palette is just something I slapped together, definitely needs improvement. TODO */
diff --git a/src/modules/plasma/plasma.c b/src/modules/plasma/plasma.c
index 8c3e921..9acd73f 100644
--- a/src/modules/plasma/plasma.c
+++ b/src/modules/plasma/plasma.c
@@ -43,7 +43,7 @@ static void init_plasma(int32_t *costab, int32_t *sintab)
/* Prepare a frame for concurrent drawing of fragment using multiple fragments */
-static void plasma_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
+static void plasma_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
{
static int initialized;
@@ -61,7 +61,7 @@ static void plasma_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rotot
/* Draw a plasma effect */
-static void plasma_render_fragment(fb_fragment_t *fragment)
+static void plasma_render_fragment(void *context, fb_fragment_t *fragment)
{
unsigned stride = fragment->stride / 4, width = fragment->width, height = fragment->height;
diff --git a/src/modules/ray/ray.c b/src/modules/ray/ray.c
index e79bfaf..a934c30 100644
--- a/src/modules/ray/ray.c
+++ b/src/modules/ray/ray.c
@@ -112,7 +112,7 @@ static float r;
/* prepare a frame for concurrent rendering */
-static void ray_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
+static void ray_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
{
/* TODO experiment with tiled fragments vs. rows */
res_frame->n_fragments = n_cpus;
@@ -146,7 +146,7 @@ static void ray_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototill
/* ray trace a simple scene into the fragment */
-static void ray_render_fragment(fb_fragment_t *fragment)
+static void ray_render_fragment(void *context, fb_fragment_t *fragment)
{
ray_scene_render_fragment(&scene, &camera, fragment);
}
diff --git a/src/modules/roto/roto.c b/src/modules/roto/roto.c
index b889a55..9c7ac18 100644
--- a/src/modules/roto/roto.c
+++ b/src/modules/roto/roto.c
@@ -154,7 +154,7 @@ static void init_roto(uint8_t texture[256][256], int32_t *costab, int32_t *sinta
/* prepare a frame for concurrent rendering */
-static void roto_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
+static void roto_prepare_frame(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame)
{
static int initialized;
@@ -174,7 +174,7 @@ static void roto_prepare_frame(unsigned n_cpus, fb_fragment_t *fragment, rototil
/* Draw a rotating checkered 256x256 texture into fragment. (32-bit version) */
-static void roto32_render_fragment(fb_fragment_t *fragment)
+static void roto32_render_fragment(void *context, fb_fragment_t *fragment)
{
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;
int x, y, stride = fragment->stride / 4, frame_width = fragment->frame_width, frame_height = fragment->frame_height;
@@ -223,7 +223,7 @@ static void roto32_render_fragment(fb_fragment_t *fragment)
/* Draw a rotating checkered 256x256 texture into fragment. (64-bit version) */
-static void roto64_render_fragment(fb_fragment_t *fragment)
+static void roto64_render_fragment(void *context, fb_fragment_t *fragment)
{
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;
int x, y, stride = fragment->stride / 8, frame_width = fragment->frame_width, frame_height = fragment->frame_height, width = fragment->width;
diff --git a/src/modules/sparkler/sparkler.c b/src/modules/sparkler/sparkler.c
index 67d68cf..deb3c53 100644
--- a/src/modules/sparkler/sparkler.c
+++ b/src/modules/sparkler/sparkler.c
@@ -20,7 +20,7 @@ extern particle_ops_t simple_ops;
/* Render a 3D particle system */
-static void sparkler_render_fragment(fb_fragment_t *fragment)
+static void sparkler_render_fragment(void *context, fb_fragment_t *fragment)
{
static particles_t *particles;
static int initialized;
diff --git a/src/modules/stars/stars.c b/src/modules/stars/stars.c
index f624a62..3712e33 100644
--- a/src/modules/stars/stars.c
+++ b/src/modules/stars/stars.c
@@ -13,7 +13,7 @@
/* Copyright (C) 2017 Philip J. Freeman <elektron@halo.nu> */
-static void stars_render_fragment(fb_fragment_t *fragment)
+static void stars_render_fragment(void *context, fb_fragment_t *fragment)
{
static int initialized, z;
static struct universe* u;
diff --git a/src/rototiller.c b/src/rototiller.c
index f9cfece..4d84c91 100644
--- a/src/rototiller.c
+++ b/src/rototiller.c
@@ -57,24 +57,24 @@ static void module_select(int *module)
}
-static void module_render_page_threaded(rototiller_module_t *module, threads_t *threads, fb_page_t *page)
+static void module_render_page_threaded(rototiller_module_t *module, void *context, threads_t *threads, fb_page_t *page)
{
rototiller_frame_t frame;
unsigned i;
- module->prepare_frame(threads_num_threads(threads), &page->fragment, &frame);
+ module->prepare_frame(context, threads_num_threads(threads), &page->fragment, &frame);
- threads_frame_submit(threads, &frame, module->render_fragment);
+ threads_frame_submit(threads, &frame, module->render_fragment, context);
threads_wait_idle(threads);
}
-static void module_render_page(rototiller_module_t *module, threads_t *threads, fb_page_t *page)
+static void module_render_page(rototiller_module_t *module, void *context, threads_t *threads, fb_page_t *page)
{
if (!module->prepare_frame)
- return module->render_fragment(&page->fragment);
+ return module->render_fragment(context, &page->fragment);
- module_render_page_threaded(module, threads, page);
+ module_render_page_threaded(module, context, threads, page);
}
@@ -87,6 +87,7 @@ int main(int argc, const char *argv[])
threads_t *threads;
int module;
fb_t *fb;
+ void *context = NULL;
drm_setup(&drm_fd, &drm_crtc_id, &drm_connector_id, &drm_mode);
module_select(&module);
@@ -97,6 +98,10 @@ int main(int argc, const char *argv[])
pexit_if(!fps_setup(),
"unable to setup fps counter");
+ exit_if(modules[module]->create_context &&
+ !(context = modules[module]->create_context()),
+ "unable to create module context");
+
pexit_if(!(threads = threads_create()),
"unable to create threads");
@@ -106,11 +111,15 @@ int main(int argc, const char *argv[])
fps_print(fb);
page = fb_page_get(fb);
- module_render_page(modules[module], threads, page);
+ module_render_page(modules[module], context, threads, page);
fb_page_put(fb, page);
}
threads_destroy(threads);
+
+ if (context)
+ modules[module]->destroy_context(context);
+
fb_free(fb);
close(drm_fd);
diff --git a/src/rototiller.h b/src/rototiller.h
index d1578fb..933f733 100644
--- a/src/rototiller.h
+++ b/src/rototiller.h
@@ -12,8 +12,10 @@ typedef struct rototiller_frame_t {
} rototiller_frame_t;
typedef struct rototiller_module_t {
- void (*prepare_frame)(unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame);
- void (*render_fragment)(fb_fragment_t *fragment);
+ void * (*create_context)(void);
+ void (*destroy_context)(void *context);
+ void (*prepare_frame)(void *context, unsigned n_cpus, fb_fragment_t *fragment, rototiller_frame_t *res_frame);
+ void (*render_fragment)(void *context, fb_fragment_t *fragment);
char *name;
char *description;
char *author;
diff --git a/src/threads.c b/src/threads.c
index cc32f63..865fe21 100644
--- a/src/threads.c
+++ b/src/threads.c
@@ -24,7 +24,8 @@ typedef struct thread_t {
pthread_t thread;
pthread_mutex_t mutex;
pthread_cond_t cond;
- void (*render_fragment_func)(fb_fragment_t *fragment);
+ void (*render_fragment_func)(void *context, fb_fragment_t *fragment);
+ void *context;
fragment_node_t *fragments;
} thread_t;
@@ -46,7 +47,7 @@ static void * thread_func(void *_thread)
pthread_cond_wait(&thread->cond, &thread->mutex);
do {
- thread->render_fragment_func(thread->fragments->fragment);
+ thread->render_fragment_func(thread->context, thread->fragments->fragment);
thread->fragments = thread->fragments->next;
} while (thread->fragments);
@@ -59,13 +60,14 @@ static void * thread_func(void *_thread)
/* submit a list of fragments to render using the specified thread and render_fragment_func */
-static void thread_fragments_submit(thread_t *thread, void (*render_fragment_func)(fb_fragment_t *fragment), fragment_node_t *fragments)
+static void thread_fragments_submit(thread_t *thread, void (*render_fragment_func)(void *context, fb_fragment_t *fragment), void *context, fragment_node_t *fragments)
{
pthread_mutex_lock(&thread->mutex);
while (thread->fragments != NULL) /* XXX: never true due to thread_wait_idle() */
pthread_cond_wait(&thread->cond, &thread->mutex);
thread->render_fragment_func = render_fragment_func;
+ thread->context = context;
thread->fragments = fragments;
pthread_mutex_unlock(&thread->mutex);
@@ -84,7 +86,7 @@ static void thread_wait_idle(thread_t *thread)
/* submit a frame's fragments to the threads */
-void threads_frame_submit(threads_t *threads, rototiller_frame_t *frame, void (*render_fragment_func)(fb_fragment_t *fragment))
+void threads_frame_submit(threads_t *threads, rototiller_frame_t *frame, void (*render_fragment_func)(void *context, fb_fragment_t *fragment), void *context)
{
unsigned i, t;
fragment_node_t *lists[threads->n_threads];
@@ -103,7 +105,7 @@ void threads_frame_submit(threads_t *threads, rototiller_frame_t *frame, void (*
}
for (i = 0; i < threads->n_threads; i++)
- thread_fragments_submit(&threads->threads[i], render_fragment_func, lists[i]);
+ thread_fragments_submit(&threads->threads[i], render_fragment_func, context, lists[i]);
}
diff --git a/src/threads.h b/src/threads.h
index 5926328..f7eec81 100644
--- a/src/threads.h
+++ b/src/threads.h
@@ -11,7 +11,7 @@ typedef struct threads_t threads_t;
threads_t * threads_create();
void threads_destroy(threads_t *threads);
-void threads_frame_submit(threads_t *threads, rototiller_frame_t *frame, void (*render_fragment_func)(fb_fragment_t *fragment));
+void threads_frame_submit(threads_t *threads, rototiller_frame_t *frame, void (*render_fragment_func)(void *context, fb_fragment_t *fragment), void *context);
void threads_wait_idle(threads_t *threads);
unsigned threads_num_threads(threads_t *threads);
© All Rights Reserved