Depsgraph: Use dedicated function for group evaluation

It is still based on generic collection evaluation, but the idea is to avoid
having view_layer pointer passed from group to it's evaluation function.

This is essential for copy-on-write, where we need to pass view_layer pointer
from a copied datablock, but that copy is not yet available at construction
time. Also, this is NOT the case where we want to expand datablock at a
construction time, just to keep our life easier.
This commit is contained in:
Sergey Sharybin 2017-12-08 14:45:15 +01:00
parent af47ae0702
commit 82c0a54168
4 changed files with 56 additions and 5 deletions

View File

@ -55,6 +55,13 @@ bool BKE_group_is_animated(struct Group *group, struct Object *parent);
void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *parent, struct Group *group);
/* Dependency graph evaluation. */
void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx,
struct Group *group);
/* Helper macros. */
#define FOREACH_GROUP_BASE(_group, _base) \
for (Base *_base = (Base *)(_group)->view_layer->object_bases.first; \
_base; \

View File

@ -55,6 +55,8 @@
#include "BKE_object.h"
#include "BKE_scene.h"
#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
/** Free (or release) any data used by this group (does not free the group itself). */
void BKE_group_free(Group *group)
{
@ -379,3 +381,36 @@ void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx
FOREACH_GROUP_OBJECT_END
}
}
/* ******** Dependency graph evaluation ******** */
static void group_eval_layer_collections(
const struct EvaluationContext *eval_ctx,
Group *group,
ListBase *layer_collections,
LayerCollection *parent_layer_collection)
{
LINKLIST_FOREACH (LayerCollection *, layer_collection, layer_collections) {
/* Evaluate layer collection itself. */
BKE_layer_eval_layer_collection(eval_ctx,
layer_collection,
parent_layer_collection);
/* Evaluate nested collections. */
group_eval_layer_collections(eval_ctx,
group,
&layer_collection->layer_collections,
layer_collection);
}
}
void BKE_group_eval_view_layers(const struct EvaluationContext *eval_ctx,
Group *group)
{
DEBUG_PRINT("%s on %s (%p)\n", __func__, group->id.name, group);
BKE_layer_eval_layer_collection_pre(eval_ctx, &group->id, group->view_layer);
group_eval_layer_collections(eval_ctx,
group,
&group->view_layer->layer_collections,
NULL);
BKE_layer_eval_layer_collection_post(eval_ctx, group->view_layer);
}

View File

@ -422,16 +422,27 @@ void DepsgraphNodeBuilder::end_build()
void DepsgraphNodeBuilder::build_group(Group *group)
{
ID *group_id = &group->id;
Group *group_cow = get_cow_datablock(group);
if (group_id->tag & LIB_TAG_DOIT) {
return;
}
group_id->tag |= LIB_TAG_DOIT;
/* Build group objects. */
LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
build_object(NULL, base->object, DEG_ID_LINKED_INDIRECTLY);
}
build_view_layer_collections(&group->id, group->view_layer);
/* Operation to evaluate the whole view layer.
*
* NOTE: We re-use DONE opcode even though the function does everything.
* This way we wouldn't need to worry about possible relations from DONE,
* regardless whether it's a group or scene or something else.
*/
add_operation_node(group_id,
DEG_NODE_TYPE_LAYER_COLLECTIONS,
function_bind(BKE_group_eval_view_layers,
_1,
group_cow),
DEG_OPCODE_VIEW_LAYER_DONE);
}
void DepsgraphNodeBuilder::build_object(Base *base,

View File

@ -429,8 +429,6 @@ void DepsgraphRelationBuilder::build_group(Object *object, Group *group)
LINKLIST_FOREACH(Base *, base, &group->view_layer->object_bases) {
build_object(NULL, base->object);
}
build_view_layer_collections(&group->id, group->view_layer);
group_id->tag |= LIB_TAG_DOIT;
}