summaryrefslogtreecommitdiff
path: root/src/modules/compose/compose.c
diff options
context:
space:
mode:
authorVito Caputo <vcaputo@pengaru.com>2022-04-28 01:46:10 -0700
committerVito Caputo <vcaputo@pengaru.com>2022-05-01 21:02:41 -0700
commita59229c5513e73348c87bcfc5cc4b39a31012437 (patch)
tree09cbc567f883b8f8677f689f658cd747ca360706 /src/modules/compose/compose.c
parent7dec62422b3b00f9a347d37f1e7f89e5bbaba0a9 (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/compose.c')
-rw-r--r--src/modules/compose/compose.c100
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;
}
© All Rights Reserved