[Bf-blender-cvs] [680f8039ebd] greasepencil-object: GP: Drawing Engine use only one batch
Antonioya
noreply at git.blender.org
Sat Nov 17 20:05:52 CET 2018
Commit: 680f8039ebd5419a1aca18c7d0b291ed1b1e4bdc
Author: Antonioya
Date: Sat Nov 17 17:52:07 2018 +0100
Branches: greasepencil-object
https://developer.blender.org/rB680f8039ebd5419a1aca18c7d0b291ed1b1e4bdc
GP: Drawing Engine use only one batch
This is part of T57829.
Reduce the number of used batches to only one by shader type. This reduces GPU overhead and increase a lot the FPS. As the number of batches is small, the time to allocate and free memory was reduced in 90% or more.
Also the code has been simplified and all batch management has been removed because this is not necessary. Now, all shading groups are created after all vertex buffer data for all strokes has been created using DRW_shgroup_call_range_add().
All batch cache data has been moved to the Object runtime struct and not as before where some parts (derived data) were saved inside GPD datablock.
For particles, now the code is faster and cleaner and gets better FPS.
Thanks to Clément Foucault for his help and advices to improve speed.
===================================================================
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/engines/gpencil/gpencil_cache_utils.c
M source/blender/draw/engines/gpencil/gpencil_draw_cache_impl.c
M source/blender/draw/engines/gpencil/gpencil_draw_utils.c
M source/blender/draw/engines/gpencil/gpencil_engine.c
M source/blender/draw/engines/gpencil/gpencil_engine.h
M source/blender/editors/gpencil/gpencil_data.c
M source/blender/editors/gpencil/gpencil_utils.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 3b8df66668a..34c61083872 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -65,7 +65,6 @@ bool BKE_gpencil_free_strokes(struct bGPDframe *gpf);
void BKE_gpencil_free_frames(struct bGPDlayer *gpl);
void BKE_gpencil_free_layers(struct ListBase *list);
bool BKE_gpencil_free_frame_runtime_data(struct bGPDframe *derived_gpf);
-void BKE_gpencil_free_derived_frames(struct bGPdata *gpd);
void BKE_gpencil_free(struct bGPdata *gpd, bool free_all);
void BKE_gpencil_batch_cache_dirty_tag(struct bGPdata *gpd);
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index f2225bca3f5..98d255df080 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -211,46 +211,6 @@ void BKE_gpencil_free_layers(ListBase *list)
}
}
-/* clear all runtime derived data */
-static void BKE_gpencil_clear_derived(bGPDlayer *gpl)
-{
- if (gpl->runtime.derived_array == NULL) {
- return;
- }
-
- 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*/
-static void BKE_gpencil_free_layers_temp_data(ListBase *list)
-{
- bGPDlayer *gpl_next;
-
- /* error checking */
- if (list == NULL) return;
- /* delete layers */
- for (bGPDlayer *gpl = list->first; gpl; gpl = gpl_next) {
- gpl_next = gpl->next;
- BKE_gpencil_clear_derived(gpl);
- }
-}
-
-/* Free temp gpf derived frames */
-void BKE_gpencil_free_derived_frames(bGPdata *gpd)
-{
- /* error checking */
- if (gpd == NULL) return;
- for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
- BKE_gpencil_clear_derived(gpl);
- }
-}
-
/** Free (or release) any data used by this grease pencil (does not free the gpencil itself). */
void BKE_gpencil_free(bGPdata *gpd, bool free_all)
{
@@ -258,9 +218,6 @@ void BKE_gpencil_free(bGPdata *gpd, bool free_all)
BKE_animdata_free(&gpd->id, false);
/* free layers */
- if (free_all) {
- BKE_gpencil_free_layers_temp_data(&gpd->layers);
- }
BKE_gpencil_free_layers(&gpd->layers);
/* materials */
@@ -639,8 +596,6 @@ 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_array = NULL;
- gpl_dst->runtime.len_derived = 0;
/* copy frames */
BLI_listbase_clear(&gpl_dst->frames);
@@ -1031,9 +986,6 @@ void BKE_gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
/* free icon providing preview of icon color */
BKE_icon_delete(gpl->runtime.icon_id);
- /* free derived data */
- BKE_gpencil_clear_derived(gpl);
-
BLI_freelinkN(&gpd->layers, gpl);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 90deb0f37ea..2745dc22960 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -6612,8 +6612,6 @@ static void direct_link_gpencil(FileData *fd, bGPdata *gpd)
gpl->actframe = newdataadr(fd, gpl->actframe);
- 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/engines/gpencil/gpencil_cache_utils.c b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
index 30887e3fb19..8cf2745f54a 100644
--- a/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_cache_utils.c
@@ -26,14 +26,14 @@
#include "DRW_engine.h"
#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 "BKE_gpencil.h"
+
#include "gpencil_engine.h"
#include "draw_cache_impl.h"
@@ -41,63 +41,6 @@
#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; i++) {
- tGPencilObjectCache *cache_elem = &cache_array[i];
- if (cache_elem->ob == ob) {
- *r_index = cache_elem->data_idx;
- return true;
- }
- }
- return false;
-}
-
-static bool gpencil_check_datablock_duplicated(
- tGPencilObjectCache *cache_array, int gp_cache_used,
- Object *ob, bGPdata *gpd)
-{
- if (gp_cache_used == 0) {
- return false;
- }
-
- for (int i = 0; i < gp_cache_used; i++) {
- tGPencilObjectCache *cache_elem = &cache_array[i];
- if ((cache_elem->ob != ob) &&
- (cache_elem->gpd == gpd))
- {
- return true;
- }
- }
- 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,
@@ -133,38 +76,15 @@ tGPencilObjectCache *gpencil_object_cache_add(
copy_m4_m4(cache_elem->obmat, ob->obmat);
cache_elem->idx = *gp_cache_used;
- /* 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;
- }
+ /* object is duplicated (particle) */
+ cache_elem->is_dup_ob = ob->base_flag & BASE_FROMDUPLI;
/* save FXs */
cache_elem->pixfactor = cache_elem->gpd->pixfactor;
cache_elem->shader_fx = ob_orig->shader_fx;
- cache_elem->init_grp = 0;
- cache_elem->end_grp = -1;
+ cache_elem->init_grp = NULL;
+ cache_elem->end_grp = NULL;
/* calculate zdepth from point of view */
float zdepth = 0.0;
@@ -198,6 +118,46 @@ tGPencilObjectCache *gpencil_object_cache_add(
return cache_array;
}
+/* add a shading group to the cache to create later */
+GpencilBatchGroup *gpencil_group_cache_add(
+ GpencilBatchGroup *cache_array,
+ bGPDframe *gpf, bGPDstroke *gps, const short type, const bool onion,
+ const int vertex_idx,
+ int *grp_size, int *grp_used)
+{
+ GpencilBatchGroup *cache_elem = NULL;
+ GpencilBatchGroup *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 (*grp_used + 1 > *grp_size) {
+ if ((*grp_size == 0) || (cache_array == NULL)) {
+ p = MEM_callocN(sizeof(struct GpencilBatchGroup) * GPENCIL_GROUPS_BLOCK_SIZE, "GpencilBatchGroup");
+ *grp_size = GPENCIL_GROUPS_BLOCK_SIZE;
+ }
+ else {
+ *grp_size += GPENCIL_GROUPS_BLOCK_SIZE;
+ p = MEM_recallocN(cache_array, sizeof(struct GpencilBatchGroup) * *grp_size);
+ }
+ cache_array = p;
+ }
+ /* zero out all data */
+ cache_elem = &cache_array[*grp_used];
+ memset(cache_elem, 0, sizeof(*cache_elem));
+
+ cache_elem->gpf = gpf;
+ cache_elem->gps = gps;
+ cache_elem->type = type;
+ cache_elem->onion = onion;
+ cache_elem->vertex_idx = vertex_idx;
+
+ /* increase slots used in cache */
+ (*grp_used)++;
+
+ return cache_array;
+}
+
/* get current cache data */
static GpencilBatchCache *gpencil_batch_get_element(Object *ob)
{
@@ -208,51 +168,26 @@ static GpencilBatchCache *gpencil_batch_get_element(Object *ob)
/* verify if cache is valid */
static bool gpencil_batch_cache_valid(GpencilBatchCache *cache, bGPdata *gpd, int cfra)
{
+ bool valid = true;
if (cache == NULL) {
return false;
}
cache->is_editmode = GPENCIL_ANY_EDIT_MODE(gpd);
-
if (cfra != cache->cache_frame) {
- return false;
+ valid = false;
}
-
- if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
- return false;
+ else if (gpd->flag & GP_DATA_CACHE_IS_DIRTY) {
+ valid = false;
}
-
- if (cache->is_editmode) {
- return false;
+ else if (cache->is_editmode) {
+ valid = false;
}
-
- if (cache->is_dirty) {
- return false;
+ else if (cache->is_dirty) {
+ valid = 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);
- }
+ return valid;
}
/* cache init */
@@ -263,10 +198,6 @@ static GpencilBatchCache *gpencil_batch_cache_init(Object
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list