[Bf-blender-cvs] [223f7e79f9f] master: DRW: Add batch garbage collection

Clément Foucault noreply at git.blender.org
Fri Apr 19 15:20:34 CEST 2019


Commit: 223f7e79f9fa221f60841afcff9a9ed8a97d9306
Author: Clément Foucault
Date:   Fri Apr 19 02:22:22 2019 +0200
Branches: master
https://developer.blender.org/rB223f7e79f9fa221f60841afcff9a9ed8a97d9306

DRW: Add batch garbage collection

This is only working for shading batches for the moment and only if some Custom data layer are not needed anymore.

The collection rate is hardcoded at 60 sec but could be exposed to the user.

This system can be extended and discard most unused batches in the future.

This commit is in prevision of removing BKE_MESH_BATCH_DIRTY_SHADING when changing shader parameters.

===================================================================

M	source/blender/draw/DRW_engine.h
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/space_view3d/view3d_draw.c

===================================================================

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;
     }
@@ -965,6 +966,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)
  * \{ */
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();



More information about the Bf-blender-cvs mailing list