diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2017-04-22 08:04:21 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2017-04-22 12:25:53 -0700 |
commit | 90ad3469f3772218ce1842cf79cbc8235368bba2 (patch) | |
tree | 13e2dd4fdf987e9e47797580578ea911d3020571 /src/rototiller.c | |
parent | 5ba408fd9ce88a3635f745930cf09cb47a1400a2 (diff) |
rototiller: add threaded rendering
This is a simple worker thread implementation derived from the ray_threads
code in the ray module. The ray_threads code should be discarded in a
future commit now that rototiller can render fragments using threads.
If a module supplies a prepare_frame() method, then it is called
per-frame to prepare a rototiller_frame_t which specifies how to divvy
up the page into fragments. Those fragments are then dispatched to a
thread per CPU which call the module's rendering function in parallel.
There is no coupling of the number of fragments in a frame to the number of
threads/CPUs. Some modules may benefit from the locality of tile-based
rendering, so the fragments are simply dispatched across the available CPUs
in a striped fashion.
Helpers will be added later to the fb interface for tiling fragments, which
modules desiring tiled rendering may utilize in their prepare_frame()
methods.
This commit does not modify any modules to become threaded, it only adds
the scaffolding.
Diffstat (limited to 'src/rototiller.c')
-rw-r--r-- | src/rototiller.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/src/rototiller.c b/src/rototiller.c index 50df52e..f9cfece 100644 --- a/src/rototiller.c +++ b/src/rototiller.c @@ -13,6 +13,7 @@ #include "fb.h" #include "fps.h" #include "rototiller.h" +#include "threads.h" #include "util.h" /* Copyright (C) 2016 Vito Caputo <vcaputo@pengaru.com> */ @@ -56,14 +57,36 @@ static void module_select(int *module) } +static void module_render_page_threaded(rototiller_module_t *module, threads_t *threads, fb_page_t *page) +{ + rototiller_frame_t frame; + unsigned i; + + module->prepare_frame(threads_num_threads(threads), &page->fragment, &frame); + + threads_frame_submit(threads, &frame, module->render_fragment); + threads_wait_idle(threads); +} + + +static void module_render_page(rototiller_module_t *module, threads_t *threads, fb_page_t *page) +{ + if (!module->prepare_frame) + return module->render_fragment(&page->fragment); + + module_render_page_threaded(module, threads, page); +} + + int main(int argc, const char *argv[]) { int drm_fd; drmModeModeInfoPtr drm_mode; uint32_t drm_crtc_id; uint32_t drm_connector_id; - fb_t *fb; + threads_t *threads; int module; + fb_t *fb; drm_setup(&drm_fd, &drm_crtc_id, &drm_connector_id, &drm_mode); module_select(&module); @@ -74,16 +97,20 @@ int main(int argc, const char *argv[]) pexit_if(!fps_setup(), "unable to setup fps counter"); + pexit_if(!(threads = threads_create()), + "unable to create threads"); + for (;;) { fb_page_t *page; fps_print(fb); page = fb_page_get(fb); - modules[module]->render_fragment(&page->fragment); + module_render_page(modules[module], threads, page); fb_page_put(fb, page); } + threads_destroy(threads); fb_free(fb); close(drm_fd); |