[Bf-blender-cvs] [d8a37d3e7c0] greasepencil-object: WIP: Add a cache system for strokes

Antonio Vazquez noreply at git.blender.org
Mon May 15 10:43:01 CEST 2017


Commit: d8a37d3e7c081b1db1a3873c8b603a955467bd1e
Author: Antonio Vazquez
Date:   Mon May 15 10:41:37 2017 +0200
Branches: greasepencil-object
https://developer.blender.org/rBd8a37d3e7c081b1db1a3873c8b603a955467bd1e

WIP: Add a cache system for strokes

The new cache is allocated to save the strokes and is only recalculated when there are changes.

Need more testing to be sure all situations are working fine.

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

M	source/blender/blenkernel/BKE_gpencil.h
M	source/blender/blenkernel/intern/gpencil.c
M	source/blender/blenloader/intern/readfile.c
M	source/blender/draw/CMakeLists.txt
A	source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M	source/blender/draw/engines/gpencil/gpencil_engine.c
M	source/blender/draw/engines/gpencil/gpencil_engine.h
R096	source/blender/draw/engines/gpencil/gpencil_draw.c	source/blender/draw/engines/gpencil/gpencil_geom.c
M	source/blender/draw/intern/draw_cache_impl.h
M	source/blender/draw/intern/draw_manager.c
M	source/blender/editors/gpencil/gpencil_paint.c
M	source/blender/makesdna/DNA_gpencil_types.h

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

diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 20bd4f2d6a2..14e242a54d5 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -50,7 +50,10 @@ void BKE_gpencil_free_frames(struct bGPDlayer *gpl);
 void BKE_gpencil_free_layers(struct ListBase *list);
 void BKE_gpencil_free_brushes(struct ListBase *list);
 void BKE_gpencil_free_palettes(struct ListBase *list);
-void BKE_gpencil_free(struct bGPdata *gpd, bool free_palettes);
+void BKE_gpencil_free(struct bGPdata *gpd, bool free_all);
+
+void BKE_gpencil_batch_cache_dirty(struct bGPdata *gpd, int mode);
+void BKE_gpencil_batch_cache_free(struct bGPdata *gpd);
 
 void BKE_gpencil_stroke_sync_selection(struct bGPDstroke *gps);
 
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 85223593493..ff8dc1e842c 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -56,6 +56,23 @@
 #include "BKE_library.h"
 #include "BKE_main.h"
 
+ /* Draw Engine */
+void(*BKE_gpencil_batch_cache_dirty_cb)(bGPdata *gpd, int mode) = NULL;
+void(*BKE_gpencil_batch_cache_free_cb)(bGPdata *gpd) = NULL;
+
+void BKE_gpencil_batch_cache_dirty(bGPdata *gpd, int mode)
+{
+	if (gpd->batch_cache) {
+		BKE_gpencil_batch_cache_dirty_cb(gpd, mode);
+	}
+}
+
+void BKE_gpencil_batch_cache_free(bGPdata *gpd)
+{
+	if (gpd->batch_cache) {
+		BKE_gpencil_batch_cache_free_cb(gpd);
+	}
+}
 
 /* ************************************************** */
 /* GENERAL STUFF */
@@ -194,15 +211,18 @@ void BKE_gpencil_free_layers(ListBase *list)
 }
 
 /** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */
-void BKE_gpencil_free(bGPdata *gpd, bool free_palettes)
+void BKE_gpencil_free(bGPdata *gpd, bool free_all)
 {
+	/* clear animation data */
 	BKE_animdata_free(&gpd->id, false);
 
 	/* free layers */
 	BKE_gpencil_free_layers(&gpd->layers);
 
-	/* free palettes */
-	if (free_palettes) {
+	/* free all data */
+	if (free_all) {
+		/* clear cache */
+		BKE_gpencil_batch_cache_free(gpd);
 		BKE_gpencil_free_palettes(&gpd->palettes);
 	}
 }
@@ -634,6 +654,7 @@ bGPdata *BKE_gpencil_data_addnew(const char name[])
 	 * since this is more useful...
 	 */
 	gpd->flag |= GP_DATA_VIEWALIGN;
+	gpd->batch_cache = NULL;
 	
 	return gpd;
 }
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 5514091ecd0..025aad1f27c 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6461,6 +6461,9 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
 	gpd->adt = newdataadr(fd, gpd->adt);
 	direct_link_animdata(fd, gpd->adt);
 
