diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2022-04-28 01:46:10 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2022-05-01 21:02:41 -0700 |
commit | a59229c5513e73348c87bcfc5cc4b39a31012437 (patch) | |
tree | 09cbc567f883b8f8677f689f658cd747ca360706 /src/modules/compose | |
parent | 7dec62422b3b00f9a347d37f1e7f89e5bbaba0a9 (diff) |
til_fb: introduce a fragment texture source
Idea here is to provide texture sources for obtaining pixel
colors at the til_fb_put_pixel/fill drawing API, making it
possible for at least overlayable modules to serve as
mask/stencil operators where their drawn areas are populated by
the contents of another fragment produced dynamically,
potentially by other modules altogether.
This commit adds a texture=modulename option to the compose
module for specifying if a texture should be used when
compositing, excepting and defaulting to "none" for disabling
texturing.
A future commit should expand this compose option to accept a
potential list of modules for composing the texture in the same
way as the main layers= list functions.
Something this all immediately makes clear is the need for
a better settings syntax, probably in the form of all module
setting specifiers optionally being followed by a squence
of settings, with support for escaping to handle nested
situations.
Diffstat (limited to 'src/modules/compose')
-rw-r--r-- | src/modules/compose/compose.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/src/modules/compose/compose.c b/src/modules/compose/compose.c index d672bf0..a331b3f 100644 --- a/src/modules/compose/compose.c +++ b/src/modules/compose/compose.c @@ -33,12 +33,15 @@ typedef struct compose_layer_t { typedef struct compose_context_t { unsigned n_cpus; + til_fb_fragment_t texture_fb; + compose_layer_t texture; size_t n_layers; compose_layer_t layers[]; } compose_context_t; typedef struct compose_setup_t { til_setup_t til_setup; + char *texture; size_t n_layers; char *layers[]; } compose_setup_t; @@ -93,6 +96,16 @@ static void * compose_create_context(unsigned ticks, unsigned n_cpus, til_setup_ ctxt->n_layers++; } + if (((compose_setup_t *)setup)->texture) { + til_setup_t *texture_setup = NULL; + + ctxt->texture.module = til_lookup_module(((compose_setup_t *)setup)->texture); + (void) til_module_randomize_setup(ctxt->texture.module, &texture_setup, NULL); + + (void) til_module_create_context(ctxt->texture.module, ticks, texture_setup, &ctxt->texture.module_ctxt); + til_setup_free(texture_setup); + } + return ctxt; } @@ -103,6 +116,12 @@ static void compose_destroy_context(void *context) for (int i = 0; i < ctxt->n_layers; i++) til_module_destroy_context(ctxt->layers[i].module, ctxt->layers[i].module_ctxt); + + if (ctxt->texture.module) + til_module_destroy_context(ctxt->texture.module, ctxt->texture.module_ctxt); + + free(ctxt->texture_fb.buf); + free(context); } @@ -113,8 +132,38 @@ static void compose_prepare_frame(void *context, unsigned ticks, unsigned n_cpus til_fb_fragment_clear(fragment); - for (int i = 0; i < ctxt->n_layers; i++) - til_module_render(ctxt->layers[i].module, ctxt->layers[i].module_ctxt, ticks, fragment); + if (ctxt->texture.module) { + if (!ctxt->texture_fb.buf || + ctxt->texture_fb.frame_width != fragment->frame_width || + ctxt->texture_fb.frame_height != fragment->frame_height) { + + ctxt->texture_fb = (til_fb_fragment_t){ + .buf = realloc(ctxt->texture_fb.buf, fragment->frame_height * fragment->frame_width * sizeof(uint32_t)), + + .frame_width = fragment->frame_width, + .frame_height = fragment->frame_height, + .width = fragment->frame_width, + .height = fragment->frame_height, + .pitch = fragment->frame_width, + }; + } + + ctxt->texture_fb.cleared = 0; + til_module_render(ctxt->texture.module, ctxt->texture.module_ctxt, ticks, &ctxt->texture_fb); + + til_module_render(ctxt->layers[0].module, ctxt->layers[0].module_ctxt, ticks, fragment); + + for (size_t i = 1; i < ctxt->n_layers; i++) { + til_fb_fragment_t textured = *fragment; + + textured.texture = &ctxt->texture_fb; + + til_module_render(ctxt->layers[i].module, ctxt->layers[i].module_ctxt, ticks, &textured); + } + } else { + for (size_t i = 0; i < ctxt->n_layers; i++) + til_module_render(ctxt->layers[i].module, ctxt->layers[i].module_ctxt, ticks, fragment); + } } @@ -179,6 +228,21 @@ static char * compose_random_layers_setting(void) static int compose_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup) { const char *layers; + const char *texture; + const char *texture_values[] = { + "none", + "blinds", + "checkers", + "drizzle", + "julia", + "plasma", + "roto", + "stars", + "submit", + "swab", + "voronoi", + NULL + }; int r; r = til_settings_get_and_describe_value(settings, @@ -195,6 +259,20 @@ static int compose_setup(const til_settings_t *settings, til_setting_t **res_set if (r) return r; + r = til_settings_get_and_describe_value(settings, + &(til_setting_desc_t){ + .name = "Module to use for source texture, \"none\" to disable", + .key = "texture", + .preferred = texture_values[0], + .annotations = NULL, + .values = texture_values, + }, + &texture, + res_setting, + res_desc); + if (r) + return r; + /* turn layers colon-separated list into a null-terminated array of strings */ if (res_setup) { compose_setup_t *setup; @@ -257,6 +335,24 @@ static int compose_setup(const til_settings_t *settings, til_setting_t **res_set setup = new; } while (layer = strtok(NULL, ":")); + if (strcasecmp(texture, "none")) { + const til_module_t *texture_module; + + texture_module = til_lookup_module(texture); + if (!texture_module) { + til_setup_free(&setup->til_setup); + + return -EINVAL; + } + + setup->texture = strdup(texture); + if (!setup->texture) { + til_setup_free(&setup->til_setup); + + return -ENOMEM; + } + } + *res_setup = &setup->til_setup; } |