--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/render_multi.c Fri Jun 06 18:35:46 2008 +0300
@@ -0,0 +1,143 @@
+
+
+#include "render_multi.h"
+#include "remote_node.h"
+
+
+struct render_multi {
+ // these are used as arguments to render_remote
+ struct render_sub_ctx {
+ // our offset in the list
+ int index;
+
+ // the remote_render_ctx
+ struct remote_render_ctx *remote_render;
+
+ // a pointer to ourself
+ struct render_multi *self;
+
+ // _render_sent called for this?
+ int render_sent;
+ } remote_renders[RENDER_MULTI_NODES_MAX];
+
+ // how many remote_renders we have
+ int remote_render_count;
+
+ // our own callbacks that we call
+ void (*cb_sent)(void *arg);
+ void (*cb_data)(struct evbuffer *buf, void *arg);
+ void (*cb_done)(void *arg);
+ void (*cb_fail)(void *arg);
+
+ void *cb_arg;
+
+};
+
+// our render_remote callbacks
+void _render_sent (void *arg) {
+ struct render_sub_ctx *ctx, *ctx2 = arg;
+
+ ctx->render_sent = 1;
+
+ // have all render_sub_ctxs been sent?
+ int i;
+ for (i = 0; i < ctx->self->remote_render_count; i++) {
+ if (!ctx->self->remote_renders[i].render_sent)
+ break;
+ }
+
+ if (i == ctx->self->remote_render_count) {
+ // call cb_sent
+ ctx->self->cb_sent(ctx->self->cb_arg);
+ }
+}
+
+void _render_data (struct evbuffer *buf, void *arg) {
+
+}
+
+void _render_done (void *arg) {
+
+}
+
+void _render_fail (void *arg) {
+
+}
+
+#define ROUND_DOWN(dividend, divisor) ((dividend) / (divisor))
+#define ROUND_UP(dividend, divisor) (((dividend) / (divisor)) + ((dividend) % (divisor)))
+
+#define HALF(a, b) (( a + b) / 2)
+
+struct render_multi *render_multi (
+ render_t *render_ctx, // what to render
+ struct remote_pool *render_pool, // what render pool to use
+ void (*cb_sent)(void *arg),
+ void (*cb_data)(struct evbuffer *buf, void *arg),
+ void (*cb_done)(void *arg),
+ void (*cb_fail)(void *arg),
+ void *cb_arg
+) {
+ struct render_multi *ctx = NULL;
+ render_t r_left, r_right;
+
+ // for now, just split it in half into two render_ts
+ assert(RENDER_MULTI_NODES_MAX >= 2);
+
+ if (
+ render_init(&r_left, RENDER_RAW)
+ || render_init(&r_right, RENDER_RAW)
+ || render_set_size(&r_left, render_ctx->img_w / 2, render_ctx->img_h)
+ || render_set_size(&r_right, render_ctx->img_w / 2 + render_ctx->img_w % 2, render_ctx->img_h)
+ || render_set_region_raw(&r_left, render_ctx->x1, render_ctx->y1, HALF(render_ctx->x1, render_ctx->x2), render_ctx->y2)
+ || render_set_region_raw(&r_right, HALF(render_ctx->x1, render_ctx->x2), render_ctx->y1, render_ctx->x2, render_ctx->y2)
+ )
+ ERROR("render_{init,set_size,set_region_raw}");
+
+ // alloc the render_multi
+ ctx = calloc(1, sizeof(struct render_multi));
+
+ if (!ctx)
+ ERROR("calloc");
+
+ // store the provided callback functions
+ ctx->cb_sent = cb_sent;
+ ctx->cb_data = cb_data;
+ ctx->cb_done = cb_done;
+ ctx->cb_fail = cb_fail;
+ ctx->cb_arg = cb_arg;
+
+ // pull two nodes from the pool
+ struct remote_node *node_left, *node_right;
+
+ if (
+ !(node_left = remote_pool_get(pool_info))
+ || !(node_right = remote_pool_get(pool_info))
+ )
+ ERROR("remote_pool_get");
+
+ // init the remote_render
+ ctx->remote_renders[0].index = 0;
+ ctx->remote_renders[0].self = &ctx
+ ctx->remote_renders[1].index = 1;
+ ctx->remote_renders[1].self = &ctx
+ ctx->remote_render_count = 2;
+
+ // the two render_remote calls
+ if (
+ !(ctx->remote_renders[0].remote_render = render_remote(&r_left, node_left,
+ &_render_sent, &_render_data, &_render_done, &_render_fail, &ctx->remote_renders[0]))
+ || !(ctx->remote_renders[1].remote_render = render_remote(&r_right, node_right,
+ &_render_sent, &_render_data, &_render_done, &_render_fail, &ctx->remote_renders[1]))
+ )
+ ERROR("render_remote");
+
+ // I guess that's a succesfull start now
+ return 0;
+
+error:
+ free(ctx);
+
+ return -1;
+}
+