diff options
author | Ton Roosendaal <ton@blender.org> | 2010-12-19 23:12:12 +0300 |
---|---|---|
committer | Ton Roosendaal <ton@blender.org> | 2010-12-19 23:12:12 +0300 |
commit | b8e47fd160c4474032468390b40ca238381b560f (patch) | |
tree | b4402ac43ec39cad0b6627227cb042adb430f128 | |
parent | 7899765836d42037f685ee9c506d959997559cde (diff) |
Bugfix #25301
Preview render for node shaders broke, caused by localizing
materials last week, to prevent thread crashes. Fixed now.
Also added a temp fix to draw color-management corrected
node previews default. Will follow scene setting tomorrow.
Also: SSS in nodes doesn't render yet. Was issue in 2.4 too...
-rw-r--r-- | source/blender/blenkernel/BKE_material.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 34 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/node.c | 137 | ||||
-rw-r--r-- | source/blender/editors/render/render_preview.c | 33 | ||||
-rw-r--r-- | source/blender/render/intern/source/pipeline.c | 2 | ||||
-rw-r--r-- | source/blender/render/intern/source/sss.c | 2 |
6 files changed, 144 insertions, 65 deletions
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h index 53bb95cb8be..16c99cd850f 100644 --- a/source/blender/blenkernel/BKE_material.h +++ b/source/blender/blenkernel/BKE_material.h @@ -49,6 +49,7 @@ void resize_object_material(struct Object *ob, const short totcol); void init_material(struct Material *ma); struct Material *add_material(const char *name); struct Material *copy_material(struct Material *ma); +struct Material *localize_material(struct Material *ma); struct Material *give_node_material(struct Material *ma); /* returns node material or self */ void make_local_material(struct Material *ma); diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 30df1887077..cac41e457a6 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -44,6 +44,7 @@ #include "DNA_scene_types.h" #include "BLI_math.h" +#include "BLI_listbase.h" #include "BKE_animsys.h" #include "BKE_displist.h" @@ -196,6 +197,7 @@ Material *add_material(const char *name) return ma; } +/* XXX keep synced with next function */ Material *copy_material(Material *ma) { Material *man; @@ -227,6 +229,38 @@ Material *copy_material(Material *ma) return man; } +/* XXX (see above) material copy without adding to main dbase */ +Material *localize_material(Material *ma) +{ + Material *man; + int a; + + man= copy_libblock(ma); + BLI_remlink(&G.main->mat, man); + + for(a=0; a<MAX_MTEX; a++) { + if(ma->mtex[a]) { + man->mtex[a]= MEM_mallocN(sizeof(MTex), "copymaterial"); + memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex)); + /* free_material decrements! */ + id_us_plus((ID *)man->mtex[a]->tex); + } + } + + if(ma->ramp_col) man->ramp_col= MEM_dupallocN(ma->ramp_col); + if(ma->ramp_spec) man->ramp_spec= MEM_dupallocN(ma->ramp_spec); + + if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview); + + if(ma->nodetree) { + man->nodetree= ntreeLocalize(ma->nodetree); + } + + man->gpumaterial.first= man->gpumaterial.last= NULL; + + return man; +} + void make_local_material(Material *ma) { Main *bmain= G.main; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 4b158f4b405..663a2d8844c 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1186,12 +1186,12 @@ static void node_init_preview(bNode *node, int xsize, int ysize) } if(node->preview->rect==NULL) { - node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(float)*4, "node preview rect"); + node->preview->rect= MEM_callocN(4*xsize + xsize*ysize*sizeof(char)*4, "node preview rect"); node->preview->xsize= xsize; node->preview->ysize= ysize; } else - memset(node->preview->rect, 0, 4*xsize + xsize*ysize*sizeof(float)*4); + memset(node->preview->rect, 0, 4*xsize + xsize*ysize*sizeof(char)*4); } void ntreeInitPreview(bNodeTree *ntree, int xsize, int ysize) @@ -1241,12 +1241,18 @@ void nodeAddToPreview(bNode *node, float *col, int x, int y) if(x>=0 && y>=0) { if(x<preview->xsize && y<preview->ysize) { unsigned char *tar= preview->rect+ 4*((preview->xsize*y) + x); - //if(tar[0]==0.0f) { - tar[0]= FTOCHAR(col[0]); - tar[1]= FTOCHAR(col[1]); - tar[2]= FTOCHAR(col[2]); + + if(TRUE) { + tar[0]= FTOCHAR(linearrgb_to_srgb(col[0])); + tar[1]= FTOCHAR(linearrgb_to_srgb(col[1])); + tar[2]= FTOCHAR(linearrgb_to_srgb(col[2])); + } + else { + tar[0]= FTOCHAR(col[0]); + tar[1]= FTOCHAR(col[1]); + tar[2]= FTOCHAR(col[2]); + } tar[3]= FTOCHAR(col[3]); - //} } //else printf("prv out bound x y %d %d\n", x, y); } @@ -1699,33 +1705,36 @@ static void ntreeSetOutput(bNodeTree *ntree) { bNode *node; - /* find the active outputs, might become tree type dependant handler */ - for(node= ntree->nodes.first; node; node= node->next) { - if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { - bNode *tnode; - int output= 0; - - /* we need a check for which output node should be tagged like this, below an exception */ - if(node->type==CMP_NODE_OUTPUT_FILE) - continue; - - /* there is more types having output class, each one is checked */ - for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { - if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { - /* same type, exception for viewer */ - if(tnode->type==node->type || - (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && - ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) { - if(tnode->flag & NODE_DO_OUTPUT) { - output++; - if(output>1) - tnode->flag &= ~NODE_DO_OUTPUT; + if(ntree->type==NTREE_COMPOSIT) { + + /* find the active outputs, might become tree type dependant handler */ + for(node= ntree->nodes.first; node; node= node->next) { + if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) { + bNode *tnode; + int output= 0; + + /* we need a check for which output node should be tagged like this, below an exception */ + if(node->type==CMP_NODE_OUTPUT_FILE) + continue; + + /* there is more types having output class, each one is checked */ + for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) { + if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) { + /* same type, exception for viewer */ + if(tnode->type==node->type || + (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) && + ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) { + if(tnode->flag & NODE_DO_OUTPUT) { + output++; + if(output>1) + tnode->flag &= ~NODE_DO_OUTPUT; + } } } } + if(output==0) + node->flag |= NODE_DO_OUTPUT; } - if(output==0) - node->flag |= NODE_DO_OUTPUT; } } @@ -2586,8 +2595,6 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) /* ensures only a single output node is enabled */ ntreeSetOutput(ntree); - /* move over the compbufs */ - /* right after ntreeCopyTree() oldsock pointers are valid */ for(node= ntree->nodes.first; node; node= node->next) { /* store new_node pointer to original */ @@ -2595,22 +2602,27 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree) /* ensure new user input gets handled ok */ node->need_exec= 0; - if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { - if(node->id) { - if(node->flag & NODE_DO_OUTPUT) - node->new_node->id= (ID *)copy_image((Image *)node->id); - else - node->new_node->id= NULL; - } - } - - for(sock= node->outputs.first; sock; sock= sock->next) { + if(ntree->type==NTREE_COMPOSIT) { + /* move over the compbufs */ + /* right after ntreeCopyTree() oldsock pointers are valid */ - sock->new_sock->ns.data= sock->ns.data; - compbuf_set_node(sock->new_sock->ns.data, node->new_node); + if(ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER)) { + if(node->id) { + if(node->flag & NODE_DO_OUTPUT) + node->new_node->id= (ID *)copy_image((Image *)node->id); + else + node->new_node->id= NULL; + } + } - sock->ns.data= NULL; - sock->new_sock->new_sock= sock; + for(sock= node->outputs.first; sock; sock= sock->next) { + + sock->new_sock->ns.data= sock->ns.data; + compbuf_set_node(sock->new_sock->ns.data, node->new_node); + + sock->ns.data= NULL; + sock->new_sock->new_sock= sock; + } } } @@ -2638,19 +2650,38 @@ static int outsocket_exists(bNode *node, bNodeSocket *testsock) /* sync local composite with real tree */ /* local composite is supposed to be running, be careful moving previews! */ +/* is called by jobs manager, outside threads, so it doesnt happen during draw */ void ntreeLocalSync(bNodeTree *localtree, bNodeTree *ntree) { bNode *lnode; - /* move over the compbufs and previews */ - for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { - if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) { + if(ntree->type==NTREE_COMPOSIT) { + /* move over the compbufs and previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { + if( (lnode->exec & NODE_READY) && !(lnode->exec & NODE_SKIPPED) ) { + if(node_exists(ntree, lnode->new_node)) { + + if(lnode->preview && lnode->preview->rect) { + node_free_preview(lnode->new_node); + lnode->new_node->preview= lnode->preview; + lnode->preview= NULL; + } + } + } + } + } + else if(ntree->type==NTREE_SHADER) { + /* copy over contents of previews */ + for(lnode= localtree->nodes.first; lnode; lnode= lnode->next) { if(node_exists(ntree, lnode->new_node)) { + bNode *node= lnode->new_node; - if(lnode->preview && lnode->preview->rect) { - node_free_preview(lnode->new_node); - lnode->new_node->preview= lnode->preview; - lnode->preview= NULL; + if(node->preview && node->preview->rect) { + if(lnode->preview && lnode->preview->rect) { + int xsize= node->preview->xsize; + int ysize= node->preview->ysize; + memcpy(node->preview->rect, lnode->preview->rect, 4*xsize + xsize*ysize*sizeof(char)*4); + } } } } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 61fb9305a83..f492d9a2f0f 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -343,13 +343,12 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre strcpy(sce->r.engine, scene->r.engine); if(id_type==ID_MA) { - Material *mat= NULL; + Material *mat= NULL, *origmat= (Material *)id; if(id) { /* work on a copy */ - mat= copy_material((Material *)id); + mat= localize_material(origmat); sp->matcopy= mat; - BLI_remlink(&G.main->mat, mat); BLI_addtail(&pr_main->mat, mat); init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ @@ -403,18 +402,16 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre } else { sce->lay= 1<<mat->pr_type; - if(mat->nodetree && sp->pr_method==PR_NODE_RENDER) + if(mat->nodetree && sp->pr_method==PR_NODE_RENDER) { + /* two previews, they get copied by wmJob */ ntreeInitPreview(mat->nodetree, sp->sizex, sp->sizey); + ntreeInitPreview(origmat->nodetree, sp->sizex, sp->sizey); + } } } else { sce->r.mode &= ~(R_OSA|R_RAYTRACE|R_SSS); - /* get rid of copied material */ - BLI_remlink(&pr_main->mat, sp->matcopy); - free_material(sp->matcopy); - MEM_freeN(sp->matcopy); - sp->matcopy= NULL; } for(base= sce->base.first; base; base= base->next) { @@ -918,10 +915,14 @@ static int shader_preview_break(void *spv) } /* outside thread, called before redraw notifiers, it moves finished preview over */ -static void shader_preview_updatejob(void *UNUSED(spv)) +static void shader_preview_updatejob(void *spv) { -// ShaderPreview *sp= spv; + ShaderPreview *sp= spv; + Material *mat= (Material *)sp->id; + if(sp->matcopy && mat->nodetree) + ntreeLocalSync(sp->matcopy->nodetree, mat->nodetree); + } static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int first) @@ -1027,6 +1028,16 @@ static void shader_preview_free(void *customdata) { ShaderPreview *sp= customdata; + if(sp->matcopy) { + /* node previews */ + shader_preview_updatejob(sp); + + /* get rid of copied material */ + BLI_remlink(&pr_main->mat, sp->matcopy); + free_material(sp->matcopy); + MEM_freeN(sp->matcopy); + } + MEM_freeN(sp); } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 4dedcbdd323..5df593e945e 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2050,7 +2050,7 @@ static void load_backbuffer(Render *re) char name[256]; strcpy(name, re->r.backbuf); - BLI_path_abs(name, G.main->name); + BLI_path_abs(name, re->main->name); BLI_path_frame(name, re->r.cfra, 0); if(re->backbuf) { diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 1e8709d09f7..993e0aeb9c3 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -56,6 +56,7 @@ #include "DNA_material_types.h" #include "BKE_colortools.h" +#include "BKE_global.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_node.h" @@ -995,6 +996,7 @@ void make_sss_tree(Render *re) for(mat= re->main->mat.first; mat; mat= mat->id.next) if(mat->id.us && (mat->flag & MA_IS_USED) && (mat->sss_flag & MA_DIFF_SSS)) sss_create_tree_mat(re, mat); + } void free_sss(Render *re) |