[Bf-blender-cvs] [541d07045b7] blender2.8: GP: Redesign drawing cache to support particles

Antonioya noreply at git.blender.org
Sat Oct 20 09:17:20 CEST 2018


Commit: 541d07045b79cef52bdcf8bd1d90fc60793c9872
Author: Antonioya
Date:   Fri Oct 19 20:39:21 2018 +0200
Branches: blender2.8
https://developer.blender.org/rB541d07045b79cef52bdcf8bd1d90fc60793c9872

GP: Redesign drawing cache to support particles

Full redesign of the cache system used for drawing strokes and handle derived frame data.

Before, the cache was saved in bGPdata and a hash was used to manage several objects with the same datablock.

Old design made the use of particles very inefficient and prone to bugs and segment faults, and especially when this was mixed with onion skinning and multiple objects using same datablock. Also, there were some conflicts with the depsgrah logic (the old design was done before despgraph was in place) that made the use of hash not working.

The new design saves the data in the object runtime struct and avoid the use of any hash to find the right data. This improves the speed and reduce a lot the complexity of the code, memory allocation, hash overload and adds full support for particles and reused datablocks.

The particles can reuse the modifiers and shader effects of the original grease pencil object.

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

M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/draw/DRW_engine.h
M	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_utils.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
M	source/blender/editors/gpencil/gpencil_data.c
M	source/blender/makesdna/DNA_gpencil_types.h
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/makesrna/intern/rna_shader_fx.c

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

diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 33c2587e800..97aed40e998 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -169,8 +169,6 @@ bool BKE_gpencil_free_frame_runtime_data(bGPDframe *derived_gpf)
 	}
 	BLI_listbase_clear(&derived_gpf->strokes);
 
-	MEM_SAFE_FREE(derived_gpf);
-
 	return true;
 }
 
@@ -216,18 +214,17 @@ void BKE_gpencil_free_layers(ListBase *list)
 /* clear all runtime derived data */
 static void BKE_gpencil_clear_derived(bGPDlayer *gpl)
 {
-	GHashIterator gh_iter;
-
-	if (gpl->runtime.derived_data == NULL) {
+	if (gpl->runtime.derived_array == NULL) {
 		return;
 	}
 
-	GHASH_ITER(gh_iter, gpl->runtime.derived_data) {
-		bGPDframe *gpf = (bGPDframe *)BLI_ghashIterator_getValue(&gh_iter);
-		if (gpf) {
-			BKE_gpencil_free_frame_runtime_data(gpf);
-		}
+	for (int i = 0; i < gpl->runtime.len_derived; i++) {
+		bGPDframe *derived_gpf = &gpl->runtime.derived_array[i];
+		BKE_gpencil_free_frame_runtime_data(derived_gpf);
+		derived_gpf = NULL;
 	}
+	gpl->runtime.len_derived = 0;
+	MEM_SAFE_FREE(gpl->runtime.derived_array);
 }
 
 /* Free all of the gp-layers temp data*/
@@ -241,11 +238,6 @@ static void BKE_gpencil_free_layers_temp_data(ListBase *list)
 	for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
 		gpl_next = gpl->next;
 		BKE_gpencil_clear_derived(gpl);
-
-		if (gpl->runtime.derived_data) {
-			BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL);
-			gpl->runtime.derived_data = NULL;
-		}
 	}
 }
 
@@ -256,11 +248,6 @@ void BKE_gpencil_free_derived_frames(bGPdata *gpd)
 	if (gpd == NULL) return;
 	for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
 		BKE_gpencil_clear_derived(gpl);
-
-		if (gpl->runtime.derived_data) {
-			BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL);
-			gpl->runtime.derived_data = NULL;
-		}
 	}
 }
 
@@ -464,7 +451,6 @@ bGPdata *BKE_gpencil_data_addnew(Main *bmain, const char name[])
 	ARRAY_SET_ITEMS(gpd->line_color, 0.6f, 0.6f, 0.6f, 0.5f);
 
 	gpd->xray_mode = GP_XRAY_3DSPACE;
-	gpd->runtime.batch_cache_data = NULL;
 	gpd->pixfactor = GP_DEFAULT_PIX_FACTOR;
 
 	/* grid settings */
@@ -645,7 +631,8 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
 	/* make a copy of source layer */
 	gpl_dst = MEM_dupallocN(gpl_src);
 	gpl_dst->prev = gpl_dst->next = NULL;
