render_multi.c
changeset 11 082bfaf38cf0
child 13 ee426f453cf5
--- /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;
+}
+