Fix T94362: GPUMaterialTexture references freed ImageUser

The issue was caused by rB7e712b2d6a0d257d272ed35622b41d06274af8df
and the fact that `GPUMaterialTexture` contains an `ImageUser *` which
references the `ImageUser` on e.g. `NodeTexImage`.

Since the node tree update refactor, it is possible that the node tree changes
without changing the actual material. Therefore, either the renderer should
check if the node tree has changed or it should not store pointers to data in
node storage. The latter approach is implemented in this patch.

Differential Revision: https://developer.blender.org/D13663
This commit is contained in:
Jacques Lucke 2021-12-25 11:14:02 +01:00
parent f1e04116f0
commit 28df0107d4
Notes: blender-bot 2023-02-14 00:29:15 +01:00
Referenced by issue #95624, Video texture not refreshing when changing ImageUser `Start Frame` / `Offset`
Referenced by issue #94464, Blender Video texture not refreshing
Referenced by issue #94362, heap-use-after-free after assigning a material
3 changed files with 11 additions and 5 deletions

View File

@ -1364,14 +1364,15 @@ void DRW_shgroup_add_material_resources(DRWShadingGroup *grp, struct GPUMaterial
if (tex->ima) {
/* Image */
GPUTexture *gputex;
ImageUser *iuser = tex->iuser_available ? &tex->iuser : NULL;
if (tex->tiled_mapping_name[0]) {
gputex = BKE_image_get_gpu_tiles(tex->ima, tex->iuser, NULL);
gputex = BKE_image_get_gpu_tiles(tex->ima, iuser, NULL);
drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
gputex = BKE_image_get_gpu_tilemap(tex->ima, tex->iuser, NULL);
gputex = BKE_image_get_gpu_tilemap(tex->ima, iuser, NULL);
drw_shgroup_material_texture(grp, gputex, tex->tiled_mapping_name, tex->sampler_state);
}
else {
gputex = BKE_image_get_gpu_texture(tex->ima, tex->iuser, NULL);
gputex = BKE_image_get_gpu_texture(tex->ima, iuser, NULL);
drw_shgroup_material_texture(grp, gputex, tex->sampler_name, tex->sampler_state);
}
}

View File

@ -24,6 +24,7 @@
#pragma once
#include "DNA_customdata_types.h" /* for CustomDataType */
#include "DNA_image_types.h"
#include "DNA_listBase.h"
#include "BLI_sys_types.h" /* for bool */
@ -256,7 +257,8 @@ typedef struct GPUMaterialAttribute {
typedef struct GPUMaterialTexture {
struct GPUMaterialTexture *next, *prev;
struct Image *ima;
struct ImageUser *iuser;
struct ImageUser iuser;
bool iuser_available;
struct GPUTexture **colorband;
char sampler_name[32]; /* Name of sampler in GLSL. */
char tiled_mapping_name[32]; /* Name of tile mapping sampler in GLSL. */

View File

@ -439,7 +439,10 @@ static GPUMaterialTexture *gpu_node_graph_add_texture(GPUNodeGraph *graph,
if (tex == NULL) {
tex = MEM_callocN(sizeof(*tex), __func__);
tex->ima = ima;
tex->iuser = iuser;
if (iuser != NULL) {
tex->iuser = *iuser;
tex->iuser_available = true;
}
tex->colorband = colorband;
tex->sampler_state = sampler_state;
BLI_snprintf(tex->sampler_name, sizeof(tex->sampler_name), "samp%d", num_textures);