To aid generating a cache ID, each viewer node needs a UUID. Previous iterations
tried to hash a name and time, but a UUID is a much more efficient way to do
this.
With differently set speeds, these functions would mess with the timing in ways
that would be confusing to the user. Now they act in a much more intuitive way
and also prevent negative media times.
OCIO config was set on a per-project basis, but we were using a singleton for
the ColorManager that would break if more than one project was ever open.
Now the ColorManager belongs to the Project and is always accessed through the
Project.
This commit adds the background functionality of the render cache invalidating
whenever a footage's color space is changed. This includes when the project's
configuration is changed as well.
Uniform values cannot be set if the shader is not bound, and calling Blit would
release the shader making subsequent iteration count updates not work. This
commit makes sure the shader is bound before trying to do so.
Ultimately it would be nice if nodes could configure this themselves, but
CLAMP_TO_BORDER behavior can be written manually into the shader if that
behavior is desired, whereas CLAMP_TO_EDGE cannot.
Creating and destroying textures is a slow process, particularly when we can
re-use them throughout most of the render chain. We now keep them stored so
they can be re-used which improves performance substantially.
This was many changes that were largely fundamentally related. They included:
- More const modifiers to enforce read only node graphs
- Support for fragment and vertex shaders from the nodes
- Support for node code loaded externally (embedded into the binary)
- Fixed issue preventing two textures from being used in a shader
- Removed several unused functions and cleaned up code
- Fixed video media node misreading its matrix input
Workers run in different threads and the backends can poll whether the worker
is currently busy or not. However the previous iteration has the worker (and an
atomic int) provide the busy state which could easily desync with the main
thread (since all workers run in different threads). By holding the busy states
in the main thread, the main thread will always be able to poll the busy state
accurately.
If the nodes are now stateless, there's nothing stopping the renderer from
rendering multiple frames at once. Earlier since the nodes held some of their
input/output data (and that data could change per frame), it was not possible
to render multiple frames at once without conflicts. Now that the node state is
held in render threads, they can do whatever they want at any time.
If Nodes only have the one output, we don't need to do so much differentiation
between them. Previous iteration used outputs as like a distinct function
within a Node (e.g. length output would return one result, buffer output would
produce a different result - each run different code to produce their results).
Now in this iteration, it's more accurate to say a Node is just one function
(which seems more appropriate for a node system anyway).
Largely conforming renderers to new NodeValue system. Code seems a lot cleaner
this way which is a nice advantage. Likely non-functional as this won't
compile just yet and still needs probably another day or two of testing to get
it back to where it was before.
Old code assumes that a NodeParam's parent will always be a Node. The function
has been separated off and tweaked in the event that this is not the case.
For accuracy, whenever we need to perform an audio resample, we need to do it
in advance. This is in a process called "conforming" and this commit introduces
the framework by which the decoder can automatically conform an audio stream
to arbitrary parameters for accurate rendering.
I was under the impression Q_DISABLE_COPY_MOVE was a much older function than
it is. Since we historically target 5.6 and these functions are small
convenience functions, I just implemented them in the actual codebase.
Previous iteration had params attached to the backend and the params couldn't
change without being destroyed and re-instantiated. This is not necessary in
this iteration so doing so only wastes resources.
Since we're now working with a separate proxy copy of the original node graph,
if the user changes a parameter in one of those nodes (triggering an
InvalidateCache signal), the values in our copied graph need to be updated
with these new values too.
Previous iterations would use mutexes to prevent changing of the graph
mid-render, however several user actions would need to capture these mutexes
causing the main thread to hang until the current render job (frame/range of
samples) was complete. We now copy the nodes necessary as part of the "compile"
process so that the main thread shouldn't need nearly as much blocking while
caching occurs.