Fix T77893: Crash drawmanager threading custom data

Tangent normals were temporarily saved in the original given layers but
the typeinfo wasn't updated. This lead to several issues since we
changed the threading of the mesh extraction.

This patch stores the tangent normals in a temporary custom data on the
stack this way the typemap doesn't need to be updated.

Still need to run the tests for an hour to see if it is fixed

Reviewed By: Clément Foucault, Philipp Oeser

Differential Revision: https://developer.blender.org/D8095
This commit is contained in:
Jeroen Bakker 2020-06-23 14:28:08 +02:00 committed by Jeroen Bakker
parent 439b40e601
commit 8f97a64dec
Notes: blender-bot 2023-02-14 01:11:05 +01:00
Referenced by issue #78361, Blender crashes on many modeling operations (loopcut, extrude, duplication, ...) on mesh with normal map node connected to material
Referenced by issue #78334, Shift-D in edit mode, with normal map node connected to material causes exception
Referenced by issue #78054, Crash with Material preview
Referenced by issue #77893, Crash doing certain modeling operations [customdata_typemap_is_valid]
1 changed files with 10 additions and 8 deletions

View File

@ -2010,8 +2010,9 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
}
/* Start Fresh */
CustomData_free_layers(cd_ldata, CD_TANGENT, mr->loop_len);
CustomData loop_data;
CustomData_reset(&loop_data);
CustomData *ldata = cd_ldata;
if (tan_len != 0 || use_orco_tan) {
short tangent_mask = 0;
bool calc_active_tangent = false;
@ -2041,9 +2042,10 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
mr->poly_normals,
mr->loop_normals,
orco,
cd_ldata,
&loop_data,
mr->loop_len,
&tangent_mask);
ldata = &loop_data;
}
}
@ -2075,7 +2077,7 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
short(*tan_data)[4] = (short(*)[4])vbo->data;
for (int i = 0; i < tan_len; i++) {
const char *name = tangent_names[i];
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(ldata, CD_TANGENT, name);
for (int l = 0; l < mr->loop_len; l++) {
normal_float_to_short_v3(*tan_data, layer_data[l]);
(*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
@ -2083,7 +2085,7 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
}
}
if (use_orco_tan) {
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(ldata, CD_TANGENT, 0);
for (int l = 0; l < mr->loop_len; l++) {
normal_float_to_short_v3(*tan_data, layer_data[l]);
(*tan_data)[3] = (layer_data[l][3] > 0.0f) ? SHRT_MAX : SHRT_MIN;
@ -2095,7 +2097,7 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
GPUPackedNormal *tan_data = (GPUPackedNormal *)vbo->data;
for (int i = 0; i < tan_len; i++) {
const char *name = tangent_names[i];
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(cd_ldata, CD_TANGENT, name);
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_named(ldata, CD_TANGENT, name);
for (int l = 0; l < mr->loop_len; l++) {
*tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
@ -2103,7 +2105,7 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
}
}
if (use_orco_tan) {
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(cd_ldata, CD_TANGENT, 0);
float(*layer_data)[4] = (float(*)[4])CustomData_get_layer_n(ldata, CD_TANGENT, 0);
for (int l = 0; l < mr->loop_len; l++) {
*tan_data = GPU_normal_convert_i10_v3(layer_data[l]);
tan_data->w = (layer_data[l][3] > 0.0f) ? 1 : -2;
@ -2112,7 +2114,7 @@ static void extract_tan_ex(const MeshRenderData *mr, GPUVertBuf *vbo, const bool
}
}
CustomData_free_layers(cd_ldata, CD_TANGENT, mr->loop_len);
CustomData_free(&loop_data, mr->loop_len);
}
static void *extract_tan_init(const MeshRenderData *mr, void *buf)