Add a new node to the dependency graph, to act as a single entry point
before drivers are evaluated in parallel.
The node will take all the driven RNA properties, and write their
current value to the property again. This ensures that any implicitly
shared data is copied to ensure writability. Subsequent concurrent
writes by the driver evaluation will then be safe, as the
thread-unsafe part has already been performed.
Fixes: #132423
Pull Request: https://projects.blender.org/blender/blender/pulls/135802
I observed allocation becoming a bottleneck when building the depsgraph
with scenes with many simple data-blocks. One of the main culprits was
the struct that encodes relations between nodes in the graph.
Instead of allocating each `Relation` with a separate allocation call,
combine them into a `LinearAllocator`. That is must faster because it
allocates in large chunks and just bumps an offset on each allocation.
In a test file with 30 thousand cube objects, I observe a 1.18x
improvement in depsgraph evaluation time, from 1370 to 1163 ms.
The depsgraph isn't completely re-allocated when it's rebuilt, so the
allocator added in this PR has to be cleared manually. In the future,
it can be used for other structs or potentially strings.
Pull Request: https://projects.blender.org/blender/blender/pulls/137303
While profiling a scene with many objects, I noticed some unexpected
functions taking a significant time of depsgraph creation/evaluation.
String length calculation and equality comparison was taking longer than
it should, and some simple methods were appearing in profiles that should
be inlined instead.
There are more places where this sort of change would be helpful, this
commit just changes places using `OperationIDKey` and `ComponentIDKey`.
Pull Request: https://projects.blender.org/blender/blender/pulls/136795
Instead of the monolothic `depsgraph_type.hh` header that includes
most types used in the despgraph, just add includes where they are
actually necessary. Also remove the `using` keywords for `std` types.
The lack of specificity isn't considered good practice nowadays.
Removing unnecessary transitive includes can help improve compile
times because the time spent parsing headers decreases. Using the
"include what you use" pattern makes futher improvements much
easier too, since it the path to further reduce transitive includes
becomes much clearer.
Pull Request: https://projects.blender.org/blender/blender/pulls/133749
The issue is due to a dependency cycle which leads to access of data
which is not ready yet.
The dependency cycle was introduced in ada367a0e9.
This change makes it so there is no dependency cycle in the setup from
the report by re-routing dependencies a bit: the light linking now
bypasses the geometry component and is only wired to an operation
related on instancing collection (but not use by a boolean modifier).
Pull Request: https://projects.blender.org/blender/blender/pulls/127143
There is some special code in the Object's freeing which did
special checks for SubdivCCG based on the evaluated mesh state.
If the depsgraph is destroyed prior to the evaluated object it
makes object to access freed components of ID node.
The fix makes it so the evaluated ID is freed prior to freeing
components.
While the evaluated result is not well defined, we expect Blender to not crash
when there are dependency cycles.
The evaluation of one object often takes the evaluated geometry of another
object into account. This works fine if the other object is already fully
evaluated. However, if there is a dependency cycle, the other object may not be
evaluated already. Currently, we have no way to check for this and were mostly
just relying on luck that the other objects geometry is in some valid state
(even if it's not the fully evaluated geometry).
This patch adds the ability to explicitly check if an objects geometry is fully
evaluated already, so that it can be accessed by other objects. If there are not
dependency cycles, this should always be true. If not, it may be false
sometimes, and in this case the other objects geometry should be ignored. The
same also applies to the object transforms and the geometry of a collection.
For that, new functions are added in `DEG_depsgraph_query.hh`. Those should be
used whenever accessing another objects or collections object during depsgraph
evaluation. More similar functions may be added in the future.
```
bool DEG_object_geometry_is_evaluated(const Object &object);
bool DEG_object_transform_is_evaluated(const Object &object);
bool DEG_collection_geometry_is_evaluated(const Collection &collection);
```
To determine if the these components are fully evaluated, a reference to the
corresponding depsgraph is needed. A possible solution to that is to pass the
depsgraph through the call stack to these functions. While possible, there are a
couple of annoyances. For one, the parameter would need to be added in many new
places. I don't have an exact number, but it's like 50 or so. Another
complication is that under some circumstances, multiple depsgraphs may have to
be passed around, for example when evaluating node tools (also see
`GeoNodesOperatorDepsgraphs`).
To simplify the patch and other code in the future, a different route is taken
where the depsgraph pointer is added to `ID_Runtime`, making it readily
accessible similar to the `ID.orig_id`. The depsgraph pointer is set in the same
place where the `orig_id` is set.
As a nice side benefit, this also improves the situation in simple cases like
having two cubes with a boolean modifier and they union each other.
Pull Request: https://projects.blender.org/blender/blender/pulls/123444
Avoid re-copying the scene when the scene is tagged for frame change.
For scenes with many objects scrubbing & jumping between first/last
caused noticeably worse performances.
Resolve by:
- Returning false from need_tag_cow_before_update when the recalc flag
is ID_RECALC_FRAME_CHANGE.
- Change deg_graph_tag_parameters_if_needed to consider
ID_RECALC_FRAME_CHANGE a clean flag.
Ref !104801
The depsgraph CoW mechanism is a bit of a misnomer. It creates an
evaluated copy for data-blocks regardless of whether the copy will
actually be written to. The point is to have physical separation between
original and evaluated data. This is in contrast to the commonly used
performance improvement of keeping a user count and copying data
implicitly when it needs to be changed. In Blender code we call this
"implicit sharing" instead. Importantly, the dependency graph has no
idea about the _actual_ CoW behavior in Blender.
Renaming this functionality in the despgraph removes some of the
confusion that comes up when talking about this, and will hopefully
make the depsgraph less confusing to understand initially too. Wording
like "the evaluated copy" (as opposed to the original data-block) has
also become common anyway.
Pull Request: https://projects.blender.org/blender/blender/pulls/118338
The issue was caused by Cycles doing dependency tracking on its
side, relying on the fact that view layer needs to be tagged as
modified when its properties change.
This was not the case when custom property on the a view layer is
modified via a driver.
Now the dependency graph will tag IDs which generic properties did
change as ID_RECALC_PARAMETERS, giving it a chance to render engines
to react to it.
Since this is quite generic code which might have unforeseen side
effects the change is not targeted to the current release branch.
Note that this chaneg does not fix the #103140, as the issue there
is use of RNA path to another data-block, without the node tree
registering relation to that data-block.
Pull Request: https://projects.blender.org/blender/blender/pulls/118134
`UUID` generally stands for "universally unique identifier". The session identifier that
we use is neither universally unique, nor does it follow the standard. Therefor, the term
"session uuid" is confusing and should be replaced.
In #116888 we briefly talked about a better name and ended up with "session uid".
The reason for "uid" instead of "id" is that the latter is a very overloaded term in Blender
already.
This patch changes all uses of "uuid" to "uid" where it's used in the context of a
"session uid". It's not always trivial to see whether a specific mention of "uuid" refers
to an actual uuid or something else. Therefore, I might have missed some renames.
I can't think of an automated way to differentiate the case.
BMesh also uses the term "uuid" sometimes in a the wrong context (e.g. `UUIDFaceStepItem`)
but there it also does not mean "session uid", so it's *not* changed by this patch.
Pull Request: https://projects.blender.org/blender/blender/pulls/117350
This node is needed to ensure evaluation order of scene and modifiers
which might access scene for custom data masks, or for the current
frame.
Move it to own component, so that evaluation of scene does not lead
to changes in the parameters component, hence does not trigger
driver evaluation.
Should be no functional changes.
Ref #117335
Instead of having a set of hardcoded rules in the collection and
object instance collection builder introduce new node on object's
INSTANCING component which is to be hooked up to the node which is
duplicating the object.
Should be no functional changes.
Currently there is no functional changes.
In the future it allows to more easily hook the shading component
to other nodes to ensure the visibility flow.
Note that since the operation is not used by any relation it will
appear disconnected in the graphviz debugger. This is due to the
current behavior of deg_graph_remove_unused_noops().
This adds a new `Bake` node which allows saving and loading intermediate geometries.
Typical use cases we want address with this currently are:
* Bake some data for use with a render engine.
* Bake parts of the node tree explicitly for better performance.
For now, the format that is written to disk is not considered to be an import/export format.
It's not guaranteed that data written with one Blender version can be read by another
Blender version. For that it's better to use proper interchange formats. Better support for
those will be added eventually as well. We also plan an `Import Bake` node that allows
reading the blender-specific baked data independent of the Bake node and at different frames.
The baking works very similar to the baking in the simulation zone (UI and implementation
wise). Major differences are:
* The Bake node has a `Bake Still` and `Bake Animation` mode.
* The Bake node doesn't do automatic caching.
Implementation details:
* Refactored how we create the Python operators for moving socket items so that it also
makes sense for non-zones.
* The `ModifierCache` stores an independent map of `SimulationNodeCache` and
`BakeNodeCache`, but both share a common data structure for the actually baked data.
* For baking, the `Bake` node is added as a side-effect-node in the modifier. This will make
sure that the node is baked even if it's currently not connected to the output.
* Had to add a new `DEG_id_tag_update_for_side_effect_request` function that is used
during baking. It's necessary because I want to evaluate the object again even though none
of its inputs changed. The reevaluation is necessary to create the baked data. Using
`DEG_id_tag_update` technically works as well, but has the problem that it also uses the
`DEG_UPDATE_SOURCE_USER_EDIT` flag which (rightly) invalidates simulation caches
which shouldn't happen here.
* Slightly refactored the timeline drawing so that it can also show the baked ranges of
Bake nodes. It does not show anything for baked nodes with a in Still mode though.
* The bake operator is refactored to bake a list of `NodeBakeRequest` which makes the
code easier to follow compared to the previous nested
`ObjectBakeData > ModifierBakeData > NodeBakeData` data structure.
* The bake operators are disabled when the .blend file is not yet saved. This is technically
only necessary when the bake path depends on the .blend file path but seems ok to force
the user anyway (otherwise the bake path may be lost as well if it's set explicitly).
* The same operators are used to bake and delete single bakes in `Bake` nodes and
`Simulation Zones`. On top of that, there are separate operators of baking and deleting all
simulation bakes (those ignore bake nodes).
* The `Bake` node remembers which inputs have been fields and thus may be baked as attributes.
For that it uses an `Is Attribute` flag on the socket item. This is needed because the baked data
may still contain attribute data, even if the inputs to the bake node are disconnected.
* Similar to simulation zones, the behavior of `Bake` nodes is passed into the geometry nodes
evaluation from the outside (from the modifier only currently). This is done by providing the
new `GeoNodesBakeParams` in `GeoNodesCallData` when executing geometry nodes.
Next Steps (mostly because they also involve simulations):
* Visualize nodes that have not been evaluated in the last evaluation.
* Fix issue with seemingly loosing baked data after undo.
* Improve error handling when baked data is not found.
* Show bake node in link drag search.
* Higher level tools for managing bakes.
Pull Request: https://projects.blender.org/blender/blender/pulls/115466
Listing the "Blender Foundation" as copyright holder implied the Blender
Foundation holds copyright to files which may include work from many
developers.
While keeping copyright on headers makes sense for isolated libraries,
Blender's own code may be refactored or moved between files in a way
that makes the per file copyright holders less meaningful.
Copyright references to the "Blender Foundation" have been replaced with
"Blender Authors", with the exception of `./extern/` since these this
contains libraries which are more isolated, any changed to license
headers there can be handled on a case-by-case basis.
Some directories in `./intern/` have also been excluded:
- `./intern/cycles/` it's own `AUTHORS` file is planned.
- `./intern/opensubdiv/`.
An "AUTHORS" file has been added, using the chromium projects authors
file as a template.
Design task: #110784
Ref !110783.
This data-block was originally added in eb4e3bbe68.
However, that original plan wasn't fully implemented, with simulations
now integrated with geometry nodes and modifiers instead of a separate
data-block. We kept the data-block around anyway since we have the
loose plan of using a similar data-block to make global simulations
connected between multiple objects. But it may be a while before we
implement that, and in the meantime having this just causes confusion.
A lot of files were missing copyright field in the header and
the Blender Foundation contributed to them in a sense of bug
fixing and general maintenance.
This change makes it explicit that those files are at least
partially copyrighted by the Blender Foundation.
Note that this does not make it so the Blender Foundation is
the only holder of the copyright in those files, and developers
who do not have a signed contract with the foundation still
hold the copyright as well.
Another aspect of this change is using SPDX format for the
header. We already used it for the license specification,
and now we state it for the copyright as well, following the
FAQ:
https://reuse.software/faq/
Stored `ComponentIDKey` and `OperationIDKey` would still use string
references (char pointers) to data in related IDs, instead of using the
already locally stored std::string name of their matching `ComponentNode`
or `OperationNode` for that.
During undo, to reduce updates and speedup undo steps, a lot of IDs get
'replaced in place', i.e. new data read from the undo memfile is moved
into the existing 'old' ID memory address. And the depsgraph is also
re-used from the old BMain.
Calling `DEG_id_tag_update` and similar on the ID could then cause
depsgraph code to access freed memory from the 'old' data.
Joint effort with @sergey and the rest of the depsgraph team, thanks!
The goal is to solve confusion of the "All rights reserved" for licensing
code under an open-source license.
The phrase "All rights reserved" comes from a historical convention that
required this phrase for the copyright protection to apply. This convention
is no longer relevant.
However, even though the phrase has no meaning in establishing the copyright
it has not lost meaning in terms of licensing.
This change makes it so code under the Blender Foundation copyright does
not use "all rights reserved". This is also how the GPL license itself
states how to apply it to the source code:
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software ...
This change does not change copyright notice in cases when the copyright
is dual (BF and an author), or just an author of the code. It also does
mot change copyright which is inherited from NaN Holding BV as it needs
some further investigation about what is the proper way to handle it.
For example
```
OIIOOutputDriver::~OIIOOutputDriver()
{
}
```
becomes
```
OIIOOutputDriver::~OIIOOutputDriver() {}
```
Saves quite some vertical space, which is especially handy for
constructors.
Pull Request: https://projects.blender.org/blender/blender/pulls/105594
As an optimization, dependency graph evaluation skips through
no-op nodes at the scheduling stage. However, that leaves update
flags enabled on the node, and the most problematic one is the
USER_MODIFIED flag, which get flushed to children every time
the no-op node is tagged.
This in turn can cause simulation caches downstream to be
permanently stuck in an outdated state until the depsgraph
is rebuilt and the stuck flag cleared out.
Differential Revision: https://developer.blender.org/D16868
The function is already doing a lot of memory indirections and
sub-optimal lookups, so for the simplicity and robustness of the
system might as well just do copy-on-write update.
This is the conventional way of dealing with unused arguments in C++,
since it works on all compilers.
Regex find and replace: `UNUSED\((\w+)\)` -> `/*$1*/`
The ID nodes will use the provided component name to maintain
the map-based storage, while the component node itself could
override the empty name with a type name.
This lead to situations when it is not possible to lookup
the operation from its owner parameters.
This was essentially a use-after-free issue. When a geometry nodes
group changes it has to be preprocessed again before it can be evaluated.
This part was working, the issue was that parent node groups have to be
preprocessed as well, which was missing. The lazy-function graph cached
on the parent node group was still referencing data that was freed when
the child group changed.
Now the depsgraph makes sure that all relevant geometry node groups are
preprocessed again after a change.
This issue was found by Simon Thommes.
The internal state tracking is not fully suited for such kind
of optimization yet.
It is probably not that much work to make them work, but the
issue caused by the changes is serious enough for the studio
so it feels better to revert changes for now and have a closer
look into remaining issues without pressure.
A regression since ac20970bc2
The issue was caused by depsgraph clearing all id->recalc flags
wrongly assuming that all IDs are fully evaluated.
This change makes it so the depsgraph becomes aware of possibly
incompletely evaluated IDs.
Differential Revision: https://developer.blender.org/D15946