DRW: Fix animated material not refreshing

This introduces a garbage collection system similar to gpu_texture.
This commit is contained in:
Dalai Felinto 2018-06-08 16:11:34 +02:00
parent 0417f205f5
commit 9d59d20957
Notes: blender-bot 2023-02-14 05:45:30 +01:00
Referenced by issue #55409, Can't animated keyframed material node value after moving keyframe on timeline
5 changed files with 69 additions and 21 deletions

View File

@ -1315,4 +1315,5 @@ void paste_matcopybuf(Main *bmain, Material *ma)
void BKE_material_eval(struct Depsgraph *depsgraph, Material *material)
{
DEG_debug_print_eval(depsgraph, __func__, material->id.name, material);
GPU_material_free(&material->gpumaterial);
}

View File

@ -253,6 +253,11 @@ void GPU_material_free(struct ListBase *gpumaterial);
void GPU_materials_free(void);
void GPU_material_orphans_init(void);
void GPU_material_orphans_exit(void);
/* This has to be called from a thread with an ogl context bound. */
void GPU_material_orphans_delete(void);
struct Scene *GPU_material_scene(GPUMaterial *material);
GPUMatType GPU_Material_get_type(GPUMaterial *material);
struct GPUPass *GPU_material_get_pass(GPUMaterial *material);

View File

@ -58,6 +58,7 @@ void GPU_init(void)
gpu_extensions_init(); /* must come first */
GPU_texture_orphans_init();
GPU_material_orphans_init();
gpu_codegen_init();
if (G.debug & G_DEBUG_GPU)
@ -83,6 +84,7 @@ void GPU_exit(void)
gpu_batch_exit();
GPU_texture_orphans_exit();
GPU_material_orphans_exit();
if (G.debug & G_DEBUG_GPU)
gpu_debug_exit();

View File

@ -46,6 +46,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
#include "BLI_rand.h"
#include "BLI_threads.h"
#include "BKE_anim.h"
#include "BKE_colorband.h"
@ -74,6 +75,9 @@
# include "BKE_DerivedMesh.h"
#endif
static ListBase g_orphaned_mat = {NULL, NULL};
static ThreadMutex g_orphan_lock;
/* Structs */
struct GPUMaterial {
@ -143,38 +147,72 @@ enum {
/* Functions */
static void gpu_material_free_single(GPUMaterial *material)
{
/* Cancel / wait any pending lazy compilation. */
DRW_deferred_shader_remove(material);
GPU_pass_free_nodes(&material->nodes);
GPU_inputs_free(&material->inputs);
if (material->pass)
GPU_pass_release(material->pass);
if (material->ubo != NULL) {
GPU_uniformbuffer_free(material->ubo);
}
if (material->sss_tex_profile != NULL) {
GPU_texture_free(material->sss_tex_profile);
}
if (material->sss_profile != NULL) {
GPU_uniformbuffer_free(material->sss_profile);
}
}
void GPU_material_free(ListBase *gpumaterial)
{
for (LinkData *link = gpumaterial->first; link; link = link->next) {
GPUMaterial *material = link->data;
/* Cancel / wait any pending lazy compilation. */
DRW_deferred_shader_remove(material);
GPU_pass_free_nodes(&material->nodes);
GPU_inputs_free(&material->inputs);
if (material->pass)
GPU_pass_release(material->pass);
if (material->ubo != NULL) {
GPU_uniformbuffer_free(material->ubo);
/* TODO(fclem): Check if the thread has an ogl context. */
if (BLI_thread_is_main()) {
gpu_material_free_single(material);
MEM_freeN(material);
}
if (material->sss_tex_profile != NULL) {
GPU_texture_free(material->sss_tex_profile);
else {
BLI_mutex_lock(&g_orphan_lock);
BLI_addtail(&g_orphaned_mat, BLI_genericNodeN(material));
BLI_mutex_unlock(&g_orphan_lock);
}
if (material->sss_profile != NULL) {
GPU_uniformbuffer_free(material->sss_profile);
}
MEM_freeN(material);
}
BLI_freelistN(gpumaterial);
}
void GPU_material_orphans_init(void)
{
BLI_mutex_init(&g_orphan_lock);
}
void GPU_material_orphans_delete(void)
{
BLI_mutex_lock(&g_orphan_lock);
LinkData *link;
while ((link = BLI_pophead(&g_orphaned_mat))) {
gpu_material_free_single((GPUMaterial *)link->data);
MEM_freeN(link->data);
MEM_freeN(link);
}
BLI_mutex_unlock(&g_orphan_lock);
}
void GPU_material_orphans_exit(void)
{
GPU_material_orphans_delete();
BLI_mutex_end(&g_orphan_lock);
}
GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
{
return material->builtins;

View File

@ -85,6 +85,7 @@
#include "GPU_framebuffer.h"
#include "GPU_init_exit.h"
#include "GPU_immediate.h"
#include "GPU_material.h"
#include "GPU_texture.h"
#include "BLF_api.h"
@ -2029,6 +2030,7 @@ void wm_window_raise(wmWindow *win)
void wm_window_swap_buffers(wmWindow *win)
{
GPU_texture_orphans_delete(); /* XXX should be done elsewhere. */
GPU_material_orphans_delete(); /* XXX Amen to that. */
GHOST_SwapWindowBuffers(win->ghostwin);
}