Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/scene.c
| Show First 20 Lines • Show All 2,630 Lines • ▼ Show 20 Lines | |||||
| static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged) | static void scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain, bool only_if_tagged) | ||||
| { | { | ||||
| if (only_if_tagged && DEG_is_fully_evaluated(depsgraph)) { | if (only_if_tagged && DEG_is_fully_evaluated(depsgraph)) { | ||||
| return; | return; | ||||
| } | } | ||||
| Scene *scene = DEG_get_input_scene(depsgraph); | Scene *scene = DEG_get_input_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); | ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); | ||||
| bool used_multiple_passes = false; | |||||
| bool run_callbacks = DEG_id_type_any_updated(depsgraph); | bool run_callbacks = DEG_id_type_any_updated(depsgraph); | ||||
| if (run_callbacks) { | if (run_callbacks) { | ||||
| BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE); | BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_DEPSGRAPH_UPDATE_PRE); | ||||
| } | } | ||||
| for (int pass = 0; pass < 2; pass++) { | for (int pass = 0; pass < 2; pass++) { | ||||
| /* (Re-)build dependency graph if needed. */ | /* (Re-)build dependency graph if needed. */ | ||||
| Show All 20 Lines | if (run_callbacks) { | ||||
| * Should be safe because relations update is supposed to preserve flags of all IDs which are | * Should be safe because relations update is supposed to preserve flags of all IDs which are | ||||
| * still a part of the dependency graph. If an ID is kicked out of the dependency graph it | * still a part of the dependency graph. If an ID is kicked out of the dependency graph it | ||||
| * should also be fine because when/if it's added to another dependency graph it will need to | * should also be fine because when/if it's added to another dependency graph it will need to | ||||
| * be tagged for an update anyway. | * be tagged for an update anyway. | ||||
| * | * | ||||
| * If there are no relations changed by the callback this call will do nothing. */ | * If there are no relations changed by the callback this call will do nothing. */ | ||||
| DEG_graph_relations_update(depsgraph); | DEG_graph_relations_update(depsgraph); | ||||
| } | } | ||||
| /* Inform editors about possible changes. */ | |||||
| DEG_editors_update(bmain, depsgraph, scene, view_layer, false); | |||||
| /* If user callback did not tag anything for update we can skip second iteration. | /* If user callback did not tag anything for update we can skip second iteration. | ||||
| * Otherwise we update scene once again, but without running callbacks to bring | * Otherwise we update scene once again, but without running callbacks to bring | ||||
| * scene to a fully evaluated state with user modifications taken into account. */ | * scene to a fully evaluated state with user modifications taken into account. */ | ||||
| if (DEG_is_fully_evaluated(depsgraph)) { | if (DEG_is_fully_evaluated(depsgraph)) { | ||||
| break; | break; | ||||
| } | } | ||||
| /* Clear recalc flags for second pass, but back them up for editors update. */ | |||||
| const bool backup = true; | |||||
| DEG_ids_clear_recalc(depsgraph, backup); | |||||
| used_multiple_passes = true; | |||||
| run_callbacks = false; | run_callbacks = false; | ||||
| } | } | ||||
| /* Inform editors about changes, using recalc flags from both passes. */ | |||||
| if (used_multiple_passes) { | |||||
| DEG_ids_restore_recalc(depsgraph); | |||||
| } | |||||
| const bool is_time_update = false; | |||||
| DEG_editors_update(depsgraph, is_time_update); | |||||
| const bool backup = false; | |||||
| DEG_ids_clear_recalc(depsgraph, backup); | |||||
| } | } | ||||
| void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain) | void BKE_scene_graph_update_tagged(Depsgraph *depsgraph, Main *bmain) | ||||
| { | { | ||||
| scene_graph_update_tagged(depsgraph, bmain, false); | scene_graph_update_tagged(depsgraph, bmain, false); | ||||
| } | } | ||||
| void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain) | void BKE_scene_graph_evaluated_ensure(Depsgraph *depsgraph, Main *bmain) | ||||
| { | { | ||||
| scene_graph_update_tagged(depsgraph, bmain, true); | scene_graph_update_tagged(depsgraph, bmain, true); | ||||
| } | } | ||||
| /* applies changes right away, does all sets too */ | /* applies changes right away, does all sets too */ | ||||
| void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph) | void BKE_scene_graph_update_for_newframe_ex(Depsgraph *depsgraph, const bool clear_recalc) | ||||
| { | { | ||||
| Scene *scene = DEG_get_input_scene(depsgraph); | Scene *scene = DEG_get_input_scene(depsgraph); | ||||
| ViewLayer *view_layer = DEG_get_input_view_layer(depsgraph); | |||||
| Main *bmain = DEG_get_bmain(depsgraph); | Main *bmain = DEG_get_bmain(depsgraph); | ||||
| bool used_multiple_passes = false; | |||||
| /* Keep this first. */ | /* Keep this first. */ | ||||
| BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE); | BKE_callback_exec_id(bmain, &scene->id, BKE_CB_EVT_FRAME_CHANGE_PRE); | ||||
| for (int pass = 0; pass < 2; pass++) { | for (int pass = 0; pass < 2; pass++) { | ||||
| /* Update animated image textures for particles, modifiers, gpu, etc, | /* Update animated image textures for particles, modifiers, gpu, etc, | ||||
| * call this at the start so modifiers with textures don't lag 1 frame. | * call this at the start so modifiers with textures don't lag 1 frame. | ||||
| */ | */ | ||||
| Show All 20 Lines | for (int pass = 0; pass < 2; pass++) { | ||||
| if (pass == 0) { | if (pass == 0) { | ||||
| BKE_callback_exec_id_depsgraph(bmain, &scene->id, depsgraph, BKE_CB_EVT_FRAME_CHANGE_POST); | BKE_callback_exec_id_depsgraph(bmain, &scene->id, depsgraph, BKE_CB_EVT_FRAME_CHANGE_POST); | ||||
| /* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that | /* NOTE: Similar to this case in scene_graph_update_tagged(). Need to ensure that | ||||
| * DEG_editors_update() doesn't access freed memory of possibly removed ID. */ | * DEG_editors_update() doesn't access freed memory of possibly removed ID. */ | ||||
| DEG_graph_relations_update(depsgraph); | DEG_graph_relations_update(depsgraph); | ||||
| } | } | ||||
| /* Inform editors about possible changes. */ | |||||
| DEG_editors_update(bmain, depsgraph, scene, view_layer, true); | |||||
| /* If user callback did not tag anything for update we can skip second iteration. | /* If user callback did not tag anything for update we can skip second iteration. | ||||
| * Otherwise we update scene once again, but without running callbacks to bring | * Otherwise we update scene once again, but without running callbacks to bring | ||||
| * scene to a fully evaluated state with user modifications taken into account. */ | * scene to a fully evaluated state with user modifications taken into account. */ | ||||
| if (DEG_is_fully_evaluated(depsgraph)) { | if (DEG_is_fully_evaluated(depsgraph)) { | ||||
| break; | break; | ||||
| } | } | ||||
| /* Clear recalc flags for second pass, but back them up for editors update. */ | |||||
| const bool backup = true; | |||||
| DEG_ids_clear_recalc(depsgraph, backup); | |||||
| used_multiple_passes = true; | |||||
| } | |||||
| /* Inform editors about changes, using recalc flags from both passes. */ | |||||
| if (used_multiple_passes) { | |||||
| DEG_ids_restore_recalc(depsgraph); | |||||
| } | |||||
| const bool is_time_update = true; | |||||
| DEG_editors_update(depsgraph, is_time_update); | |||||
| /* Clear recalc flags, can be skipped for e.g. renderers that will read these | |||||
| * and clear the flags later. */ | |||||
| if (clear_recalc) { | |||||
| const bool backup = false; | |||||
| DEG_ids_clear_recalc(depsgraph, backup); | |||||
| } | } | ||||
| } | } | ||||
| void BKE_scene_graph_update_for_newframe(Depsgraph *depsgraph) | |||||
| { | |||||
| BKE_scene_graph_update_for_newframe_ex(depsgraph, true); | |||||
| } | |||||
| /** | /** | ||||
| * Ensures given scene/view_layer pair has a valid, up-to-date depsgraph. | * Ensures given scene/view_layer pair has a valid, up-to-date depsgraph. | ||||
| * | * | ||||
| * \warning Sets matching depsgraph as active, | * \warning Sets matching depsgraph as active, | ||||
| * so should only be called from the active editing context (usually, from operators). | * so should only be called from the active editing context (usually, from operators). | ||||
| */ | */ | ||||
| void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, ViewLayer *view_layer) | void BKE_scene_view_layer_graph_evaluated_ensure(Main *bmain, Scene *scene, ViewLayer *view_layer) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 741 Lines • ▼ Show 20 Lines | |||||
| GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain) | GHash *BKE_scene_undo_depsgraphs_extract(Main *bmain) | ||||
| { | { | ||||
| GHash *depsgraph_extract = BLI_ghash_new( | GHash *depsgraph_extract = BLI_ghash_new( | ||||
| BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__); | BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__); | ||||
| for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { | for (Scene *scene = bmain->scenes.first; scene != NULL; scene = scene->id.next) { | ||||
| if (scene->depsgraph_hash == NULL) { | if (scene->depsgraph_hash == NULL) { | ||||
| /* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will be | /* In some cases, e.g. when undo has to perform multiple steps at once, no depsgraph will | ||||
| * built so this pointer may be NULL. */ | * be built so this pointer may be NULL. */ | ||||
| continue; | continue; | ||||
| } | } | ||||
| for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL; | for (ViewLayer *view_layer = scene->view_layers.first; view_layer != NULL; | ||||
| view_layer = view_layer->next) { | view_layer = view_layer->next) { | ||||
| DepsgraphKey key; | DepsgraphKey key; | ||||
| key.view_layer = view_layer; | key.view_layer = view_layer; | ||||
| Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key); | Depsgraph **depsgraph = (Depsgraph **)BLI_ghash_lookup_p(scene->depsgraph_hash, &key); | ||||
| ▲ Show 20 Lines • Show All 275 Lines • Show Last 20 Lines | |||||