Changeset View
Changeset View
Standalone View
Standalone View
source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
| Show All 37 Lines | |||||
| #include "BLI_listbase.h" | #include "BLI_listbase.h" | ||||
| #include "BLI_string.h" | #include "BLI_string.h" | ||||
| #include "BLI_threads.h" | #include "BLI_threads.h" | ||||
| #include "BLI_utildefines.h" | #include "BLI_utildefines.h" | ||||
| #include "BKE_curve.h" | #include "BKE_curve.h" | ||||
| #include "BKE_global.h" | #include "BKE_global.h" | ||||
| #include "BKE_gpencil.h" | #include "BKE_gpencil.h" | ||||
| #include "BKE_gpencil_update_cache.h" | |||||
| #include "BKE_idprop.h" | #include "BKE_idprop.h" | ||||
| #include "BKE_layer.h" | #include "BKE_layer.h" | ||||
| #include "BKE_lib_id.h" | #include "BKE_lib_id.h" | ||||
| #include "BKE_scene.h" | #include "BKE_scene.h" | ||||
| #include "DEG_depsgraph.h" | #include "DEG_depsgraph.h" | ||||
| #include "DEG_depsgraph_query.h" | #include "DEG_depsgraph_query.h" | ||||
| ▲ Show 20 Lines • Show All 678 Lines • ▼ Show 20 Lines | case ID_OB: { | ||||
| const bArmature *armature_orig = (bArmature *)object_orig->data; | const bArmature *armature_orig = (bArmature *)object_orig->data; | ||||
| bArmature *armature_cow = (bArmature *)object_cow->data; | bArmature *armature_cow = (bArmature *)object_cow->data; | ||||
| BKE_pose_remap_bone_pointers(armature_cow, object_cow->pose); | BKE_pose_remap_bone_pointers(armature_cow, object_cow->pose); | ||||
| if (armature_orig->edbo == nullptr) { | if (armature_orig->edbo == nullptr) { | ||||
| update_pose_orig_pointers(object_orig->pose, object_cow->pose); | update_pose_orig_pointers(object_orig->pose, object_cow->pose); | ||||
| } | } | ||||
| BKE_pose_pchan_index_rebuild(object_cow->pose); | BKE_pose_pchan_index_rebuild(object_cow->pose); | ||||
| } | } | ||||
| if (object_cow->type == OB_GPENCIL) { | |||||
| BKE_gpencil_update_orig_pointers(object_orig, object_cow); | |||||
| } | |||||
| update_particles_after_copy(depsgraph, object_orig, object_cow); | update_particles_after_copy(depsgraph, object_orig, object_cow); | ||||
| break; | break; | ||||
| } | } | ||||
| case ID_SCE: { | case ID_SCE: { | ||||
| Scene *scene_cow = (Scene *)id_cow; | Scene *scene_cow = (Scene *)id_cow; | ||||
| const Scene *scene_orig = (const Scene *)id_orig; | const Scene *scene_orig = (const Scene *)id_orig; | ||||
| scene_cow->toolsettings = scene_orig->toolsettings; | scene_cow->toolsettings = scene_orig->toolsettings; | ||||
| scene_cow->eevee.light_cache_data = scene_orig->eevee.light_cache_data; | scene_cow->eevee.light_cache_data = scene_orig->eevee.light_cache_data; | ||||
| ▲ Show 20 Lines • Show All 136 Lines • ▼ Show 20 Lines | if (OB_DATA_SUPPORT_EDITMODE(id_type) && BKE_object_data_is_in_editmode(id_orig)) { | ||||
| * - ObjectA in SceneA is using Mesh. | * - ObjectA in SceneA is using Mesh. | ||||
| * - ObjectB in SceneB is using Mesh (same exact datablock). | * - ObjectB in SceneB is using Mesh (same exact datablock). | ||||
| * - Depsgraph of SceneA is evaluated. | * - Depsgraph of SceneA is evaluated. | ||||
| * - Depsgraph of SceneB is evaluated. | * - Depsgraph of SceneB is evaluated. | ||||
| * - User enters edit mode of ObjectA in SceneA. */ | * - User enters edit mode of ObjectA in SceneA. */ | ||||
| update_edit_mode_pointers(depsgraph, id_orig, id_cow); | update_edit_mode_pointers(depsgraph, id_orig, id_cow); | ||||
| return id_cow; | return id_cow; | ||||
| } | } | ||||
| /* In case we don't need to do a copy-on-write, we can use the update cache of the grease | |||||
| * pencil data to do an update-on-write.*/ | |||||
| if (id_type == ID_GD && BKE_gpencil_can_avoid_full_copy_on_write( | |||||
sergey: Don't use `else`after `return`.
The `BKE_gpencil_update_on_write_check` sounds ambiguous. | |||||
| (const ::Depsgraph *)depsgraph, (bGPdata *)id_orig)) { | |||||
| BKE_gpencil_update_on_write((bGPdata *)id_orig, (bGPdata *)id_cow); | |||||
| return id_cow; | |||||
| } | |||||
| } | } | ||||
| RuntimeBackup backup(depsgraph); | RuntimeBackup backup(depsgraph); | ||||
| backup.init_from_id(id_cow); | backup.init_from_id(id_cow); | ||||
| deg_free_copy_on_write_datablock(id_cow); | deg_free_copy_on_write_datablock(id_cow); | ||||
| deg_expand_copy_on_write_datablock(depsgraph, id_node); | deg_expand_copy_on_write_datablock(depsgraph, id_node); | ||||
| backup.restore_to_id(id_cow); | backup.restore_to_id(id_cow); | ||||
| return id_cow; | return id_cow; | ||||
| } | } | ||||
| /** | /** | ||||
| * \note Depsgraph is supposed to have ID node already. | * \note Depsgraph is supposed to have ID node already. | ||||
| */ | */ | ||||
| ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, ID *id_orig) | ID *deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, ID *id_orig) | ||||
| { | { | ||||
| IDNode *id_node = depsgraph->find_id_node(id_orig); | IDNode *id_node = depsgraph->find_id_node(id_orig); | ||||
| BLI_assert(id_node != nullptr); | BLI_assert(id_node != nullptr); | ||||
| return deg_update_copy_on_write_datablock(depsgraph, id_node); | return deg_update_copy_on_write_datablock(depsgraph, id_node); | ||||
| } | } | ||||
| namespace { | namespace { | ||||
| void discard_armature_edit_mode_pointers(ID *id_cow) | void discard_armature_edit_mode_pointers(ID *id_cow) | ||||
| { | { | ||||
| bArmature *armature_cow = (bArmature *)id_cow; | bArmature *armature_cow = (bArmature *)id_cow; | ||||
| armature_cow->edbo = nullptr; | armature_cow->edbo = nullptr; | ||||
| } | } | ||||
| void discard_curve_edit_mode_pointers(ID *id_cow) | void discard_curve_edit_mode_pointers(ID *id_cow) | ||||
Done Inline ActionsI think it would be better to reorganize this code to make it more similar to other data types. For the !!BKE_gpencil_check_copy_on_write_needed case, move it before RuntimeBackup like the edit mode exception. Maybe it also needs that same is_cow_explicitly_tagged check? Something like: if (check_datablock_expanded(id_cow) && !id_node->is_cow_explicitly_tagged) {
const ID_Type id_type = GS(id_orig->name);
if (OB_DATA_SUPPORT_EDITMODE(id_type) && BKE_object_data_is_in_editmode(id_orig)) {
...
}
else if {id_type == ID_GD && BKE_gpencil_check_copy_on_write_needed) {
...
}Then for the other case, I think a RuntimeBackup should be implemented for grease pencil consistent with other datablocks. brecht: I think it would be better to reorganize this code to make it more similar to other data types. | |||||
| { | { | ||||
| Curve *curve_cow = (Curve *)id_cow; | Curve *curve_cow = (Curve *)id_cow; | ||||
| curve_cow->editnurb = nullptr; | curve_cow->editnurb = nullptr; | ||||
| curve_cow->editfont = nullptr; | curve_cow->editfont = nullptr; | ||||
| } | } | ||||
| void discard_mball_edit_mode_pointers(ID *id_cow) | void discard_mball_edit_mode_pointers(ID *id_cow) | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 145 Lines • Show Last 20 Lines | |||||
Don't use elseafter return.
The BKE_gpencil_update_on_write_check sounds ambiguous. Maybe something BKE_gpencil_check_can_avoid_full_copy_on_write() ?