52struct DepsgraphEvalState;
54void deg_task_run_func(
TaskPool *pool,
void *taskdata);
56void schedule_children(DepsgraphEvalState *
state,
61enum class EvaluationStage {
77 SINGLE_THREADED_WORKAROUND,
80struct DepsgraphEvalState {
83 EvaluationStage stage;
84 bool need_update_pending_parents =
true;
85 bool need_single_thread_pass =
false;
93 BLI_assert_msg(!operation_node->is_noop(),
"NOOP nodes should not actually be scheduled");
95 if (
state->do_stats) {
111void deg_task_run_func(
TaskPool *pool,
void *taskdata)
114 DepsgraphEvalState *
state = (DepsgraphEvalState *)userdata_v;
118 evaluate_node(
state, operation_node);
126bool check_operation_node_visible(
const DepsgraphEvalState *
state,
OperationNode *op_node)
137 if (
state->stage == EvaluationStage::DYNAMIC_VISIBILITY) {
141 return comp_node->affects_visible_id;
144void calculate_pending_parents_for_node(
const DepsgraphEvalState *
state,
OperationNode *node)
147 node->num_links_pending = 0;
148 node->scheduled =
false;
150 if (!check_operation_node_visible(
state, node)) {
157 for (
Relation *rel : node->inlinks) {
164 if (!check_operation_node_visible(
state, from)) {
171 ++node->num_links_pending;
176void calculate_pending_parents_if_needed(DepsgraphEvalState *
state)
178 if (!
state->need_update_pending_parents) {
183 calculate_pending_parents_for_node(
state, node);
186 state->need_update_pending_parents =
false;
189void initialize_execution(DepsgraphEvalState *
state,
Depsgraph *graph)
192 if (
state->do_stats) {
194 node->stats.reset_current();
199bool is_metaball_object_operation(
const OperationNode *operation_node)
202 const IDNode *id_node = component_node->owner;
203 if (
GS(id_node->id_cow->name) !=
ID_OB) {
206 const Object *
object =
reinterpret_cast<const Object *
>(id_node->id_cow);
210bool need_evaluate_operation_at_stage(DepsgraphEvalState *
state,
214 switch (
state->stage) {
215 case EvaluationStage::COPY_ON_EVAL:
218 case EvaluationStage::DYNAMIC_VISIBILITY:
221 case EvaluationStage::THREADED_EVALUATION:
222 if (is_metaball_object_operation(operation_node)) {
223 state->need_single_thread_pass =
true;
228 case EvaluationStage::SINGLE_THREADED_WORKAROUND:
231 BLI_assert_msg(0,
"Unhandled evaluation stage, should never happen.");
239void schedule_node(DepsgraphEvalState *
state,
245 if (!check_operation_node_visible(
state, node)) {
261 if (node->num_links_pending != 0) {
265 if (!need_evaluate_operation_at_stage(
state, node)) {
271 if (node->is_noop()) {
277 schedule_children(
state, node, schedule_fn);
286void schedule_graph(DepsgraphEvalState *
state,
290 schedule_node(
state, node,
false, schedule_fn);
294void schedule_children(DepsgraphEvalState *
state,
298 for (
Relation *rel : node->outlinks) {
301 if (child->scheduled) {
312void evaluate_graph_threaded_stage(DepsgraphEvalState *
state,
314 const EvaluationStage stage)
316 state->stage = stage;
318 calculate_pending_parents_if_needed(
state);
327void evaluate_graph_single_threaded_if_needed(DepsgraphEvalState *
state)
329 if (!
state->need_single_thread_pass) {
335 state->stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
341 schedule_graph(
state, schedule_node_to_queue);
347 evaluate_node(
state, operation_node);
348 schedule_children(
state, operation_node, schedule_node_to_queue);
354void depsgraph_ensure_view_layer(
Depsgraph *graph)
360 Scene *scene_cow = graph->scene_cow;
367 const IDNode *scene_id_node = graph->find_id_node(&graph->scene->id);
371TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *
state)
399 depsgraph_ensure_view_layer(graph);
402 DepsgraphEvalState
state;
407 initialize_execution(&
state, graph);
428 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::COPY_ON_EVAL);
433 state.need_update_pending_parents =
true;
435 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::DYNAMIC_VISIBILITY);
444 state.need_update_pending_parents =
true;
447 evaluate_graph_threaded_stage(&
state,
task_pool, EvaluationStage::THREADED_EVALUATION);
451 evaluate_graph_single_threaded_if_needed(&
state);
456 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