summaryrefslogtreecommitdiff
path: root/src/modules
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
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')
-rw-r--r--src/modules/blinds/blinds.c14
-rw-r--r--src/modules/compose/compose.c100
-rw-r--r--src/modules/montage/montage.c25
3 files changed, 122 insertions, 17 deletions
diff --git a/src/modules/blinds/blinds.c b/src/modules/blinds/blinds.c
index b14997e..0a8342e 100644
--- a/src/modules/blinds/blinds.c
+++ b/src/modules/blinds/blinds.c
@@ -66,8 +66,11 @@ static inline void draw_blind_horizontal(til_fb_fragment_t *fragment, unsigned r
unsigned row_height = fragment->frame_height / count;
unsigned height = roundf(t * (float)row_height);
- for (unsigned y = 0; y < height; y++)
- memset(fragment->buf + ((row * row_height) + y ) * fragment->pitch, 0xff, fragment->width * 4);
+/* 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_unchecked(fragment, fragment->x + x, fragment->y + y + row * row_height, 0xffffffff);
+ }
}
@@ -77,8 +80,11 @@ static inline void draw_blind_vertical(til_fb_fragment_t *fragment, unsigned col
unsigned column_width = fragment->frame_width / count;
unsigned width = roundf(t * (float)column_width);
- for (unsigned y = 0; y < fragment->height; y++)
- memset(fragment->buf + y * fragment->pitch + column * column_width, 0xff, width * 4);
+/* 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_unchecked(fragment, fragment->x + x + column * column_width, fragment->y + y, 0xffffffff);
+ }
}
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;
}
diff --git a/src/modules/montage/montage.c b/src/modules/montage/montage.c
index 8444616..65aabe6 100644
--- a/src/modules/montage/montage.c
+++ b/src/modules/montage/montage.c
@@ -141,17 +141,20 @@ static int montage_fragment_tile(const til_fb_fragment_t *fragment, unsigned til
xoff = x * tile_width;
yoff = y * tile_height;
- res_fragment->buf = fragment->buf + (yoff * fragment->pitch) + xoff;
- res_fragment->x = 0; /* fragment is a new frame */
- res_fragment->y = 0; /* fragment is a new frame */
- res_fragment->width = MIN(fragment->width - xoff, tile_width);
- res_fragment->height = MIN(fragment->height - yoff, tile_height);
- res_fragment->frame_width = res_fragment->width; /* fragment is a new frame */
- res_fragment->frame_height = res_fragment->height; /* fragment is a new frame */
- res_fragment->stride = fragment->stride + (fragment->width - res_fragment->width);
- res_fragment->pitch = fragment->pitch;
- res_fragment->number = number;
- res_fragment->cleared = fragment->cleared;
+ *res_fragment = (til_fb_fragment_t){
+ .texture = fragment->texture,
+ .buf = fragment->buf + (yoff * fragment->pitch) + xoff,
+ .x = 0, /* fragment is a new frame */
+ .y = 0, /* fragment is a new frame */
+ .width = MIN(fragment->width - xoff, tile_width),
+ .height = MIN(fragment->height - yoff, tile_height),
+ .frame_width = MIN(fragment->width - xoff, tile_width), /* fragment is a new frame */
+ .frame_height = MIN(fragment->height - yoff, tile_height), /* fragment is a new frame */
+ .stride = fragment->stride + (fragment->width - MIN(fragment->width - xoff, tile_width)),
+ .pitch = fragment->pitch,
+ .number = number,
+ .cleared = fragment->cleared,
+ };
return 1;
}
© All Rights Reserved