@@ -2971,8 +2971,23 @@ void RendererCanvasRenderRD::_uniform_set_invalidation_callback(void *p_userdata
2971
2971
static_cast <RendererCanvasRenderRD *>(singleton)->rid_set_to_uniform_set .erase (*key);
2972
2972
}
2973
2973
2974
+ void RendererCanvasRenderRD::_canvas_texture_invalidation_callback (bool p_deleted, void *p_userdata) {
2975
+ KeyValue<RID, TightLocalVector<RID>> *kv = static_cast <KeyValue<RID, TightLocalVector<RID>> *>(p_userdata);
2976
+ RD *rd = RD::get_singleton ();
2977
+ for (RID rid : kv->value ) {
2978
+ // the invalidation callback will take care of clearing rid_set_to_uniform_set cache also
2979
+ rd->free (rid);
2980
+ }
2981
+ kv->value .clear ();
2982
+ if (p_deleted) {
2983
+ static_cast <RendererCanvasRenderRD *>(singleton)->canvas_texture_to_uniform_set .erase (kv->key );
2984
+ }
2985
+ }
2986
+
2974
2987
void RendererCanvasRenderRD::_render_batch (RD::DrawListID p_draw_list, CanvasShaderData *p_shader_data, RenderingDevice::FramebufferFormatID p_framebuffer_format, Light *p_lights, Batch const *p_batch, RenderingMethod::RenderInfo *r_render_info) {
2975
2988
{
2989
+ RendererRD::TextureStorage *ts = RendererRD::TextureStorage::get_singleton ();
2990
+
2976
2991
RIDSetKey key (
2977
2992
p_batch->tex_info ->state ,
2978
2993
state.canvas_instance_data_buffers [state.current_data_buffer_index ].instance_buffers [p_batch->instance_buffer_index ]);
@@ -2992,6 +3007,19 @@ void RendererCanvasRenderRD::_render_batch(RD::DrawListID p_draw_list, CanvasSha
2992
3007
const RIDCache::Pair *iter = rid_set_to_uniform_set.insert (key, rid);
2993
3008
uniform_set = &iter->data ;
2994
3009
RD::get_singleton ()->uniform_set_set_invalidation_callback (rid, RendererCanvasRenderRD::_uniform_set_invalidation_callback, (void *)&iter->key );
3010
+
3011
+ // If this is a CanvasTexture, it must be tracked so that any changes to the diffuse, normal
3012
+ // or specular channels invalidate all associated uniform sets.
3013
+ if (ts->owns_canvas_texture (p_batch->tex_info ->state .texture )) {
3014
+ KeyValue<RID, TightLocalVector<RID>> *kv = nullptr ;
3015
+ if (HashMap<RID, TightLocalVector<RID>>::Iterator i = canvas_texture_to_uniform_set.find (p_batch->tex_info ->state .texture ); i == canvas_texture_to_uniform_set.end ()) {
3016
+ kv = &*canvas_texture_to_uniform_set.insert (p_batch->tex_info ->state .texture , { *uniform_set });
3017
+ } else {
3018
+ i->value .push_back (rid);
3019
+ kv = &*i;
3020
+ }
3021
+ ts->canvas_texture_set_invalidation_callback (p_batch->tex_info ->state .texture , RendererCanvasRenderRD::_canvas_texture_invalidation_callback, kv);
3022
+ }
2995
3023
}
2996
3024
2997
3025
if (state.current_batch_uniform_set != *uniform_set) {
0 commit comments