51struct DepsgraphEvalState;
53void deg_task_run_func(
TaskPool *pool,
void *taskdata);
55void schedule_children(DepsgraphEvalState *
state,
60enum class EvaluationStage {
76 SINGLE_THREADED_WORKAROUND,
79struct DepsgraphEvalState {
82 EvaluationStage stage;
83 bool need_update_pending_parents =
true;
84 bool need_single_thread_pass =
false;
92 BLI_assert_msg(!operation_node->is_noop(),
"NOOP nodes should not actually be scheduled");
94 if (
state->do_stats) {
110void deg_task_run_func(
TaskPool *pool,
void *taskdata)
113 DepsgraphEvalState *
state = (DepsgraphEvalState *)userdata_v;
117 evaluate_node(
state, operation_node);
125bool check_operation_node_visible(
const DepsgraphEvalState *
state,
OperationNode *op_node)
136 if (
state->stage == EvaluationStage::DYNAMIC_VISIBILITY) {
140 return comp_node->affects_visible_id;
143void calculate_pending_parents_for_node(
const DepsgraphEvalState *
state,
OperationNode *node)
146 node->num_links_pending = 0;
147 node->scheduled =
false;
149 if (!check_operation_node_visible(
state, node)) {
156 for (
Relation *rel : node->inlinks) {
163 if (!check_operation_node_visible(
state, from)) {
170 ++node->num_links_pending;
175void calculate_pending_parents_if_needed(DepsgraphEvalState *
state)
177 if (!
state->need_update_pending_parents) {
182 calculate_pending_parents_for_node(
state, node);
185 state->need_update_pending_parents =
false;
188void initialize_execution(DepsgraphEvalState *
state,
Depsgraph *graph)
191 if (
state->do_stats) {
193 node->stats.reset_current();
198bool is_metaball_object_operation(
const OperationNode *operation_node)
201 const IDNode *id_node = component_node->owner;
202 if (
GS(id_node->id_cow->name) !=
ID_OB) {
205 const Object *
object =
reinterpret_cast<const Object *
>(id_node->id_cow);
209bool need_evaluate_operation_at_stage(DepsgraphEvalState *
state,
213 switch (
state->stage) {
214 case EvaluationStage::COPY_ON_EVAL:
217 case EvaluationStage::DYNAMIC_VISIBILITY:
220 case EvaluationStage::THREADED_EVALUATION:
221 if (is_metaball_object_operation(operation_node)) {
222 state->need_single_thread_pass =
true;
227 case EvaluationStage::SINGLE_THREADED_WORKAROUND:
230 BLI_assert_msg(0,
"Unhandled evaluation stage, should never happen.");
238void schedule_node(DepsgraphEvalState *
state,
244 if (!check_operation_node_visible(
state, node)) {
260 if (node->num_links_pending != 0) {
264 if (!need_evaluate_operation_at_stage(
state, node)) {
270 if (node->is_noop()) {
276 schedule_children(
state, node, schedule_fn);
285void schedule_graph(DepsgraphEvalState *
state,
289 schedule_node(
state, node,
false, schedule_fn);
293void schedule_children(DepsgraphEvalState *
state,
297 for (
Relation *rel : node->outlinks) {
300 if (child->scheduled) {
311void evaluate_graph_threaded_stage(DepsgraphEvalState *
state,
313 const EvaluationStage stage)
315 state->stage = stage;
317 calculate_pending_parents_if_needed(
state);
326void evaluate_graph_single_threaded_if_needed(DepsgraphEvalState *
state)
328 if (!
state->need_single_thread_pass) {
334 state->stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
340 schedule_graph(
state, schedule_node_to_queue);
346 evaluate_node(
state, operation_node);
347 schedule_children(
state, operation_node, schedule_node_to_queue);
353void depsgraph_ensure_view_layer(
Depsgraph *graph)
359 Scene *scene_cow = graph->scene_cow;
366 const IDNode *scene_id_node = graph->find_id_node(&graph->scene->id);
370TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *
state)
396 static std::atomic<uint64_t> global_update_count = 0;
397 graph->
update_count = global_update_count.fetch_add(1) + 1;
407 depsgraph_ensure_view_layer(graph);
410 DepsgraphEvalState
state;
415 initialize_execution(&
state, graph);
436 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::COPY_ON_EVAL);
441 state.need_update_pending_parents =
true;
443 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::DYNAMIC_VISIBILITY);
452 state.need_update_pending_parents =
true;
455 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::THREADED_EVALUATION);
459 evaluate_graph_single_threaded_if_needed(&
state);
464 if (
state.do_stats) {
@ G_DEBUG_DEPSGRAPH_NO_THREADS
#define BLI_assert_msg(a, msg)
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
GSQueue * BLI_gsqueue_new(size_t elem_size)
bool BLI_gsqueue_is_empty(const GSQueue *queue)
TaskPool * BLI_task_pool_create_suspended(void *userdata, eTaskPriority priority)
void * BLI_task_pool_user_data(TaskPool *pool)
TaskPool * BLI_task_pool_create_no_threads(void *userdata)
void BLI_task_pool_work_and_wait(TaskPool *pool)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
Platform independent time functions.
double BLI_time_now_seconds(void)
#define BPy_BEGIN_ALLOW_THREADS
#define BPy_END_ALLOW_THREADS
Object is a sort of wrapper for general info.
Provides wrapper around system-specific atomic primitives, and some extensions (faked-atomic operatio...
ATOMIC_INLINE uint8_t atomic_fetch_and_or_uint8(uint8_t *p, uint8_t b)
ATOMIC_INLINE uint32_t atomic_sub_and_fetch_uint32(uint32_t *p, uint32_t x)
BPy_StructRNA * depsgraph
void begin_graph_evaluation()
void end_graph_evaluation()
bool do_time_debug() const
void deg_eval_stats_aggregate(Depsgraph *graph)
bool deg_eval_copy_is_expanded(const ID *id_cow)
void deg_graph_clear_tags(Depsgraph *graph)
ID * deg_update_eval_copy_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
void deg_evaluate_on_refresh(Depsgraph *graph)
@ DEPSOP_FLAG_CLEAR_ON_EVAL
@ DEPSOP_FLAG_NEEDS_UPDATE
@ DEPSOP_FLAG_AFFECTS_VISIBILITY
void deg_graph_flush_visibility_flags_if_needed(Depsgraph *graph)
bool need_update_nodes_visibility
bool has_animated_visibility
Set< OperationNode * > entry_tags