[Bf-blender-cvs] [9e46bbd3058] greasepencil-object: Cleanup: Move cache functions to own module

Antonio Vazquez noreply at git.blender.org
Wed Apr 4 17:02:49 CEST 2018


Commit: 9e46bbd3058b9c10e7d8903de334d65cb3da3699
Author: Antonio Vazquez
Date:   Wed Apr 4 17:02:41 2018 +0200
Branches: greasepencil-object
https://developer.blender.org/rB9e46bbd3058b9c10e7d8903de334d65cb3da3699

Cleanup: Move cache functions to own module

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

M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/engines/gpencil/gpencil_cache_utils.c
M	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h

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

diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index ddbea6d2681..7720a60397c 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -107,6 +107,7 @@ set(SRC
 	engines/external/external_engine.c
 	engines/gpencil/gpencil_engine.h
 	engines/gpencil/gpencil_engine.c
+	engines/gpencil/gpencil_cache_utils.c
 	engines/gpencil/gpencil_draw_cache_impl.c
 	engines/gpencil/gpencil_geom.c
 	engines/gpencil/gpencil_vfx.c
diff --git a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
new file mode 100644
index 00000000000..a925bb4aca6
--- /dev/null
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2017, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Antonio Vazquez
+ *
+ */
+
+/** \file blender/draw/engines/gpencil/gpencil_cache_utils.c
+ *  \ingroup draw
+ */
+
+#include "DRW_render.h"
+
+#include "BKE_global.h"
+
+#include "ED_gpencil.h"
+#include "ED_view3d.h"
+
+#include "DNA_gpencil_types.h"
+#include "DNA_view3d_types.h"
+
+#include "gpencil_engine.h"
+
+ /* allocate cache to store GP objects */
+tGPencilObjectCache *gpencil_object_cache_allocate(tGPencilObjectCache *cache, int *gp_cache_size, int *gp_cache_used)
+{
+	tGPencilObjectCache *p = NULL;
+
+	/* By default a cache is created with one block with a predefined number of free slots,
+	if the size is not enough, the cache is reallocated adding a new block of free slots.
+	This is done in order to keep cache small */
+	if (*gp_cache_used + 1 > *gp_cache_size) {
+		if ((*gp_cache_size == 0) || (cache == NULL)) {
+			p = MEM_callocN(sizeof(struct tGPencilObjectCache) * GP_CACHE_BLOCK_SIZE, "tGPencilObjectCache");
+			*gp_cache_size = GP_CACHE_BLOCK_SIZE;
+		}
+		else {
+			*gp_cache_size += GP_CACHE_BLOCK_SIZE;
+			p = MEM_recallocN(cache, sizeof(struct tGPencilObjectCache) * *gp_cache_size);
+		}
+		cache = p;
+	}
+	return cache;
+}
+
+/* add a gpencil object to cache to defer drawing */
+void gpencil_object_cache_add(tGPencilObjectCache *cache_array, Object *ob, bool is_temp, int *gp_cache_used)
+{
+	const DRWContextState *draw_ctx = DRW_context_state_get();
+	tGPencilObjectCache *cache = &cache_array[*gp_cache_used];
+	RegionView3D *rv3d = draw_ctx->rv3d;
+	
+	/* zero out all vfx_* pointers */
+	memset(cache, 0, sizeof(*cache));
+	
+	/* save object */
+	cache->ob = ob;
+	cache->temp_ob = is_temp;
+	cache->idx = *gp_cache_used;
+
+	cache->init_grp = 0;
+	cache->end_grp = -1;
+	
+	/* calculate zdepth from point of view */
+	float zdepth = 0.0;
+	if (rv3d) {
+		if (rv3d->is_persp) {
+			zdepth = ED_view3d_calc_zfac(rv3d, ob->loc, NULL);
+		}
+		else {
+			zdepth = -dot_v3v3(rv3d->viewinv[2], ob->loc);
+		}
+	}
+	else {
+		/* In render mode, rv3d is not available, so use the distance to camera.
+		 * The real distance is not important, but the relative distance to the camera plane
+		 * in order to sort by z_depth of the objects
+		 */
+		float vn[3] = { 0.0f, 0.0f, -1.0f }; /* always face down */
+		float plane_cam[4];
+		struct Object *camera = draw_ctx->scene->camera;
+		if (camera) {
+			mul_m4_v3(camera->obmat, vn);
+			normalize_v3(vn);
+			plane_from_point_normal_v3(plane_cam, camera->loc, vn);
+			zdepth = dist_squared_to_plane_v3(ob->loc, plane_cam);
+		}
+	}
+	cache->zdepth = zdepth;
+	/* increase slots used in cache */
+	(*gp_cache_used)++;
+}
+
+/* get current cache data */
+static GpencilBatchCache *gpencil_batch_get_element(Object *ob)
+{
+	bGPdata *gpd = ob->data;
+	if (gpd->batch_cache_data == NULL) {
+		gpd->batch_cache_data = BLI_ghash_str_new("GP batch cache data");
+		return NULL;
+	}
+
+	return (GpencilBatchCache *) BLI_ghash_lookup(gpd->batch_cache_data, ob->id.name);
+}
+
+/* verify if cache is valid */
+static bool gpencil_batch_cache_valid(Object *ob, bGPdata *gpd, int cfra)
+{
+	GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+
+	if (cache == NULL) {
+		return false;
+	}
+
+	cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
+
+	if (cfra != cache->cache_frame) {
+		return false;
+	}
+
+	if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+		return false;
+	}
+
+	if (cache->is_editmode) {
+		return false;
+	}
+
+	if (cache->is_dirty) {
+		return false;
+	}
+
+	return true;
+}
+
+/* resize the cache to the number of slots */
+static void gpencil_batch_cache_resize(GpencilBatchCache *cache, int slots)
+{
+	cache->cache_size = slots;
+	cache->batch_stroke = MEM_recallocN(cache->batch_stroke, sizeof(struct Gwn_Batch *) * slots);
+	cache->batch_fill = MEM_recallocN(cache->batch_fill, sizeof(struct Gwn_Batch *) * slots);
+	cache->batch_edit = MEM_recallocN(cache->batch_edit, sizeof(struct Gwn_Batch *) * slots);
+	cache->batch_edlin = MEM_recallocN(cache->batch_edlin, sizeof(struct Gwn_Batch *) * slots);
+}
+
+/* check size and increase if no free slots */
+void gpencil_batch_cache_check_free_slots(Object *ob)
+{
+	GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+
+	/* the memory is reallocated by chunks, not for one slot only to improve speed */
+	if (cache->cache_idx >= cache->cache_size) {
+		cache->cache_size += GPENCIL_MIN_BATCH_SLOTS_CHUNK;
+		gpencil_batch_cache_resize(cache, cache->cache_size);
+	}
+}
+
+/* cache init */
+static void gpencil_batch_cache_init(Object *ob, int cfra)
+{
+	GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+	bGPdata *gpd = ob->data;
+
+	if (G.debug_value >= 664) {
+		printf("gpencil_batch_cache_init: %s\n", ob->id.name);
+	}
+
+	if (!cache) {
+		cache = MEM_callocN(sizeof(*cache), __func__);
+		BLI_ghash_insert(gpd->batch_cache_data, ob->id.name, cache);
+	}
+	else {
+		memset(cache, 0, sizeof(*cache));
+	}
+
+	cache->cache_size = GPENCIL_MIN_BATCH_SLOTS_CHUNK;
+	cache->batch_stroke = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Stroke");
+	cache->batch_fill = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Fill");
+	cache->batch_edit = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Edit");
+	cache->batch_edlin = MEM_callocN(sizeof(struct Gwn_Batch *) * cache->cache_size, "Gpencil_Batch_Edlin");
+
+	cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
+	gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
+
+	cache->cache_idx = 0;
+	cache->is_dirty = true;
+	cache->cache_frame = cfra;
+}
+
+/* clear cache */
+static void gpencil_batch_cache_clear(GpencilBatchCache *cache, bGPdata *gpd)
+{
+	if (!cache) {
+		return;
+	}
+
+	if (cache->cache_size == 0) {
+		return;
+	}
+
+	if (G.debug_value >= 664) {
+		printf("gpencil_batch_cache_clear: %s\n", gpd->id.name);
+	}
+
+	if (cache->cache_size > 0) {
+		for (int i = 0; i < cache->cache_size; i++) {
+			GWN_BATCH_DISCARD_SAFE(cache->batch_stroke[i]);
+			GWN_BATCH_DISCARD_SAFE(cache->batch_fill[i]);
+			GWN_BATCH_DISCARD_SAFE(cache->batch_edit[i]);
+			GWN_BATCH_DISCARD_SAFE(cache->batch_edlin[i]);
+		}
+		MEM_SAFE_FREE(cache->batch_stroke);
+		MEM_SAFE_FREE(cache->batch_fill);
+		MEM_SAFE_FREE(cache->batch_edit);
+		MEM_SAFE_FREE(cache->batch_edlin);
+	}
+
+	MEM_SAFE_FREE(cache);
+}
+
+/* get cache */
+GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
+{
+	bGPdata *gpd = ob->data;
+
+	if (!gpencil_batch_cache_valid(ob, gpd, cfra)) {
+		if (G.debug_value >= 664) {
+			printf("gpencil_batch_cache: %s\n", gpd->id.name);
+		}
+
+		GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+		if (cache) {
+			gpencil_batch_cache_clear(cache, gpd);
+			BLI_ghash_remove(gpd->batch_cache_data, ob->id.name, NULL, NULL);
+		}
+		gpencil_batch_cache_init(ob, cfra);
+	}
+
+	return gpencil_batch_get_element(ob);
+}
+
+/* set cache as dirty */
+void DRW_gpencil_batch_cache_dirty(bGPdata *gpd)
+{
+	if (gpd->batch_cache_data == NULL) {
+		return;
+	}
+
+	GHashIterator *ihash = BLI_ghashIterator_new(gpd->batch_cache_data);
+	while (!BLI_ghashIterator_done(ihash)) {
+		GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash);
+		if (cache) {
+			cache->is_dirty = true;
+		}
+		BLI_ghashIterator_step(ihash);
+	}
+	BLI_ghashIterator_free(ihash);
+}
+
+/* free batch cache */
+void DRW_gpencil_batch_cache_free(bGPdata *gpd)
+{
+	if (gpd->batch_cache_data == NULL) {
+		return;
+	}
+
+	GHashIterator *ihash = BLI_ghashIterator_new(gpd->batch_cache_data);
+	while (!BLI_ghashIterator_done(ihash)) {
+		GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash);
+		if (cache) {
+			gpencil_batch_cache_clear(cache, gpd);
+		}
+		BLI_ghashIterator_step(ihash);
+	}
+	BLI_ghashIterator_free(ihash);
+
+	/* free hash */
+	if (gpd->batch_cache_data) {
+		BLI_ghash_free(gpd->batch_cache_data, NULL, NULL);
+		gpd->batch_cache_data = NULL;
+	}
+}
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index 0f27811e191..899d1fb7228 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -52,223 +52,6 @@
 #include "draw_cache_impl.h"
 #include "gpencil_engine.h"
 
- /* allocate cache to store GP objects */
-tGPencilObjectCache *gpencil_object_cache_allocate(tGPencilObjectCache *cache, int *gp_cache_size, int *gp_cache_used)
-{
-	tGPencilObjectCache *p = NULL;
-
-	/* By default a cache is created with one block with a predefined number of free slots,
-	if the size is not enough, the cache is reallocated adding a new block of 

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list