diff options
-rw-r--r-- | source/blender/blenkernel/intern/image.c | 22 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 2 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_ops.c | 100 | ||||
-rw-r--r-- | source/blender/editors/space_image/image_draw.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_node/node_edit.c | 4 | ||||
-rw-r--r-- | source/blender/nodes/intern/CMP_nodes/CMP_composite.c | 2 | ||||
-rw-r--r-- | source/blender/render/extern/include/RE_pipeline.h | 3 | ||||
-rw-r--r-- | source/blender/render/intern/include/render_types.h | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 13 |
9 files changed, 120 insertions, 32 deletions
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index ee631a89083..f6d604bdec7 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1797,14 +1797,30 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser) /* showing RGBA result itself (from compo/sequence) or like exr, using layers etc */ +/* always returns a single ibuf, also during render progress */ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser) { + Render *re; RenderResult *rr= NULL; - if(iuser->scene) - rr= RE_GetResult(RE_GetRender(iuser->scene->id.name)); + if(iuser->scene) { + re= RE_GetRender(iuser->scene->id.name); + rr= RE_GetResult(re); + } + if(rr==NULL) return NULL; - if(rr) { + if(RE_RenderInProgress(re)) { + ImBuf *ibuf= image_get_ibuf(ima, IMA_NO_INDEX, 0); + + /* make ibuf if needed, and initialize it */ + /* this only gets called when mutex locked */ + if(ibuf==NULL) { + ibuf= IMB_allocImBuf(rr->rectx, rr->recty, 32, IB_rect, 0); + image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0); + } + return ibuf; + } + else { RenderResult rres; float *rectf; unsigned int *rect; diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 40561a1a63a..de920ff9f25 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3678,7 +3678,7 @@ static void composite_patch(bNodeTree *ntree, Scene *scene) bNode *node; for(node= ntree->nodes.first; node; node= node->next) - if(node->id==NULL && node->type==CMP_NODE_R_LAYERS) + if(node->id==NULL && ELEM(node->type, CMP_NODE_R_LAYERS, CMP_NODE_COMPOSITE)) node->id= &scene->id; } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 71fa0bb953c..2e7df0d71c1 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -1952,6 +1952,8 @@ typedef struct RenderJob { Render *re; wmWindow *win; int anim; + Image *image; + ImageUser iuser; short *stop; short *do_update; } RenderJob; @@ -1964,28 +1966,85 @@ static void render_freejob(void *rjv) } /* called inside thread! */ -static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *rect) +static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect) { - /* rect null means per tile */ - if(rect==NULL) { - RenderJob *rj= rjv; - ScrArea *sa; + RenderJob *rj= rjv; + ImBuf *ibuf; + float x1, y1, *rectf= NULL; + int ymin, ymax, xmin, xmax; + int rymin, rxmin; + char *rectc; + + ibuf= BKE_image_get_ibuf(rj->image, &rj->iuser); + if(ibuf==NULL) return; + + /* if renrect argument, we only refresh scanlines */ + if(renrect) { + /* if ymax==recty, rendering of layer is ready, we should not draw, other things happen... */ + if(rr->renlay==NULL || renrect->ymax>=rr->recty) + return; - // XXX validate window? + /* xmin here is first subrect x coord, xmax defines subrect width */ + xmin = renrect->xmin; + xmax = renrect->xmax - xmin; + if (xmax<2) return; - /* find an imagewindow showing render result */ - for(sa= rj->win->screen->areabase.first; sa; sa= sa->next) { - if(sa->spacetype==SPACE_IMAGE) { - SpaceImage *sima= sa->spacedata.first; - - if(sima->image && sima->image->type==IMA_TYPE_R_RESULT) { - /* force refresh */ - sima->pad= 1; // XXX temp - *(rj->do_update)= 1; - } - } + ymin= renrect->ymin; + ymax= renrect->ymax - ymin; + if(ymax<2) + return; + renrect->ymin= renrect->ymax; + } + else { + xmin = ymin = rr->crop; + xmax = rr->rectx - 2*rr->crop; + ymax = rr->recty - 2*rr->crop; + } + + /* xmin ymin is in tile coords. transform to ibuf */ + rxmin= rr->tilerect.xmin + xmin; + if(rxmin >= ibuf->x) return; + rymin= rr->tilerect.ymin + ymin; + if(rymin >= ibuf->y) return; + + if(rxmin + xmax > ibuf->x) + xmax= ibuf->x - rxmin; + if(rymin + ymax > ibuf->y) + ymax= ibuf->y - rymin; + if(xmax < 1 || ymax < 1) return; + + /* find current float rect for display, first case is after composit... still weak */ + if(rr->rectf) + rectf= rr->rectf; + else { + if(rr->rect32) + return; + else { + if(rr->renlay==NULL || rr->renlay->rectf==NULL) return; + rectf= rr->renlay->rectf; } } + if(rectf==NULL) return; + + rectf+= 4*(rr->rectx*ymin + xmin); + rectc= (char *)(ibuf->rect + ibuf->x*rymin + rxmin); + + for(y1= 0; y1<ymax; y1++) { + float *rf= rectf; + char *rc= rectc; + + for(x1= 0; x1<xmax; x1++, rf += 4, rc+=4) { + rc[0]= FTOCHAR(rf[0]); + rc[1]= FTOCHAR(rf[1]); + rc[2]= FTOCHAR(rf[2]); + rc[3]= FTOCHAR(rf[3]); + } + rectf += 4*rr->rectx; + rectc += 4*ibuf->x; + } + + /* make jobs timer to send notifier */ + *(rj->do_update)= 1; } static void render_startjob(void *rjv, short *stop, short *do_update) @@ -2046,6 +2105,8 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) rj->scene= scene; rj->win= CTX_wm_window(C); rj->anim= RNA_boolean_get(op->ptr, "anim"); + rj->iuser.scene= scene; + rj->iuser.ok= 1; /* setup job */ steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene); @@ -2053,10 +2114,11 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event) WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0); WM_jobs_callbacks(steve, render_startjob, NULL, NULL); - /* get a render result image, and make sure it is clean */ + /* get a render result image, and make sure it is empty */ ima= BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); - + rj->image= ima; + /* setup new render */ re= RE_NewRender(scene->id.name); RE_test_break_cb(re, rj, render_breakjob); diff --git a/source/blender/editors/space_image/image_draw.c b/source/blender/editors/space_image/image_draw.c index 623877415ea..70a05d52376 100644 --- a/source/blender/editors/space_image/image_draw.c +++ b/source/blender/editors/space_image/image_draw.c @@ -121,10 +121,6 @@ static void image_verify_buffer_float(SpaceImage *sima, ImBuf *ibuf) else IMB_rect_from_float(ibuf); } - else if(sima->pad) { - sima->pad= 0; // XXX temp for render updates! - IMB_rect_from_float(ibuf); - } } } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 46242b7f244..b317c01e6c6 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -510,7 +510,7 @@ void node_composit_default(Scene *sce) sce->nodetree= ntreeAddTree(NTREE_COMPOSIT); - out= nodeAddNodeType(sce->nodetree, CMP_NODE_COMPOSITE, NULL, NULL); + out= nodeAddNodeType(sce->nodetree, CMP_NODE_COMPOSITE, NULL, &sce->id); out->locx= 300.0f; out->locy= 400.0f; in= nodeAddNodeType(sce->nodetree, CMP_NODE_R_LAYERS, NULL, &sce->id); @@ -2302,6 +2302,8 @@ void node_read_fullsamplelayers(SpaceNode *snode) * goes over all scenes other than the input, checks if they have * render layer nodes referencing the to-be-deleted scene, and * resets them to NULL. */ + +/* XXX needs to get current scene then! */ void clear_scene_in_nodes(Scene *sce) { Scene *sce1; diff --git a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c index 8e47e17d868..ee9545c3196 100644 --- a/source/blender/nodes/intern/CMP_nodes/CMP_composite.c +++ b/source/blender/nodes/intern/CMP_nodes/CMP_composite.c @@ -50,7 +50,7 @@ static void node_composit_exec_composite(void *data, bNode *node, bNodeStack **i RenderData *rd= data; if(scene && (rd->scemode & R_DOCOMP)) { - RenderResult *rr= RE_GetResult(RE_GetRender(scene->id.name)); /* G.scene is WEAK! */ + RenderResult *rr= RE_GetResult(RE_GetRender(scene->id.name)); if(rr) { CompBuf *outbuf, *zbuf=NULL; diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h index 538372d5558..04f7d264229 100644 --- a/source/blender/render/extern/include/RE_pipeline.h +++ b/source/blender/render/extern/include/RE_pipeline.h @@ -139,6 +139,9 @@ typedef struct RenderStats { struct Render *RE_NewRender (const char *name); struct Render *RE_GetRender(const char *name); +/* returns 1 while render is working (or renders called from within render) */ +int RE_RenderInProgress(struct Render *re); + /* use free render as signal to do everything over (previews) */ void RE_FreeRender (struct Render *re); /* only called on exit */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 66722ea983f..ab3758781ce 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -113,7 +113,7 @@ struct Render char name[RE_MAXNAME]; /* state settings */ - short flag, osa, ok, do_gamma; + short flag, osa, ok, result_ok; /* result of rendering */ RenderResult *result; diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index b271af0cc70..cc2cf290795 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -135,6 +135,11 @@ static void int_nothing(void *unused, int val) {} static int void_nothing(void *unused) {return 0;} static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);} +int RE_RenderInProgress(Render *re) +{ + return re->result_ok==0; +} + static void stats_background(void *unused, RenderStats *rs) { uintptr_t mem_in_use= MEM_get_memory_in_use(); @@ -1013,9 +1018,10 @@ Render *RE_NewRender(const char *name) strncpy(re->name, name, RE_MAXNAME); } - /* prevent UI to draw old results immediately */ + /* prevent UI to draw old results */ RE_FreeRenderResult(re->result); re->result= NULL; + re->result_ok= 0; /* set default empty callbacks */ re->display_init= result_nothing; @@ -2487,8 +2493,8 @@ static int render_initialize_from_scene(Render *re, Scene *scene, int anim) void RE_BlenderFrame(Render *re, Scene *scene, int frame) { /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ - /* is also set by caller renderwin.c */ G.rendering= 1; + re->result_ok= 0; scene->r.cfra= frame; @@ -2498,6 +2504,7 @@ void RE_BlenderFrame(Render *re, Scene *scene, int frame) /* UGLY WARNING */ G.rendering= 0; + re->result_ok= 1; } static void do_write_image_or_movie(Render *re, Scene *scene, bMovieHandle *mh) @@ -2586,6 +2593,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra) /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* is also set by caller renderwin.c */ G.rendering= 1; + re->result_ok= 0; if(BKE_imtype_is_movie(scene->r.imtype)) mh->start_movie(&re->r, re->rectx, re->recty); @@ -2673,6 +2681,7 @@ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra, int tfra) /* UGLY WARNING */ G.rendering= 0; + re->result_ok= 1; } /* note; repeated win/disprect calc... solve that nicer, also in compo */ |