summaryrefslogtreecommitdiff
path: root/src/rototiller.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2017-04-22 08:04:21 -0700
committerVito Caputo <vcaputo@pengaru.com>2017-04-22 12:25:53 -0700
commit90ad3469f3772218ce1842cf79cbc8235368bba2 (patch)
tree13e2dd4fdf987e9e47797580578ea911d3020571 /src/rototiller.c
parent5ba408fd9ce88a3635f745930cf09cb47a1400a2 (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.c31
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);
© All Rights Reserved