61 struct DepsgraphEvalState;
65 template<
typename ScheduleFunction,
typename... ScheduleFunctionArgs>
66 void schedule_children(DepsgraphEvalState *
state,
68 ScheduleFunction *schedule_function,
69 ScheduleFunctionArgs... schedule_function_args);
77 enum class EvaluationStage {
90 SINGLE_THREADED_WORKAROUND,
93 struct DepsgraphEvalState {
100 void evaluate_node(
const DepsgraphEvalState *
state, OperationNode *operation_node)
105 BLI_assert(!operation_node->is_noop() &&
"NOOP nodes should not actually be scheduled");
107 if (
state->do_stats) {
120 DepsgraphEvalState *
state = (DepsgraphEvalState *)userdata_v;
123 OperationNode *operation_node =
reinterpret_cast<OperationNode *
>(taskdata);
124 evaluate_node(
state, operation_node);
127 schedule_children(
state, operation_node, schedule_node_to_pool,
pool);
130 bool check_operation_node_visible(OperationNode *op_node)
132 const ComponentNode *comp_node = op_node->owner;
138 return comp_node->affects_directly_visible;
141 void calculate_pending_parents_for_node(OperationNode *
node)
147 if (!check_operation_node_visible(
node)) {
156 OperationNode *
from = (OperationNode *)rel->from;
161 if (!check_operation_node_visible(
from)) {
176 calculate_pending_parents_for_node(
node);
183 calculate_pending_parents(
graph);
192 bool is_metaball_object_operation(
const OperationNode *operation_node)
194 const ComponentNode *component_node = operation_node->owner;
195 const IDNode *
id_node = component_node->owner;
203 bool need_evaluate_operation_at_stage(DepsgraphEvalState *
state,
204 const OperationNode *operation_node)
206 const ComponentNode *component_node = operation_node->owner;
207 switch (
state->stage) {
208 case EvaluationStage::COPY_ON_WRITE:
211 case EvaluationStage::THREADED_EVALUATION:
216 if (is_metaball_object_operation(operation_node)) {
217 state->need_single_thread_pass =
true;
222 case EvaluationStage::SINGLE_THREADED_WORKAROUND:
225 BLI_assert(!
"Unhandled evaluation stage, should never happen.");
233 template<
typename ScheduleFunction,
typename... ScheduleFunctionArgs>
234 void schedule_node(DepsgraphEvalState *
state,
237 ScheduleFunction *schedule_function,
238 ScheduleFunctionArgs... schedule_function_args)
241 if (!check_operation_node_visible(
node)) {
261 if (!need_evaluate_operation_at_stage(
state,
node)) {
269 schedule_children(
state,
node, schedule_function, schedule_function_args...);
273 schedule_function(
node, 0, schedule_function_args...);
278 template<
typename ScheduleFunction,
typename... ScheduleFunctionArgs>
279 void schedule_graph(DepsgraphEvalState *
state,
280 ScheduleFunction *schedule_function,
281 ScheduleFunctionArgs... schedule_function_args)
283 for (OperationNode *
node :
state->graph->operations) {
284 schedule_node(
state,
node,
false, schedule_function, schedule_function_args...);
288 template<
typename ScheduleFunction,
typename... ScheduleFunctionArgs>
289 void schedule_children(DepsgraphEvalState *
state,
291 ScheduleFunction *schedule_function,
292 ScheduleFunctionArgs... schedule_function_args)
295 OperationNode *child = (OperationNode *)rel->to;
297 if (child->scheduled) {
305 schedule_function_args...);
309 void schedule_node_to_queue(OperationNode *
node,
316 void evaluate_graph_single_threaded(DepsgraphEvalState *
state)
319 schedule_graph(
state, schedule_node_to_queue, evaluation_queue);
322 OperationNode *operation_node;
325 evaluate_node(
state, operation_node);
326 schedule_children(
state, operation_node, schedule_node_to_queue, evaluation_queue);
376 depsgraph_ensure_view_layer(
graph);
378 DepsgraphEvalState
state;
381 state.need_single_thread_pass =
false;
387 state.stage = EvaluationStage::COPY_ON_WRITE;
394 state.stage = EvaluationStage::THREADED_EVALUATION;
400 if (
state.need_single_thread_pass) {
401 state.stage = EvaluationStage::SINGLE_THREADED_WORKAROUND;
402 evaluate_graph_single_threaded(&
state);
408 if (
state.do_stats) {
@ G_DEBUG_DEPSGRAPH_NO_THREADS
void BLI_gsqueue_free(GSQueue *queue)
void BLI_gsqueue_push(GSQueue *queue, const void *item)
GSQueue * BLI_gsqueue_new(const size_t elem_size)
void BLI_gsqueue_pop(GSQueue *queue, void *r_item)
bool BLI_gsqueue_is_empty(const GSQueue *queue)
void * BLI_task_pool_user_data(TaskPool *pool)
void BLI_task_pool_work_and_wait(TaskPool *pool)
TaskPool * BLI_task_pool_create_no_threads(void *userdata)
TaskPool * BLI_task_pool_create_suspended(void *userdata, TaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
struct Depsgraph Depsgraph
@ ID_RECALC_COPY_ON_WRITE
Object is a sort of wrapper for general info.
Platform independent time functions.
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)
void begin_graph_evaluation()
void end_graph_evaluation()
bool do_time_debug() const
bool need_single_thread_pass
const Depsgraph * depsgraph
void deg_eval_stats_aggregate(Depsgraph *graph)
ID * deg_update_copy_on_write_datablock(const Depsgraph *depsgraph, const IDNode *id_node)
void deg_graph_clear_tags(Depsgraph *graph)
static TaskPool * deg_evaluate_task_pool_create(DepsgraphEvalState *state)
void deg_evaluate_on_refresh(Depsgraph *graph)
bool deg_copy_on_write_is_expanded(const ID *id_cow)
@ DEPSOP_FLAG_NEEDS_UPDATE
IDNode * find_id_node(const ID *id) const
OperationNodes operations
Set< OperationNode * > entry_tags
uint32_t num_links_pending
double PIL_check_seconds_timer(void)