Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/draw/DRW_engine.h3
-rw-r--r--source/blender/draw/intern/draw_cache.c21
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h5
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c26
-rw-r--r--source/blender/draw/intern/draw_manager.c42
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c1
6 files changed, 95 insertions, 3 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index 161e28db2d3..8ff4fbbe5a5 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -152,6 +152,9 @@ void DRW_opengl_context_destroy(void);
void DRW_opengl_context_enable(void);
void DRW_opengl_context_disable(void);
+/* For garbage collection */
+void DRW_cache_free_old_batches(struct Main *bmain);
+
/* Never use this. Only for closing blender. */
void DRW_opengl_context_enable_ex(bool restore);
void DRW_opengl_context_disable_ex(bool restore);
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index 6b6a79bfb60..8a13d8be622 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -4031,4 +4031,25 @@ void drw_batch_cache_generate_requested(Object *ob)
}
}
+void DRW_batch_cache_free_old(Object *ob, int ctime)
+{
+ struct Mesh *mesh_eval = ob->runtime.mesh_eval;
+
+ switch (ob->type) {
+ case OB_MESH:
+ DRW_mesh_batch_cache_free_old((Mesh *)ob->data, ctime);
+ break;
+ case OB_CURVE:
+ case OB_FONT:
+ case OB_SURF:
+ if (mesh_eval) {
+ DRW_mesh_batch_cache_free_old(mesh_eval, ctime);
+ }
+ break;
+ /* TODO all cases */
+ default:
+ break;
+ }
+}
+
/** \} */
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 94d8a82f2e4..e4ce3ed9d49 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -61,6 +61,11 @@ void DRW_particle_batch_cache_free(struct ParticleSystem *psys);
void DRW_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
void DRW_gpencil_batch_cache_free(struct bGPdata *gpd);
+/* Garbage collection */
+void DRW_batch_cache_free_old(struct Object *ob, int ctime);
+
+void DRW_mesh_batch_cache_free_old(struct Mesh *me, int ctime);
+
/* Curve */
void DRW_curve_batch_cache_create_requested(struct Object *ob);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 6b43fbed49f..41de51fde96 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -364,6 +364,11 @@ BLI_INLINE bool mesh_cd_layers_type_overlap(DRW_MeshCDMask a, DRW_MeshCDMask b)
return (*((uint32_t *)&a) & *((uint32_t *)&b)) == *((uint32_t *)&b);
}
+BLI_INLINE bool mesh_cd_layers_type_equal(DRW_MeshCDMask a, DRW_MeshCDMask b)
+{
+ return *((uint32_t *)&a) == *((uint32_t *)&b);
+}
+
BLI_INLINE void mesh_cd_layers_type_merge(DRW_MeshCDMask *a, DRW_MeshCDMask b)
{
atomic_fetch_and_or_uint32((uint32_t *)a, *(uint32_t *)&b);
@@ -1997,7 +2002,7 @@ typedef struct MeshBatchCache {
struct DRW_MeshWeightState weight_state;
- DRW_MeshCDMask cd_used, cd_needed;
+ DRW_MeshCDMask cd_used, cd_needed, cd_used_over_time;
/* XXX, only keep for as long as sculpt mode uses shaded drawing. */
bool is_sculpt_points_tag;
@@ -2121,6 +2126,8 @@ static void mesh_batch_cache_discard_shaded_tri(MeshBatchCache *cache)
MEM_SAFE_FREE(cache->auto_layer_names);
MEM_SAFE_FREE(cache->auto_layer_is_srgb);
+ mesh_cd_layers_type_clear(&cache->cd_used);
+
cache->mat_len = 0;
}
@@ -4717,6 +4724,22 @@ static void mesh_create_uvedit_buffers(MeshRenderData *rdata,
/** \name Grouped batch generation
* \{ */
+/* Thread safety need to be assured by caller. Don't call this during drawing.
+ * Note: For now this only free the shading batches / vbo if any cd layers is
+ * not needed anymore. */
+void DRW_mesh_batch_cache_free_old(Mesh *me, int UNUSED(ctime))
+{
+ MeshBatchCache *cache = me->runtime.batch_cache;
+
+ if (cache == NULL)
+ return;
+
+ if (mesh_cd_layers_type_equal(cache->cd_used_over_time, cache->cd_used) == false) {
+ mesh_batch_cache_discard_shaded_tri(cache);
+ }
+ mesh_cd_layers_type_clear(&cache->cd_used_over_time);
+}
+
/* Can be called for any surface type. Mesh *me is the final mesh. */
void DRW_mesh_batch_cache_create_requested(
Object *ob, Mesh *me, const ToolSettings *ts, const bool is_paint_mode, const bool use_hide)
@@ -4769,6 +4792,7 @@ void DRW_mesh_batch_cache_create_requested(
mesh_cd_layers_type_merge(&cache->cd_used, cache->cd_needed);
}
+ mesh_cd_layers_type_merge(&cache->cd_used_over_time, cache->cd_needed);
mesh_cd_layers_type_clear(&cache->cd_needed);
/* Discard UV batches if sync_selection changes */
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 9e078fd2774..b3546092667 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -35,6 +35,7 @@
#include "BKE_global.h"
#include "BKE_gpencil.h"
#include "BKE_lattice.h"
+#include "BKE_main.h"
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
@@ -404,7 +405,7 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16_DEPTH_TEST;
break;
default:
- BLI_assert("Mulisample count unsupported by blit shader.");
+ BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2_DEPTH_TEST;
break;
}
@@ -424,7 +425,7 @@ void DRW_multisamples_resolve(GPUTexture *src_depth, GPUTexture *src_color, bool
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_16;
break;
default:
- BLI_assert("Mulisample count unsupported by blit shader.");
+ BLI_assert(!"Mulisample count unsupported by blit shader.");
builtin = GPU_SHADER_2D_IMAGE_MULTISAMPLE_2;
break;
}
@@ -969,6 +970,43 @@ static void drw_drawdata_unlink_dupli(ID *id)
/** \name Rendering (DRW_engines)
* \{ */
+#define DRW_BATCH_COLLECTION_RATE 60 /* in sec */
+
+void DRW_cache_free_old_batches(Main *bmain)
+{
+ Scene *scene;
+ ViewLayer *view_layer;
+ static int lasttime = 0;
+ int ctime = (int)PIL_check_seconds_timer();
+
+ if (ctime % DRW_BATCH_COLLECTION_RATE || ctime == lasttime)
+ return;
+
+ lasttime = ctime;
+
+ for (scene = bmain->scenes.first; scene; scene = scene->id.next) {
+ for (view_layer = scene->view_layers.first; view_layer; view_layer = view_layer->next) {
+ Depsgraph *depsgraph = BKE_scene_get_depsgraph(scene, view_layer, false);
+
+ /* TODO(fclem): This is not optimal since it iter over all dupli instances.
+ * In this case only the source object should be tagged. */
+ int iter_flags = DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY | DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET |
+ DEG_ITER_OBJECT_FLAG_VISIBLE | DEG_ITER_OBJECT_FLAG_DUPLI;
+
+ DEG_OBJECT_ITER_BEGIN (depsgraph, ob, iter_flags) {
+ DRW_batch_cache_free_old(ob, ctime);
+ }
+ DEG_OBJECT_ITER_END;
+ }
+ }
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Rendering (DRW_engines)
+ * \{ */
+
static void drw_engines_init(void)
{
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 2c831c0877c..a298e668f44 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1450,6 +1450,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
view3d_draw_view(C, ar);
+ DRW_cache_free_old_batches(bmain);
GPU_free_images_old(bmain);
GPU_pass_cache_garbage_collect();