Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/draw')
-rw-r--r--source/blender/draw/DRW_engine.h1
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_cache_utils.c158
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_draw_utils.c84
-rw-r--r--source/blender/draw/engines/gpencil/gpencil_engine.h5
4 files changed, 143 insertions, 105 deletions
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(GpencilBatchCache *cache, bGPdata *gpd, int cfra)
{
- GpencilBatchCache *cache = gpencil_batch_get_element(ob);
-
if (cache == NULL) {
return false;
}
@@ -218,10 +254,12 @@ void gpencil_batch_cache_check_free_slots(Object *ob)
}
/* cache init */
-static void gpencil_batch_cache_init(Object *ob, int cfra)
+static GpencilBatchCache *gpencil_batch_cache_init(Object *ob, int cfra)
{
+ Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
+ bGPdata *gpd = (bGPdata *)ob_orig->data;
+
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);
@@ -229,7 +267,7 @@ static void gpencil_batch_cache_init(Object *ob, int cfra)
if (!cache) {
cache = MEM_callocN(sizeof(*cache), __func__);
- BLI_ghash_insert(gpd->runtime.batch_cache_data, ob->id.name, cache);
+ ob_orig->runtime.gpencil_cache = cache;
}
else {
memset(cache, 0, sizeof(*cache));
@@ -247,6 +285,8 @@ static void gpencil_batch_cache_init(Object *ob, int cfra)
cache->cache_idx = 0;
cache->is_dirty = true;
cache->cache_frame = cfra;
+
+ return cache;
}
/* clear cache */
@@ -273,68 +313,54 @@ static void gpencil_batch_cache_clear(GpencilBatchCache *cache)
MEM_SAFE_FREE(cache->batch_edlin);
}
- MEM_SAFE_FREE(cache);
+ cache->cache_size = 0;
}
/* get cache */
GpencilBatchCache *gpencil_batch_cache_get(Object *ob, int cfra)
{
- bGPdata *gpd = ob->data;
+ Object *ob_orig = (Object *)DEG_get_original_id(&ob->id);
+ bGPdata *gpd = (bGPdata *)ob_orig->data;
- if (!gpencil_batch_cache_valid(ob, gpd, cfra)) {
+ GpencilBatchCache *cache = gpencil_batch_get_element(ob);
+ if (!gpencil_batch_cache_valid(cache, 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);
- BLI_ghash_remove(gpd->runtime.batch_cache_data, ob->id.name, NULL, NULL);
}
- gpencil_batch_cache_init(ob, cfra);
+ return gpencil_batch_cache_init(ob, cfra);
+ }
+ else {
+ return cache;
}
-
- return gpencil_batch_get_element(ob);
}
/* set cache as dirty */
void DRW_gpencil_batch_cache_dirty_tag(bGPdata *gpd)
{
- if (gpd->runtime.batch_cache_data == NULL) {
- return;
- }
-
- GHashIterator *ihash = BLI_ghashIterator_new(gpd->runtime.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);
+ bGPdata *gpd_orig = (bGPdata *)DEG_get_original_id(&gpd->id);
+ gpd_orig->flag |= GP_DATA_CACHE_IS_DIRTY;
}
/* free batch cache */
void DRW_gpencil_batch_cache_free(bGPdata *gpd)
{
- if (gpd->runtime.batch_cache_data == NULL) {
- return;
- }
+ return;
+}
- GHashIterator *ihash = BLI_ghashIterator_new(gpd->runtime.batch_cache_data);
- while (!BLI_ghashIterator_done(ihash)) {
- GpencilBatchCache *cache = (GpencilBatchCache *)BLI_ghashIterator_getValue(ihash);
- if (cache) {
- gpencil_batch_cache_clear(cache);
+/* wrapper to clear cache */
+void DRW_gpencil_freecache(struct Object *ob)
+{
+ if ((ob) && (ob->type == OB_GPENCIL)) {
+ gpencil_batch_cache_clear(ob->runtime.gpencil_cache);
+ MEM_SAFE_FREE(ob->runtime.gpencil_cache);
+ bGPdata *gpd = (bGPdata *)ob->data;
+ if (gpd) {
+ gpd->flag |= GP_DATA_CACHE_IS_DIRTY;
}
- BLI_ghashIterator_step(ihash);
- }
- BLI_ghashIterator_free(ihash);
-
- /* free hash */
- if (gpd->runtime.batch_cache_data) {
- BLI_ghash_free(gpd->runtime.batch_cache_data, NULL, NULL);
- gpd->runtime.batch_cache_data = NULL;
}
}
+
diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
index 943bd5202db..6d15c8145e1 100644
--- a/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
+++ b/source/blender/draw/engines/gpencil/gpencil_draw_utils.c
@@ -1218,6 +1218,24 @@ void DRW_gpencil_populate_multiedit(
cache->is_dirty = false;
}
+void static gpencil_copy_frame(bGPDframe *gpf, bGPDframe *derived_gpf)
+{
+ derived_gpf->prev = gpf->prev;
+ derived_gpf->next = gpf->next;
+ derived_gpf->framenum = gpf->framenum;
+ derived_gpf->flag = gpf->flag;
+ derived_gpf->key_type = gpf->key_type;
+ derived_gpf->runtime = gpf->runtime;
+
+ /* copy strokes */
+ BLI_listbase_clear(&derived_gpf->strokes);
+ for (bGPDstroke *gps_src = gpf->strokes.first; gps_src; gps_src = gps_src->next) {
+ /* make copy of source stroke */
+ bGPDstroke *gps_dst = BKE_gpencil_stroke_duplicate(gps_src);
+ BLI_addtail(&derived_gpf->strokes, gps_dst);
+ }
+}
+
/* helper for populate a complete grease pencil datablock */
void DRW_gpencil_populate_datablock(
GPENCIL_e_data *e_data, void *vedata,
@@ -1226,7 +1244,9 @@ void DRW_gpencil_populate_datablock(
{
GPENCIL_StorageList *stl = ((GPENCIL_Data *)vedata)->stl;
const DRWContextState *draw_ctx = DRW_context_state_get();
- bGPdata *gpd = (bGPdata *)ob->data;
+ bGPdata *gpd_eval = (bGPdata *)ob->data;
+ bGPdata *gpd = (bGPdata *)DEG_get_original_id(&gpd_eval->id);
+
View3D *v3d = draw_ctx->v3d;
int cfra_eval = (int)DEG_get_ctime(draw_ctx->depsgraph);
ToolSettings *ts = scene->toolsettings;
@@ -1235,6 +1255,7 @@ void DRW_gpencil_populate_datablock(
const bool do_onion = (bool)((gpd->flag & GP_DATA_STROKE_WEIGHTMODE) == 0) && main_onion;
const bool overlay = v3d != NULL ? (bool)((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) : true;
float opacity;
+ bGPDframe *p = NULL;
/* check if playing animation */
bool playing = stl->storage->is_playing;
@@ -1260,7 +1281,7 @@ void DRW_gpencil_populate_datablock(
/* if pose mode, maybe the overlay to fade geometry is enabled */
if ((draw_ctx->obact) && (draw_ctx->object_mode == OB_MODE_POSE) &&
- (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT))
+ (v3d->overlay.flag & V3D_OVERLAY_BONE_SELECT))
{
opacity = gpl->opacity * v3d->overlay.bone_select_alpha;
}
@@ -1268,53 +1289,42 @@ void DRW_gpencil_populate_datablock(
opacity = gpl->opacity;
}
- /* create GHash if need */
- if (gpl->runtime.derived_data == NULL) {
- gpl->runtime.derived_data = (GHash *)BLI_ghash_str_new(gpl->info);
- }
-
- if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) {
- derived_gpf = BLI_ghash_lookup(gpl->runtime.derived_data, ob->id.name);
- }
- else {
- /* verify we have frame duplicated already */
- if (cache_ob->is_dup_ob) {
- continue;
+ /* create derived array data or expand */
+ if (cache_ob->data_idx + 1 > gpl->runtime.len_derived) {
+ if ((gpl->runtime.len_derived == 0) ||
+ (gpl->runtime.derived_array == NULL))
+ {
+ p = MEM_callocN(sizeof(struct bGPDframe), "bGPDframe array");
+ gpl->runtime.len_derived = 1;
}
- derived_gpf = NULL;
- }
+ else {
+ gpl->runtime.len_derived++;
+ p = MEM_recallocN(gpl->runtime.derived_array, sizeof(struct bGPDframe) * gpl->runtime.len_derived);
+ }
+ gpl->runtime.derived_array = p;
- if (derived_gpf == NULL) {
- cache->is_dirty = true;
+ derived_gpf = &gpl->runtime.derived_array[cache_ob->data_idx];
}
- if ((!cache_ob->is_dup_ob) && (cache->is_dirty)) {
+
+ derived_gpf = &gpl->runtime.derived_array[cache_ob->data_idx];
+
+ /* if no derived frame or dirty cache, create a new one */
+ if ((derived_gpf == NULL) || (cache->is_dirty)) {
if (derived_gpf != NULL) {
/* first clear temp data */
- if (BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) {
- BLI_ghash_remove(gpl->runtime.derived_data, ob->id.name, NULL, NULL);
- }
-
BKE_gpencil_free_frame_runtime_data(derived_gpf);
}
- /* create new data */
- derived_gpf = BKE_gpencil_frame_duplicate(gpf);
- if (!BLI_ghash_haskey(gpl->runtime.derived_data, ob->id.name)) {
- BLI_ghash_insert(gpl->runtime.derived_data, ob->id.name, derived_gpf);
- }
- else {
- BLI_ghash_reinsert(gpl->runtime.derived_data, ob->id.name, derived_gpf, NULL, NULL);
- }
+ /* create new data (do not assign new memory)*/
+ gpencil_copy_frame(gpf, derived_gpf);
}
+
/* draw onion skins */
if (!ID_IS_LINKED(&gpd->id)) {
- ID *orig_id = gpd->id.orig_id;
- /* GPXX: Now only a datablock with one use is allowed to be compatible
- * with instances
- */
- if ((!cache_ob->is_dup_onion) && (gpd->flag & GP_DATA_SHOW_ONIONSKINS) &&
+ if ((!cache_ob->is_dup_data) &&
+ (gpd->flag & GP_DATA_SHOW_ONIONSKINS) &&
(do_onion) && (gpl->onion_flag & GP_LAYER_ONIONSKIN) &&
((!playing) || (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)) &&
- (!cache_ob->is_dup_ob) && (orig_id->us <= 1))
+ (!cache_ob->is_dup_ob) && (gpd->id.us <= 1))
{
if (((!stl->storage->is_render) && (overlay)) ||
((stl->storage->is_render) && (gpd->onion_flag & GP_ONION_GHOST_ALWAYS)))
diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.h b/source/blender/draw/engines/gpencil/gpencil_engine.h
index b8844d3c3e9..e2e6bf4edf0 100644
--- a/source/blender/draw/engines/gpencil/gpencil_engine.h
+++ b/source/blender/draw/engines/gpencil/gpencil_engine.h
@@ -58,8 +58,8 @@ struct RenderLayer;
/* used to save gpencil object data for drawing */
typedef struct tGPencilObjectCache {
+ struct Object *ob;
struct bGPdata *gpd;
- char ob_name[64];
int init_grp, end_grp;
int idx; /*original index, can change after sort */
@@ -82,7 +82,8 @@ typedef struct tGPencilObjectCache {
float obmat[4][4];
float zdepth; /* z-depth value to sort gp object */
bool is_dup_ob; /* flag to tag duplicate objects */
- bool is_dup_onion; /* other object display onion already */
+ bool is_dup_data; /* other object uses datablock already */
+ int data_idx; /* derived data index */
} tGPencilObjectCache;
/* *********** LISTS *********** */