summaryrefslogtreecommitdiff
path: root/src/rototiller.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2018-02-26 03:29:12 -0800
committerVito Caputo <vcaputo@pengaru.com>2018-02-26 05:18:26 -0800
commit6fabe39ba8841ffe392c9b659505e12edaff43d6 (patch)
tree7a1f94427e9046679042225f1bd779067edab785 /src/rototiller.c
parent1bf11626543c2b0dd10e8e0e4f3f75c99ea4f16c (diff)
rototiller,fb: swap dispatch with page flipping
For the sake of sdl_fb, move page flipping into the main thread and run module render dispatch from another thread instead. This eliminates the fb flipper thread, moving its functionality into fb_flip() which synchronously consumes and performs a single flip from the same queue as before - the function is verbatim the loop body of the flipper thread. Now main() calls fb_flip() in a loop where it previously dispatched pages for rendering. Rendering dispatch is now performed in a created thread. See the comment in fb.c for more explanation of this shuffle.
Diffstat (limited to 'src/rototiller.c')
-rw-r--r--src/rototiller.c72
1 files changed, 49 insertions, 23 deletions
diff --git a/src/rototiller.c b/src/rototiller.c
index 79d0778..0fbc794 100644
--- a/src/rototiller.c
+++ b/src/rototiller.c
@@ -129,6 +129,7 @@ int parse_argv(int argc, const char *argv[], argv_t *res_args)
return 0;
}
+
typedef struct setup_t {
settings_t *module;
settings_t *video;
@@ -182,6 +183,7 @@ static int setup_video(settings_t *settings, setting_desc_t **next_setting)
return -EINVAL;
}
+
/* select module if not yet selected, then setup the module. */
static int setup_module(settings_t *settings, setting_desc_t **next_setting)
{
@@ -223,6 +225,7 @@ static int setup_module(settings_t *settings, setting_desc_t **next_setting)
return 0;
}
+
/* turn args into settings, automatically applying defaults if appropriate, or interactively if appropriate. */
/* returns negative value on error, 0 when settings unchanged from args, 1 when changed */
static int setup_from_args(argv_t *args, int defaults, setup_t *res_setup)
@@ -321,6 +324,30 @@ static int print_help(void)
}
+typedef struct rototiller_t {
+ rototiller_module_t *module;
+ void *module_context;
+ threads_t *threads;
+ pthread_t thread;
+ fb_t *fb;
+} rototiller_t;
+
+void * rototiller_thread(void *_rt)
+{
+ rototiller_t *rt = _rt;
+
+ for (;;) {
+ fb_page_t *page;
+
+ page = fb_page_get(rt->fb);
+ module_render_page(rt->module, rt->module_context, rt->threads, page);
+ fb_page_put(rt->fb, page);
+ }
+
+ return NULL;
+}
+
+
/* When run with partial/no arguments, if stdin is a tty, enter an interactive setup.
* If stdin is not a tty, or if --defaults is supplied in argv, default settings are used.
* If any changes to the settings occur in the course of execution, either interactively or
@@ -329,13 +356,10 @@ static int print_help(void)
*/
int main(int argc, const char *argv[])
{
- argv_t args = {};
- setup_t setup = {};
- void *context = NULL;
- rototiller_module_t *module;
- threads_t *threads;
- fb_t *fb;
- int r;
+ rototiller_t rototiller = {};
+ setup_t setup = {};
+ argv_t args = {};
+ int r;
exit_if(parse_argv(argc, argv, &args) < 0,
"unable to process arguments");
@@ -349,38 +373,40 @@ int main(int argc, const char *argv[])
exit_if(r && print_setup_as_args(&setup) < 0,
"unable to print setup");
- exit_if(!(module = module_lookup(settings_get_key(setup.module, 0))),
+ exit_if(!(rototiller.module = module_lookup(settings_get_key(setup.module, 0))),
"unable to lookup module from settings \"%s\"", settings_get_key(setup.module, 0));
- exit_if(!(fb = fb_new(fb_ops, setup.video, NUM_FB_PAGES)),
+ exit_if(!(rototiller.fb = fb_new(fb_ops, setup.video, NUM_FB_PAGES)),
"unable to create fb");
exit_if(!fps_setup(),
"unable to setup fps counter");
- exit_if(module->create_context &&
- !(context = module->create_context()),
+ exit_if(rototiller.module->create_context &&
+ !(rototiller.module_context = rototiller.module->create_context()),
"unable to create module context");
- pexit_if(!(threads = threads_create()),
- "unable to create threads");
+ pexit_if(!(rototiller.threads = threads_create()),
+ "unable to create rendering threads");
- for (;;) {
- fb_page_t *page;
+ pexit_if(pthread_create(&rototiller.thread, NULL, rototiller_thread, &rototiller) != 0,
+ "unable to create dispatch thread");
- fps_print(fb);
+ for (;;) {
+ if (fb_flip(rototiller.fb) < 0)
+ break;
- page = fb_page_get(fb);
- module_render_page(module, context, threads, page);
- fb_page_put(fb, page);
+ fps_print(rototiller.fb);
}
- threads_destroy(threads);
+ pthread_cancel(rototiller.thread);
+ pthread_join(rototiller.thread, NULL);
+ threads_destroy(rototiller.threads);
- if (context)
- module->destroy_context(context);
+ if (rototiller.module_context)
+ rototiller.module->destroy_context(rototiller.module_context);
- fb_free(fb);
+ fb_free(rototiller.fb);
return EXIT_SUCCESS;
}
© All Rights Reserved