summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/modules/montage/montage.c59
1 files changed, 51 insertions, 8 deletions
diff --git a/src/modules/montage/montage.c b/src/modules/montage/montage.c
index 697c28d..bf5aef4 100644
--- a/src/modules/montage/montage.c
+++ b/src/modules/montage/montage.c
@@ -109,6 +109,50 @@ static void montage_destroy_context(void *context)
}
+
+/* this is a hacked up derivative of fb_fragment_tile_single() */
+static int montage_fragment_tile(const fb_fragment_t *fragment, unsigned tile_width, unsigned tile_height, unsigned number, fb_fragment_t *res_fragment)
+{
+ unsigned w = fragment->width / tile_width, h = fragment->height / tile_height;
+ unsigned x, y, xoff, yoff;
+
+#if 0
+ /* total coverage isn't important in montage, leave blank gaps */
+ /* I'm keeping this here for posterity though and to record a TODO:
+ * it might be desirable to try center the montage when there must be gaps,
+ * rather than letting the gaps always fall on the far side.
+ */
+ if (w * tile_width < fragment->width)
+ w++;
+
+ if (h * tile_height < fragment->height)
+ h++;
+#endif
+
+ y = number / w;
+ if (y >= h)
+ return 0;
+
+ x = number - (y * w);
+
+ xoff = x * tile_width;
+ yoff = y * tile_height;
+
+ res_fragment->buf = (void *)fragment->buf + (yoff * fragment->pitch) + (xoff * 4);
+ 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) * 4);
+ res_fragment->pitch = fragment->pitch;
+ res_fragment->number = number;
+
+ return 1;
+}
+
+
/* The fragmenter in montage is serving double-duty:
* 1. it divides the frame into subfragments for threaded rendering
* 2. it determines which modules will be rendered where via fragment->number
@@ -116,18 +160,18 @@ static void montage_destroy_context(void *context)
static int montage_fragmenter(void *context, const fb_fragment_t *fragment, unsigned number, fb_fragment_t *res_fragment)
{
montage_context_t *ctxt = context;
- float root = sqrtf((float)ctxt->n_modules);
+ float root = sqrtf(ctxt->n_modules);
+ unsigned tile_width = fragment->frame_width / ceilf(root); /* screens are wide, give excess to the width */
+ unsigned tile_height = fragment->frame_height / floorf(root); /* take from the height */
int ret;
- ret = fb_fragment_tile_single(fragment, fragment->frame_height / root, number, res_fragment);
+ /* XXX: this could all be more clever and make some tiles bigger than others to deal with fractional square roots,
+ * but this is good enough for now considering the simplicity.
+ */
+ ret = montage_fragment_tile(fragment, tile_width, tile_height, number, res_fragment);
if (!ret)
return 0;
- /* as these tiles are frames of their own rather than subfragments, override these values */
- res_fragment->x = res_fragment->y = 0;
- res_fragment->frame_width = res_fragment->width;
- res_fragment->frame_height = res_fragment->height;
-
return ret;
}
@@ -147,7 +191,6 @@ static void montage_render_fragment(void *context, unsigned cpu, fb_fragment_t *
const rototiller_module_t *module = ctxt->modules[fragment->number];
if (fragment->number >= ctxt->n_modules) {
-
fb_fragment_zero(fragment);
return;
© All Rights Reserved