From fa268acb0490f7f05bef96902aee84ad4f69151d Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Tue, 11 Jul 2023 16:20:06 -0700 Subject: modules/blinds: make blinds threaded This is a first stab at threading blinds, while here I got rid of the reliance on _checked() put_pixel for clipping. This could be better, things like using a block put/copy instead of put_pixel would be a huge advantage for blinds due to its naturally contiguous blocks per-blind. While this module when non-threaded wasn't especially slow, any module leaving cores idle is depriving other potentially threaded modules of utilizing them for the duration of the non-threaded render. So now that rototiller is being used for compositions and increasingly becoming something of a meta-demo, it's become important to make everything as threaded as possible. --- src/modules/blinds/blinds.c | 71 +++++++++++++++++++++++++++++++++++---------- 1 file changed, 56 insertions(+), 15 deletions(-) (limited to 'src/modules/blinds') diff --git a/src/modules/blinds/blinds.c b/src/modules/blinds/blinds.c index 8acfae8..c4ee07f 100644 --- a/src/modules/blinds/blinds.c +++ b/src/modules/blinds/blinds.c @@ -75,16 +75,39 @@ static til_module_context_t * blinds_create_context(const til_module_t *module, } +static void blinds_prepare_frame(til_module_context_t *context, til_stream_t *stream, unsigned ticks, til_fb_fragment_t **fragment_ptr, til_frame_plan_t *res_frame_plan) +{ + *res_frame_plan = (til_frame_plan_t){ .fragmenter = til_fragmenter_tile64 }; +} + + /* draw a horizontal blind over fragment */ static inline void draw_blind_horizontal(til_fb_fragment_t *fragment, unsigned row, unsigned count, float t) { - unsigned row_height = fragment->frame_height / count; - unsigned height = roundf(t * (float)row_height); - -/* XXX FIXME: use faster block style fill/copy if til_fb gets that */ - for (unsigned y = 0; y < height; y++) { - for (unsigned x = 0; x < fragment->width; x++) - til_fb_fragment_put_pixel_checked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x, fragment->y + y + row * row_height, 0xffffffff); /* FIXME: use _unchecked() variant, but must not assume frame_height == height */ + float row_height = fragment->frame_height / (float)count; + unsigned height = roundf(t * row_height); + unsigned row_y = row * row_height; + + if (row_y >= fragment->y + fragment->height) + return; + + if (row_y + height <= fragment->y) + return; + + { + unsigned ystart = MAX(row_y, fragment->y); + unsigned yend = MIN(row_y + height, fragment->y + fragment->height); + unsigned xstart = fragment->x; + unsigned xend = fragment->x + fragment->width; + + for (unsigned y = ystart; y < yend; y++) { + /* XXX FIXME: use faster block style fill/copy if til_fb gets that */ + for (unsigned x = xstart; x < xend; x++) { + til_fb_fragment_put_pixel_unchecked(fragment, + TIL_FB_DRAW_FLAG_TEXTURABLE, + x, y, 0xffffffff); + } + } } } @@ -92,13 +115,30 @@ static inline void draw_blind_horizontal(til_fb_fragment_t *fragment, unsigned r /* draw a vertical blind over fragment */ static inline void draw_blind_vertical(til_fb_fragment_t *fragment, unsigned column, unsigned count, float t) { - unsigned column_width = fragment->frame_width / count; - unsigned width = roundf(t * (float)column_width); - -/* XXX FIXME: use faster block style fill/copy if til_fb gets that */ - for (unsigned y = 0; y < fragment->height; y++) { - for (unsigned x = 0; x < width; x++) - til_fb_fragment_put_pixel_checked(fragment, TIL_FB_DRAW_FLAG_TEXTURABLE, fragment->x + x + column * column_width, fragment->y + y, 0xffffffff); /* FIXME: use _unchecked() variant, but must not assume frame_width == width */ + float column_width = fragment->frame_width / (float)count; + unsigned width = roundf(t * column_width); + unsigned column_x = column * column_width; + + if (column_x >= fragment->x + fragment->width) + return; + + if (column_x + width <= fragment->x) + return; + + { + unsigned xstart = MAX(column_x, fragment->x); + unsigned xend = MIN(column_x + width, fragment->x + fragment->width); + unsigned ystart = fragment->y; + unsigned yend = fragment->y + fragment->height; + + for (unsigned y = ystart; y < yend; y++) { + /* XXX FIXME: use faster block style fill/copy if/when til_fb gets that */ + for (unsigned x = xstart; x < xend; x++) { + til_fb_fragment_put_pixel_unchecked(fragment, + TIL_FB_DRAW_FLAG_TEXTURABLE, + x, y, 0xffffffff); + } + } } } @@ -208,10 +248,11 @@ static int blinds_setup(const til_settings_t *settings, til_setting_t **res_sett til_module_t blinds_module = { .create_context = blinds_create_context, + .prepare_frame = blinds_prepare_frame, .render_fragment = blinds_render_fragment, .setup = blinds_setup, .name = "blinds", - .description = "Retro 80s-inspired window blinds", + .description = "Retro 80s-inspired window blinds (threaded)", .author = "Vito Caputo ", .flags = TIL_MODULE_OVERLAYABLE, }; -- cgit v1.2.1