+	/* clear drawing cache */
+	gpd->batch_cache = NULL;
+
 	/* relink palettes */
 	link_list(fd, &gpd->palettes);
 	for (palette = gpd->palettes.first; palette; palette = palette->next) {
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 635f50f7aff..0ff2930caba 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -86,7 +86,8 @@ set(SRC
 	engines/external/external_engine.c
 	engines/gpencil/gpencil_engine.h
 	engines/gpencil/gpencil_engine.c
-	engines/gpencil/gpencil_draw.c
+	engines/gpencil/gpencil_draw_cache_impl.c
+	engines/gpencil/gpencil_geom.c
 
 	DRW_engine.h
 	intern/DRW_render.h
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
similarity index 51%
copy from source/blender/draw/engines/gpencil/gpencil_engine.c
copy to source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
index dc35fe6babc..75daba2131b 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
@@ -19,13 +19,14 @@
  *
  */
 
-/** \file blender/draw/engines/gpencil/gpencil_mode.c
+/** \file blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
  *  \ingroup draw
  */
 
 #include "DRW_engine.h"
 #include "DRW_render.h"
 
+#include "BKE_main.h"
 #include "BKE_gpencil.h"
 #include "BKE_image.h"
 #include "ED_gpencil.h"
@@ -45,127 +46,130 @@
 
 #include "IMB_imbuf_types.h"
 
-extern char datatoc_gpencil_fill_vert_glsl[];
-extern char datatoc_gpencil_fill_frag_glsl[];
-extern char datatoc_gpencil_stroke_vert_glsl[];
-extern char datatoc_gpencil_stroke_geom_glsl[];
-extern char datatoc_gpencil_stroke_frag_glsl[];
-
-/* *********** LISTS *********** */
-#define MAX_GPENCIL_MAT 512 
-
-typedef struct GPENCIL_Storage {
-	int pal_id;
-	int t_mix[MAX_GPENCIL_MAT];
-	int t_flip[MAX_GPENCIL_MAT];
-	int t_clamp[MAX_GPENCIL_MAT];
-	int fill_style[MAX_GPENCIL_MAT];
-	PaletteColor *materials[MAX_GPENCIL_MAT];
-	DRWShadingGroup *shgrps_fill[MAX_GPENCIL_MAT];
-	DRWShadingGroup *shgrps_stroke[MAX_GPENCIL_MAT];
-	float unit_matrix[4][4];
-} GPENCIL_Storage;
-
-/* keep it under MAX_STORAGE */
-typedef struct GPENCIL_StorageList {
-	struct GPENCIL_Storage *storage;
-	struct g_data *g_data;
-} GPENCIL_StorageList;
-
-/* keep it under MAX_PASSES */
-typedef struct GPENCIL_PassList {
-	struct DRWPass *stroke_pass;
-	struct DRWPass *edit_pass;
-	struct DRWPass *drawing_pass;
-} GPENCIL_PassList;
-
-/* keep it under MAX_BUFFERS */
-typedef struct GPENCIL_FramebufferList {
-	struct GPUFrameBuffer *fb;
-} GPENCIL_FramebufferList;
-
-/* keep it under MAX_TEXTURES */
-typedef struct GPENCIL_TextureList {
-	struct GPUTexture *texture;
-} GPENCIL_TextureList;
-
-typedef struct GPENCIL_Data {
-	void *engine_type; /* Required */
-	GPENCIL_FramebufferList *fbl;
-	GPENCIL_TextureList *txl;
-	GPENCIL_PassList *psl;
-	GPENCIL_StorageList *stl;
-} GPENCIL_Data;
-
-/* *********** STATIC *********** */
-typedef struct g_data{
-	DRWShadingGroup *shgrps_edit_volumetric;
-	DRWShadingGroup *shgrps_point_volumetric;
-	DRWShadingGroup *shgrps_drawing_stroke;
-	DRWShadingGroup *shgrps_drawing_fill;
-	bool scene_draw;
-} g_data; /* Transient data */
-
-static struct {
-	struct GPUShader *gpencil_fill_sh;
-	struct GPUShader *gpencil_stroke_sh;
-	struct GPUShader *gpencil_volumetric_sh;
-	struct GPUShader *gpencil_drawing_fill_sh;
-} e_data = {NULL}; /* Engine data */
-
-/* *********** FUNCTIONS *********** */
-
-static void GPENCIL_engine_init(void *vedata)
+
+/* verify if cache is valid */
+static bool gpencil_batch_cache_valid(bGPdata *gpd, int cfra)
 {
-	GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
+	GpencilBatchCache *cache = gpd->batch_cache;
+
+	if (cache == NULL) {
+		return false;
+	}
 
-	/* normal fill shader */
-	if (!e_data.gpencil_fill_sh) {
-		e_data.gpencil_fill_sh = DRW_shader_create(datatoc_gpencil_fill_vert_glsl, NULL,
-			datatoc_gpencil_fill_frag_glsl,
-			NULL);
+	if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+		return false;
 	}
 
-	/* normal stroke shader using geometry to display lines */
-	if (!e_data.gpencil_stroke_sh) {
-		e_data.gpencil_stroke_sh = DRW_shader_create(datatoc_gpencil_stroke_vert_glsl,
-			datatoc_gpencil_stroke_geom_glsl,
-			datatoc_gpencil_stroke_frag_glsl,
-			NULL);
+	cache->is_editmode = gpd->flag & GP_DATA_STROKE_EDITMODE;
+	if (cache->is_editmode) {
+		return false;
 	}
 
-	/* used for edit points or strokes with one point only */
-	if (!e_data.gpencil_volumetric_sh) {
-		e_data.gpencil_volumetric_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_POINT_VARYING_SIZE_VARYING_COLOR);
+	if (cfra != cache->cache_frame) {
+		return false;
+	}
+
+	return true;
+}
+
+/* resize the cache to the number of slots */
+static void gpencil_batch_cache_resize(bGPdata *gpd, int slots)
+{
+	GpencilBatchCache *cache = gpd->batch_cache;
+	cache->cache_size = slots;
+	cache->batch_stroke = MEM_recallocN(cache->batch_stroke, sizeof(struct Batch) * slots);
+	cache->batch_fill = MEM_recallocN(cache->batch_fill, sizeof(struct Batch) * slots);
+	cache->batch_point = MEM_recallocN(cache->batch_point, sizeof(struct Batch) * slots);
+	cache->batch_edit = MEM_recallocN(cache->batch_edit, sizeof(struct Batch) * slots);
+}
+
+/* check size and increase if no free slots */
+static void gpencil_batch_cache_check_free_slots(bGPdata *gpd)
+{
+	GpencilBatchCache *cache = gpd->batch_cache;
+
+	/* 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(gpd, cache->cache_size);
 	}
+}
+/* cache init */
+static void gpencil_batch_cache_init(bGPdata *gpd, int cfra)
+{
+	GpencilBatchCache *cache = gpd->batch_cache;
 
-	/* used to filling during drawing */
-	if (!e_data.gpencil_drawing_fill_sh) {
-		e_data.gpencil_drawing_fill_sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_SMOOTH_COLOR);
+	if (!cache) {
+		cache = gpd->batch_cache = MEM_callocN(sizeof(*cache), __func__);
 	}
+	else {
+		memset(cache, 0, sizeof(*cache));
+	}
+
+	cache->cache_size = GPENCIL_MIN_BATCH_SLOTS_CHUNK;
+	cache->batch_stroke = MEM_callocN(sizeof(struct Batch) * cache->cache_size, "Gpencil_Batch_Stroke");
+	cache->batch_fill = MEM_callocN(sizeof(struct Batch) * cache->cache_size, "Gpencil_Batch_Fill");
+	cache->batch_point = MEM_callocN(sizeof(struct Batch) * cache->cache_size, "Gpencil_Batch_Point");
+	cache->batch_edit = MEM_callocN(sizeof(struct Batch) * cache->cache_size, "Gpencil_Batch_Edit");
+
+	cache->is_editmode = gpd->flag & GP_DATA_STROKE_EDITMODE;
+	gpd->flag &= ~GP_DATA_CACHE_IS_DIRTY;
 
-	if (!stl->storage) {
-		stl->storage = MEM_callocN(sizeof(GPENCIL_Storage), "GPENCIL_Storage");
+	cache->cache_idx = 0;
+	cache->is_dirty = true;
+	cache->cache_frame = cfra;
+}
+
+/*  clear cache */
+void gpencil_batch_cache_clear(bGPdata *gpd)
+{
+	GpencilBatchCache *cache = gpd->batch_cache;
+	if (!cache) {
+		return;
+	}
+	if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+		return;
 	}
 
-	unit_m4(stl->storage->unit_matrix);
+	if (cache->cache_size > 0) {
+		for (int i = 0; i < cache->cache_size; ++i) {
+		BATCH_DISCARD_ALL_SAFE(cache->batch_stroke[i]);
+		BATCH_DISCARD_ALL_SAFE(cache->batch_fill[i]);
+		BATCH_DISCARD_ALL_SAFE(cache->batch_point[i]);
+		BATCH_DISCARD_ALL_SAFE(cache->batch_edit[i

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list