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.
A signal emitted and received in the same thread will call other functions
before returning to the one that emitted the signal. If these other functions
try to lock a mutex while a mutex is already locked by the emitting function,
we get stuck in a deadlock. These changes ensure that a signal is never emitted
by any function until all the nodes locked by it are unlocked.
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.
Useful for detecting when a graph needs recompiling, in tandem with the
"InvalidateCache()" signal when necessary, this signal ripples through the
nodes when any of the connections change which will likely need handling by
the renderer.
Sometimes we'll be copying nodes without wanting to copy their connections,
since we'll want to connect them to equivalent copies rather than connecting
them to the same nodes the originals were connected to. We now have an extra
parameter to distinguish such operations.
Both audio and video renderers were working off the same invalidation signal
(i.e. changing audio would also trigger a re-render of the video). This is
obviously suboptimal and now they are separate.
Many changes were made throughout the codebase to support audio, these are
most of the small changes necessary.
The audio support still is not perfect. I still need to write in resampling
support. After that it should work correctly with all audio types.
commit
For testing the new iteration, the texture cache disk download was written
into the main thread instead of into the separate threads. Now they're back
in separate threads again.
Also I think some of these files probably should have been in the previous
commit.
Once again, conceptually this system should work, however it does not seem to
be the most efficient and it wouldn't surprise me if the multithreading was
eventually upgraded to an even more coherent system one day. However for
"core principles" this should be fairly decent.
The new rendering pipeline strives to simplify the nodes themselves as much
as possible and move much of the logic to an external rendering engine. This
change removes all of the responsibilities that no longer belong to the
nodes themselves and will soon be folded into the renderer.
This design, while not completely illogical, seems to betray the DAG design
and borders on impossible to actually recompile. The plan is to build this
functionality into the renderer instead.
Nodes were previously written to be "strongly typed" in that a parameter's
"type" enforced whether it could be connected to another. All code related
to that has now been removed since not only is it hard to maintain and
likely unnecessary, it's possible the nodes will work differently later on
anyway.
Rather than convoluting the MediaInput node, te MediaInput is now an abstract
base class that provides access to a Decoder and derived classes are
responsible for handling it