Fix threading conflicts in multitex_ext_safe()

This function was modifying texture datablock, which makes the call
unsafe for call from multiple threads. Now we pass the argument that
we don't need nodes to the underlying functions.

There will be still race condition in noise texture, but that should
at least be free from crashes. Doesn't mean we shouldn't fix it tho.
This commit is contained in:
Sergey Sharybin 2017-03-31 16:09:27 +02:00
parent 90df1142a3
commit 25ab3aac9d

@ -1112,14 +1112,15 @@ static int multitex(Tex *tex,
const short which_output, const short which_output,
struct ImagePool *pool, struct ImagePool *pool,
const bool skip_load_image, const bool skip_load_image,
const bool texnode_preview) const bool texnode_preview,
const bool use_nodes)
{ {
float tmpvec[3]; float tmpvec[3];
int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */
texres->talpha = false; /* is set when image texture returns alpha (considered premul) */ texres->talpha = false; /* is set when image texture returns alpha (considered premul) */
if (tex->use_nodes && tex->nodetree) { if (use_nodes && tex->use_nodes && tex->nodetree) {
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
tex, which_output, R.r.cfra, texnode_preview, NULL, NULL); tex, which_output, R.r.cfra, texnode_preview, NULL, NULL);
} }
@ -1239,7 +1240,8 @@ static int multitex_nodes_intern(Tex *tex,
ImagePool *pool, ImagePool *pool,
const bool scene_color_manage, const bool scene_color_manage,
const bool skip_load_image, const bool skip_load_image,
const bool texnode_preview) const bool texnode_preview,
const bool use_nodes)
{ {
if (tex==NULL) { if (tex==NULL) {
memset(texres, 0, sizeof(TexResult)); memset(texres, 0, sizeof(TexResult));
@ -1264,7 +1266,8 @@ static int multitex_nodes_intern(Tex *tex,
which_output, which_output,
pool, pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
use_nodes);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
@ -1311,7 +1314,8 @@ static int multitex_nodes_intern(Tex *tex,
which_output, which_output,
pool, pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
use_nodes);
{ {
ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool); ImBuf *ibuf = BKE_image_pool_acquire_ibuf(tex->ima, &tex->iuser, pool);
@ -1341,7 +1345,8 @@ static int multitex_nodes_intern(Tex *tex,
which_output, which_output,
pool, pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
use_nodes);
} }
} }
@ -1354,7 +1359,8 @@ int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int os
return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres, return multitex_nodes_intern(tex, texvec, dxt, dyt, osatex, texres,
thread, which_output, shi, mtex, pool, R.scene_color_manage, thread, which_output, shi, mtex, pool, R.scene_color_manage,
(R.r.scemode & R_NO_IMAGE_LOAD) != 0, (R.r.scemode & R_NO_IMAGE_LOAD) != 0,
(R.r.scemode & R_TEXNODE_PREVIEW) != 0); (R.r.scemode & R_TEXNODE_PREVIEW) != 0,
true);
} }
/* this is called for surface shading */ /* this is called for surface shading */
@ -1378,7 +1384,8 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
mtex->which_output, mtex->which_output,
pool, pool,
skip_load_image, skip_load_image,
(R.r.scemode & R_TEXNODE_PREVIEW) != 0); (R.r.scemode & R_TEXNODE_PREVIEW) != 0,
true);
} }
} }
@ -1408,7 +1415,8 @@ int multitex_ext(Tex *tex,
pool, pool,
scene_color_manage, scene_color_manage,
skip_load_image, skip_load_image,
false); false,
true);
} }
/* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\ /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on)\
@ -1417,13 +1425,19 @@ int multitex_ext(Tex *tex,
*/ */
int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image) int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres, struct ImagePool *pool, bool scene_color_manage, const bool skip_load_image)
{ {
int use_nodes= tex->use_nodes, retval; return multitex_nodes_intern(tex,
texvec,
tex->use_nodes = false; NULL, NULL,
retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image, false); 0,
tex->use_nodes= use_nodes; texres,
0,
return retval; 0,
NULL, NULL,
pool,
scene_color_manage,
skip_load_image,
false,
false);
} }
@ -2873,7 +2887,8 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_
mtex->which_output, mtex->which_output,
re->pool, re->pool,
skip_load_image, skip_load_image,
texnode_preview); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */ texnode_preview,
true); /* NULL = dxt/dyt, 0 = shi->osatex - not supported */
/* texture output */ /* texture output */
@ -3051,7 +3066,8 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
mtex->which_output, mtex->which_output,
har->pool, har->pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
true);
/* texture output */ /* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@ -3274,7 +3290,8 @@ void do_sky_tex(
mtex->which_output, mtex->which_output,
R.pool, R.pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
true);
/* texture output */ /* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@ -3500,7 +3517,8 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
mtex->which_output, mtex->which_output,
R.pool, R.pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
true);
/* texture output */ /* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) { if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@ -3614,7 +3632,8 @@ int externtex(MTex *mtex,
mtex->which_output, mtex->which_output,
pool, pool,
skip_load_image, skip_load_image,
texnode_preview); texnode_preview,
true);
if (rgb) { if (rgb) {
texr.tin = IMB_colormanagement_get_luminance(&texr.tr); texr.tin = IMB_colormanagement_get_luminance(&texr.tr);