diff options
author | Dalai Felinto <dfelinto@gmail.com> | 2018-06-08 17:11:34 +0300 |
---|---|---|
committer | Dalai Felinto <dfelinto@gmail.com> | 2018-06-08 17:29:33 +0300 |
commit | 9d59d20957b5fe042f4132d9ed23e9ac25cb4ce0 (patch) | |
tree | 2cea4a7b6a9217e4474ae08778d833581483e433 /source | |
parent | 0417f205f564bb883181c27db86d5639a97b0121 (diff) |
DRW: Fix animated material not refreshing
This introduces a garbage collection system similar to gpu_texture.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 1 | ||||
-rw-r--r-- | source/blender/gpu/GPU_material.h | 5 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_init_exit.c | 2 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_material.c | 76 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 2 |
5 files changed, 67 insertions, 19 deletions
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index 373cb4e4f06..1ea2f170922 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -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); } diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h index 2e102838b3d..0805cc25d04 100644 --- a/source/blender/gpu/GPU_material.h +++ b/source/blender/gpu/GPU_material.h @@ -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); diff --git a/source/blender/gpu/intern/gpu_init_exit.c b/source/blender/gpu/intern/gpu_init_exit.c index 0d624bbb15c..92ad9d81b6c 100644 --- a/source/blender/gpu/intern/gpu_init_exit.c +++ b/source/blender/gpu/intern/gpu_init_exit.c @@ -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(); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index 212a6226118..302ddc62188 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -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,36 +147,70 @@ enum { /* Functions */ -void GPU_material_free(ListBase *gpumaterial) +static void gpu_material_free_single(GPUMaterial *material) { - for (LinkData *link = gpumaterial->first; link; link = link->next) { - GPUMaterial *material = link->data; + /* Cancel / wait any pending lazy compilation. */ + DRW_deferred_shader_remove(material); - /* Cancel / wait any pending lazy compilation. */ - DRW_deferred_shader_remove(material); + GPU_pass_free_nodes(&material->nodes); + GPU_inputs_free(&material->inputs); - GPU_pass_free_nodes(&material->nodes); - GPU_inputs_free(&material->inputs); + if (material->pass) + GPU_pass_release(material->pass); - if (material->pass) - GPU_pass_release(material->pass); + if (material->ubo != NULL) { + GPU_uniformbuffer_free(material->ubo); + } - 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_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; - if (material->sss_profile != NULL) { - GPU_uniformbuffer_free(material->sss_profile); + /* TODO(fclem): Check if the thread has an ogl context. */ + if (BLI_thread_is_main()) { + gpu_material_free_single(material); + MEM_freeN(material); + } + else { + BLI_mutex_lock(&g_orphan_lock); + BLI_addtail(&g_orphaned_mat, BLI_genericNodeN(material)); + BLI_mutex_unlock(&g_orphan_lock); } + } + BLI_freelistN(gpumaterial); +} - MEM_freeN(material); +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); +} - BLI_freelistN(gpumaterial); +void GPU_material_orphans_exit(void) +{ + GPU_material_orphans_delete(); + BLI_mutex_end(&g_orphan_lock); } GPUBuiltin GPU_get_material_builtins(GPUMaterial *material) diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 84b9539eff1..e1528551c12 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -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); } |