diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2023-08-19 09:29:18 -0700 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2023-08-19 12:11:09 -0700 |
commit | acdb14ebe504c0a0c361bc9bdb306fcfcebe2b8a (patch) | |
tree | 1fcfb58c1040dcca09c097f4ed94038d4002b777 | |
parent | 0a8088b3b34f9efed3f8905969a1d16bfd485a65 (diff) |
til_stream: the first tap per-frame should drive the pipe
In the case of clones there's multiple identical contexts at the
same path, putting their taps on the same pipe.
Since these clones likely exist for the purpose of parallel
rendering, chaotically scheduled, it's arbitrary which of the
clones will render first in a given frame. So it would just be a
matter of luck if the first to render was also the driving tap
established at context create time. Until the driving context
rendered, the non-driving contexts would render potentially stale
values from their taps, carried from the last frame. Then the
driving tap's context would render, advancing all taps it drove,
and it plus any subsequent renders sharing the pipe in the frame
would have the new tapped values, producing randomly inconsistent
results.
You can easily cause this today with checkers::fill_module=plato,
since plato has some taps for the orbit/spin rates, and checkers
uses context clones for parallel fill_module= rendering.
Note this is orthogonal to cases like modules/rkt, where hooks
are used to steal ownership of the pipes when they're created.
rkt also becomes the driver of the taps from its ctor hook, since
it bridges Rocket data to the taps, and this commit does
potentially interfere with that by introducing a per-frame
competition to determine driver. But since rkt is the top-level
rendering module when its in use, calling into the per-scene
module contexts when appropriate, it's guaranteed to always win
the race as long as it maintains its taps using Rocket-provided
values before rendering the scene - which is the way it works
today.
-rw-r--r-- | src/til_stream.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/til_stream.c b/src/til_stream.c index 3c0a4f5..72351ca 100644 --- a/src/til_stream.c +++ b/src/til_stream.c @@ -255,7 +255,8 @@ int til_stream_tap(til_stream_t *stream, const void *owner, const void *owner_fo } /* this looks to be the pipe, but we're not driving, should we be? */ - if (pipe->driving_tap->inactive) + if (pipe->driving_tap->inactive || + pipe->frame != stream->frame) /* every frame's a race for who's driving, because clones */ pipe->driving_tap = tap; *(tap->ptr) = pipe->driving_tap->elems; |