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
1 changed files with 40 additions and 21 deletions

View File

@ -1112,14 +1112,15 @@ static int multitex(Tex *tex,
const short which_output,
struct ImagePool *pool,
const bool skip_load_image,
const bool texnode_preview)
const bool texnode_preview,
const bool use_nodes)
{
float tmpvec[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) */
if (tex->use_nodes && tex->nodetree) {
if (use_nodes && tex->use_nodes && tex->nodetree) {
retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread,
tex, which_output, R.r.cfra, texnode_preview, NULL, NULL);
}
@ -1239,7 +1240,8 @@ static int multitex_nodes_intern(Tex *tex,
ImagePool *pool,
const bool scene_color_manage,
const bool skip_load_image,
const bool texnode_preview)
const bool texnode_preview,
const bool use_nodes)
{
if (tex==NULL) {
memset(texres, 0, sizeof(TexResult));
@ -1264,7 +1266,8 @@ static int multitex_nodes_intern(Tex *tex,
which_output,
pool,
skip_load_image,
texnode_preview);
texnode_preview,
use_nodes);
if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) {
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,
pool,
skip_load_image,
texnode_preview);
texnode_preview,
use_nodes);
{
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,
pool,
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,
thread, which_output, shi, mtex, pool, R.scene_color_manage,
(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 */
@ -1378,7 +1384,8 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt
mtex->which_output,
pool,
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,
scene_color_manage,
skip_load_image,
false);
false,
true);
}
/* 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 use_nodes= tex->use_nodes, retval;
tex->use_nodes = false;
retval= multitex_nodes_intern(tex, texvec, NULL, NULL, 0, texres, 0, 0, NULL, NULL, pool, scene_color_manage, skip_load_image, false);
tex->use_nodes= use_nodes;
return retval;
return multitex_nodes_intern(tex,
texvec,
NULL, NULL,
0,
texres,
0,
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,
re->pool,
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 */
@ -3051,7 +3066,8 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4])
mtex->which_output,
har->pool,
skip_load_image,
texnode_preview);
texnode_preview,
true);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@ -3274,7 +3290,8 @@ void do_sky_tex(
mtex->which_output,
R.pool,
skip_load_image,
texnode_preview);
texnode_preview,
true);
/* texture output */
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,
R.pool,
skip_load_image,
texnode_preview);
texnode_preview,
true);
/* texture output */
if (rgb && (mtex->texflag & MTEX_RGBTOINT)) {
@ -3614,7 +3632,8 @@ int externtex(MTex *mtex,
mtex->which_output,
pool,
skip_load_image,
texnode_preview);
texnode_preview,
true);
if (rgb) {
texr.tin = IMB_colormanagement_get_luminance(&texr.tr);