Fix #104798: Slow frame-change & scrubbing with many objects #104801
|
@ -291,7 +291,9 @@ static void deg_debug_graphviz_relation_arrowhead(const Relation *rel, dot::Dire
|
|||
OperationNode *op_from = (OperationNode *)rel->from;
|
||||
OperationNode *op_to = (OperationNode *)rel->to;
|
||||
if (op_from->owner->type == NodeType::COPY_ON_EVAL &&
|
||||
!op_to->owner->need_tag_cow_before_update())
|
||||
/* The #ID::recalc flag depends on run-time state which is not valid at this point in time.
|
||||
* Pass in all flags although there may be a better way to represent this. */
|
||||
!op_to->owner->need_tag_cow_before_update(ID_RECALC_ALL))
|
||||
{
|
||||
shape = shape_no_cow;
|
||||
}
|
||||
|
|
|
@ -296,7 +296,7 @@ void depsgraph_tag_component(Depsgraph *graph,
|
|||
}
|
||||
}
|
||||
/* If component depends on copy-on-evaluation, tag it as well. */
|
||||
if (component_node->need_tag_cow_before_update()) {
|
||||
if (component_node->need_tag_cow_before_update(IDRecalcFlag(id_node->id_cow->recalc))) {
|
||||
depsgraph_id_tag_copy_on_write(graph, id_node, update_source);
|
||||
}
|
||||
if (component_type == NodeType::COPY_ON_EVAL) {
|
||||
|
@ -531,8 +531,12 @@ void deg_graph_tag_parameters_if_needed(Main *bmain,
|
|||
}
|
||||
|
||||
/* Clear flags which are known to not affect parameters usable by drivers. */
|
||||
const uint clean_flags = flags & ~(ID_RECALC_SYNC_TO_EVAL | ID_RECALC_SELECT |
|
||||
ID_RECALC_BASE_FLAGS | ID_RECALC_SHADING);
|
||||
const uint clean_flags = flags &
|
||||
~(ID_RECALC_SYNC_TO_EVAL | ID_RECALC_SELECT | ID_RECALC_BASE_FLAGS |
|
||||
ID_RECALC_SHADING |
|
||||
/* While drivers may use the current-frame, this value is assigned
|
||||
explicitly and doesn't require a the scene to be copied again. */
|
||||
ID_RECALC_FRAME_CHANGE);
|
||||
|
||||
if (clean_flags == 0) {
|
||||
/* Changes are limited to only things which are not usable by drivers. */
|
||||
|
|
|
@ -132,7 +132,7 @@ struct ComponentNode : public Node {
|
|||
|
||||
/* Denotes whether copy-on-eval component is to be tagged when this component
|
||||
* is tagged for update. */
|
||||
virtual bool need_tag_cow_before_update()
|
||||
virtual bool need_tag_cow_before_update(const IDRecalcFlag /*tag*/)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ struct ComponentNode : public Node {
|
|||
#define DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(name) \
|
||||
struct name##ComponentNode : public ComponentNode { \
|
||||
DEG_COMPONENT_NODE_DECLARE; \
|
||||
virtual bool need_tag_cow_before_update() \
|
||||
virtual bool need_tag_cow_before_update(const IDRecalcFlag /*tag*/) \
|
||||
{ \
|
||||
return false; \
|
||||
} \
|
||||
|
@ -204,7 +204,6 @@ DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(ObjectFromLayer);
|
|||
DEG_COMPONENT_NODE_DECLARE_NO_COW_TAG_ON_UPDATE(Hierarchy);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Instancing);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Synchronization);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Audio);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Armature);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(GenericDatablock);
|
||||
DEG_COMPONENT_NODE_DECLARE_GENERIC(Scene);
|
||||
|
@ -226,7 +225,7 @@ struct BoneComponentNode : public ComponentNode {
|
|||
/* Eventually we would not tag parameters in all cases.
|
||||
* Support for this each ID needs to be added on an individual basis. */
|
||||
struct ParametersComponentNode : public ComponentNode {
|
||||
virtual bool need_tag_cow_before_update() override
|
||||
virtual bool need_tag_cow_before_update(const IDRecalcFlag /*tag*/) override
|
||||
{
|
||||
if (ID_TYPE_SUPPORTS_PARAMS_WITHOUT_COW(owner->id_type)) {
|
||||
/* Disabled as this is not true for newly added objects, needs investigation. */
|
||||
|
@ -239,6 +238,18 @@ struct ParametersComponentNode : public ComponentNode {
|
|||
DEG_COMPONENT_NODE_DECLARE;
|
||||
};
|
||||
|
||||
/* Audio component. */
|
||||
struct AudioComponentNode : public ComponentNode {
|
||||
virtual bool need_tag_cow_before_update(const IDRecalcFlag tag) override
|
||||
ideasman42 marked this conversation as resolved
Outdated
|
||||
{
|
||||
/* Frame change doesn't require a copy of the scene, doing so can be a heavy operation
|
||||
* especially when the collection contains many objects, see #104798. */
|
||||
return (tag != ID_RECALC_FRAME_CHANGE);
|
||||
ideasman42 marked this conversation as resolved
Outdated
Sybren A. Stüvel
commented
Personally I'd prefer No strong feelings, it mostly depends on how likely it is that other cases will be added. If you keep the Personally I'd prefer `return tag != ID_RECALC_FRAME_CHANGE;`
No strong feelings, it mostly depends on how likely it is that other cases will be added. If you keep the `if`, I think it's better to put the explanation inside the conditional block.
|
||||
}
|
||||
|
||||
DEG_COMPONENT_NODE_DECLARE;
|
||||
};
|
||||
|
||||
void deg_register_component_depsnodes();
|
||||
|
||||
} // namespace blender::deg
|
||||
|
|
Loading…
Reference in New Issue
const IDRecalcFlag flag