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:
Diffstat (limited to 'source/blender/depsgraph/intern/eval/deg_eval_flush.cc')
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc128
1 files changed, 71 insertions, 57 deletions
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index daf008ddb7d..c0d5e08b80f 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -36,6 +36,7 @@
#include <deque>
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BLI_task.h"
#include "BLI_ghash.h"
@@ -51,6 +52,7 @@ extern "C" {
#include "intern/nodes/deg_node_operation.h"
#include "intern/depsgraph_intern.h"
+#include "intern/eval/deg_eval_copy_on_write.h"
#include "util/deg_util_foreach.h"
namespace DEG {
@@ -70,19 +72,6 @@ typedef std::deque<OperationDepsNode *> FlushQueue;
namespace {
-// TODO(sergey): De-duplicate with depsgraph_tag,cc
-void lib_id_recalc_tag(Main *bmain, ID *id)
-{
- id->recalc |= ID_RECALC;
- DEG_id_type_tag(bmain, GS(id->name));
-}
-
-void lib_id_recalc_data_tag(Main *bmain, ID *id)
-{
- id->recalc |= ID_RECALC_DATA;
- DEG_id_type_tag(bmain, GS(id->name));
-}
-
void flush_init_operation_node_func(
void *__restrict data_v,
const int i,
@@ -146,9 +135,10 @@ BLI_INLINE void flush_handle_id_node(IDDepsNode *id_node)
}
/* TODO(sergey): We can reduce number of arguments here. */
-BLI_INLINE void flush_handle_component_node(Depsgraph * /*graph*/,
+BLI_INLINE void flush_handle_component_node(Depsgraph *graph,
IDDepsNode *id_node,
ComponentDepsNode *comp_node,
+ bool use_copy_on_write,
FlushQueue *queue)
{
/* We only handle component once. */
@@ -156,46 +146,27 @@ BLI_INLINE void flush_handle_component_node(Depsgraph * /*graph*/,
return;
}
comp_node->done = COMPONENT_STATE_DONE;
+ /* Currently this is needed to get object->mesh to be replaced with
+ * original mesh (rather than being evaluated_mesh).
+ *
+ * TODO(sergey): This is something we need to avoid.
+ */
+ if (use_copy_on_write && comp_node->depends_on_cow()) {
+ ComponentDepsNode *cow_comp =
+ id_node->find_component(DEG_NODE_TYPE_COPY_ON_WRITE);
+ cow_comp->tag_update(graph);
+ }
/* Tag all required operations in component for update. */
foreach (OperationDepsNode *op, comp_node->operations) {
- op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
- }
- if (GS(id_node->id->name) == ID_OB) {
- Object *object = (Object *)id_node->id;
- /* This code is used to preserve those areas which does
- * direct object update,
+ /* We don't want to flush tags in "upstream" direction for
+ * certain types of operations.
*
- * Plus it ensures visibility changes and relations and
- * layers visibility update has proper flags to work with.
+ * TODO(sergey): Need a more generic solution for this.
*/
- switch (comp_node->type) {
- case DEG_NODE_TYPE_UNDEFINED:
- case DEG_NODE_TYPE_OPERATION:
- case DEG_NODE_TYPE_TIMESOURCE:
- case DEG_NODE_TYPE_ID_REF:
- case DEG_NODE_TYPE_SEQUENCER:
- case NUM_DEG_NODE_TYPES:
- /* Ignore, does not translate to object component. */
- BLI_assert(!"This should never happen!");
- break;
- case DEG_NODE_TYPE_ANIMATION:
- object->recalc |= OB_RECALC_TIME;
- break;
- case DEG_NODE_TYPE_TRANSFORM:
- object->recalc |= OB_RECALC_OB;
- break;
- case DEG_NODE_TYPE_GEOMETRY:
- case DEG_NODE_TYPE_EVAL_POSE:
- case DEG_NODE_TYPE_BONE:
- case DEG_NODE_TYPE_EVAL_PARTICLES:
- case DEG_NODE_TYPE_SHADING:
- case DEG_NODE_TYPE_CACHE:
- case DEG_NODE_TYPE_PROXY:
- object->recalc |= OB_RECALC_DATA;
- break;
- case DEG_NODE_TYPE_PARAMETERS:
- break;
+ if (op->opcode == DEG_OPCODE_PARTICLE_SETTINGS_EVAL) {
+ continue;
}
+ op->flag |= DEPSOP_FLAG_NEEDS_UPDATE;
}
/* When some target changes bone, we might need to re-run the
* whole IK solver, otherwise result might be unpredictable.
@@ -237,19 +208,54 @@ BLI_INLINE OperationDepsNode *flush_schedule_children(
return result;
}
-BLI_INLINE void flush_editors_id_update(Main *bmain,
- Depsgraph *graph)
+void flush_engine_data_update(ID *id)
+{
+ if (GS(id->name) != ID_OB) {
+ return;
+ }
+ Object *object = (Object *)id;
+ BLI_LISTBASE_FOREACH(ObjectEngineData *, engine_data, &object->drawdata) {
+ engine_data->recalc |= id->recalc;
+ }
+}
+
+/* NOTE: It will also accumulate flags from changed components. */
+void flush_editors_id_update(Main *bmain,
+ Depsgraph *graph,
+ const DEGEditorUpdateContext *update_ctx)
{
foreach (IDDepsNode *id_node, graph->id_nodes) {
if (id_node->done != ID_STATE_MODIFIED) {
continue;
}
+ DEG_id_type_tag(bmain, GS(id_node->id_orig->name));
/* TODO(sergey): Do we need to pass original or evaluated ID here? */
- ID *id = id_node->id;
- deg_editors_id_update(bmain, id);
- lib_id_recalc_tag(bmain, id);
- /* TODO(sergey): For until we've got proper data nodes in the graph. */
- lib_id_recalc_data_tag(bmain, id);
+ ID *id_orig = id_node->id_orig;
+ ID *id_cow = id_node->id_cow;
+ /* Copy tag from original data to CoW storage.
+ * This is because DEG_id_tag_update() sets tags on original
+ * data.
+ */
+ id_cow->recalc |= (id_orig->recalc & ID_RECALC_ALL);
+ /* Gather recalc flags from all changed components. */
+ GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, id_node->components)
+ {
+ if (comp_node->done != COMPONENT_STATE_DONE) {
+ continue;
+ }
+ DepsNodeFactory *factory = deg_type_get_factory(comp_node->type);
+ BLI_assert(factory != NULL);
+ id_cow->recalc |= factory->id_recalc_tag();
+ }
+ GHASH_FOREACH_END();
+ DEG_DEBUG_PRINTF("Accumulated recalc bits for %s: %u\n",
+ id_orig->name, (unsigned int)id_cow->recalc);
+ /* Inform editors. */
+ if (deg_copy_on_write_is_expanded(id_cow)) {
+ deg_editors_id_update(update_ctx, id_cow);
+ /* Inform draw engines that something was changed. */
+ flush_engine_data_update(id_cow);
+ }
}
}
@@ -260,6 +266,7 @@ BLI_INLINE void flush_editors_id_update(Main *bmain,
*/
void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
{
+ const bool use_copy_on_write = DEG_depsgraph_use_copy_on_write();
/* Sanity checks. */
BLI_assert(bmain != NULL);
BLI_assert(graph != NULL);
@@ -272,6 +279,12 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
/* Starting from the tagged "entry" nodes, flush outwards. */
FlushQueue queue;
flush_schedule_entrypoints(graph, &queue);
+ /* Prepare update context for editors. */
+ DEGEditorUpdateContext update_ctx;
+ update_ctx.bmain = bmain;
+ update_ctx.depsgraph = (::Depsgraph *)graph;
+ update_ctx.scene = graph->scene;
+ update_ctx.view_layer = graph->view_layer;
/* Do actual flush. */
while (!queue.empty()) {
OperationDepsNode *op_node = queue.front();
@@ -286,13 +299,14 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
flush_handle_component_node(graph,
id_node,
comp_node,
+ use_copy_on_write,
&queue);
/* Flush to nodes along links. */
op_node = flush_schedule_children(op_node, &queue);
}
}
/* Inform editors about all changes. */
- flush_editors_id_update(bmain, graph);
+ flush_editors_id_update(bmain, graph, &update_ctx);
}
static void graph_clear_func(