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:
-rw-r--r--source/blender/draw/intern/DRW_render.h1
-rw-r--r--source/blender/draw/intern/draw_manager.c73
-rw-r--r--source/blender/draw/intern/draw_manager.h4
3 files changed, 76 insertions, 2 deletions
diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h
index 82584ebbb8d..db5bab3abaa 100644
--- a/source/blender/draw/intern/DRW_render.h
+++ b/source/blender/draw/intern/DRW_render.h
@@ -631,6 +631,7 @@ DrawData *DRW_drawdata_ensure(ID *id,
size_t size,
DrawDataInitCb init_cb,
DrawDataFreeCb free_cb);
+void **DRW_duplidata_get(void *vedata);
/* Settings */
bool DRW_object_is_renderable(const struct Object *ob);
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 6afb1fdf854..95f34fec131 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -790,6 +790,69 @@ void DRW_viewport_request_redraw(void)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Duplis
+ * \{ */
+
+static void drw_duplidata_load(DupliObject *dupli)
+{
+ if (dupli == NULL) {
+ return;
+ }
+
+ if (DST.dupli_origin != dupli->ob) {
+ DST.dupli_origin = dupli->ob;
+ }
+ else {
+ /* Same data as previous iter. No need to poll ghash for this. */
+ return;
+ }
+
+ if (DST.dupli_ghash == NULL) {
+ DST.dupli_ghash = BLI_ghash_ptr_new(__func__);
+ }
+
+ void **value;
+ if (!BLI_ghash_ensure_p(DST.dupli_ghash, DST.dupli_origin, &value)) {
+ *value = MEM_callocN(sizeof(void *) * DST.enabled_engine_count, __func__);
+ }
+ DST.dupli_datas = *(void ***)value;
+}
+
+static void duplidata_value_free(void *val)
+{
+ void **dupli_datas = val;
+ for (int i = 0; i < DST.enabled_engine_count; i++) {
+ MEM_SAFE_FREE(dupli_datas[i]);
+ }
+ MEM_freeN(val);
+}
+
+static void drw_duplidata_free(void)
+{
+ if (DST.dupli_ghash != NULL) {
+ BLI_ghash_free(DST.dupli_ghash, NULL, duplidata_value_free);
+ DST.dupli_ghash = NULL;
+ }
+}
+
+/* Return NULL if not a dupli or a pointer of pointer to the engine data */
+void **DRW_duplidata_get(void *vedata)
+{
+ if (DST.dupli_source == NULL) {
+ return NULL;
+ }
+ /* XXX Search engine index by using vedata array */
+ for (int i = 0; i < DST.enabled_engine_count; i++) {
+ if (DST.vedata_array[i] == vedata) {
+ return &DST.dupli_datas[i];
+ }
+ }
+ return NULL;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name ViewLayers (DRW_scenelayer)
* \{ */
@@ -1045,8 +1108,8 @@ static void drw_engines_init(void)
static void drw_engines_cache_init(void)
{
- int enabled_engine_count = BLI_listbase_count(&DST.enabled_engines);
- DST.vedata_array = MEM_mallocN(sizeof(void *) * enabled_engine_count, __func__);
+ DST.enabled_engine_count = BLI_listbase_count(&DST.enabled_engines);
+ DST.vedata_array = MEM_mallocN(sizeof(void *) * DST.enabled_engine_count, __func__);
int i = 0;
for (LinkData *link = DST.enabled_engines.first; link; link = link->next, i++) {
@@ -1586,11 +1649,13 @@ void DRW_draw_render_loop_ex(struct Depsgraph *depsgraph,
}
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
drw_engines_cache_populate(ob);
}
DEG_OBJECT_ITER_END;
}
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
@@ -2304,12 +2369,14 @@ void DRW_draw_select_loop(struct Depsgraph *depsgraph,
}
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
drw_engines_cache_populate(ob);
}
}
DEG_OBJECT_ITER_END;
}
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
@@ -2404,10 +2471,12 @@ static void drw_draw_depth_loop_imp(void)
DST.dupli_parent = data_.dupli_parent;
DST.dupli_source = data_.dupli_object_current;
+ drw_duplidata_load(DST.dupli_source);
drw_engines_cache_populate(ob);
}
DEG_OBJECT_ITER_END;
+ drw_duplidata_free();
drw_engines_cache_finish();
DRW_render_instance_buffer_finish();
diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h
index 6dd112e3ad7..e592101b10c 100644
--- a/source/blender/draw/intern/draw_manager.h
+++ b/source/blender/draw/intern/draw_manager.h
@@ -329,6 +329,9 @@ typedef struct DRWManager {
uchar state_cache_id; /* Could be larger but 254 view changes is already a lot! */
struct DupliObject *dupli_source;
struct Object *dupli_parent;
+ struct Object *dupli_origin;
+ struct GHash *dupli_ghash;
+ void **dupli_datas; /* Array of dupli_data (one for each enabled engine) to handle duplis. */
/* Rendering state */
GPUShader *shader;
@@ -365,6 +368,7 @@ typedef struct DRWManager {
ListBase enabled_engines; /* RenderEngineType */
void **vedata_array; /* ViewportEngineData */
+ int enabled_engine_count; /* Length of enabled_engines list. */
bool buffer_finish_called; /* Avoid bad usage of DRW_render_instance_buffer_finish */