Age | Commit message (Collapse) | Author |
|
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.
|
|
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.
|
|
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
|
|
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 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.
|
|
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.
|
|
This was prevented before but lost in the shift to
til_module_setup_full() wrappers...
|
|
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
|
|
The existing code wasn't clipping correctly to the right/bottom
edges of the incoming fragment when the xoff/yoff was 0 but
xshift/yshift non-zero. In that case the incoming fragment bound
was unintentionally being enlarged, resulting in an overrun when
the such a cell was filled/cleared.
It was discovered watching montage under rtv, which stumbled
across running checkers w/size=128 on a montage tile of 128x96.
The height/y coords of the single checker cell filling the whole
montage tile weren't getting clamped properly down to the 96-tall
tile.
The shifting for centering checkers introduced some really
annoying arithmetic in this fragmenter.
|
|
Trivial changes to improve some naming / scoping, done while
investigating a bug.
Nothing functionally changed
|
|
This module is here to stay
|
|
Blend is a more accurate word for what's being done.
Fading is something you can achieve with the blend mode, if you
use something like "blank" as one of the modules. But when you
have two modules generating content, it's not a fade, it's just a
blend.
It might make sense in the future to support a "fade" which
assumes a solid color for one module rather than having to use
the "blank" builtin which burns memory bandwidth on a blank
frame.
|
|
Just more largely mechanical changes transitioning ad-hoc nested
module handling over to til_module_setup_full().
|
|
|
|
Now you can seed the scene editing with a top-level serialized
scene in "as_arg" form, just like NEWSCENE.
The current scene being edited is shown in serialized form for
convenient copy & paste into an editor for manipulation, between
the []s both to also show what the default seed will be if you
just press enter. When using the copy & paste w/editor approach,
you'd just paste the tweaked form directly into the waiting
prompt before hitting <enter>.
Regardless of what happens at the initial EDITSCENE prompt, the
current implementation always goes through an interactive
visiting of all the settings. Simply pressing enter at those
individual settings will accept their current value from the
serialized seed, or a default if not present in the settings.
|
|
This doesn't need to be a distinct state since it's basically
just a banner for the start of the newscene process which never
recurs, it's not an interactive prompt or dialog of any kind...
|
|
Running something like:
'--module=checkers,size=64,fill_module=shapes,style=circle --defaults --go'
Would show some artifacts in the top portion of the filled cells
at certain phases of the spining shape. This was introduce by
the radcache, and it's caused by the overhanging tiles on the
perimeter and how their being clipped was carrying into the
radcache contents then used for all subsequent renders.
This commit just makes setting radcache.initialized conditional
on the incoming fragment being a full-frame fragment as a quick
fix. See comment for more info on what to do long-term.
|
|
There's potential for some of the per-cpu fill_module_contexts to
go unused for an entire frame. When this occurs, depending on
the fill_module in use, it can lead to their context's state
diverging.
To mitigate this possibility, add a tidying up pass in
checkers_finish_frame() where such straggler contexts are
identified and forced to render once into a cell-sized waste_fb
of off-screen memory.
This ensures all contexts see all frames/ticks that any
participated in, preserving their clone status across the board.
Prior to this you could see jittering in something like
'--module=checkers,fill_module=roto' as the roto contexts
diverged on the r/rr variables when some didn't get in on the
action of some frames.
See large TODO comment for why this approach is used instead of
something less wasteful of cpu time.
If this approach is kept, it might make sense to do the waste
rendering in parallel. Systems with large numbers of cores could
end up with many stragglers, depending on how many cells there
are vs. cpus. I don't have any such systems so it's difficult to
test any efforts in that vein.
|
|
In compositions where roto recurs in the same frame, it's
wasteful to keep rendering the fill_fb contents manifold for the
same tick. They shouldn't be varying anyways...
It'd be different if the fill_module rendered directly to the
output fragment in an overlay manner, but the current
roto implementation doesn't do that. It's just sampling fill_fb
like a tiled texture sampler would.
The performance hit here is easily observed by doing something
like:
--module='checkers,size=4,fill_module=roto\,fill_module\=moire' --video=mem --defaults --go
Before this change, FPS=1 on my i7 X230. After, FPS=~400.
|
|
Switch to til_module_setup_full() for handling the module setup
of the input {a,b}_module settings
|
|
Switch to til_module_setup_full() for handling the module setup
of the individual layer module settings as well as the texture.
Since compose served as the development mule for adding nested
settings, there was a lot of verbose comments that no longer
seemed necessary since much of the dust has settled.
The separate compose_layer_module_setup() and
compose_texture_module_setup() wrappers feel a bit like
copy-pasta too. I'm tempted to stop using these and just open
code the til_module_setup_full() calls, except they get performed
twice due to the split finalize, so it's probably still a net win
as-is.
|
|
Switch to til_module_setup_full() for handling the module setup
of the individual tile module settings.
|
|
Switch to the generic til_module_setup_full() and rely on the
"none" builtin's NULL res_setup on finalize to indicate when no
fill_module is desired.
This gets rid of the need for a separate til_module_t* handle for
the fill_module, since til_setup_t.creator can be used for that,
and the NULL til_setup_t* to indicate no fill_module.
Basically discards some busy work style code, there's more
cleanups needed surrounding this stuff though.
More or less identical to the previous change to modules/checkers.
|
|
Switch to the generic til_module_setup_full() and rely on the
"none" builtin's NULL res_setup on finalize to indicate when no
fill_module is desired.
This gets rid of the need for a separate til_module_t* handle for
the fill_module, since til_setup_t.creator can be used for that,
and the NULL til_setup_t* to indicate no fill_module.
Basically discards some busy work style code, there's more
cleanups needed surrounding this stuff though.
|
|
Basically everywhere the
TIL_MODULE_HERMETIC|TIL_MODULE_EXPERIMENTAL exclusions were being
applied needed TIL_MODULE_BUILTIN added.
Mostly this is to prevent randomizers from tripping over builtins
in the available modules lists they draw from.
Because builtins aren't visually interesting by themselves, and
in some cases don't currently even have a means of being
randomized properly like ref's path setting.
This wasn't needed previously since builtins were kept off the
modules list altogether. But since 1a6210be that changed and
they must be explicitly filtered by flag instead.
Note I deliberately left the rkt case with just a TODO comment.
It's not a randomizer situation, and it might be acceptable to
let rkt just show everything all the time in the module lists.
That whole situation there is for advanced users.
Also note that without this, rtv et al would easily trigger an
assert on NULL setup due to the "none" builtin. Since there's
still work to be done there in callers properly handling NULL
@res_setup on a successful finalize. But this commit mitigates
that by avoiding the builtins in the randomizers.
|
|
This gets rid of the ad-hoc module lookups previously necessary
for finalizing the nested module setups. Now that the
til_estup_t.creator tracks the creating module, the
rkt_scene_module_setup() wrapper can take care of finalizing.
|
|
Particularly with nested modules it's annoying to have to stow
the module separate from the setup during the setup process.
If the baked setup included the module pointer in the
non-module-specific-setup part of the setup, then nested settings
could finalize using the generic module setup wrapper and just
rely on this til_setup_t.creator pointer to contain the
appropriate module. Which should enable tossing out a bunch of
copy-n-pasta surrounding nested modules setup.
Note this has to be a void* since til_setup_t is a generic thing
used equally by both the fb code and the module code. Hence why
this is called "creator" and not "module", as well as the void*
as opposed to til_module_t*.
Also if rototiller ever grows a sound backend, the setup
machinery will be reused there as well, and it'll be yet another
creator handle that isn't an til_fb_ops_t or a til_module_t.
It's assumed that the callers producing these setups won't be
trying to pass them to the wrong places i.e. a module setup
getting passed to an fb backend and vice versa.
I'm mildly annoyed about having to move the various til_module_t
blocks to above the module's foo_setup(), but it seemed like the
least annoying option. This may be revisited.
|
|
Most of the time in scener you want to add a compose, you
basically never want blank, so the :blank thing was kind of silly
from the perspective of what happens most often.
|
|
rkt_setup() and rkt_scener_update() had distinct implementations
for scene module setup. This consolidates that where trivial to
both use the new til_module_setup_full() with appropriate
parameters, wrapped up in rkt_scene_module_setup().
The finalizing phase is still ad-hoc which is mildly annoying,
but if finalizing just passed into rkt_scene_module_setup() there
wouldn't be the til_module_t onhand for sticking in rkt_scene_t.
So the code to extract and lookup the module from the settings
would still be needed anyways, as the whole til setup_func api
isn't limited to modules so the baked til_setup_t doesn't come
back with a til_module_t hanging in there. Maybe in the future
this gets changed a bit, there could for instance be a void* in
til_setup_t where something usage-specific goes, like the
relevant module in the case of a module's setup. Something to
consider for the future.
Consolidating these in the pre-finalize phase at least ensures
consistent behavior in initial rkt::scenes setup vs. scener
editing/new scenes.
|
|
When creating nested setting instances, just pass down the full
raw value so if there's any prefix on the value it can be
realized as a prefix for the first entry in the nested instance.
|
|
The application of overrides was still done via ad-hoc value
manipulation. This changes to use til_setting_set_raw_value() in
the obvious manner.
|
|
Trivial refactor s/til_setting_spec_check/til_setting_check_spec/
so it operates on a til_setting_t as opposed to the bare value.
With the containing til_setting_t onhand it can be responsible
for bypassing the check when til_setting_t.nocheck is set.
Adjusted callers in setup_interactively() and rkt_scener_update()
accordingly.
|
|
It's relatively acceptable to use this hammer for the other
errors like ENOMEM especially when this isn't some enterprise-y
service that must endure overload conditions gracefully.
But the setup_finalize() step is rather likely to find invalid
settings, especially now that til_setting_t.nocheck with the ':'
prefix is a thing.
This commit doesn't try resume the setup at the invalid setting
(yet, that will require further til_module_t.setup() method
work), but it at least doesn't rudely disconnect. The user just
gets dumped back to the SCENES state main prompt.
|