Age | Commit message (Collapse) | Author |
|
More setup_func conversion to returning the failed setting on
errors during res_setup baking.
|
|
More setup_func conversion to returning the failed setting on
errors during res_setup baking.
|
|
More setup_func conversion to returning the failed setting on
errors during res_setup baking.
Also fixed a bug while here in the style_values error detection;
it was misusing nelems() on the array when it's NULL-terminated
with a sentinel. But this was only triggered if a user force
overrided the setting with the :-prefix syntax, since otherwise
the setting had to be in the values set according to the
front-end. It was known there'd prolly be bugs when adding that
: override prefix support. A lot of the module-local setup
baking code has been neglected/bitrotted/carelessly changed over
time, depending on front-end values policing to keep things on
the rails.
|
|
More setup_func conversion to returning the failed setting on
errors during res_setup baking.
|
|
Switching over to the newly added setting-centric variants
enables ergonomically returning the failed setting during baking.
With this commit, modules/plato becomes the first to properly
return the setting which failed to parse during baking res_setup.
|
|
This introduces til_setup_free_with_failed_setting_ret_err()
which just does the common idiom of:
- free the setup
- store the failed setting
- return with err code
so all these failure cases can be reduced to just a direct return
of calling this function.
|
|
This is kinda icky copy-pasta vs. the previous commit.
But this function is just an inherently crufty helper, hopefully
the value-centric variant can be removed at some point.
|
|
Currently everything wanting to get a settings value goes through
til_settings_get_value_by_{idx,key}() functions which return the
value rather than the setting directly to the callers.
This was a convenient thing initially, but it's becoming apparent
that most of the setup_funcs using these actually need the
til_setting_t* for improved error handling in the res_setup
baking phase.
So this commit basically just converts the existing functions
into bare til_setting_t* returns, leaving the existing get_value
variants as helper wrappers around them.
Subsequent commits will rework the myriad setup_funcs to use the
new variants, eventually letting setup front-ends like
setup_interactively() to make use of the res_setting on res_setup
baking failures too.
For now both variants will coexist, during the reworking. The
get_value variants may go away at some point if nothing is making
use of them.
|
|
Several modules still had vestigial ad-hoc free() cleanups on
error paths in their create_context().
Largely mechanical change of replacing those with
til_module_context_free() which is more appropriate, since the
til_module_context_t holds a reference on the setup. A plain
free() will leak that reference.
But it's only on create_context() failures which are uncommon,
so this was in practice mostly harmless...
|
|
Having everything in fixed defines severely constrains the
diversity of particle behaviors and appearances.
This commit has been sitting around bitrotting since 2017, but
now that there's all this settings infra. and randomizing via
rtv, it seems worth landing, so I've rebased and am merging to
prevent a bitrot->rebase recurrence.
As-is, this commit ~minimally establishes a somewhat streamlined
parameterizing mechanism w/X-Macro patterns, while wiring up a
few of the obvious use cases surrounding xplode/burst, colorizing
the default sparkler explosions while at it.
It appears that when I first hacked this up I did some
experimentation with parameters as well, so there are some tweaks
to the behavior as opposed to a strict conversion of the fixed
defines to parameters. They seem minor enough to just leave be.
Plus a few minor optimizations like converting divides to
multiplies were in there.
Future commits can now wire up settings to choose from parameter
presets for different sparklers...
|
|
Mechanical rename for clarity reasons, primarily to better
differentiate from the setup_func style
til_module_setup()/til_module_setup_full() functions.
|
|
Mechanical rename for clarity reasons, primarily to better
differentiate from the setup_func style
til_module_setup()/til_module_setup_full() functions.
|
|
This sets the flash state when driven by something (like rkt).
When driven, the toggle tap will override hz altogether.
|
|
This enables dynamic external control of the strobe's frequency.
|
|
Clarifying trivial mechanical rename
|
|
Preparatory commit for exposing strobe::hz as a tap, it seems
awkward to work in periods especially in the track data.
Though I do like the 0-1 range of period, though that doesn't
even hold for slower than 1HZ frequencies so... it's kind of a
lie anyways.
At least if the track is called "hz" anyone will know what the
values mean and easily reason about them. So I'm making the
setting consistent with the soon to be added "hz" tap.
|
|
Commit 64a5b17 added this to til_module_context_t, so it's
already being tracked now making this redundant.
|
|
Outside of overflow (which I'm ignoring for now) ticks shouldn't
go backwards. With the introduction of adding the frame-buffer
delays, which vary, there's the potential for the delay to go
from large to short in quick succession, to such a degree that
the next render's now+delay is in the past relative to the
previous now+delay.
For now this simple fix is to just track the last_ticks and
always use the maximum of the last_ticks and now+delay, ensuring
it never goes backwards.
This was making alphazed exit prematurely at spurious times by
sending the rocket_row into oblivion because (ticks - last_ticks)
was negative w/unsigned arithmetic. This will all get more work,
and maybe ticks should be allowed to go backwards actually, but
some things are assuming that's not the case as-is.
Regardless, it's not desirable for ticks to go backwards because
of the frame-buffer delay. In that case just chill on the ticks
advancement for a frame. This will need revisiting for sure, as
I don't think re-rendering the exact same tick as the last frame
is likely to be what's wanted either. Probably some little
advancement should still be performed...
|
|
This should push the ticks value ahead by 1-2 frames worth of
time, when rendering is meeting/exceeding the frame rate. Which
is the appropriate thing to do, since rendering is effectively
slightly ahead of the clock, producing visuals for now+N-frames
into the future.
When rendering lags behind, there's basically no delay, and
rendering is just operating on the "now" ticks which will be
flipped to ASAP once submitted.
This will probably be revisited once audio is rolled in, since
that too will need to be kept in sync with the visuals'
perspective of time.
|
|
til_fb is triple buffered, but when rendering lags behind the
queue is empty making present-to-delay intervals smaller than
when rendering is keeping up and the queue is kept full.
This returns the duration of the returned pages last
submit-to-present delay, effectively measuring how long a page
can expect to wait to be flipped to/presented currently.
A subsequent commit will apply this delay value to the ticks
supplied to rendering.
|
|
Preparatory commit for returning submit-to-present intervals
w/til_fb_page_get().
|
|
This needs a bit more work, but at least filtering the same-tick
renders avoids the many-movements-per-frame potential when used
as something like a checkers::fill_module
|
|
This needs a bit more work, but at least filtering the same-tick
renders avoids the many-increments-per-frame potential when used
as something like a checkers::fill_module
|
|
This commit makes ops_sin stateful by tracking last_ticks_ms and its
theta angle.
Unfortunately that necessitates serializing ops_sin on the output
path, currently done using a mutex.
See larger comment in ops_sin.c for why this is all necessary.
|
|
It might be worthwhile to support >1 for these, but as-is it
crashes due to assumptions WRT shape size not exceeding frame
dimensions.
This just prevents crashes if someone tries putting a >1 value in
something like a rkt track for scale/pinch_factor.
|
|
First stab at tapping the parameterized stuff in shapes.
|
|
This also makes the pinches-dependent settings always get
initialized, since when tapped if you moved n_pinches from 0 to
non-zero, the pinches-dependent settings would abruptly become
relevant mid-flight. So this ensures they can have some sane
values, in case they haven't also been set via taps when
n_pinches became non-zero.
|
|
Preparatory commit for potential n_pinches=0, sin(0)=0 which
behaves better here where n_pinches=0 should be a noop.
|
|
Threaded rendering was added in 011d4df35
|
|
This was made redundant by til_ticks_now(), and get_ticks() looks
buggy in its usecs arithmetic on top of it.
|
|
There are no users of this, it can come back if needed.
|
|
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.
|
|
This needs the stream pulled in so the signature changed to
accomodate that.
Also modules/rkt was calling this conditionally which won't be
compatible with the per-frame driver race model, so always call
it to maintain the driving position every frame.
|
|
This is needed for determining which tap's first on a given pipe
per-frame.
|
|
Tell the stream when starting a new frame...
|
|
This adds til_stream_start_frame() which advances a per-stream
counter.
Subsequent commits will make use of this for implementing a
pre-frame competition for pipe ownership.
|
|
Mechanical change of ensuring what little taps are implemented
always get updated @ til_module_t.context_create() time as well
as on every frame.
This ensures the pipes are registered on stream immediately upon
context creation, rather than appearing only once the context
gets rendered the first time.
|
|
Another trivial leak fixup.
|
|
This triggers immediate cleanup of the replaced context.
It's being done after the new context is fully installed as the
replacement, with an eye towards enabling a baton style handoff
of the existing context's owned pipes to the replacement, for
taps they have in common. That's not being done yet, but it'd be
impossible if the gc occurred before creating the replacement,
since the existing context's pipes would already be untapped (and
removed).
|
|
Another trivial leak fixup
|
|
On shutdown til_stream_untap_owner() will call into the pipe_dtor
hook if set. So until now this was just (harmlessly) leaking the
rkt_pipe_t allocated by the pipe_ctor hook on the road to process
exit.
But in the interests of silencing ASAN about leaks on graceful
exit, I'm tying up these loose ends.
This dtor will also be utilized for performing a FORGET_TRACK via
Rocket once that's a thing.
While here I also got rid of the pipe_dtor return value, as it's
unused with no clear potential purpose (for now).
|
|
This is mainly to prevent the mixer's b_module=compose default
from always sending the randomizer down a deep nested compose
scenario.
But it's also just giving the mixer random variety in both a/b
modules, while keeping compose out.
This alone seems to go a long way towards preventing
problematically deep randomized setups under rtv.
|
|
Not bothering with fixing this because rtv needs its channels
setup redone altogether to better resemble something like
rkt::scenes, but allowing partial specification of the settings
as a means of controlling specific settings while randomizing the
rest.
|
|
til_str_appendf() preventing overflows doesn't do much good if we
don't notice the errors and behave appropriately...
|
|
In the wholesale transition to til_module_setup_full() there's
been a lot more problematic randomized setups either extremely
deep or plain infinite.
Due to the primitive escaping mechanism performed by
til_settings_as_arg(), where escape patterns grow exponentially
with depth, it's quite realistic (and observed) for these
problematic setups to exceed SIZE_MAX.
So I'm putting some guard rails in to cap a given til_str_t to
SIZE_MAX. It might make more sense to move the limit well below
SIZE_MAX, but this should at least prevent overflows.
|
|
Typically people do a exponential style growth in such
circumstances, but in my experience that tends to allocate nearly
double what's needed quite often.
Trying just a linearly increasing allocation size that bumps up
the minimum amount every time a resize is triggered. If the
needed amount exceeds the new growth increment, the larger value
is used, but the growth rate still follows the minimum bump.
I expect this to evolve more, just wanted to do something to
speed up til_str a bit from it's naive approach.
|
|
This was prevented before but lost in the shift to
til_module_setup_full() wrappers...
|
|
more cleaning up stuff on exit
|
|
cleanup_channel() is called from rtv_destroy_context(), which
can be called by a gc. The gc isn't reentrant and generally
isn't expecting this, so it breaks in hilarious ways when this
happens, usually ending in a segfault.
gc should probably get some defenses for asserting on reentry...
for now let's just prevent crashing by removing the gc call from
the destroy path.
|
|
b6362c54 introduced shapes_destroy_context() for the radcache,
but didn't actually cleanup the context, oops.
trivial fix
|