Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTon Roosendaal <ton@blender.org>2009-02-05 22:28:28 +0300
committerTon Roosendaal <ton@blender.org>2009-02-05 22:28:28 +0300
commite1b92bc166ac27e29dfdbec315a7b6233d8724d2 (patch)
tree2ed3ef7d6d3ac107ff4bd578ae0f2544570087b2
parent0a3697ccf7f16bd328a8894c62995de0ff12adb0 (diff)
2.5
Safe method to move render results to the displayed image. It now allocates a single image for display, and on each refresh callback from render, it copies the refreshed section over to this image, in 32 bits. While rendering that image then only shows progress updates, as usual. This also now works for scenes in composte and results for composite. This should solve reported crashes for MBlur or SSS.
-rw-r--r--source/blender/blenkernel/intern/image.c22
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/editors/screen/screen_ops.c100
-rw-r--r--source/blender/editors/space_image/image_draw.c4
-rw-r--r--source/blender/editors/space_node/node_edit.c4
-rw-r--r--source/blender/nodes/intern/CMP_nodes/CMP_composite.c2
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h3
-rw-r--r--source/blender/render/intern/include/render_types.h2
-rw-r--r--source/blender/render/intern/source/pipeline.c13
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 */