diff options
author | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-11-28 19:05:52 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey.vfx@gmail.com> | 2017-11-29 13:01:08 +0300 |
commit | a6b6689c0ab769bfdf4db932e4afd75ac0d42e10 (patch) | |
tree | 7a6b8a135ad7ac8c383b26b1ab330c2f9b594dfc /source/blender/draw | |
parent | 6208ce2e0a60fdddc1fb12ae1a2f84dcdcd32d90 (diff) |
Draw manager: Listen to depsgraph's ID update callbacks
This replaces dedicated flag which wasn't clean who sets it and who clears it,
and which was also trying to re-implement existing functionality in a way.
Flushing is not currently very efficient but there are ways to speed this up
a lot, but needs more investigation.
Diffstat (limited to 'source/blender/draw')
-rw-r--r-- | source/blender/draw/DRW_engine.h | 2 | ||||
-rw-r--r-- | source/blender/draw/engines/basic/basic_engine.c | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/clay/clay_engine.c | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_data.c | 1 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_engine.c | 23 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_lightprobes.c | 4 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_lights.c | 4 | ||||
-rw-r--r-- | source/blender/draw/engines/eevee/eevee_private.h | 12 | ||||
-rw-r--r-- | source/blender/draw/engines/external/external_engine.c | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/DRW_render.h | 1 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_manager.c | 42 |
11 files changed, 83 insertions, 9 deletions
diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index f3e1bf5ceac..ba0f8681f10 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -34,6 +34,7 @@ struct Main; struct Material; struct Scene; struct DrawEngineType; +struct ID; struct IDProperty; struct bContext; struct Object; @@ -78,6 +79,7 @@ typedef struct DRWUpdateContext { struct RenderEngineType *engine_type; } DRWUpdateContext; void DRW_notify_view_update(const DRWUpdateContext *update_ctx); +void DRW_notify_id_update(const DRWUpdateContext *update_ctx, struct ID *id); void DRW_draw_view(const struct bContext *C); diff --git a/source/blender/draw/engines/basic/basic_engine.c b/source/blender/draw/engines/basic/basic_engine.c index 92ffa8a1794..b41420ab95b 100644 --- a/source/blender/draw/engines/basic/basic_engine.c +++ b/source/blender/draw/engines/basic/basic_engine.c @@ -263,6 +263,7 @@ DrawEngineType draw_engine_basic_type = { NULL, &BASIC_draw_scene, NULL, + NULL, }; /* Note: currently unused, we may want to register so we can see this when debugging the view. */ diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c index fe81e1e484c..27ae4639e8b 100644 --- a/source/blender/draw/engines/clay/clay_engine.c +++ b/source/blender/draw/engines/clay/clay_engine.c @@ -916,6 +916,7 @@ DrawEngineType draw_engine_clay_type = { NULL, &CLAY_draw_scene, NULL, + NULL, }; RenderEngineType DRW_engine_viewport_clay_type = { diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index 6b95844591d..c105567ddb3 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -109,6 +109,7 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob) if (*pedata == NULL) { *pedata = MEM_callocN(sizeof(**pedata), "EEVEE_LightProbeEngineData"); + (*pedata)->need_full_update = true; (*pedata)->need_update = true; } diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index f059fbe2268..300a10d7b09 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -128,8 +128,6 @@ static void EEVEE_cache_populate(void *vedata, Object *ob) } else { BLI_addtail(&sldata->shadow_casters, BLI_genericNodeN(ob)); - EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(ob); - oedata->need_update = ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0); } } } @@ -287,6 +285,26 @@ static void EEVEE_view_update(void *vedata) } } +static void EEVEE_id_update(void *UNUSED(vedata), ID *id) +{ + const ID_Type id_type = GS(id->name); + if (id_type == ID_OB) { + Object *object = (Object *)id; + EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object); + if (ped != NULL) { + ped->need_full_update = true; + } + EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object); + if (led != NULL) { + led->need_update = true; + } + EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object); + if (oedata != NULL) { + oedata->need_update = true; + } + } +} + static void EEVEE_engine_free(void) { EEVEE_bloom_free(); @@ -395,6 +413,7 @@ DrawEngineType draw_engine_eevee_type = { &EEVEE_draw_scene, NULL, //&EEVEE_draw_scene &EEVEE_view_update, + &EEVEE_id_update, }; RenderEngineType DRW_engine_viewport_eevee_type = { diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index a58e6e20c58..1441c173a21 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -490,7 +490,9 @@ void EEVEE_lightprobes_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) ped->num_cell = probe->grid_resolution_x * probe->grid_resolution_y * probe->grid_resolution_z; - if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) { + if (ped->need_full_update) { + ped->need_full_update = false; + ped->need_update = true; ped->probe_id = 0; diff --git a/source/blender/draw/engines/eevee/eevee_lights.c b/source/blender/draw/engines/eevee/eevee_lights.c index e57c5a6db41..7cc3e86384e 100644 --- a/source/blender/draw/engines/eevee/eevee_lights.c +++ b/source/blender/draw/engines/eevee/eevee_lights.c @@ -257,10 +257,6 @@ void EEVEE_lights_cache_add(EEVEE_ViewLayerData *sldata, Object *ob) Lamp *la = (Lamp *)ob->data; EEVEE_LampEngineData *led = EEVEE_lamp_data_get(ob); - if ((ob->deg_update_flag & DEG_RUNTIME_DATA_UPDATE) != 0) { - led->need_update = true; - } - MEM_SAFE_FREE(led->storage); if (la->mode & (LA_SHAD_BUF | LA_SHAD_RAY)) { diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index 8e754e71506..281e9e2fce1 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -568,7 +568,19 @@ typedef struct EEVEE_LampEngineData { } EEVEE_LampEngineData; typedef struct EEVEE_LightProbeEngineData { + /* NOTE: need_full_update is set by dependency graph when the probe or it's + * object is updated. This triggers full probe update, including it's + * "progressive" GI refresh. + * + * need_update is always set to truth when need_full_update is tagged, but + * might also be forced to be kept truth during GI refresh stages. + * + * TODO(sergey): Is there a way to avoid two flags here, or at least make + * it more clear what's going on here? + */ + bool need_full_update; bool need_update; + bool ready_to_shade; int updated_cells; int updated_lvl; diff --git a/source/blender/draw/engines/external/external_engine.c b/source/blender/draw/engines/external/external_engine.c index bdf53fd3046..2127dbe1f63 100644 --- a/source/blender/draw/engines/external/external_engine.c +++ b/source/blender/draw/engines/external/external_engine.c @@ -217,6 +217,7 @@ DrawEngineType draw_engine_external_type = { NULL, &EXTERNAL_draw_scene, NULL, + NULL, }; /* Note: currently unused, we should not register unless we want to see this when debugging the view. */ diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index 793608c62a9..f9ee87dfd89 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -138,6 +138,7 @@ typedef struct DrawEngineType { void (*draw_scene)(void *vedata); void (*view_update)(void *vedata); + void (*id_update)(void *vedata, struct ID *id); } DrawEngineType; #ifndef __DRW_ENGINE_H__ diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index 5eb88123208..0986e4c48b4 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -3259,6 +3259,46 @@ void DRW_notify_view_update(const DRWUpdateContext *update_ctx) /** \} */ +/** \name ID Update + * \{ */ + +/* TODO(sergey): This code is run for each changed ID (including the ones which + * are changed indirectly via update flush. Need to find a way to make this to + * run really fast, hopefully without any memory allocations on a heap + * Idea here could be to run every known engine's id_update() and make them + * do nothing if there is no engine-specific data yet. + */ +void DRW_notify_id_update(const DRWUpdateContext *update_ctx, ID *id) +{ + RenderEngineType *engine_type = update_ctx->engine_type; + ARegion *ar = update_ctx->ar; + View3D *v3d = update_ctx->v3d; + RegionView3D *rv3d = ar->regiondata; + Scene *scene = update_ctx->scene; + ViewLayer *view_layer = update_ctx->view_layer; + if (rv3d->viewport == NULL) { + return; + } + /* Reset before using it. */ + memset(&DST, 0x0, sizeof(DST)); + DST.viewport = rv3d->viewport; + DST.draw_ctx = (DRWContextState){ + ar, rv3d, v3d, scene, view_layer, OBACT(view_layer), engine_type, NULL, + }; + DRW_engines_enable(scene, view_layer, engine_type); + for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { + DrawEngineType *draw_engine = link->data; + ViewportEngineData *data = DRW_viewport_engine_data_get(draw_engine); + if (draw_engine->id_update) { + draw_engine->id_update(data, id); + } + } + DST.viewport = NULL; + DRW_engines_disable(); +} + +/** \} */ + /* -------------------------------------------------------------------- */ /** \name Main Draw Loops (DRW_draw) @@ -3329,8 +3369,6 @@ void DRW_draw_render_loop_ex( DEG_OBJECT_ITER(graph, ob, DEG_OBJECT_ITER_FLAG_ALL); { DRW_engines_cache_populate(ob); - /* XXX find a better place for this. maybe Depsgraph? */ - ob->deg_update_flag = 0; } DEG_OBJECT_ITER_END |