-	gpl_dst->runtime.derived_data = NULL;
+	gpl_dst->runtime.derived_array = NULL;
+	gpl_dst->runtime.len_derived = 0;
 
 	/* copy frames */
 	BLI_listbase_clear(&gpl_dst->frames);
@@ -673,9 +660,6 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
  */
 void BKE_gpencil_copy_data(bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag))
 {
-	/* cache data is not duplicated */
-	gpd_dst->runtime.batch_cache_data = NULL;
-
 	/* duplicate material array */
 	if (gpd_src->mat) {
 		gpd_dst->mat = MEM_dupallocN(gpd_src->mat);
@@ -721,7 +705,6 @@ bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool in
 	else {
 		BLI_assert(bmain != NULL);
 		BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_dst, 0, false);
-		gpd_dst->runtime.batch_cache_data = NULL;
 	}
 
 	/* Copy internal data (layers, etc.) */
@@ -1035,10 +1018,6 @@ void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
 
 	/* free derived data */
 	BKE_gpencil_clear_derived(gpl);
-	if (gpl->runtime.derived_data) {
-		BLI_ghash_free(gpl->runtime.derived_data, NULL, NULL);
-		gpl->runtime.derived_data = NULL;
-	}
 
 	BLI_freelinkN(&gpd->layers, gpl);
 }
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index f73e61f56e6..c5e1c0cff87 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -481,6 +481,9 @@ void BKE_object_free_derived_caches(Object *ob)
 	}
 
 	BKE_object_free_curve_cache(ob);
+
+	/* clear grease pencil data */
+	DRW_gpencil_freecache(ob);
 }
 
 void BKE_object_free_derived_mesh_caches(struct Object *ob)
@@ -1406,10 +1409,6 @@ void BKE_object_copy_data(Main *bmain, Object *ob_dst, const Object *ob_src, con
 	BLI_listbase_clear((ListBase *)&ob_dst->drawdata);
 	BLI_listbase_clear(&ob_dst->pc_ids);
 
-	/* grease pencil: clean derived data */
-	if (ob_dst->type == OB_GPENCIL)
-		BKE_gpencil_free_derived_frames(ob_dst->data);
-
 	ob_dst->avs = ob_src->avs;
 	ob_dst->mpath = animviz_copy_motionpath(ob_src->mpath);
 
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index bae71fba036..3b0d946ba47 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6574,9 +6574,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 		}
 	}
 
-	/* clear drawing cache */
-	gpd->runtime.batch_cache_data = NULL;
-
 	/* materials */
 	gpd->mat = newdataadr(fd, gpd->mat);
 	test_pointer_array(fd, (void **)&gpd->mat);
@@ -6590,7 +6587,8 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 
 		gpl->actframe = newdataadr(fd, gpl->actframe);
 
-		gpl->runtime.derived_data = NULL;
+		gpl->runtime.derived_array = NULL;
+		gpl->runtime.len_derived = 0;
 		gpl->runtime.icon_id = 0;
 
 		for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h
