Previously, the modifier name was used to identify it in a compute context or
viewer path. Using `ModifierData.persistent_uid` (which was only introduced
later) has two main benefits: * It is stable even when the modifier name
changes. * It's cheaper and easier to work with since it's just an integer
instead of a string.
Note: Pinned viewer nodes will need to be re-pinned after the change.
Pull Request: https://projects.blender.org/blender/blender/pulls/138864
Like other runtime structs, it doesn't make sense to write this
data to files. And moving it out of DNA to an allocated C++ struct
means we can use other C++ features in it, like the new Mutex
type which I switched to in this commit.
Pull Request: https://projects.blender.org/blender/blender/pulls/138551
This patch adds a new `BLI_mutex.hh` header which adds `blender::Mutex` as alias
for either `tbb::mutex` or `std::mutex` depending on whether TBB is enabled.
Description copied from the patch:
```
/**
* blender::Mutex should be used as the default mutex in Blender. It implements a subset of the API
* of std::mutex but has overall better guaranteed properties. It can be used with RAII helpers
* like std::lock_guard. However, it is not compatible with e.g. std::condition_variable. So one
* still has to use std::mutex for that case.
*
* The mutex provided by TBB has these properties:
* - It's as fast as a spin-lock in the non-contended case, i.e. when no other thread is trying to
* lock the mutex at the same time.
* - In the contended case, it spins a couple of times but then blocks to avoid draining system
* resources by spinning for a long time.
* - It's only 1 byte large, compared to e.g. 40 bytes when using the std::mutex of GCC. This makes
* it more feasible to have many smaller mutexes which can improve scalability of algorithms
* compared to using fewer larger mutexes. Also it just reduces "memory slop" across Blender.
* - It is *not* a fair mutex, i.e. it's not guaranteed that a thread will ever be able to lock the
* mutex when there are always more than one threads that try to lock it. In the majority of
* cases, using a fair mutex just causes extra overhead without any benefit. std::mutex is not
* guaranteed to be fair either.
*/
```
The performance benchmark suggests that the impact is negilible in almost
all cases. The only benchmarks that show interesting behavior are the once
testing foreach zones in Geometry Nodes. These tests are explicitly testing
overhead, which I still have to reduce over time. So it's not unexpected that
changing the mutex has an impact there. What's interesting is that on macos the
performance improves a lot while on linux it gets worse. Since that overhead
should eventually be removed almost entirely, I don't really consider that
blocking.
Links:
* Documentation of different mutex flavors in TBB:
https://www.intel.com/content/www/us/en/docs/onetbb/developer-guide-api-reference/2021-12/mutex-flavors.html
* Older implementation of a similar mutex by me:
https://archive.blender.org/developer/differential/0016/0016711/index.html
* Interesting read regarding how a mutex can be this small:
https://webkit.org/blog/6161/locking-in-webkit/
Pull Request: https://projects.blender.org/blender/blender/pulls/138370
Previously to handle unevaluated objects in line art "load all"
iteration, a `include_objects` variable is added in depsgraph
iteration settings, and this was only processed by object iterator
but not for any of the dupli objects. Now `make_duplis_collection`
will also handle `include_objects`
The only case where this border case can lead to crash is that a
line art grease pencil object is inside one of the dupli collection,
which isn't a valid use in the first place. But this fix makes it
more robust.
Pull Request: https://projects.blender.org/blender/blender/pulls/137323
Checking whether relations already existed was a bottleneck when building
collection -> object hierarchy relations. The duplicate checking would be
unnecessary since an object can only be in a collection once, but this function
to build relations can be called multiple times for the same collection.
To avoid the need to check for duplicates, only run the relation creation
once for each collection. The `BuilderMap` gives a simple way to do that.
Note that because a collection might be built separately as a non-layer
collection, there may still be duplicate hierarchy relations.
Building a Depsgraph for 60k simple objects became 1.86x faster, from 2.39
to 1.29 seconds.
Pull Request: https://projects.blender.org/blender/blender/pulls/137737
* Remove `DEG_get_evaluated_object` in favor of `DEG_get_evaluated`.
* Remove `DEG_is_original_object` in favor of `DEG_is_original`.
* Remove `DEG_is_evaluated_object` in favor of `DEG_is_evaluated`.
Pull Request: https://projects.blender.org/blender/blender/pulls/138317
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
Ref: #132179
Renames:
- `Editing.act_seq` -> `Editing.act_strip`
- `SequenceModifierData` -> `StripModifierData`
- Its member `mask_sequence` is now `mask_strip`.
- `MetaStack.parseq` -> `MetaStack.parent_strip`
- Remaining function names/parameters that were not dealt with in #132748
- Various references to `seq` or `sequence` throughout code and docs when
referring to a strip
Also moves `_get` to the end of the renamed function names where
applicable for standardization (unless "by" or "from" are used).
There should be no changes to current behavior.
Pull Request: https://projects.blender.org/blender/blender/pulls/138077
Allows to log human-readable list of recalc bits that are set.
The usage is pretty simple:
```
printf("%s: %s %s\n", __func__, id->name, DEG_stringify_recalc_flags(id->recalc).c_str());
```
Pull Request: https://projects.blender.org/blender/blender/pulls/137715
The goal here is to avoid having to cast to and from `ID` when getting the
evaluated or original ID using the depsgraph API, which is often verbose and not
type safe. To solve this, there are now `DEG_get_original` and
`DEG_get_evaluated` methods which are templated on the type and use a new
`is_ID_v` static type check to make sure it's only used with valid types.
This allows removing quite some verbosity on all the call sites. I also removed
`DEG_get_original_object`, because that does not have to be a special case
anymore.
Pull Request: https://projects.blender.org/blender/blender/pulls/137629
Use `blender::Stack` instead of `BLI_Stack`. Theoretically this can
improve performance because it makes use of inlining to remove function
call overhead and give the compiler more information. I observed a build
time improvement of about 4%, from 1156 to 1113 ms with 30k cube objects.
Notably, now `deg_graph_flush_visibility_flags` doesn't call any
non-inlined functions.
Pull Request: https://projects.blender.org/blender/blender/pulls/137355
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
Adding "writeback" callbacks to the depsgraph should be temporary, since these
callbacks can bind pointers that become invalid. In this case: the evaluated
nodes modifier bound by a bake node callback. These callbacks are cleared after
being added in the `deg_flush_updates_and_refresh` function, but there are other
cases where depsgraph updates are executed which don't support writeback
callbacks (`object_force_modifier_update_for_bind` run by the smooth modifier
"bind" function).
To prevent dangling invalid pointers in outdated callbacks, disallow adding
callbacks in any case other than the `deg_flush_updates_and_refresh` function.
Since callbacks can be added from any depsgraph update, the safest way to
prevent adding them is in the depsgraph itself. If the `use_writeback_callbacks`
flag is not set, any callback is simply discarded.
Pull Request: https://projects.blender.org/blender/blender/pulls/137083
When the collection is disabled and was only referenced by a node tree, it was
missing from the depsgraph. The Geometry Nodes modifier tried to add a relation
to it, but it couldn't because the collection was not in the depsgraph in the first place.
Now, the collection is always added to the depsgraph when it's referenced by a
node tree that's in the depsgraph too. This makes the existing code that adds the
relation from the collection to the Geometry Nodes modifier work.
Pull Request: https://projects.blender.org/blender/blender/pulls/136328
This implements bundles and closures which are described in more detail in this
blog post: https://code.blender.org/2024/11/geometry-nodes-workshop-october-2024/
tl;dr:
* Bundles are containers that allow storing multiple socket values in a single
value. Each value in the bundle is identified by a name. Bundles can be
nested.
* Closures are functions that are created with the Closure Zone and can be
evaluated with the Evaluate Closure node.
To use the patch, the `Bundle and Closure Nodes` experimental feature has to be
enabled. This is necessary, because these features are not fully done yet and
still need iterations to improve the workflow before they can be officially
released. These iterations are easier to do in `main` than in a separate branch
though. That's because this patch is quite large and somewhat prone to merge
conflicts. Also other work we want to do, depends on this.
This adds the following new nodes:
* Combine Bundle: can pack multiple values into one.
* Separate Bundle: extracts values from a bundle.
* Closure Zone: outputs a closure zone for use in the `Evaluate Closure` node.
* Evaluate Closure: evaluates the passed in closure.
Things that will be added soon after this lands:
* Fields in bundles and closures. The way this is done changes with #134811, so
I rather implement this once both are in `main`.
* UI features for keeping sockets in sync (right now there are warnings only).
One bigger issue is the limited support for lazyness. For example, all inputs of
a Combine Bundle node will be evaluated, even if they are not all needed. The
same is true for all captured values of a closure. This is a deeper limitation
that needs to be resolved at some point. This will likely be done after an
initial version of this patch is done.
Pull Request: https://projects.blender.org/blender/blender/pulls/128340
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
This replaces the deprecated DrawData mechanism by the
usage of the update timestamp `last_update`.
The compositor keeps the `last_update` value of the cached ID
and compares it with the value on the ID at the time of evaluation.
Rel #134690
Pull Request: https://projects.blender.org/blender/blender/pulls/134878
This was cause by the legacy undo recreating the depsgraph for
every update.
Depsgraph is recreated for each undo step which make the update
counter stay at 1. The fix is to protect for this case using a
global atomic counter.
This PR creates 2 namespaces for VSE code:
- `blender::seq` for sequencer core code
- `blender::ed::vse` for editor code
These names are chosen to not be in conflict with each other.
No namespace was used for RNA.
Finally, file `BKE_sequencer_offscreen.h` was moved from BKE to sequencer.
Pull Request: https://projects.blender.org/blender/blender/pulls/135500
The general idea is to keep the 'old', C-style MEM_callocN signature, and slowly
replace most of its usages with the new, C++-style type-safer template version.
* `MEM_cnew<T>` allocation version is renamed to `MEM_callocN<T>`.
* `MEM_cnew_array<T>` allocation version is renamed to `MEM_calloc_arrayN<T>`.
* `MEM_cnew<T>` duplicate version is renamed to `MEM_dupallocN<T>`.
Similar templates type-safe version of `MEM_mallocN` will be added soon
as well.
Following discussions in !134452.
NOTE: For now static type checking in `MEM_callocN` and related are slightly
different for Windows MSVC. This compiler seems to consider structs using the
`DNA_DEFINE_CXX_METHODS` macro as non-trivial (likely because their default
copy constructors are deleted). So using checks on trivially
constructible/destructible instead on this compiler/system.
Pull Request: https://projects.blender.org/blender/blender/pulls/134771
This patch refactors static cache invalidation of images by tracking an
update count. Images now store a runtime update count that is updated
every time the image is tagged for update. Cached images store a copy of
the update count at the moment they were cached, and are invalidated if
if it changed.
Compared to #134878, this is simpler and more robust, since update IDs
are isolated to images only and not to the DEG update count. Though this
only supports images specifically because they are not covered by the
copy-on-evaluation system, which means #134878 will cause multiple
depsgraph to fight over images.
Pull Request: https://projects.blender.org/blender/blender/pulls/134905
Grease Pencil ID data was being evaluated in the
`BKE_grease_pencil_data_update` function, but this function
is called from the evaluated objects.
The fix adds a new `BKE_grease_pencil_eval_geometry` function
thats called as a callback from `build_object_data_geometry_datablock`.
Resolves#134980, #135004.
Pull Request: https://projects.blender.org/blender/blender/pulls/135051
The main goal of these changes are to improve static (i.e. build-time)
checks on whether a given data can be allocated and freed with `malloc`
and `free` (C-style), or requires proper C++-style construction and
destruction (`new` and `delete`).
* Add new `MEM_malloc_arrayN_aligned` API.
* Make `MEM_freeN` a template function in C++, which does static assert on
type triviality.
* Add `MEM_SAFE_DELETE`, similar to `MEM_SAFE_FREE` but calling
`MEM_delete`.
The changes to `MEM_freeN` was painful and useful, as it allowed to fix a bunch
of invalid calls in existing codebase already.
It also highlighted a fair amount of places where it is called to free incomplete
type pointers, which is likely a sign of badly designed code (there should
rather be an API to destroy and free these data then, if the data type is not fully
publicly exposed). For now, these are 'worked around' by explicitly casting the
freed pointers to `void *` in these cases - which also makes them easy to search for.
Some of these will be addressed separately (see blender/blender!134765).
Finally, MSVC seems to consider structs defining new/delete operators (e.g. by
using the `MEM_CXX_CLASS_ALLOC_FUNCS` macro) as non-trivial. This does not
seem to follow the definition of type triviality, so for now static type checking in
`MEM_freeN` has been disabled for Windows. We'll likely have to do the same
with type-safe `MEM_[cm]allocN` API being worked on in blender/blender!134771
Based on ideas from Brecht in blender/blender!134452
Pull Request: https://projects.blender.org/blender/blender/pulls/134463
`DEGCustomDataMeshMasks` makes `IDInfo` struct non-trivial, so it should
not be allocated or freed with C-style allocation.
Instead of allocating this data, now use its only persistent user
(the `DepsgraphNodeBuilder::id_info_hash_` map) as owner, move the rest
of the code releasing COW IDs to a new destructor for `IDInfo`, and let
standard C++ destruction do the job.
NOTE: This change seems to give some performances improvements in
affected code (e.g. about 4% improvement in affected area of
`DepsgraphNodeBuilder::begin_build`). However, this does not affect global
performances in a measurable way.
Related to work on improving our memory allocation code in !134463.
Pull Request: https://projects.blender.org/blender/blender/pulls/134563
This fixes the (unreported) issue where solo'ing an NLA track would only
play back animation when _any_ of the tracks were unmuted.
Some code considered a track to be muted when its `NLATRACK_MUTED` flag
was set regardless of the `NLATRACK_SOLO` flag, whereas other code did
consider the `NLATRACK_SOLO` flag.
Now all the code is consistent with what actual animation evaluation is
doing.
Pull Request: https://projects.blender.org/blender/blender/pulls/134500
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
When duplicating an action, it is stashed in the NLA on a muted track.
Over time this can slow down blender, because certain code will look at every
FCurve in every action in the NLA.
To fix the performance issue, we can take advantage of the fact that
stashed actions are put onto a muted NLA track.
With this patch any strip on a muted NLA track is ignored in the
Depsgraph evaluation.
Measurements of `DEG_graph_relations_update`
| - | Before | After |
| - | - | - |
| 50 actions | ~140 ms | ~10.0 ms |
| 100 actions | ~250 ms | ~10.7 ms |
Pull Request: https://projects.blender.org/blender/blender/pulls/133864
The recent addition of DEG_disable_visibility_optimization in #133358
almost fixed this, but it was not fully working. By ensuring objects
are evaluated we avoid modifying original objects.
If for some reason (like a Python handler) the object is still missing,
report an error in the bake operator.
Pull Request: https://projects.blender.org/blender/blender/pulls/133439
This uses the following accessor methods in more places in more places:
`is_group()`, `is_group_input()`, `is_group_output()`, `is_muted()`,
`is_frame()` and `is_reroute()`.
This results in simpler code and reduces the use of `bNode.type_legacy`.
Pull Request: https://projects.blender.org/blender/blender/pulls/132899
The new description for `bNode.type_legacy`:
```
/**
* Legacy integer type for nodes. It does not uniquely identify a node type, only the `idname`
* does that. For example, all custom nodes use #NODE_CUSTOM but do have different idnames.
* This is mainly kept for compatibility reasons.
*
* Currently, this type is also used in many parts of Blender, but that should slowly be phased
* out by either relying on idnames, accessor methods like `node.is_reroute()`.
*
* A main benefit of this integer type over using idnames currently is that integer comparison is
* much cheaper than string comparison, especially if many idnames have the same prefix (e.g.
* "GeometryNode"). Eventually, we could introduce cheap-to-compare runtime identifier for node
* types. That could mean e.g. using `ustring` for idnames (where string comparison is just
* pointer comparison), or using a run-time generated integer that is automatically assigned when
* node types are registered.
*/
```
Pull Request: https://projects.blender.org/blender/blender/pulls/132858