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.
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.
Major refactoring work to try sharing as much code as possible between the
video renderers and audio renderers, as well as make them as
platform-independent as possible.