From 873d7f7e14e080f75e75ed7c6c07f326e588cecb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Foucault?= Date: Tue, 10 Jul 2018 14:14:55 +0200 Subject: DrawData: Change drawdata to a generic struct shared accross ID types This makes tagging much more generic and make the world updates more in line with the new tagging system (Depsgraph). --- source/blender/blenkernel/BKE_world.h | 6 - source/blender/blenkernel/intern/object.c | 11 +- source/blender/blenkernel/intern/world.c | 13 +- source/blender/depsgraph/CMakeLists.txt | 1 + .../depsgraph/intern/builder/deg_builder_nodes.cc | 4 +- .../intern/eval/deg_eval_copy_on_write.cc | 25 ++-- .../depsgraph/intern/eval/deg_eval_flush.cc | 10 +- source/blender/draw/DRW_engine.h | 3 + source/blender/draw/engines/eevee/eevee_data.c | 72 +++++++---- source/blender/draw/engines/eevee/eevee_engine.c | 27 +++- .../blender/draw/engines/eevee/eevee_lightprobes.c | 3 +- source/blender/draw/engines/eevee/eevee_private.h | 12 +- .../draw/engines/workbench/workbench_deferred.c | 12 +- .../draw/engines/workbench/workbench_forward.c | 8 +- .../draw/engines/workbench/workbench_private.h | 8 +- source/blender/draw/intern/DRW_render.h | 15 +-- source/blender/draw/intern/draw_manager.c | 142 +++++++++++++++++---- source/blender/draw/modes/object_mode.c | 12 +- source/blender/editors/render/render_update.c | 3 - source/blender/makesdna/DNA_ID.h | 21 +++ source/blender/makesdna/DNA_object_types.h | 18 +-- source/blender/makesdna/DNA_world_types.h | 4 +- 22 files changed, 280 insertions(+), 150 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h index f703fefec97..6a9a75828e5 100644 --- a/source/blender/blenkernel/BKE_world.h +++ b/source/blender/blenkernel/BKE_world.h @@ -44,10 +44,4 @@ struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld); struct World *BKE_world_localize(struct World *wrld); void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local); -/* Evaluation. */ - -struct Depsgraph; - -void BKE_world_eval(struct Depsgraph *depsgraph, struct World *world); - #endif diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index a7c13ab2a81..95e408f593e 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -424,6 +424,8 @@ void BKE_object_free(Object *ob) { BKE_animdata_free((ID *)ob, false); + DRW_drawdata_free((ID *)ob); + /* BKE__free shall never touch to ID->us. Never ever. */ BKE_object_free_modifiers(ob, LIB_ID_CREATE_NO_USER_REFCOUNT); @@ -451,13 +453,6 @@ void BKE_object_free(Object *ob) sbFree(ob); - for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) { - if (oed->free != NULL) { - oed->free(oed); - } - } - BLI_freelistN(&ob->drawdata); - BKE_sculptsession_free(ob); BLI_freelistN(&ob->pc_ids); @@ -1210,7 +1205,7 @@ void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_ ob_dst->derivedFinal = NULL; BLI_listbase_clear(&ob_dst->gpulamp); - BLI_listbase_clear(&ob_dst->drawdata); + BLI_listbase_clear((ListBase *)&ob_dst->drawdata); BLI_listbase_clear(&ob_dst->pc_ids); ob_dst->avs = ob_src->avs; diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c index 69096ad7a08..3e1a9a4f57b 100644 --- a/source/blender/blenkernel/intern/world.c +++ b/source/blender/blenkernel/intern/world.c @@ -53,6 +53,8 @@ #include "BKE_node.h" #include "BKE_world.h" +#include "DRW_engine.h" + #include "DEG_depsgraph.h" #include "GPU_material.h" @@ -62,6 +64,8 @@ void BKE_world_free(World *wrld) { BKE_animdata_free((ID *)wrld, false); + DRW_drawdata_free((ID *)wrld); + /* is no lib link block, but world extension */ if (wrld->nodetree) { ntreeFreeTree(wrld->nodetree); @@ -119,6 +123,7 @@ void BKE_world_copy_data(Main *bmain, World *wrld_dst, const World *wrld_src, co } BLI_listbase_clear(&wrld_dst->gpumaterial); + BLI_listbase_clear((ListBase *)&wrld_dst->drawdata); if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) { BKE_previewimg_id_copy(&wrld_dst->id, &wrld_src->id); @@ -154,6 +159,7 @@ World *BKE_world_localize(World *wrld) wrldn->preview = NULL; BLI_listbase_clear(&wrldn->gpumaterial); + BLI_listbase_clear((ListBase *)&wrldn->drawdata); return wrldn; } @@ -163,10 +169,3 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local) BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local); } -void BKE_world_eval(struct Depsgraph *depsgraph, World *world) -{ - DEG_debug_print_eval(depsgraph, __func__, world->id.name, world); - if (!BLI_listbase_is_empty(&world->gpumaterial)) { - world->update_flag = 1; - } -} diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt index 0673a3177b7..185a98f2a2b 100644 --- a/source/blender/depsgraph/CMakeLists.txt +++ b/source/blender/depsgraph/CMakeLists.txt @@ -28,6 +28,7 @@ set(INC ../blenkernel ../blenlib ../bmesh + ../draw ../makesdna ../makesrna ../modifiers diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc index cb455130d4c..ab7ddb507a0 100644 --- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc +++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc @@ -873,9 +873,7 @@ void DepsgraphNodeBuilder::build_world(World *world) /* world itself */ add_operation_node(&world->id, DEG_NODE_TYPE_SHADING, - function_bind(BKE_world_eval, - _1, - get_cow_datablock(world)), + NULL, DEG_OPCODE_WORLD_UPDATE); /* world's nodetree */ if (world->nodetree != NULL) { diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc index 447a8af6235..794cc22f4e3 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc @@ -70,6 +70,8 @@ extern "C" { #include "DNA_object_types.h" #include "DNA_particle_types.h" +#include "DRW_engine.h" + #ifdef NESTED_ID_NASTY_WORKAROUND # include "DNA_curve_types.h" # include "DNA_key_types.h" @@ -713,7 +715,6 @@ typedef struct ObjectRuntimeBackup { CurveCache *curve_cache; Object_Runtime runtime; short base_flag; - ListBase drawdata; } ObjectRuntimeBackup; /* Make a backup of object's evaluation runtime data, additionally @@ -740,9 +741,6 @@ static void deg_backup_object_runtime( object->curve_cache = NULL; /* Make a backup of base flags. */ object_runtime_backup->base_flag = object->base_flag; - /* Make backup of object draw data.*/ - object_runtime_backup->drawdata = object->drawdata; - BLI_listbase_clear(&object->drawdata); } static void deg_restore_object_runtime( @@ -782,8 +780,6 @@ static void deg_restore_object_runtime( object->curve_cache = object_runtime_backup->curve_cache; } object->base_flag = object_runtime_backup->base_flag; - /* Restore draw data. */ - object->drawdata = object_runtime_backup->drawdata; } ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, @@ -812,6 +808,8 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, */ ListBase gpumaterial_backup; ListBase *gpumaterial_ptr = NULL; + DrawDataList drawdata_backup; + DrawDataList *drawdata_ptr = NULL; ObjectRuntimeBackup object_runtime_backup = {NULL}; if (check_datablock_expanded(id_cow)) { switch (id_type) { @@ -847,9 +845,11 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, break; } case ID_OB: - deg_backup_object_runtime((Object *)id_cow, - &object_runtime_backup); + { + Object *ob = (Object *)id_cow; + deg_backup_object_runtime(ob, &object_runtime_backup); break; + } default: break; } @@ -857,6 +857,11 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, gpumaterial_backup = *gpumaterial_ptr; gpumaterial_ptr->first = gpumaterial_ptr->last = NULL; } + drawdata_ptr = DRW_drawdatalist_from_id(id_cow); + if (drawdata_ptr != NULL) { + drawdata_backup = *drawdata_ptr; + drawdata_ptr->first = drawdata_ptr->last = NULL; + } } deg_free_copy_on_write_datablock(id_cow); deg_expand_copy_on_write_datablock(depsgraph, id_node); @@ -864,6 +869,10 @@ ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, if (gpumaterial_ptr != NULL) { *gpumaterial_ptr = gpumaterial_backup; } + /* Restore DrawData. */ + if (drawdata_ptr != NULL) { + *drawdata_ptr = drawdata_backup; + } if (id_type == ID_OB) { deg_restore_object_runtime((Object *)id_cow, &object_runtime_backup); } diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc index bd31931d0a9..16cb1b394f6 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc @@ -46,6 +46,8 @@ extern "C" { #include "DNA_object_types.h" + +#include "DRW_engine.h" } /* extern "C" */ #include "DEG_depsgraph.h" @@ -219,12 +221,12 @@ BLI_INLINE OperationDepsNode *flush_schedule_children( void flush_engine_data_update(ID *id) { - if (GS(id->name) != ID_OB) { + DrawDataList *drawdata = DRW_drawdatalist_from_id(id); + if (drawdata == NULL) { return; } - Object *object = (Object *)id; - LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) { - engine_data->recalc |= id->recalc; + LISTBASE_FOREACH(DrawData *, dd, drawdata) { + dd->recalc |= id->recalc; } } diff --git a/source/blender/draw/DRW_engine.h b/source/blender/draw/DRW_engine.h index d126dcb71aa..d2a3bab9b20 100644 --- a/source/blender/draw/DRW_engine.h +++ b/source/blender/draw/DRW_engine.h @@ -138,4 +138,7 @@ void DRW_opengl_context_disable(void); void DRW_deferred_shader_remove(struct GPUMaterial *mat); +struct DrawDataList *DRW_drawdatalist_from_id(struct ID *id); +void DRW_drawdata_free(struct ID *id); + #endif /* __DRW_ENGINE_H__ */ diff --git a/source/blender/draw/engines/eevee/eevee_data.c b/source/blender/draw/engines/eevee/eevee_data.c index e9883cc3054..bf039871d52 100644 --- a/source/blender/draw/engines/eevee/eevee_data.c +++ b/source/blender/draw/engines/eevee/eevee_data.c @@ -91,9 +91,9 @@ EEVEE_ViewLayerData *EEVEE_view_layer_data_ensure(void) /* Object data. */ -static void eevee_object_data_init(ObjectEngineData *engine_data) +static void eevee_object_data_init(DrawData *dd) { - EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)engine_data; + EEVEE_ObjectEngineData *eevee_data = (EEVEE_ObjectEngineData *)dd; eevee_data->shadow_caster_id = -1; } @@ -102,15 +102,15 @@ EEVEE_ObjectEngineData *EEVEE_object_data_get(Object *ob) if (ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)) { return NULL; } - return (EEVEE_ObjectEngineData *)DRW_object_engine_data_get( - ob, &draw_engine_eevee_type); + return (EEVEE_ObjectEngineData *)DRW_drawdata_get( + &ob->id, &draw_engine_eevee_type); } EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob) { BLI_assert(!ELEM(ob->type, OB_LIGHTPROBE, OB_LAMP)); - return (EEVEE_ObjectEngineData *)DRW_object_engine_data_ensure( - ob, + return (EEVEE_ObjectEngineData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_eevee_type, sizeof(EEVEE_ObjectEngineData), eevee_object_data_init, @@ -119,18 +119,10 @@ EEVEE_ObjectEngineData *EEVEE_object_data_ensure(Object *ob) /* Light probe data. */ -static void eevee_lightprobe_data_init(ObjectEngineData *engine_data) +static void eevee_lightprobe_data_init(DrawData *dd) { - EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data; - ped->need_full_update = true; - ped->need_update = true; -} - -static void eevee_lightprobe_data_free(ObjectEngineData *engine_data) -{ - EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)engine_data; - - BLI_freelistN(&ped->captured_object_list); + EEVEE_LightProbeEngineData *ped = (EEVEE_LightProbeEngineData *)dd; + ped->need_update = false; } EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob) @@ -138,26 +130,26 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob) if (ob->type != OB_LIGHTPROBE) { return NULL; } - return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_get( - ob, &draw_engine_eevee_type); + return (EEVEE_LightProbeEngineData *)DRW_drawdata_get( + &ob->id, &draw_engine_eevee_type); } EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob) { BLI_assert(ob->type == OB_LIGHTPROBE); - return (EEVEE_LightProbeEngineData *)DRW_object_engine_data_ensure( - ob, + return (EEVEE_LightProbeEngineData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_eevee_type, sizeof(EEVEE_LightProbeEngineData), eevee_lightprobe_data_init, - eevee_lightprobe_data_free); + NULL); } /* Lamp data. */ -static void eevee_lamp_data_init(ObjectEngineData *engine_data) +static void eevee_lamp_data_init(DrawData *dd) { - EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)engine_data; + EEVEE_LampEngineData *led = (EEVEE_LampEngineData *)dd; led->need_update = true; led->prev_cube_shadow_id = -1; } @@ -167,17 +159,41 @@ EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob) if (ob->type != OB_LAMP) { return NULL; } - return (EEVEE_LampEngineData *)DRW_object_engine_data_get( - ob, &draw_engine_eevee_type); + return (EEVEE_LampEngineData *)DRW_drawdata_get( + &ob->id, &draw_engine_eevee_type); } EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob) { BLI_assert(ob->type == OB_LAMP); - return (EEVEE_LampEngineData *)DRW_object_engine_data_ensure( - ob, + return (EEVEE_LampEngineData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_eevee_type, sizeof(EEVEE_LampEngineData), eevee_lamp_data_init, NULL); } + +/* World data. */ + +static void eevee_world_data_init(DrawData *dd) +{ + EEVEE_WorldEngineData *wed = (EEVEE_WorldEngineData *)dd; + wed->dd.recalc |= 1; +} + +EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo) +{ + return (EEVEE_WorldEngineData *)DRW_drawdata_get( + &wo->id, &draw_engine_eevee_type); +} + +EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo) +{ + return (EEVEE_WorldEngineData *)DRW_drawdata_ensure( + &wo->id, + &draw_engine_eevee_type, + sizeof(EEVEE_WorldEngineData), + eevee_world_data_init, + NULL); +} diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c index 99adc21bf56..70af3b4067c 100644 --- a/source/blender/draw/engines/eevee/eevee_engine.c +++ b/source/blender/draw/engines/eevee/eevee_engine.c @@ -365,21 +365,31 @@ static void eevee_view_update(void *vedata) static void eevee_id_object_update(void *UNUSED(vedata), Object *object) { - /* This is a bit mask of components which update is to be ignored. */ EEVEE_LightProbeEngineData *ped = EEVEE_lightprobe_data_get(object); - if (ped != NULL && ped->engine_data.recalc != 0) { + if (ped != NULL && ped->dd.recalc != 0) { ped->need_full_update = true; - ped->engine_data.recalc = 0; + ped->dd.recalc = 0; } EEVEE_LampEngineData *led = EEVEE_lamp_data_get(object); - if (led != NULL && led->engine_data.recalc != 0) { + if (led != NULL && led->dd.recalc != 0) { led->need_update = true; - led->engine_data.recalc = 0; + led->dd.recalc = 0; } EEVEE_ObjectEngineData *oedata = EEVEE_object_data_get(object); - if (oedata != NULL && oedata->engine_data.recalc != 0) { + if (oedata != NULL && oedata->dd.recalc != 0) { oedata->need_update = true; - oedata->engine_data.recalc = 0; + oedata->dd.recalc = 0; + } +} + +static void eevee_id_world_update(void *vedata, World *wo) +{ + EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl; + + EEVEE_WorldEngineData *wedata = EEVEE_world_data_ensure(wo); + + if (wedata != NULL && wedata->dd.recalc != 0) { + wedata->dd.recalc = 0; } } @@ -387,6 +397,9 @@ static void eevee_id_update(void *vedata, ID *id) { /* Handle updates based on ID type. */ switch (GS(id->name)) { + case ID_WO: + eevee_id_world_update(vedata, (World *)id); + break; case ID_OB: eevee_id_object_update(vedata, (Object *)id); break; diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index c4cf56483fa..95b015cb044 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -451,13 +451,12 @@ void EEVEE_lightprobes_cache_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedat } } - if (wo->update_flag != 0 || pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) { + if (pinfo->prev_world != wo || pinfo->prev_wo_sh_compiled != wo_sh_compiled) { pinfo->update_world |= PROBE_UPDATE_ALL; pinfo->studiolight_index = 0; pinfo->prev_wo_sh_compiled = wo_sh_compiled; pinfo->prev_world = wo; } - wo->update_flag = 0; } else if (pinfo->prev_world) { pinfo->update_world |= PROBE_UPDATE_ALL; diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h index ef1d03c244e..fe837baf20e 100644 --- a/source/blender/draw/engines/eevee/eevee_private.h +++ b/source/blender/draw/engines/eevee/eevee_private.h @@ -711,7 +711,7 @@ typedef struct EEVEE_ShadowCascadeData { * It works with even if the object is in multiple layers * because we don't get the same "Object *" for each layer. */ typedef struct EEVEE_LampEngineData { - ObjectEngineData engine_data; + DrawData dd; bool need_update; /* This needs to be out of the union to avoid undefined behaviour. */ @@ -724,7 +724,7 @@ typedef struct EEVEE_LampEngineData { } EEVEE_LampEngineData; typedef struct EEVEE_LightProbeEngineData { - ObjectEngineData engine_data; + DrawData dd; /* 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 @@ -752,7 +752,7 @@ typedef struct EEVEE_LightProbeEngineData { } EEVEE_LightProbeEngineData; typedef struct EEVEE_ObjectEngineData { - ObjectEngineData engine_data; + DrawData dd; Object *ob; /* self reference */ EEVEE_LightProbeVisTest *test_data; @@ -762,6 +762,10 @@ typedef struct EEVEE_ObjectEngineData { uint shadow_caster_id; } EEVEE_ObjectEngineData; +typedef struct EEVEE_WorldEngineData { + DrawData dd; +} EEVEE_WorldEngineData; + /* *********************************** */ typedef struct EEVEE_Data { @@ -810,6 +814,8 @@ EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_get(Object *ob); EEVEE_LightProbeEngineData *EEVEE_lightprobe_data_ensure(Object *ob); EEVEE_LampEngineData *EEVEE_lamp_data_get(Object *ob); EEVEE_LampEngineData *EEVEE_lamp_data_ensure(Object *ob); +EEVEE_WorldEngineData *EEVEE_world_data_get(World *wo); +EEVEE_WorldEngineData *EEVEE_world_data_ensure(World *wo); /* eevee_materials.c */ struct GPUTexture *EEVEE_materials_get_util_tex(void); /* XXX */ diff --git a/source/blender/draw/engines/workbench/workbench_deferred.c b/source/blender/draw/engines/workbench/workbench_deferred.c index d153728a000..784ed861014 100644 --- a/source/blender/draw/engines/workbench/workbench_deferred.c +++ b/source/blender/draw/engines/workbench/workbench_deferred.c @@ -258,9 +258,9 @@ static struct GPUTexture *create_jitter_texture(int num_samples) /* Functions */ -static void workbench_init_object_data(ObjectEngineData *engine_data) +static void workbench_init_object_data(DrawData *dd) { - WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data; + WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd; data->object_id = ((e_data.next_object_id++) & 0xff) + 1; data->shadow_bbox_dirty = true; } @@ -561,8 +561,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data( WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_MaterialData *material; - WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( - ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); + WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); WORKBENCH_MaterialData material_template; /* Solid */ @@ -731,8 +731,8 @@ void workbench_deferred_solid_cache_populate(WORKBENCH_Data *vedata, Object *ob) // DRW_shgroup_call_sculpt_add(wpd->shadow_shgrp, ob, ob->obmat); } else { - WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( - ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); + WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); if (studiolight_object_cast_visible_shadow(wpd, ob, engine_object_data)) { diff --git a/source/blender/draw/engines/workbench/workbench_forward.c b/source/blender/draw/engines/workbench/workbench_forward.c index 24ba3aa8981..e921b2ac2f7 100644 --- a/source/blender/draw/engines/workbench/workbench_forward.c +++ b/source/blender/draw/engines/workbench/workbench_forward.c @@ -126,9 +126,9 @@ static char *workbench_build_forward_composite_frag(void) return str; } -static void workbench_init_object_data(ObjectEngineData *engine_data) +static void workbench_init_object_data(DrawData *dd) { - WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)engine_data; + WORKBENCH_ObjectData *data = (WORKBENCH_ObjectData *)dd; data->object_id = ((e_data.next_object_id++) & 0xff) + 1; } @@ -139,8 +139,8 @@ static WORKBENCH_MaterialData *get_or_create_material_data( WORKBENCH_PassList *psl = vedata->psl; WORKBENCH_PrivateData *wpd = stl->g_data; WORKBENCH_MaterialData *material; - WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_object_engine_data_ensure( - ob, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); + WORKBENCH_ObjectData *engine_object_data = (WORKBENCH_ObjectData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_workbench_solid, sizeof(WORKBENCH_ObjectData), &workbench_init_object_data, NULL); WORKBENCH_MaterialData material_template; DRWShadingGroup *grp; diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h index a8fa1beb3b7..4210e03f470 100644 --- a/source/blender/draw/engines/workbench/workbench_private.h +++ b/source/blender/draw/engines/workbench/workbench_private.h @@ -201,12 +201,8 @@ typedef struct WORKBENCH_MaterialData { } WORKBENCH_MaterialData; typedef struct WORKBENCH_ObjectData { - struct ObjectEngineData *next, *prev; - struct DrawEngineType *engine_type; - /* Only nested data, NOT the engine data itself. */ - ObjectEngineDataFreeCb free; - /* Accumulated recalc flags, which corresponds to ID->recalc flags. */ - int recalc; + DrawData dd; + /* Shadow direction in local object space. */ float shadow_dir[3], shadow_depth; float shadow_min[3], shadow_max[3]; /* Min, max in shadow space */ diff --git a/source/blender/draw/intern/DRW_render.h b/source/blender/draw/intern/DRW_render.h index f732082018d..e0c8cb36e2f 100644 --- a/source/blender/draw/intern/DRW_render.h +++ b/source/blender/draw/intern/DRW_render.h @@ -44,6 +44,7 @@ #include "DNA_lamp_types.h" #include "DNA_material_types.h" #include "DNA_scene_types.h" +#include "DNA_world_types.h" #include "GPU_framebuffer.h" #include "GPU_texture.h" @@ -460,16 +461,14 @@ void **DRW_view_layer_engine_data_ensure_ex( void **DRW_view_layer_engine_data_ensure( DrawEngineType *engine_type, void (*callback)(void *storage)); -/* Objects */ -ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type); -ObjectEngineData *DRW_object_engine_data_ensure( - Object *ob, +/* DrawData */ +DrawData *DRW_drawdata_get(ID *ib, DrawEngineType *engine_type); +DrawData *DRW_drawdata_ensure( + ID *id, DrawEngineType *engine_type, size_t size, - ObjectEngineDataInitCb init_cb, - ObjectEngineDataFreeCb free_cb); -struct LampEngineData *DRW_lamp_engine_data_ensure(Object *ob, struct RenderEngineType *engine_type); -void DRW_lamp_engine_data_free(struct LampEngineData *led); + DrawDataInitCb init_cb, + DrawDataFreeCb free_cb); /* Settings */ bool DRW_object_is_renderable(struct Object *ob); diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c index a1e44e479d4..311a223dcdd 100644 --- a/source/blender/draw/intern/draw_manager.c +++ b/source/blender/draw/intern/draw_manager.c @@ -44,6 +44,7 @@ #include "DNA_camera_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_world_types.h" #include "ED_space_api.h" #include "ED_screen.h" @@ -696,34 +697,96 @@ void **DRW_view_layer_engine_data_ensure(DrawEngineType *engine_type, void (*cal /* -------------------------------------------------------------------- */ -/** \name Objects (DRW_object) +/** \name Draw Data (DRW_drawdata) * \{ */ -ObjectEngineData *DRW_object_engine_data_get(Object *ob, DrawEngineType *engine_type) +/* Used for DRW_drawdata_from_id() + * All ID-datablocks which have their own 'local' DrawData + * should have the same arrangement in their structs. + */ +typedef struct IdDdtTemplate { + ID id; + struct AnimData *adt; + DrawDataList drawdata; +} IdDdtTemplate; + +/* Check if ID can have AnimData */ +static bool id_type_can_have_drawdata(const short id_type) +{ + /* Only some ID-blocks have this info for now */ + /* TODO: finish adding this for the other blocktypes */ + switch (id_type) { + /* has DrawData */ + case ID_OB: + case ID_WO: + return true; + + /* no DrawData */ + default: + return false; + } +} + +static bool id_can_have_drawdata(const ID *id) +{ + /* sanity check */ + if (id == NULL) + return false; + + return id_type_can_have_drawdata(GS(id->name)); +} + +/* Get DrawData from the given ID-block. In order for this to work, we assume that + * the DrawData pointer is stored in the struct in the same fashion as in IdDdtTemplate. + */ +DrawDataList *DRW_drawdatalist_from_id(ID *id) +{ + /* only some ID-blocks have this info for now, so we cast the + * types that do to be of type IdDdtTemplate, and extract the + * DrawData that way + */ + if (id_can_have_drawdata(id)) { + IdDdtTemplate *idt = (IdDdtTemplate *)id; + return &idt->drawdata; + } + else + return NULL; +} + +DrawData *DRW_drawdata_get(ID *id, DrawEngineType *engine_type) { - for (ObjectEngineData *oed = ob->drawdata.first; oed; oed = oed->next) { - if (oed->engine_type == engine_type) { - return oed; + DrawDataList *drawdata = DRW_drawdatalist_from_id(id); + + if (drawdata == NULL) + return NULL; + + LISTBASE_FOREACH(DrawData *, dd, drawdata) { + if (dd->engine_type == engine_type) { + return dd; } } return NULL; } -ObjectEngineData *DRW_object_engine_data_ensure( - Object *ob, +DrawData *DRW_drawdata_ensure( + ID *id, DrawEngineType *engine_type, size_t size, - ObjectEngineDataInitCb init_cb, - ObjectEngineDataFreeCb free_cb) + DrawDataInitCb init_cb, + DrawDataFreeCb free_cb) { - BLI_assert(size >= sizeof(ObjectEngineData)); + BLI_assert(size >= sizeof(DrawData)); + BLI_assert(id_can_have_drawdata(id)); /* Try to re-use existing data. */ - ObjectEngineData *oed = DRW_object_engine_data_get(ob, engine_type); - if (oed != NULL) { - return oed; + DrawData *dd = DRW_drawdata_get(id, engine_type); + if (dd != NULL) { + return dd; } + + DrawDataList *drawdata = DRW_drawdatalist_from_id(id); + /* Allocate new data. */ - if ((ob->base_flag & BASE_FROMDUPLI) != 0) { + if ((GS(id->name) == ID_OB) && (((Object *)id)->base_flag & BASE_FROMDUPLI) != 0) { /* NOTE: data is not persistent in this case. It is reset each redraw. */ BLI_assert(free_cb == NULL); /* No callback allowed. */ /* Round to sizeof(float) for DRW_instance_data_request(). */ @@ -734,21 +797,37 @@ ObjectEngineData *DRW_object_engine_data_ensure( if (DST.object_instance_data[fsize] == NULL) { DST.object_instance_data[fsize] = DRW_instance_data_request(DST.idatalist, fsize); } - oed = (ObjectEngineData *)DRW_instance_data_next(DST.object_instance_data[fsize]); - memset(oed, 0, size); + dd = (DrawData *)DRW_instance_data_next(DST.object_instance_data[fsize]); + memset(dd, 0, size); } else { - oed = MEM_callocN(size, "ObjectEngineData"); + dd = MEM_callocN(size, "DrawData"); } - oed->engine_type = engine_type; - oed->free = free_cb; + dd->engine_type = engine_type; + dd->free = free_cb; /* Perform user-side initialization, if needed. */ if (init_cb != NULL) { - init_cb(oed); + init_cb(dd); } /* Register in the list. */ - BLI_addtail(&ob->drawdata, oed); - return oed; + BLI_addtail((ListBase *)drawdata, dd); + return dd; +} + +void DRW_drawdata_free(ID *id) +{ + DrawDataList *drawdata = DRW_drawdatalist_from_id(id); + + if (drawdata == NULL) + return; + + LISTBASE_FOREACH(DrawData *, dd, drawdata) { + if (dd->free != NULL) { + dd->free(dd); + } + } + + BLI_freelistN((ListBase *)drawdata); } /** \} */ @@ -794,6 +873,22 @@ static void drw_engines_cache_init(void) } } +static void drw_engines_world_update(Scene *scene) +{ + if (scene->world == NULL) { + return; + } + + for (LinkData *link = DST.enabled_engines.first; link; link = link->next) { + DrawEngineType *engine = link->data; + ViewportEngineData *data = drw_viewport_engine_data_ensure(engine); + + if (engine->id_update) { + engine->id_update(data, &scene->world->id); + } + } +} + static void drw_engines_cache_populate(Object *ob) { DST.ob_state = NULL; @@ -1273,6 +1368,7 @@ void DRW_draw_render_loop_ex( { PROFILE_START(stime); drw_engines_cache_init(); + drw_engines_world_update(scene); const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) @@ -1697,6 +1793,7 @@ void DRW_draw_select_loop( { drw_engines_cache_init(); + drw_engines_world_update(scene); if (use_obedit) { #if 0 @@ -1891,6 +1988,7 @@ void DRW_draw_depth_loop( { drw_engines_cache_init(); + drw_engines_world_update(scene); const int object_type_exclude_viewport = v3d->object_type_exclude_viewport; DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN(depsgraph, ob) diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index da44d9d8c0b..359b4eb77e4 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -1355,14 +1355,14 @@ static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, ViewLayer *vie static float zero = 0.0f; typedef struct LampEngineData { - ObjectEngineData engine_data; + DrawData dd; float shape_mat[4][4]; float spot_blend_mat[4][4]; } LampEngineData; LampEngineData *lamp_engine_data = - (LampEngineData *)DRW_object_engine_data_ensure( - ob, + (LampEngineData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_object_type, sizeof(LampEngineData), NULL, @@ -1712,7 +1712,7 @@ static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, ViewLayer * } typedef struct OBJECT_LightProbeEngineData { - ObjectEngineData engine_data; + DrawData dd; float prb_mats[6][4][4]; float probe_cube_mat[4][4]; @@ -1733,8 +1733,8 @@ static void DRW_shgroup_lightprobe(OBJECT_StorageList *stl, OBJECT_PassList *psl int theme_id = DRW_object_wire_theme_get(ob, view_layer, &color); OBJECT_LightProbeEngineData *prb_data = - (OBJECT_LightProbeEngineData *)DRW_object_engine_data_ensure( - ob, + (OBJECT_LightProbeEngineData *)DRW_drawdata_ensure( + &ob->id, &draw_engine_object_type, sizeof(OBJECT_LightProbeEngineData), NULL, diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 97fd7295a7b..e473b98b4a1 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -294,9 +294,6 @@ static void world_changed(Main *UNUSED(bmain), World *wo) /* icons */ BKE_icon_changed(BKE_icon_id_ensure(&wo->id)); - /* XXX temporary flag waiting for depsgraph proper tagging */ - wo->update_flag = 1; - /* glsl */ if (wo->id.recalc & ID_RECALC) { if (!BLI_listbase_is_empty(&defmaterial.gpumaterial)) { diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index fa97fd53f32..ec71f28cb23 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -45,6 +45,27 @@ struct ID; struct PackedFile; struct GPUTexture; +/* Runtime display data */ +struct DrawData; +typedef void (*DrawDataInitCb)(struct DrawData *engine_data); +typedef void (*DrawDataFreeCb)(struct DrawData *engine_data); + +# +# +typedef struct DrawData { + struct DrawData *next, *prev; + struct DrawEngineType *engine_type; + /* Only nested data, NOT the engine data itself. */ + DrawDataFreeCb free; + /* Accumulated recalc flags, which corresponds to ID->recalc flags. */ + int recalc; +} DrawData; + +typedef struct DrawDataList { + struct DrawData *first, *last; +} DrawDataList; + + typedef struct IDPropertyData { void *pointer; ListBase group; diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3bcc0fb6dcc..999ebe0ccc3 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -76,22 +76,6 @@ typedef struct bFaceMap { char pad[7]; } bFaceMap; -/* Object Runtime display data */ -struct ObjectEngineData; -typedef void (*ObjectEngineDataInitCb)(struct ObjectEngineData *engine_data); -typedef void (*ObjectEngineDataFreeCb)(struct ObjectEngineData *engine_data); - -# -# -typedef struct ObjectEngineData { - struct ObjectEngineData *next, *prev; - struct DrawEngineType *engine_type; - /* Only nested data, NOT the engine data itself. */ - ObjectEngineDataFreeCb free; - /* Accumulated recalc flags, which corresponds to ID->recalc flags. */ - int recalc; -} ObjectEngineData; - #define MAX_VGROUP_NAME 64 /* bDeformGroup->flag */ @@ -163,6 +147,7 @@ typedef struct Object_Runtime { typedef struct Object { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ + struct DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */ struct SculptSession *sculpt; @@ -312,7 +297,6 @@ typedef struct Object { struct PreviewImage *preview; - ListBase drawdata; /* runtime, ObjectEngineData */ int pad6; int select_color; diff --git a/source/blender/makesdna/DNA_world_types.h b/source/blender/makesdna/DNA_world_types.h index 2e38a402abb..7769833a835 100644 --- a/source/blender/makesdna/DNA_world_types.h +++ b/source/blender/makesdna/DNA_world_types.h @@ -51,6 +51,7 @@ struct MTex; typedef struct World { ID id; struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */ + DrawDataList drawdata; /* runtime (must be immediately after id for utilities to use it). */ char _pad0[4]; short texact, mistype; @@ -81,8 +82,7 @@ typedef struct World { short flag, pad3[3]; struct Ipo *ipo DNA_DEPRECATED; /* old animation system, deprecated for 2.5 */ - short pr_texture, use_nodes, pad; - short update_flag; /* XXX temporary flag waiting for depsgraph proper tagging */ + short pr_texture, use_nodes, pad[2]; /* previews */ struct PreviewImage *preview; -- cgit v1.2.3