Age | Commit message (Collapse) | Author |
|
The return value was just being ignored previously, and that
really starts mattering in a world with contexts finding others
by user-supplied paths making such failures far more likely.
|
|
These are already reality as of late
|
|
Just a boring replacement of the ad-hoc n_cpus context creates
for the fill_module contexts with the newly added libtil
equivalent function.
Future commits will expand the libtil side to get module contexts
registered for discovery purposes on-stream. This change moves a
bit closer towards that goal...
|
|
Somewhere along the line this leak was created, there's been a
lot of activity surrounding this stuff so it's unsurprising.
A little janky surrounding the conditional on snow module, but
that's just how snow is handled today - it doesn't get randomized
like the other channels do.
|
|
Rather than creating an orphaned settings instance private to
til_module_setup_randomize(), the function now requires the
settings instance be provided.
The one remaining caller of this function is modules::rtv. Now
that rtv is responsible for creating the settings beforehand, and
the settings may be created with a path prefix, rtv gets its
til_module_context_t->setup.path prefixed for all the channel
settings.
Another improvement is now the channel settings instance gets
created from the module name as the settings string. So while
it's not yet possible to sparsely specify settings with others
being randomized, at least now when log_channels=on is in effect,
the printed args include the top-level channel module.
Having proper complete paths for the rtv channel modules is
especially visible in --print-paths output FYI.
An interesting test for exercising all this is:
```
$ src/rototiller --module=rtv,duration=0,context_duration=0,snow_module=none,channels=all,log_channels=on --print-pipes --defaults --go 2>/tmp/channels
in another terminal:
$ tail -F /tmp/channels
```
watch the chaos unfold
|
|
Montage would randomize orphaned setting instances for the
participating modules @ context create time.
This not only produced montage tiles one couldn't configure via
settings even if they wanted to, but it also produced partial
paths due to the orphaned settings instances.
With this commit montage tiles are configurable in the same way
compose::layers are; a comma-separated list of modules with
settings accompanying them.
Randomizing is no longer performed, but if seen via something
like rtv, that randomizer will operate on the regular setup
machinery to produce randomized montages.
One new ability delivered with tiles= is you can specify the same
module repeatedly to produce a tiled display of the same thing.
Those instances may have the same or different settings, it's
totally controllable.
This also opens up the future for more interesting things like
shiftng ticks in the montage tiles... imagine showing the same
module a few times in each row, but offsetting ticks into the
future/past in the columns. For ticks-driven modules, you'd see
the future/past frames side by side, like a flipbook effect.
This leaves rtv as the only til_module_setup_randomize() caller
remaining...
|
|
Once til_module_context_t.module was introduced, this vestigial
module member @ compose_layer_t.module became redundant.
So here it's dropped in the obvious manner, but the
compose_layer_t struct is retained despite only having
til_module_context_t* now. This is in anticipation of future
additions where compose settings may set per-layer/texture
rendering behaviors (think alpha, colors, texturing toggles, etc)
|
|
This drops the seq_module= setting in favor of a scenes= setting
in the same style of compose::layers; a nested settings instance
composed of more nested settings instances, one per scene.
A nice side-effect of this change is it no longer uses
til_module_setup_randomize() at all, which was being used to mix
up the seq_module's settings in a pre-nested-settings world.
A new Rocket sync track is introduced named "$context_path:scene"
for selecting which scene to render.
For now all scenes get created @ context create time, and persist
for the entire rkt context lifetime. In the future the context
lifetimes might become explicitly controllable with separate
Rocket tracks used as booleans. This becomes relevant once
modules can make use of existing contexts located within the
stream at their respective context paths. Something necessary
for integrated transitions between scenes using stuff like
fade modules which haven't been added yet.
With this change you can already enumerate a set of scenes in the
rkt settings string, each 100% explicitly configured, and have
Rocket track data select which scene to render on the timeline,
and manipulate the taps at their scene-specific
context-path-derived track names.
In addition to the need for modules picking up existing contexts
on the stream, rkt probably needs a way to interactively
add/remove/modify scenes then spit out the serialized settings
string for the current state of the world.
As these aren't functionalities provided by GNU Rocket, and it's
unclear how receptive upstream GNU Rocket/glrocket maintainers
would be to such additions, rkt will likely first add another
listener for a strictly scenes-editing client to connect
alongside the GNU Rocket stuff. Just something that shows the
current scenes table, and provides a way to edit/add/remove rows
there, with the changes realized in rkt real-time. Then the
Rocket Editor will just continue using the rkt:scene track to
numerically index into this scenes table, without the Rocket
Editor having any visibility or awareness of what's going on in
that table. Probably ok as an initial stab at making demos with
this stack.
|
|
Mechanical change removing some rkt_setup_t* casting verbosity in
rkt_create_context()
|
|
This eliminates the ad-hoc track_name[] allocation and
construction, since the track_name wasn't being used after
getting the track anyways. No point wasting the memory on it,
and the little helper constructing the name on-stack exists now
for another future use @ rkt_create_context().
|
|
Preparatory commit for adding scenes and a $rkt_setup_path:scene
track for selecting them. This will also likely replace the
whole track_name allocation/construction in rkt_pipe_t since we
don't actually make use of that name after getting the track
(except maybe for debugging purposes)
|
|
Mechanical rename just to make this consistent with
til_module_setup()/til_module_setup_finalize()
I should probably do a cleanup pass throughout the til APIs to
standardize on a subject-verb-object or subject-object-verb
order... Things have become a little inconsistent organically
over time
|
|
This changes til_setup_t* from optional to required for
til_module_context_t creation, while dropping the separate path
parameter construction and passing throughout.
|
|
This replaces the few ad-hoc til_module_t.setup() setup-baking
callers with the new til_module_setup_finalize() which always
produces a til_setup_t having an appropriate path, even when
there is no til_module_t.setup() method.
|
|
This commit adds passing the settings instance to til_setup_new()
which is used for deriving a path for the setup via
til_settings_print_path() on the supplied settings.
That path gets an allocated copy left in the returned
til_setup_t at til_setup_t.path
This path will exist for the lifetime of the til_setup_t, to be
freed along with the rest of the baked setup instance when the
refcount reaches 0.
The incoming til_settings_t is only read @ til_setup_new() in
constructing the path, no reference is kept. Basically the
til_settings_t* is just passed in for convenience reasons, since
constructing the path needs memory and may fail, this approach
lets the existing til_setup_new() call error handling also
capture the path allocation failures as-is turning
til_setup_new() into a bit more of a convenience helper.
Note that now all code may assume a til_setup_t has a set and
valid til_setup_t.path, which should be useful for context
creates when a setup is available.
|
|
Commit 7c8086020 switched the til_setup_new() api to support NULL
free_func for free().
This mechanical change pivots to that instead of the awkwardly
cast free() parameters.
|
|
When voronoi is overlayed the colors get sampled, so randomizing
them is pointless work every frame.
|
|
This seems to work on my 2c/4t laptop and is certainly faster.
But I'm not being careful about using atomics loading/storing the
d->cell pointer, which seems problematic. Surprisingly things
aren't crashing here despite that, maybe on a non-x86 smp box
it'd be a different story.
|
|
Preparatory commit for doing the voronoi distance calculations in
parallel when possible, as part of render_fragment() instead of
all in prepare_frame().
Not all of the distance calculation work can easily be threaded,
but it should be possible to compute the post-seed distances
concurrently within the spatial bounds of the tiled fragment.
This commit doesn't actually change anything functionally, as
it's just splitting the old voronoi_calculate_distances() into
two and calling them both in succession still from
voronoi_prepare_frame().
Subsequent commits will work towards making the render_pass()
fragment-aware then ultimately moved to voronoi_render_fragment()
|
|
This variant is kind of a broken hack, and its brokenness becomes
more apparent in a threaded voronoi world.
So just drop it for now.
I am interested in more voronoi variants, but they can't
compromise correctness/introduce instabilities or significantly
interfere with performance improvements like threaded rendering.
The dithered-ish look of dirty=on was an interesting variant
though... bummer.
|
|
trivial change; voronoi_sample_colors() only reads from the fragment
|
|
Like modules/checkers required for fill_module, we need to do the
same for for rtv::snow_module.
There's more work to do on rtv::channels, but that's still
unsettled stuff in terms of settings syntax since rtv randomizes
settings. It's desirable to have the rtv settings able to
specify which settings to hold constant at a specific value
per-channel, leaving everything else for randomizing on channel
switch.
But there's no syntax for that kind of stuff currently, and it
seems like there's a need to communicate during the setup_func
dance when we're in a "settings optional because we'll fill them
in automatically at time of use later" to the front-end.
It's not strictly a front-end issue though - because the back-end
setup_func actually controls the forward progress. From the
current setup_func's perspective, everything's important to it
and must be fulfilled. And we certainly want the setup_func to
continue informing the setup process.
So it's more like the channel settings being populated via rtv
still need to all get populated, rtv just needs a way to add an
attribute to mark which settings are static vs. which should get
randomized on every use.
Perhaps there should just be a special value syntax reserved for
saying "random value" and the front-end can apply that, but then
a til_module_randomize_setup() could detect that too in a
per-setting flag the front-end set. That way the value gets
re-randomized, while the ones without that value set get left
alone.
Yes, I know this isn't the appropriate place for such commentary.
But nobody is reading these things anyways on my toy side project.
|
|
|
|
This is harmless as long as rtv stays hermetic.
But if rtv gets used in a composite scenario in the future by
either removing the hermetic flag, or allowing forced overrides,
n_cpus=0 will cause the nested module contexts to become threaded
on SMP machines.
That's problematic if the outer module context is already a
threaded render. What's appropriate here is to just propagate
the n_cpus down so if an upper layer has already gone threaded,
it will be sending down n_cpus=1 to serialize the nested
instances.
In practice, as-is, this change basically changes nothing, but
prepares for a potential future where rtv participates in
threaded compositions.
Through a lens of "rtv just rejiggers scenes and there settings
on a timer from a settings-specified subset of modules and
settings" it's arguably useful as just another module. Sometimes
you want something to change itself up periodically in say a
compose layer.
So preparing for this possibility isn't really all that
far-fetched/hypothetical.
|
|
Currently settings instances get labels from three sources:
1. explicitly labeled by a root-level til_settings_new() call,
like main.c::til_settings_new(NULL, "video", args->video);
2. implicitly labeled in a spec.as_nested_settings w/spec.key
3. positionally labeled in a spec.as_nested_settings w/o spec.key
But when constructing setting/desc paths, using strictly these
settings instance labels as the "directory name path component"
equivalent, leaves something to be desired.
Take this hypothetical module setting path for example:
/module/layers/[0]/viscosity
Strictly using settings instance labels as-is, the above is what
you'd get for the drizzle::viscosity setting in something like:
--module=compose,layers=drizzle
Which is really awkward. What's really desired is more like:
/module/compose/layers/[0]/drizzle/viscosity
Now one way to achieve that is to just create more settings
instances to hold these module names as labels and things would
Just Work more or less.
But that would be rather annoying and heavyweight, when what's
_really_ wanted is a way to turn the first entry's value of a
given setting instance into a sort of synthetic directory
component in the path.
So that's what this commit does. When a spec has .as_label
specified, it's saying that path construction should treat this
setting's value as if it were a label on a settings instance.
But it's special cased to only apply to descs hanging off the
first entry of a settings instance, as that's the only scenario
we're making use of, and it avoids having to do crazy things like
search all the entries for specs w/.as_label set.
It feels a bit janky but it does achieve what's needed with
little pain/churn.
|
|
Like modules/checkers required for fill_module, we need to do the
same for for compose.
It's a little more weird in compose since compose::layers is a
nested settings full of unnamed nested settings.
But compose::texture is analogous to checkers::fill_module.
|
|
The bare-value value_as_nested_settings.entries[0] setting which
serves as the name for module lookup is in a sort of no-mans land
between checkers and the underlying fill_module's setup.
So we have to do this little bit of rigamarole in checkers, being
the entity wiring up the nested module. The fill_module's
setup_func won't be doing anything to describe the name's
setting as it's only interested in its own settings.
There will likely be some helpers made later to streamline this
process of composing module/settings hierarchies.
|
|
Using on/off for boolean settings is the established convention
in rototiller, rtv went rogue here.
Just make it consistent
Sometimes it feels like this should be more flexible and support
0/1 yes/no true/false on/off by just having "boolean" typed
settings. But I think it may actually pay off long-term to be so
opinionated here and making serialized settings heirarchies
directly hashable/comparable without major normalization steps
(nothing beyond say... case normalization).
|
|
this oversight becomes apparent when stacking checkers as compose
layers w/random pattern and/or dynamics. The stacked instances
would identical pseudo-random behaviors for lack of seeding.
|
|
These were being supplied backwards to til_module_context_new(),
which mostly just meant the seed always started @ 0 for early
checkers contexts, or were just slightly different ticks values
for later ones.
|
|
3b6e34e70 broke this with what looks to be a silly mistake in
modifying the existing put_pixel() calls.
Kept the fragment->{x,y} instead of removing those and keeping
the bare {x,y}.
|
|
These are expected to match, and it's asserted as such in various
fragmenters. Especially now that we're getting more exuberant
with recursive settings/modules, the correctness of the checkers
cells fragment is becoming more exercised/important.
|
|
As-is it's not great for rtv to randomly wind up in compositions,
see comment in commit for more context.
|
|
first step towards settings-izing rtv, channels[] remains
|
|
Now layers= is a settings instance. Each individual setting
within that layers instance is also a settings instance of its
own.
This enables specifying the modules used in the layers as well as
settings to be passed into those per-layer modules.
The escaping quickly becomes brutal if hand-constructing, but
programmatically at least it's workable. Plus, you can let the
interactive setup ask you for all the layer settings then just
copy and paste the cli invocation printed @ startup (at least
with rototiller).
texture= is also now a settings instance, which means compose no
longer randomizes the texture settings on its own - it instead
uses the settings supplied. A consequence of this is that
texture settings need to be actually populated if the texture is
used.
For rtv, which randomizes settings, it makes no difference and
rtv compose invocations w/textures will just end up randomizing
the texture through the normal setup randomizing machinery.
But for direct compose invocations for instance, there's now an
actual texture setup process - and if you just use --defaults,
the defaults will be applied which is different from before where
it would have always been randomized.
This area needs some work, like controlling how defaults are
applied perhaps in the actual settings syntax such that
randomizing can still be performed if desired instead of
"preferred" defaults. That's a more general settings syntax
problem to investigate
|
|
fill_module= now takes a settings string, so you can specify not
just the name of the module, but additional settings passed into
that module's setup.
The fill_module's context path is also now getting fill_module
appended, but see the large comment surrounding that mess WRT
checker's per-cpu fill_module context creations.
|
|
With setup refcounting and a reference bound to the context, we
should just dereference the single instance. The way setups are
used it just as a read-only thing to affect context behavior...
Note I've left the module-type-specific setup pointer despite it
duplicating the setup pointer in the module_context. This is
just a convenience thing so the accessors don't have to cast the
general til_setup_t* to my_module_setup_t* everywhere.
|
|
This just does the obvious pulling in of til_setup_t, holding the
reference throughout the lifetime of the module context.
|
|
There was a time when it made sense for context creates needing
setups but not receiving them to still be functional with some
sane defaults.
But with recursive settings, we really shouldn't ever have
orphaned nested module uses unreachable by a proper setup.
So let's just get rid of this fallback, and exclusively rely on
the baked setups provided by the .setup() methods. They still
have preferred defaults, and the proper setup production
machinery is what should be responsible for applying those
at runtime where they may also be overridden or otherwise
influenced.
|
|
This introduces a boolean style log_channels= setting for
enabling logging of channel settings on channel switch.
It might be nice to change this to accept stdout/stderr/fdnum as
the setting instead of always directing at stderr.
This also doesn't capture the seed state so it's not exactly
logging everything needed to reproduce wholly what is being
shown. Some compositions depend more on rand than others, so
it matters at varying degrees.
It'd be nice for settings syntax to have some global syntax
supported where a seed can always be embedded to be loaded.
Introducing such things as global settings to the settings syntax
is a pending TODO item... right now the only way to load seed
state is at startup passed to main as --seed=. That's not gonna
cut it long-term.
This is an easy big step in the right direction though. Trying
to make sense of what's on-screen from the truncated captions is
impossible. Even if the captions wrapped the settings, it would
be tricky to catch the settings without recording the output or
screenshotting.
This also immediately makes me wonder about the voting system for
rtv where we log settings of favorites... then roll those into
playlists.
|
|
For recursive settings the individual setting being described
needs to get added to a potentially different settings instance
than the one being operated on at the top of the current
setup_func phase.
The settings instance being passed around for a setup_func to
operate on is constified, mainly to try ensure modules don't
start directly mucking with the settings. They're supposed to
just describe what they want next and iterate back and forth,
with the front-end creating the settings from the returned descs
however is appropriate, eventually building up the settings to
completion.
But since it's the setup_func that decides which settings
instance is appropriate for containing the setting.. at some
point it must associate a settings instance with the desc it's
producing, one that is going to be necessarily written to.
So here I'm just turning the existing til_setting_desc_t to a
"spec", unchanged. And introducing a new til_setting_desc_t
embedding the spec, accompanied by a non-const til_settings_t*
"container".
Now what setup_funcs use to express settings are a spec,
otherwise identically to before. Instead of cloning a desc to
allocate it for returning to the front-end, the desc is created
from a spec with the target settings instance passed in.
This turns the desc step where we take a constified settings
instance and cast it into a non-const a more formal act of going
from spec->desc, binding the spec to a specific settings
instance. It will also serve to isolate that hacky cast to a
til_settings function, and all the accessors of
til_setting_desc_t needing to operate on the containing settings
instance can just do so.
As of this commit, the container pointer is just sitting in the
desc_t but isn't being made use of or even assigned yet. This is
just to minimize the amount of churn happening in this otherwise
mostly mechanical and sprawling commit.
There's also been some small changes surrounding the desc
generators and plumbing of the settings instance where there
previously wasn't any. It's unclear to me if desc generators
will stay desc generators or turn into spec generators. For now
those are mostly just used by the drm_fb stuff anyways, modules
haven't made use of them, so they can stay a little crufty
harmlessly for now.
|
|
Existing code was passing 0 which turns into the number of
cores/threads.
That's fine when compose isn't running nested in an already
threaded render, but falls down in something like checkers
w/fill_module=compose since checkers is already threading. But
when checkers creates its fill_module context, it's careful to
pass 1 for n_cpus to prevent that kind of thing. With this
change that no longer falls apart.
|
|
Finishes build/fs part of modules/rocket->modules/rkt rename
started in previous commit.
|
|
It's annoying to have the til module called rocket, and the sync
tracker protocol/library called rocket, so let's at least
differentiate it in code/comments/textual discussion.
Plus this results in shorter module context paths i.e.:
/rkt:scene
/rkt/compose/drizzle:rain
/rkt/compose/drizzle:viscosity
/rkt/compose/plato:spin_rate
/rkt/compose/plato:orbit_rate
vs.
/rocket:scene
etc...
These names are shown in the editor, and they'll tend to be long
but let's at least get the root name down to three chars this
way.
A rename of the files and build system update will come in a
subsequent commit
|
|
There should probably be others for the ball radiuses, and colors
|
|
this needs more work to really be useful...
clockstep should be tapped, there should probably be a T tap to
control the emitters' cycle
im doubtful how useful this module will generally be though. It
really needs interactions with other things, like fluid going
around pixbounce
|
|
Just some obvious taps...
Note the actual usable range for viscosity is quite small, like
no greater than .05 really works. There still needs to be some
way to describe bounds on the taps, that or normalizing things to
always be 0-1 or -1..+1 kind of thing, and expecting the modules
or the tap api to map those to the sane ranges.
Just leave everything raw for now, wiring up the taps at least
opens up experimentation and getting a feel for what makes most
sense.
|
|
Part of me wants to give the blinds arbitrary angle instead of
the vert/horiz options. But part of the beauty of blinds is the
jaggy-free aliasing-free sharp edges by virtue of always being
orthonormal using whole pixels.
Maybe in the future there could be a orientation setting where
you pick horiz/vert/angular. Then only when angular does it get
a theta tap and use angled blinds with anti-aliased imperfect
edges...
|
|
This adds a rudimentary but functional rocket module for
sequencing "tapped" variables in rototiller modules according to
a timeline via GNU Rocket editors.
Currently this only supports a single seq_module= as a setting
which will be used for rendering. Any tapped variables present
in the nested modules under seq_module will be available for
sequencing, and should automatically appear in a connected rocket
editor.
If you specify connect=off then rocket sync tracks will be read
from the filesystem if present. It's a bit clumsy as-is due to
how the GNU Rocket library handles this currently. There's a
"base" label concept for the virtual rocket device, and the
tracks are intended to be files in a directory named using that
base= setting.
The way you create those track files is by triggering a remote
export from the editor while connected. The location of the
directory is relative to the cwd of the rototiller process, and
you can't specify absolute paths as the base= setting to be
explicit about where things go. The setting isn't really a path,
as that's not what the library wants it to be. It's an area in
need of improvement.
In any case, as long as you start with the same base= setting,
from the same CWD, as when you did the remote export, you can
re-run with connect=off and the exported tracks will be used
automagically and things should replay without the editor
connected.
If you start with connect=on, which is the default, you need to
have the editor already running. Otherwise the rocket module
will fail @ context create, and you'll get a confusing error
about being unable to allocate memory. This is just for now, the
context create needs to start returning an errno instead of just
the context pointer so the error messages can be more informative
now that context create may be doing complicated things like
connecting to sockets.
Another thing to improve is probably having the module just
reconnect periodically if connect=on but it failed @ context
create. It could just start anyways and not fail the context
create at all there, and just start working once you get the
editor online. That'd be a better user experience.
This is a good first step regardless...
|
|
This just stubs out a rocket meta module that renders with
another module.
Future commits will integrate GNU Rocket here.
When recursive settings formally lands you'll be able to nest as
much settings content as necessary for the underlying module
used, as part of the rocket settings. That should enable
describing stuff like complex compose scenarios for rocket to
sequence.
|