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:
authorGermano Cavalcante <mano-wii>2021-06-29 15:34:50 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-07-13 00:05:13 +0300
commitbfa3dc91b75407b063f2ac991b176d98c050f92d (patch)
tree43311b486d6f9b4c516f4b37d887e89aa76116fe
parent7b6c77aa84803e4268406e394aa4556ebf7980b0 (diff)
Depsgraph: Implement 'ID_RECALC_GEOMETRY_DEFORM'
During a mesh transformation in edit mode (Move, Rotate...), only part of the batch cache needs to be updated. This commit allows only update only the drawn batches seen in `BKE_object_data_eval_batch_cache_deform_tag` if the new `ID_RECALC_GEOMETRY_DEFORM` flag is used. This new flag is used in the transforms operation for edit-mesh and results in 1.6x overall speedup in heavy subdiv cube. Differential Revision: https://developer.blender.org/D11599
-rw-r--r--source/blender/blenkernel/BKE_mesh_types.h1
-rw-r--r--source/blender/blenkernel/BKE_object.h4
-rw-r--r--source/blender/blenkernel/intern/object_update.c21
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc102
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc68
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc9
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc5
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.cc10
-rw-r--r--source/blender/depsgraph/intern/node/deg_node_operation.h10
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c11
-rw-r--r--source/blender/editors/transform/transform_convert_mesh.c2
-rw-r--r--source/blender/makesdna/DNA_ID.h9
12 files changed, 175 insertions, 77 deletions
diff --git a/source/blender/blenkernel/BKE_mesh_types.h b/source/blender/blenkernel/BKE_mesh_types.h
index aed8c44a031..b223d3872ff 100644
--- a/source/blender/blenkernel/BKE_mesh_types.h
+++ b/source/blender/blenkernel/BKE_mesh_types.h
@@ -27,6 +27,7 @@ typedef enum eMeshBatchDirtyMode {
BKE_MESH_BATCH_DIRTY_SELECT,
BKE_MESH_BATCH_DIRTY_SELECT_PAINT,
BKE_MESH_BATCH_DIRTY_SHADING,
+ BKE_MESH_BATCH_DIRTY_DEFORM,
BKE_MESH_BATCH_DIRTY_UVEDIT_ALL,
BKE_MESH_BATCH_DIRTY_UVEDIT_SELECT,
} eMeshBatchDirtyMode;
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index 4724e6dfab6..a16822fd7dd 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -374,6 +374,10 @@ void BKE_object_runtime_free_data(struct Object *object);
void BKE_object_batch_cache_dirty_tag(struct Object *ob);
void BKE_object_data_batch_cache_dirty_tag(struct ID *object_data);
+void BKE_object_data_eval_batch_cache_dirty_tag(struct Depsgraph *depsgraph,
+ struct ID *object_data);
+void BKE_object_data_eval_batch_cache_deform_tag(struct Depsgraph *depsgraph,
+ struct ID *object_data);
/* this function returns a superset of the scenes selection based on relationships */
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 7e15ac5de5d..7cdea14e9bd 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -388,12 +388,31 @@ void BKE_object_batch_cache_dirty_tag(Object *ob)
BKE_object_data_batch_cache_dirty_tag(ob->data);
}
+void BKE_object_data_eval_batch_cache_dirty_tag(Depsgraph *depsgraph, ID *object_data)
+{
+ DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data);
+ BKE_object_data_batch_cache_dirty_tag(object_data);
+}
+
+void BKE_object_data_eval_batch_cache_deform_tag(Depsgraph *depsgraph, ID *object_data)
+{
+ DEG_debug_print_eval(depsgraph, __func__, object_data->name, object_data);
+ switch (GS(object_data->name)) {
+ case ID_ME:
+ BKE_mesh_batch_cache_dirty_tag((Mesh *)object_data, BKE_MESH_BATCH_DIRTY_DEFORM);
+ break;
+ default:
+ /* Only mesh is currently supported. Fallback to dirty all for other datablocks types. */
+ BKE_object_data_batch_cache_dirty_tag(object_data);
+ break;
+ }
+}
+
void BKE_object_eval_uber_data(Depsgraph *depsgraph, Scene *scene, Object *ob)
{
DEG_debug_print_eval(depsgraph, __func__, ob->id.name, ob);
BLI_assert(ob->type != OB_ARMATURE);
BKE_object_handle_data_update(depsgraph, scene, ob);
- BKE_object_batch_cache_dirty_tag(ob);
}
void BKE_object_eval_ptcache_reset(Depsgraph *depsgraph, Scene *scene, Object *object)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 56168739fae..c8179fb1eff 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -1495,7 +1495,7 @@ void DepsgraphNodeBuilder::build_object_data_geometry(Object *object, bool is_ob
add_operation_node(
&object->id,
NodeType::BATCH_CACHE,
- OperationCode::GEOMETRY_SELECT_UPDATE,
+ OperationCode::BATCH_UPDATE_SELECT,
[object_cow](::Depsgraph *depsgraph) { BKE_object_select_update(depsgraph, object_cow); });
}
@@ -1516,33 +1516,37 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
if (key) {
build_shapekeys(key);
}
- /* Nodes for result of obdata's evaluation, and geometry
- * evaluation on object. */
+
+ /* Geometry evaluation. */
+ /* Entry operation, takes care of initialization, and some other
+ * relations which needs to be run prior to actual geometry evaluation. */
+ op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
+ op_node->set_as_entry();
+
+ add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM);
+
const ID_Type id_type = GS(obdata->name);
switch (id_type) {
case ID_ME: {
- op_node = add_operation_node(obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- [obdata_cow](::Depsgraph *depsgraph) {
- BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
- });
- op_node->set_as_entry();
+ add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_mesh_eval_geometry(depsgraph, (Mesh *)obdata_cow);
+ });
break;
}
case ID_MB: {
- op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
- op_node->set_as_entry();
+ add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
break;
}
case ID_CU: {
- op_node = add_operation_node(obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- [obdata_cow](::Depsgraph *depsgraph) {
- BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
- });
- op_node->set_as_entry();
+ add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_curve_eval_geometry(depsgraph, (Curve *)obdata_cow);
+ });
/* Make sure objects used for bevel.taper are in the graph.
* NOTE: This objects might be not linked to the scene. */
Curve *cu = (Curve *)obdata;
@@ -1558,47 +1562,41 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
break;
}
case ID_LT: {
- op_node = add_operation_node(obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- [obdata_cow](::Depsgraph *depsgraph) {
- BKE_lattice_eval_geometry(depsgraph, (Lattice *)obdata_cow);
- });
- op_node->set_as_entry();
+ add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_lattice_eval_geometry(depsgraph, (Lattice *)obdata_cow);
+ });
break;
}
case ID_GD: {
/* GPencil evaluation operations. */
- op_node = add_operation_node(obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- [obdata_cow](::Depsgraph *depsgraph) {
- BKE_gpencil_frame_active_set(depsgraph,
- (bGPdata *)obdata_cow);
- });
- op_node->set_as_entry();
+ add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_gpencil_frame_active_set(depsgraph, (bGPdata *)obdata_cow);
+ });
break;
}
case ID_HA: {
- op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
- op_node->set_as_entry();
+ add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
break;
}
case ID_PT: {
- op_node = add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
- op_node->set_as_entry();
+ add_operation_node(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
break;
}
case ID_VO: {
/* Volume frame update. */
- op_node = add_operation_node(obdata,
- NodeType::GEOMETRY,
- OperationCode::GEOMETRY_EVAL,
- [obdata_cow](::Depsgraph *depsgraph) {
- BKE_volume_eval_geometry(depsgraph, (Volume *)obdata_cow);
- });
- op_node->set_as_entry();
+ add_operation_node(obdata,
+ NodeType::GEOMETRY,
+ OperationCode::GEOMETRY_EVAL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_volume_eval_geometry(depsgraph, (Volume *)obdata_cow);
+ });
break;
}
default:
@@ -1612,10 +1610,22 @@ void DepsgraphNodeBuilder::build_object_data_geometry_datablock(ID *obdata, bool
/* Batch cache. */
add_operation_node(obdata,
NodeType::BATCH_CACHE,
- OperationCode::GEOMETRY_SELECT_UPDATE,
+ OperationCode::BATCH_UPDATE_SELECT,
[obdata_cow](::Depsgraph *depsgraph) {
BKE_object_data_select_update(depsgraph, obdata_cow);
});
+ add_operation_node(obdata,
+ NodeType::BATCH_CACHE,
+ OperationCode::BATCH_UPDATE_DEFORM,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_object_data_eval_batch_cache_deform_tag(depsgraph, obdata_cow);
+ });
+ add_operation_node(obdata,
+ NodeType::BATCH_CACHE,
+ OperationCode::BATCH_UPDATE_ALL,
+ [obdata_cow](::Depsgraph *depsgraph) {
+ BKE_object_data_eval_batch_cache_dirty_tag(depsgraph, obdata_cow);
+ });
}
void DepsgraphNodeBuilder::build_armature(bArmature *armature)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index c269ad16824..7486f798fdb 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -647,7 +647,7 @@ void DepsgraphRelationBuilder::build_collection(LayerCollection *from_layer_coll
/* Only create geometry relations to child objects, if they have a geometry component. */
OperationKey object_geometry_key{
- &cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL};
+ &cob->ob->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT};
if (find_node(object_geometry_key) != nullptr) {
add_relation(object_geometry_key, collection_geometry_key, "Collection Geometry");
}
@@ -1098,7 +1098,8 @@ void DepsgraphRelationBuilder::build_object_pointcache(Object *object)
}
else {
flag = FLAG_GEOMETRY;
- OperationKey geometry_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
+ OperationKey geometry_key(
+ &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
add_relation(point_cache_key, geometry_key, "Point Cache -> Geometry");
}
BLI_assert(flag != -1);
@@ -1868,7 +1869,8 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
void DepsgraphRelationBuilder::build_particle_systems(Object *object)
{
TimeSourceKey time_src_key;
- OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
+ OperationKey obdata_ubereval_key(
+ &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
OperationKey eval_init_key(
&object->id, NodeType::PARTICLE_SYSTEM, OperationCode::PARTICLE_SYSTEM_INIT);
OperationKey eval_done_key(
@@ -2016,7 +2018,8 @@ void DepsgraphRelationBuilder::build_particle_system_visualization_object(Object
{
OperationKey psys_key(
&object->id, NodeType::PARTICLE_SYSTEM, OperationCode::PARTICLE_SYSTEM_EVAL, psys->name);
- OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
+ OperationKey obdata_ubereval_key(
+ &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
ComponentKey dup_ob_key(&draw_object->id, NodeType::TRANSFORM);
add_relation(dup_ob_key, psys_key, "Particle Object Visualization");
if (draw_object->type == OB_MBALL) {
@@ -2073,15 +2076,15 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
/* Get nodes for result of obdata's evaluation, and geometry evaluation
* on object. */
ComponentKey obdata_geom_key(obdata, NodeType::GEOMETRY);
- ComponentKey geom_key(&object->id, NodeType::GEOMETRY);
- /* Link components to each other. */
- add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
OperationKey obdata_ubereval_key(&object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
+ /* Link components to each other. */
+ add_relation(obdata_geom_key, obdata_ubereval_key, "Object Geometry Base Data");
+
/* Special case: modifiers evaluation queries scene for various things like
* data mask to be used. We add relation here to ensure object is never
* evaluated prior to Scene's CoW is ready. */
OperationKey scene_key(&scene_->id, NodeType::PARAMETERS, OperationCode::SCENE_EVAL);
- Relation *rel = add_relation(scene_key, obdata_ubereval_key, "CoW Relation");
+ Relation *rel = add_relation(scene_key, geom_init_key, "CoW Relation");
rel->flag |= RELATION_FLAG_NO_FLUSH;
/* Modifiers */
if (object->modifiers.first != nullptr) {
@@ -2091,13 +2094,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
if (mti->updateDepsgraph) {
- DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
+ DepsNodeHandle handle = create_node_handle(geom_init_key);
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(md, &ctx);
}
if (BKE_object_modifier_use_time(object, md)) {
TimeSourceKey time_src_key;
- add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ add_relation(time_src_key, geom_init_key, "Time Source");
}
}
}
@@ -2110,13 +2113,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
const GpencilModifierTypeInfo *mti = BKE_gpencil_modifier_get_info(
(GpencilModifierType)md->type);
if (mti->updateDepsgraph) {
- DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
+ DepsNodeHandle handle = create_node_handle(geom_init_key);
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
mti->updateDepsgraph(md, &ctx, graph_->mode);
}
if (BKE_object_modifier_gpencil_use_time(object, md)) {
TimeSourceKey time_src_key;
- add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ add_relation(time_src_key, geom_init_key, "Time Source");
}
}
}
@@ -2128,13 +2131,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
LISTBASE_FOREACH (ShaderFxData *, fx, &object->shader_fx) {
const ShaderFxTypeInfo *fxi = BKE_shaderfx_get_info((ShaderFxType)fx->type);
if (fxi->updateDepsgraph) {
- DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
+ DepsNodeHandle handle = create_node_handle(geom_init_key);
ctx.node = reinterpret_cast<::DepsNodeHandle *>(&handle);
fxi->updateDepsgraph(fx, &ctx);
}
if (BKE_object_shaderfx_use_time(object, fx)) {
TimeSourceKey time_src_key;
- add_relation(time_src_key, obdata_ubereval_key, "Time Source");
+ add_relation(time_src_key, geom_init_key, "Time Source");
}
}
}
@@ -2160,6 +2163,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
add_relation(mom_transform_key, mom_geom_key, "Metaball Motherball Transform -> Geometry");
}
else {
+ ComponentKey geom_key(&object->id, NodeType::GEOMETRY);
ComponentKey transform_key(&object->id, NodeType::TRANSFORM);
add_relation(geom_key, mom_geom_key, "Metaball Motherball");
add_relation(transform_key, mom_geom_key, "Metaball Motherball");
@@ -2174,9 +2178,7 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
* Ideally we need to get rid of this relation. */
if (object_particles_depends_on_time(object)) {
TimeSourceKey time_key;
- OperationKey obdata_ubereval_key(
- &object->id, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
- add_relation(time_key, obdata_ubereval_key, "Legacy particle time");
+ add_relation(time_key, geom_init_key, "Legacy particle time");
}
/* Object data data-block. */
build_object_data_geometry_datablock((ID *)object->data);
@@ -2198,12 +2200,33 @@ void DepsgraphRelationBuilder::build_object_data_geometry(Object *object)
add_relation(final_geometry_key, synchronize_key, "Synchronize to Original");
/* Batch cache. */
OperationKey object_data_select_key(
- obdata, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
+ obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_SELECT);
OperationKey object_select_key(
- &object->id, NodeType::BATCH_CACHE, OperationCode::GEOMETRY_SELECT_UPDATE);
+ &object->id, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_SELECT);
+
add_relation(object_data_select_key, object_select_key, "Data Selection -> Object Selection");
+ add_relation(final_geometry_key,
+ object_select_key,
+ "Object Geometry -> Select Update",
+ RELATION_FLAG_NO_FLUSH);
+
+ OperationKey object_data_geom_deform_key(
+ obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM);
+ OperationKey object_data_geom_init_key(
+ obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
+
+ OperationKey object_data_batch_deform_key(
+ obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_DEFORM);
+ OperationKey object_data_batch_all_key(
+ obdata, NodeType::BATCH_CACHE, OperationCode::BATCH_UPDATE_ALL);
+
+ add_relation(geom_init_key, object_data_batch_all_key, "Object Geometry -> Batch Update All");
+
add_relation(
- geom_key, object_select_key, "Object Geometry -> Select Update", RELATION_FLAG_NO_FLUSH);
+ object_data_geom_init_key, object_data_batch_all_key, "Data Init -> Batch Update All");
+ add_relation(object_data_geom_deform_key,
+ object_data_batch_deform_key,
+ "Data Deform -> Batch Update Deform");
}
void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
@@ -2221,8 +2244,13 @@ void DepsgraphRelationBuilder::build_object_data_geometry_datablock(ID *obdata)
build_shapekeys(key);
}
/* Link object data evaluation node to exit operation. */
+ OperationKey obdata_geom_deform_key(
+ obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DEFORM);
+ OperationKey obdata_geom_init_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_INIT);
OperationKey obdata_geom_eval_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL);
OperationKey obdata_geom_done_key(obdata, NodeType::GEOMETRY, OperationCode::GEOMETRY_EVAL_DONE);
+ add_relation(obdata_geom_init_key, obdata_geom_eval_key, "ObData Init -> Geom Eval");
+ add_relation(obdata_geom_deform_key, obdata_geom_eval_key, "ObData Deform -> Geom Eval");
add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done");
/* Type-specific links. */
const ID_Type id_type = GS(obdata->name);
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index b00cae87311..e879e8d0f23 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -117,7 +117,7 @@ void depsgraph_select_tag_to_component_opcode(const ID *id,
}
else if (is_selectable_data_id_type(id_type)) {
*component_type = NodeType::BATCH_CACHE;
- *operation_code = OperationCode::GEOMETRY_SELECT_UPDATE;
+ *operation_code = OperationCode::BATCH_UPDATE_SELECT;
}
else {
*component_type = NodeType::COPY_ON_WRITE;
@@ -168,6 +168,11 @@ void depsgraph_tag_to_component_opcode(const ID *id,
break;
case ID_RECALC_GEOMETRY:
depsgraph_geometry_tag_to_component(id, component_type);
+ *operation_code = OperationCode::GEOMETRY_EVAL_INIT;
+ break;
+ case ID_RECALC_GEOMETRY_DEFORM:
+ depsgraph_geometry_tag_to_component(id, component_type);
+ *operation_code = OperationCode::GEOMETRY_EVAL_DEFORM;
break;
case ID_RECALC_ANIMATION:
*component_type = NodeType::ANIMATION;
@@ -708,6 +713,8 @@ const char *DEG_update_tag_as_string(IDRecalcFlag flag)
return "GEOMETRY";
case ID_RECALC_GEOMETRY_ALL_MODES:
return "GEOMETRY_ALL_MODES";
+ case ID_RECALC_GEOMETRY_DEFORM:
+ return "GEOMETRY_DEFORM";
case ID_RECALC_ANIMATION:
return "ANIMATION";
case ID_RECALC_PSYS_REDO:
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index 1b24e2b7ad2..2cbb0b52e34 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -144,7 +144,10 @@ inline void flush_handle_component_node(IDNode *id_node,
* special component where we don't want all operations to be tagged.
*
* TODO(sergey): Make this a more generic solution. */
- if (!ELEM(comp_node->type, NodeType::PARTICLE_SETTINGS, NodeType::PARTICLE_SYSTEM)) {
+ if (!ELEM(comp_node->type,
+ NodeType::PARTICLE_SETTINGS,
+ NodeType::PARTICLE_SYSTEM,
+ NodeType::BATCH_CACHE)) {
for (OperationNode *op : comp_node->operations) {
op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
}
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.cc b/source/blender/depsgraph/intern/node/deg_node_operation.cc
index 7e57467f905..62a3d65d1f4 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.cc
@@ -98,6 +98,8 @@ const char *operationCodeAsString(OperationCode opcode)
/* Geometry. */
case OperationCode::GEOMETRY_EVAL_INIT:
return "GEOMETRY_EVAL_INIT";
+ case OperationCode::GEOMETRY_EVAL_DEFORM:
+ return "GEOMETRY_EVAL_DEFORM";
case OperationCode::GEOMETRY_EVAL:
return "GEOMETRY_EVAL";
case OperationCode::GEOMETRY_EVAL_DONE:
@@ -160,8 +162,12 @@ const char *operationCodeAsString(OperationCode opcode)
case OperationCode::FILE_CACHE_UPDATE:
return "FILE_CACHE_UPDATE";
/* Batch cache. */
- case OperationCode::GEOMETRY_SELECT_UPDATE:
- return "GEOMETRY_SELECT_UPDATE";
+ case OperationCode::BATCH_UPDATE_SELECT:
+ return "BATCH_UPDATE_SELECT";
+ case OperationCode::BATCH_UPDATE_DEFORM:
+ return "BATCH_UPDATE_DEFORM";
+ case OperationCode::BATCH_UPDATE_ALL:
+ return "BATCH_UPDATE_ALL";
/* Masks. */
case OperationCode::MASK_ANIMATION:
return "MASK_ANIMATION";
diff --git a/source/blender/depsgraph/intern/node/deg_node_operation.h b/source/blender/depsgraph/intern/node/deg_node_operation.h
index a17186da941..b0130d03c69 100644
--- a/source/blender/depsgraph/intern/node/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/node/deg_node_operation.h
@@ -100,7 +100,11 @@ enum class OperationCode {
/* Initialize evaluation of the geometry. Is an entry operation of geometry
* component. */
GEOMETRY_EVAL_INIT,
- /* Evaluate the whole geometry, including modifiers. */
+ /* Evaluate the geometry, including modifiers, and update only batches that
+ * are affected by deform operations. */
+ GEOMETRY_EVAL_DEFORM,
+ /* Evaluate the geometry, including modifiers, but don't update the batch
+ * cache. */
GEOMETRY_EVAL,
/* Evaluation of geometry is completely done. */
GEOMETRY_EVAL_DONE,
@@ -178,7 +182,9 @@ enum class OperationCode {
WORLD_UPDATE,
/* Batch caches. -------------------------------------------------------- */
- GEOMETRY_SELECT_UPDATE,
+ BATCH_UPDATE_SELECT,
+ BATCH_UPDATE_DEFORM,
+ BATCH_UPDATE_ALL,
/* Masks. --------------------------------------------------------------- */
MASK_ANIMATION,
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 41047191efe..1da8848eeb1 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -821,6 +821,17 @@ void DRW_mesh_batch_cache_dirty_tag(Mesh *me, eMeshBatchDirtyMode mode)
mesh_batch_cache_discard_shaded_tri(cache);
mesh_batch_cache_discard_uvedit(cache);
break;
+ case BKE_MESH_BATCH_DIRTY_DEFORM:
+ FOREACH_MESH_BUFFER_CACHE (cache, mbufcache) {
+ GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.pos_nor);
+ GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.lnor);
+ GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_pos);
+ GPU_VERTBUF_DISCARD_SAFE(mbufcache->vbo.fdots_nor);
+ GPU_INDEXBUF_DISCARD_SAFE(mbufcache->ibo.tris);
+ }
+ batch_map = MDEPS_CREATE_MAP(vbo.pos_nor, vbo.lnor, vbo.fdots_pos, vbo.fdots_nor, ibo.tris);
+ mesh_batch_cache_discard_batch(cache, batch_map);
+ break;
case BKE_MESH_BATCH_DIRTY_UVEDIT_ALL:
mesh_batch_cache_discard_uvedit(cache);
break;
diff --git a/source/blender/editors/transform/transform_convert_mesh.c b/source/blender/editors/transform/transform_convert_mesh.c
index c1ee6edfef6..18cd62a0baf 100644
--- a/source/blender/editors/transform/transform_convert_mesh.c
+++ b/source/blender/editors/transform/transform_convert_mesh.c
@@ -2094,7 +2094,7 @@ void recalcData_mesh(TransInfo *t)
tc_mesh_partial_types_calc(t, &partial_state);
FOREACH_TRANS_DATA_CONTAINER (t, tc) {
- DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY);
+ DEG_id_tag_update(tc->obedit->data, ID_RECALC_GEOMETRY_DEFORM);
tc_mesh_partial_update(t, tc, &partial_state);
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index c9d652ad03d..43969bf0768 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -621,9 +621,9 @@ typedef enum IDRecalcFlag {
* When a collection gets tagged with this flag, all objects depending on the geometry and
* transforms on any of the objects in the collection are updated. */
ID_RECALC_GEOMETRY = (1 << 1),
-
- /* ** Animation or time changed and animation is to be re-evaluated. ** */
- ID_RECALC_ANIMATION = (1 << 2),
+ /* Same as #ID_RECALC_GEOMETRY, but instead of tagging the batch cache as `dirty_all`, just tags
+ what matches the deform cache. */
+ ID_RECALC_GEOMETRY_DEFORM = (1 << 2),
/* ** Particle system changed. ** */
/* Only do pathcache etc. */
@@ -683,6 +683,9 @@ typedef enum IDRecalcFlag {
* have to be copied on every update. */
ID_RECALC_PARAMETERS = (1 << 21),
+ /* ** Animation or time changed and animation is to be re-evaluated. ** */
+ ID_RECALC_ANIMATION = (1 << 22),
+
/* Input has changed and datablock is to be reload from disk.
* Applies to movie clips to inform that copy-on-written version is to be refreshed for the new
* input file or for color space changes. */