# HG changeset patch # User Tero Marttila # Date 1213027119 -10800 # Node ID 86f2e5b7191b60848fa04a448943f837c77dcd3d # Parent 8e8b56b0e0f5e7bace65d2be7387a67765bd0ff1 render_multi uses render_slices now, and seems to work committer: Tero Marttila diff -r 8e8b56b0e0f5 -r 86f2e5b7191b Makefile --- a/Makefile Mon Jun 09 03:15:34 2008 +0300 +++ b/Makefile Mon Jun 09 18:58:39 2008 +0300 @@ -1,7 +1,7 @@ LDFLAGS = -Llib/libevent-dev/lib -levent -lpng CFLAGS = -Wall -g -Ilib/libevent-dev/include -EXECS = render_file web_main render_node +EXECS = file_main web_main node_main all: web_main file_main node_main diff -r 8e8b56b0e0f5 -r 86f2e5b7191b http.c --- a/http.c Mon Jun 09 03:15:34 2008 +0300 +++ b/http.c Mon Jun 09 18:58:39 2008 +0300 @@ -39,7 +39,7 @@ int_val = strtol(qarg->value, &cptr, 10); if (*qarg->value == '\0' || *cptr != '\0' || int_val < 0) - ERROR("invalid QARG_UINT: %s: %s -> %d", qarg->key, qarg->value, int_val); + ERROR("invalid QARG_UINT: %s: %s -> %ld", qarg->key, qarg->value, int_val); *((unsigned long int *) qarg_info->hqa_addr) = (unsigned long int) int_val; diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render.c --- a/render.c Mon Jun 09 03:15:34 2008 +0300 +++ b/render.c Mon Jun 09 18:58:39 2008 +0300 @@ -1,7 +1,7 @@ #include #include -#include "render_internal.h" +#include "render_struct.h" #include "render.h" int render_init (struct render *ctx, int mode) { diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_mandelbrot.c --- a/render_mandelbrot.c Mon Jun 09 03:15:34 2008 +0300 +++ b/render_mandelbrot.c Mon Jun 09 18:58:39 2008 +0300 @@ -1,6 +1,6 @@ #include "common.h" -#include "render_internal.h" +#include "render_struct.h" #include "render_mandelbrot.h" #define DETAIL 255 diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_multi.c --- a/render_multi.c Mon Jun 09 03:15:34 2008 +0300 +++ b/render_multi.c Mon Jun 09 18:58:39 2008 +0300 @@ -53,7 +53,7 @@ // how many bytes we have already written into the current row size_t col; - // _render_multi_done called for this? + // passed in the last segment of data? int render_done; // a pointer to ourself @@ -79,8 +79,8 @@ // the render_slices thing struct render_slices slices; - // has render_png_done returned? - int png_done; + // has render_slices_done returned? + int slices_done; // buffer render_png output in this struct evbuffer *out_buf; @@ -154,10 +154,9 @@ ctx->cb_data(ctx->out_buf, ctx->cb_arg); // was that the last piece of PNG data? - if (ctx->png_done && evbuffer_get_length(ctx->out_buf) == 0) { + if (ctx->slices_done && evbuffer_get_length(ctx->out_buf) == 0) { // PNG data done! _render_multi_do_png_done(ctx); - } } @@ -188,21 +187,23 @@ assert(ctx->nodes[i].render_remote == NULL); assert(ctx->nodes[i].col == 0); } + + // finish off the render_slices + if (render_slices_done(&ctx->slices)) + ERROR("render_slices_done"); + + // mark this as complete, all data is now in the out buffer + ctx->slices_done = 1; - // and that the PNG stuff is complete - assert(ctx->png_done); - // if that all the data handled now, we're done _render_multi_do_png_data(ctx); // don't free ourself, our user does that (probably already did, via render_png_done) return; -/* error: - / * render_png_done failed, probably because we didn't have enough data * / + /* render_slices_done -> render_png_done failed, probably because we didn't have enough data */ _render_multi_do_fail(ctx, FAIL_PARTIAL); -*/ } // the request completed abnormally. Flags: @@ -301,17 +302,12 @@ ERROR("read"); } else if (ret == 0) { - // mark it as done - ctx->render_done = 1; - ctx->self->renders_done++; - // this ctx's remote render is done render_remote_done(ctx->render_remote); ctx->render_remote = NULL; - // we should only receive an EOF when ctx->col is zero or full - if (ctx->col != 0 || ctx->col != ctx->slice_width) - ERROR("incomplete data for slice %zu: %zu/%zu bytes", ctx->info->index, ctx->col, ctx->slice_width); + // count how many are done + ctx->self->renders_done++; // are all of them done? if (ctx->self->renders_done == ctx->self->node_count) { @@ -324,44 +320,43 @@ return; } - // check if we were expecting - // ok, we received some data normally ctx->col += ret; - // is our slice full now? + // is this segment full now? if (ctx->col == ctx->slice_width) { - // yes! int status; + // pass the segment in to render_slices if ((status = render_slices_segment_done(&ctx->self->slices, ctx->info->index)) == -1) ERROR("render_slices_segment_done"); - + + // reset the col marker + ctx->col = 0; + // row done? if (status & SLICE_PROCESS_ROW) { - // XXX: ignore SLICE_PROCESS_ROW from render_slices_process_row + // process the row via render_slices status = render_slices_process_row(&ctx->self->slices); - - // we should have SLICE_CONTINUE by now, unless the PNG is done - if (status & SLICE_CONTINUE) { - // clear the col values and reschedule the reads in case they were ~SLICE_CONTINUE - int i; - for (i = 0; i < ctx->self->node_count; i++) { - ctx->self->nodes[i].col = 0; - render_remote_reschedule(ctx->self->nodes[i].render_remote); - } - } else { - // XXX: assume render_slices_process_row doesn't return a SLICE_PROCESS_ROW alone - assert(status == 0); - - ctx->self->png_done = 1; - - // and wait for the EOF... - } + } - // if we got SLICE_CONTINUE here, I don't care, don't try and get another row now - // just fall through and reschedule + // do we need to continue? + if (status & SLICE_CONTINUE) { + // reschedule the reads in case they were ~SLICE_CONTINUE + int i; + + for (i = 0; i < ctx->self->node_count; i++) { + // just don't reschedule those that are already EOF... + if (ctx->self->nodes[i].render_remote) + render_remote_reschedule(ctx->self->nodes[i].render_remote); + } + + } else { + // don't read any more data yet, we'll be rescheduled by someone else + return; + + } } // ok, reschedule ourselves diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_remote.c --- a/render_remote.c Mon Jun 09 03:15:34 2008 +0300 +++ b/render_remote.c Mon Jun 09 18:58:39 2008 +0300 @@ -9,7 +9,7 @@ #include #include -#include "render_internal.h" // for render_cmd_build +#include "render_struct.h" // for render_cmd_build #include "render_remote.h" #include "common.h" diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_slices.c --- a/render_slices.c Mon Jun 09 03:15:34 2008 +0300 +++ b/render_slices.c Mon Jun 09 18:58:39 2008 +0300 @@ -113,41 +113,48 @@ int render_slices_segment_done (struct render_slices *ctx, int index) { assert(index >= 0 && index < ctx->num_slices); - assert(ctx->slices_done < ctx->num_slices); - - // keep track of the number of full slices - ctx->slices_done++; - // is the row complete? - if (ctx->slices_done == ctx->num_slices) { + // our return status + int status = 0; + + // keep track of the number of full segments in this row + ctx->segments_done++; + + // is this row complete? + if (ctx->segments_done == ctx->num_slices) { // the row is complete - ctx->slices_done = 0; + ctx->segments_done = 0; + + // once we fill up a row we can always call process_row + status |= SLICE_PROCESS_ROW; - // is the other row waiting for it to get processed? + // is the other row still waiting for it to get processed? if (ctx->done_row < 0) { // no, point the done_row at this row, point the render buffers to the unused row ctx->done_row = ctx->render_row; ctx->render_row = (ctx->render_row == 0 ? 1 : 0); int i ; + + // update the remaining render buffers for (i = 0; i < ctx->num_slices; i++) { ctx->slices[i].info.render_buf = ctx->rows[ctx->render_row] + ctx->slices[i].row_offset; } // can now continue rendering as well as call process_row - return SLICE_PROCESS_ROW & SLICE_CONTINUE; + status |= SLICE_CONTINUE; } else { // cannot continue rendering, need to have process_row complete first - return SLICE_PROCESS_ROW; } } else { // the row is not complete, do not render the next segment, do not call process_row - return 0; } + + return status; } int render_slices_process_row (struct render_slices *ctx) { @@ -159,7 +166,7 @@ // mark the row as processed ctx->done_row = -1; - + // ok, but don't call me again until I tell you to. return SLICE_CONTINUE; @@ -168,4 +175,14 @@ return -1; } +int render_slices_done (struct render_slices *ctx) { + // finish off render_png + if (render_png_done(&ctx->png_info)) + ERROR("render_png_done"); + + return 0; +error: + render_slices_free(ctx); + return -1; +} diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_slices.h --- a/render_slices.h Mon Jun 09 03:15:34 2008 +0300 +++ b/render_slices.h Mon Jun 09 18:58:39 2008 +0300 @@ -60,7 +60,7 @@ /* * The render_buf for the render_slice_info with the given index value contains * the full information for the next row of the render_info render. Returns a - * bitwise-AND of the SLICE_* flags, or -1 for an error: + * bitwise-OR of the SLICE_* flags, or -1 for an error: * * Valid return values: * zero @@ -85,7 +85,7 @@ /* * Process a completed row and generate output in the PNG format (how that is * handled depends on the render given to render_slices_alloc/init). Returns a - * bitwise-AND of the SLICE_* flags, or -1 for an error: + * bitwise-OR of the SLICE_* flags, or -1 for an error: * * Valid return values : * zero @@ -106,6 +106,12 @@ int render_slices_process_row (struct render_slices *ctx); /* + * Signifiy that the render has been completed. This will flush out buffered + * output data. + */ +int render_slices_done (struct render_slices *ctx); + +/* * Free a render_slices. The rendering may or may not be complete. */ void render_slices_free (struct render_slices *ctx); diff -r 8e8b56b0e0f5 -r 86f2e5b7191b render_slices_struct.h --- a/render_slices_struct.h Mon Jun 09 03:15:34 2008 +0300 +++ b/render_slices_struct.h Mon Jun 09 18:58:39 2008 +0300 @@ -17,16 +17,16 @@ // our offset into rowbuf size_t row_offset; - + // pointer back to parent struct render_slices *self; } slices[RENDER_SLICES_MAX]; // how many slices are in use size_t num_slices; - + // how many slices have reported the current row as done - size_t slices_done; + size_t segments_done; // the a pointer to the raw memory buffer unsigned char *rowbuf; diff -r 8e8b56b0e0f5 -r 86f2e5b7191b web_main.c --- a/web_main.c Mon Jun 09 03:15:34 2008 +0300 +++ b/web_main.c Mon Jun 09 18:58:39 2008 +0300 @@ -17,7 +17,7 @@ #include "common.h" #include "http.h" -#include "render_internal.h" +#include "render_struct.h" #include "render.h" #include "remote_node.h" #include "remote_pool.h"