index d61958931e5..f99ce1be894 100644
--- a/source/blender/draw/DRW_engine.h
+++ b/source/blender/draw/DRW_engine.h
@@ -128,6 +128,7 @@ void DRW_draw_depth_loop(
 
 /* grease pencil render */
 void DRW_render_gpencil(struct RenderEngine *engine, struct Depsgraph *depsgraph);
+void DRW_gpencil_freecache(struct Object *ob);
 
 /* This is here because GPUViewport needs it */
 void DRW_pass_free(struct DRWPass *pass);
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index e8f8254bb5b..9d8c4b6d0f8 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -37,17 +37,20 @@
 
 #include "draw_cache_impl.h"
 
-static bool gpencil_check_ob_duplicated(tGPencilObjectCache *cache_array, int gp_cache_used, Object *ob)
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
+
+static bool gpencil_check_ob_duplicated(tGPencilObjectCache *cache_array,
+	int gp_cache_used, Object *ob, int *r_index)
 {
 	if (gp_cache_used == 0) {
 		return false;
 	}
 
-	for (int i = 0; i < gp_cache_used + 1; i++) {
+	for (int i = 0; i < gp_cache_used; i++) {
 		tGPencilObjectCache *cache_elem = &cache_array[i];
-		if (STREQ(cache_elem->ob_name, ob->id.name) &&
-		    (cache_elem->is_dup_ob == false))
-		{
+		if (cache_elem->ob == ob) {
+			*r_index = cache_elem->data_idx;
 			return true;
 		}
 	}
@@ -62,9 +65,9 @@ static bool gpencil_check_datablock_duplicated(
 		return false;
 	}
 
-	for (int i = 0; i < gp_cache_used + 1; i++) {
+	for (int i = 0; i < gp_cache_used; i++) {
 		tGPencilObjectCache *cache_elem = &cache_array[i];
-		if (!STREQ(cache_elem->ob_name, ob->id.name) &&
+		if ((cache_elem->ob != ob) &&
 		    (cache_elem->gpd == gpd))
 		{
 			return true;
@@ -73,6 +76,27 @@ static bool gpencil_check_datablock_duplicated(
 	return false;
 }
 
+static int gpencil_len_datablock_duplicated(
+	tGPencilObjectCache *cache_array, int gp_cache_used,
+	Object *ob, bGPdata *gpd)
+{
+	int tot = 0;
+	if (gp_cache_used == 0) {
+		return 0;
+	}
+
+	for (int i = 0; i < gp_cache_used; i++) {
+		tGPencilObjectCache *cache_elem = &cache_array[i];
+		if ((cache_elem->ob != ob) &&
+			(cache_elem->gpd == gpd) &&
+			(!cache_elem->is_dup_ob))
+		{
+			tot++;
+		}
+	}
+	return tot;
+}
+
  /* add a gpencil object to cache to defer drawing */
 tGPencilObjectCache *gpencil_object_cache_add(
         tGPencilObjectCache *cache_array, Object *ob,
@@ -101,22 +125,41 @@ tGPencilObjectCache *gpencil_object_cache_add(
 	cache_elem = &cache_array[*gp_cache_used];
 	memset(cache_elem, 0, sizeof(*cache_elem));
 
-	cache_elem->is_dup_ob = gpencil_check_ob_duplicated(cache_array, *gp_cache_used, ob);
-	
-	STRNCPY(cache_elem->ob_name, ob->id.name);
-	cache_elem->gpd = (bGPdata *)ob->data;
-
+	Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
+	cache_elem->ob = ob_orig;
+	cache_elem->gpd = (bGPdata *)ob_orig->data;
 	copy_v3_v3(cache_elem->loc, ob->loc);
 	copy_m4_m4(cache_elem->obmat, ob->obmat);
 	cache_elem->idx = *gp_cache_used;
 
-	cache_elem->is_dup_onion = gpencil_check_datablock_duplicated(
-	        cache_array, *gp_cache_used,
-	        ob, cache_elem->gpd);
+	/* check if object is duplicated */
+	cache_elem->is_dup_ob = gpencil_check_ob_duplicated(cache_array,
+									*gp_cache_used, ob_orig,
+									&cache_elem->data_idx);
+
+	if (!cache_elem->is_dup_ob) {
+		/* check if object reuse datablock */
+		cache_elem->is_dup_data = gpencil_check_datablock_duplicated(
+			cache_array, *gp_cache_used,
+			ob_orig, cache_elem->gpd);
+		if (cache_elem->is_dup_data) {
+			cache_elem->data_idx = gpencil_len_datablock_duplicated(
+				cache_array, *gp_cache_used,
+				ob_orig, cache_elem->gpd);
+
+			cache_elem->gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
+		}
+		else {
+			cache_elem->data_idx = 0;
+		}
+	}
+	else {
+		cache_elem->is_dup_data = false;
+	}
 
 	/* save FXs */
 	cache_elem->pixfactor = cache_elem->gpd->pixfactor;
-	cache_elem->shader_fx = ob->shader_fx;
+	cache_elem->shader_fx = ob_orig->shader_fx;
 
 	cache_elem->init_grp = 0;
 	cache_elem->end_grp = -1;
@@ -156,20 +199,13 @@ tGPencilObjectCache *gpencil_object_cache_add(
 /* get current cache data */
 static GpencilBatchCache *gpencil_batch_get_element(Object *ob)
 {
-	bGPdata *gpd = (bGPdata *)ob->data;
-	if (gpd->runtime.batch_cache_data == NULL) {
-		gpd->runtime.batch_cache_data = BLI_ghash_str_new("GP batch cache data");
-		return NULL;
-	}
-
-	return (GpencilBatchCache *) BLI_ghash_lookup(gpd->runtime.batch_cache_data, ob->id.name);
+	Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
+	return ob_orig->runtime.gpencil_cache;
 }
 
 /* verify if cache is valid */
-static bool gpencil_batch_cache_valid(Object *ob, bGPdata *gpd, int cfra)
+static bool gpencil_batch_cache_valid(Gpe

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list