Age | Commit message (Collapse) | Author |
|
This is a first approximation at introducing colors to flui2d, the
emitter colors aren't really well tuned or anything yet.
|
|
Inspired by my little fomo match-four game PoC, this is a similar
style phased emitter grid layout producing some neat turbulent
interactions.
Introduces an emitters={figure8,clockgrid} setting, and when
clockgrid is used, a clockstep=[.05-.99] for the radians step
made from one grid cell's emitter to the next where 1=2PI.
|
|
|
|
During rtv runs we'd occasionally segfault in the unchecked line
drawing. This needs to be fixed, but for now just go slower.
|
|
@Ph1l tripped over this after installing just build-essential
|
|
This adds count=N and orientation={horizontal,vertical} settings.
Which was precipitated by the introduction of a vertical blinds
mode.
e.g.:
--module=blinds,count=32,orientation=vertical
or for a quick tour of the possibilities:
--module=rtv,channels=blinds,duration=1,context_duration=1,snow_duration=0
weeeee
|
|
It's getting crazy in here, this is fun:
--module=rtv,channels=compose,duration=1,snow_duration=0,context_duration=1
which will rejigger the commpose module w/randomized layers every second.
|
|
In the interests of facilitating randomized automagic layered
compositing, tell the world when you're overlay-appropriate.
|
|
For modules which are overlay-appropriate, they should indicate
it when initializing their respective til_module_t. If they
intend to participate in automagic compositing as overlays
anyways.
|
|
Just some fixups after a quick review
|
|
This should plug a bulk of the setup leaks. Some of the
free_funcs still need to be changed to bespoke ones in modules
that allocate nested things in their respective setup, so those
are still leaking the nested things which are usually just a
small strdup of some kind.
|
|
simple wrapper around til_setup_t.free()
|
|
This brings something resembling an actual type to the private
objects returrned in *res_setup. Internally libtil/rototiller
wants this to be a til_setup_t, and it's up to the private users
of what's returned in *res_setup to embed this appropriately and
either use container_of() or casting when simply embedded at the
start to go between til_setup_t and their private containing
struct.
Everywhere *res_setup was previously allocated using calloc() is
now using til_setup_new() with a free_func, which til_setup_new()
will initialize appropriately. There's still some remaining work
to do with the supplied free_func in some modules, where free()
isn't quite appropriate.
Setup freeing isn't actually being performed yet, but this sets
the foundation for that to happen in a subsequent commit that
cleans up the setup leaks.
Many modules use a static default setup for when no setup has
been provided. In those cases, the free_func would be NULL,
which til_setup_new() refuses to do. When setup freeing actually
starts happening, it'll simply skip freeing when
til_setup_t.free_func is NULL.
|
|
For use when setup functions allocate their private setup to
return in *res_setup.
They specify the size of their private setup, and supply the free
function to use. This may be libc's free() when it's a simple
setup struct, or a bespoke free function when deep/complex
freeing is required for cleanup.
It's expected that callers will be embedding til_setup_t at the
start of their private setup struct, and returning a pointer to
this in *res_setup which would be the same value as a pointer to
to their private setup struct.
|
|
Preparatory commit for providing a res_setup type to replace
void*.
The impetus for this isn't just pursuit of less void*, but
primarily implementing setup freeing by embedding this struct
into the private setup types.
An alternative method of adding setup freeing would have been to
introduce something like til_module_t.free_setup(). But that
would require having the til_module_t on hand, and the whole
setup machinery is more generalized than til_module_t anyways.
This way anything can simply embed the struct in their private
setup instance and return the pointer to that in *res_setup.
They should always be able to find their containing struct's
offset from the til_setup_t* they returned. Either by using
container_of(), or simply placing it at the start of the private
setup struct.
|
|
Randomize the setting of the layered modules like rtv does.
This needs to free the setup, similarly to the others, once
that facility is added.
|
|
Instead of always showing defaults, randomize the setup like rtv
does.
|
|
This makes the arg return optional by using a res_arg pointer,
instead returning -ENOMEM when it would have returned NULL on
allocation failures.
This also makes it possible to detect when no setup was
performed, by returning 0 in such a case. Now returns 1 when
setup occurs and res pointers populated.
|
|
This commit pulls the setup randomizer out of rtv into libtil
proper, so other modules may make use of it.
Other than adding an assert no functional changes occurred.
It may make sense to split this into two functions; one which
takes a til_module_t as-is, and a lower-level bare setup function
callback based function that doesn't know about til_module_t the
former would call into. That way generic setup randomization can
occur (the same setup machinery is used in video contexts for
example) without necessarily having a til_module_t on hand.
|
|
expose the checkers module to the rest of the world
|
|
This adds a checkers style overlay module, it's not terribly
interesting but may be made more useful if modules start
differentiating themselves as substantial vs. overlay effects.
It'd be nice if rtv/compose could automagically apply and
randomize overlay modules atop others, which would make use of
this type of thing as well as encourage more small modules like
these be written.
|
|
There's been a longstanding todo item in montage where it was
ignoring the fragmenter returned by a module's prepare_frame().
This commit continues with the single-threaded rendering of the
modules within their respective tiles, still ad-hoc open coded.
But now actually applies the fragmenter returned as if the
rendering were being threaded, since when a module returns a
fragmenter from its prepare_frame() it may strongly depend on
that fragmenting for its output.
|
|
This isn't super interesting but I might just start adding
simplistic overlay style modules for compositing/transition use.
|
|
Mechanical renaming of "zero" to "clear" throughout for this
context.
|
|
Just adding a convenience function targeting simple overlay use
cases where the fragmenter is exploited for producing patterns
and the renderer may wish to fill those fragments vs. zero them.
A future commit should also really rename til_fb_fragment_zero()
to til_fb_fragment_clear()
|
|
Currently when a threaded renderer performed
til_fb_fragment_zero() in render_fragment() vs. prepare_frame(),
the til_fb_fragment.zeroed maintenance would stay isolated to the
ephemeral fragment generated by the fragmenter.
With this commit, when all ephemeral fragments rendered in a
threaded fashion for a given frame returned a set .zeroed member,
the outer frame's .zeroed member gets set.
This should enable proper threaded zeroing of the frame in
render_fragment().
Note that since it's careful to actually count the number of
zeroed ephemeral subfragments and only propagates when that count
matches the number of subfragments rendered in the entire frame,
it's also supported to use til_fb_fragment_zero() conditionally
on just some fragments while not zeroing others and the entire
frame will not get its .zeroed member set. Imagine a renderer
which randomly zeroes out some fragments, while drawing into
others, this will be honored as a non-zeroed frame on the whole.
|
|
Oversight from when zeroed tracking was introduced in d9db26.
|
|
Just rely on til_init()'s srand() ensuring things are fresh.
|
|
A future commit will remove srand() calls from modules, relying
instead on this srand() in til_init().
As mentioned in the comment, if modules actually want
reproducible deterministic pseudo-random values they should use
rand_r() (or their own PRNG) where they can control the seed.
|
|
This was removed before, despite being left in the header by mistake.
Putting back for glimmer's sake.
|
|
Things have become sufficiently mature and featureful that
attempting to describe their usage seemed worthwhile.
There's still no cleanup of setups returned in *res_setup and
that should be both fixed and documented at some point. The
settings in general are still rather leaky as-is, even the
example in this document leaks. But it's relatively harmless for
now.
|
|
The til_settings_get_and_describe_value() helper (and the calling
setup methods in the modules) can be useful in independently
spitting out a baked setup instance from a fully resolved
til_settings_t which has already gone through the whole
rigamarole of getting populated and described.
Normally when this all happens in one place with the setup
instance then either immediately fed to create_context(), or
stowed somewhere for future use, it's not a problem to always
require the res_desc,res_setting parameters.
But especially in GUI scenarios (glimmer) the whole populate and
describe phase of til_settings_t can very easily be done in a
separate place from the convenient place to produce a setup out
of it. So when the caller /knows/ the setup is finished and a
subsequent call with the same til_settings_t would produce a
res_setup immediately, the caller should be able to omit
res_setting and res_desc as they're of no use now.
This is all kind of crufty, but it's nice to have all this
happening in a single setup method to help keep the res_setup
phase from diverging/becoming out of sync with the
populate+describe phase. Will live with it for now. Frontends
get written far less than modules, so the API cruft from the
frontend perspective is relatively benign. It's still relatively
sane and ergonomic from the module writer's perspective.
|
|
Now modules allocate and return an opaque setup pointer in
res_setup when they implement a setup method.
Defaults are utilized when ${module}_create_context() receives a
NULL setup. The default setup used in this case should match the
defaults/preferred values emitted by the module's setup method.
But performing setup should always be optional, so a NULL setup
provided to create_context() is to be expected.
No cleanup of these setup instances is currently performed, so
it's a small memory leak for now. Since these are opaque and may
contain nested references to other allocations, simply using
free() somewhere in the frontend is insufficient. There will
probably need to be something like a til_module_t.setup_free()
method added in the future which modules may assign libc's free()
to when appropriate, or their own more elaborate version.
Lifecycle for the settings is very simple; the setup method
returns an instance, the caller is expected to free it when no
longer needed (once free is implemented). The create_context
consumer of a given setup must make its own copy of the settings
if necessary, and may not keep a reference - it must assume the
setup will be freed immediately after create_context() returns.
This enables the ability to reuse a setup instance across
multiple create_context() calls if desired, one can imagine
something like running the same module with the same settings
multiple times across multiple displays for instance. If the
module has significant entropy the output will differ despite
being configured identically...
With this commit one may change settings for any of the modules
*while* the modules are actively rendering a given context, and
the settings should *not* be visible. They should only affect
the context they're supplied to.
|
|
This is a preparatory commit for cleaning up the existing sloppy
global-ish application of settings during the iterative _setup()
call sequences.
Due to how this has evolved from a very rudimentary thing
enjoying many assumptions about there ever only being a single
module instance being configured by the settings, there's a lot
of weirdness and inconsistency surrounding module setup WRT
changes being applied instantaneously to /all/ existing and
future context's renderings of a given module vs. requiring a new
context be created to realize changes.
This commit doesn't actually change any of that, but puts the
plumbing in place for the setup methods to allocate and
initialize a private struct encapsulating the parsed and
validated setup once the settings are complete. This opaque
setup pointer will then be provided to the associated
create_context() method as the setup pointer. Then the created
context can configure itself using the provided setup when
non-NULL, or simply use defaults when NULL.
A future commit will update the setup methods to allocate and
populate their respective setup structs, adding the structs as
needed, as well as updating their create_context() methods to
utilize those setups.
One consequence of these changes when fully realized will be that
every setting change will require a new context be created from
the changed settings for the change to be realized.
For settings appropriately manipulated at runtime the concept of
knobs was introduced but never finished. That will have to be
finished in the future to enable more immediate/interactive
changing of settings-like values appropriate for interactive
manipulation
|
|
Just mechanical replacement of some remaining ad-hoc
til_module_t.create_context() calls.
The montage module continues using an ad-hoc call because it
forces num_cpus=1 since it's already a threaded using a fragment
per module's tile. This suggests the til_module_create_context()
call should probably accept a num_cpus parameter, perhaps
treating a 0 value as the "automagic" discover value so callers
can explicitly set it when necessary.
|
|
Previously if you supplied an empty setting value like so:
"--module=compose,layers="
The interactive setup would get itself into an infinite loop
because the layers setting is already present, but has a NULL
value. This wasn't a NULL value, it was a "" value.
The parser should just fallthrough to the value state from the
equal state after recording the value's start pointer. This will
result in a "" value getting allocated and assigned to the value
before the loop breaks out on the '\0' immediately following the
'='.
There are probably other edge cases which need better handling
here.
|
|
Commit 7ff8ef included some fast and dirty fixups to
til_settings_apply_desc_generators(), but left an inappropriate
return path out of the iterator resulting in the caller accessing
a NULL res_desc.
The practical result of this was segfaulting in rototiller when
configuring anything utilizing desc generators, like drm_fb.
|
|
Now that there's a decoupled libtil usable by alternative
frontends by vendoring rototiller, the build should support
fb-less rototiller-less configurations.
In lieu of this change glimmer's build requires sdl2 despite not
actually utilizing sdl_fb. Now that shouldn't be necessary,
should there be neither libdrm or sdl2 present we'll only produce
libtil and no rototiller binary at all.
|
|
Introduce drawing styles, adding a line style in addition to the
existing points.
Settings are style={points,lines}, default is now lines.
|
|
No idea why this was in there. Though it makes the leader jump
by huge values, since it still winds up as samples on the same
path, just non-continuous, the swarm still appears correct,
hiding this braino.
If you reduce the SWARM_SIZE to a tiny number like 2 though, it
becomes very obvious that the leader is teleporting all over the
place.
|
|
Particularly in implementing a stateful/"retained" GUI it can be
desirable to embed something like a widget pointer in a
til_setting_t once described and shown to the user.
Management of this pointer is largely nonexistant from the
libtil perspective. It's simply initialized to NULL when a new
setting is added, and never accessed again. 100% the caller's
responsibility.
This works fine since libtil/til_settings_t only accumulates
til_setting_t entries and never removes them except when
discarding an entire til_settings_t wholesale.
|
|
This resulted in a NULL ptr deref, simply treating as invalid
since what's the point of handling a composition devoid of any
layers - it's probably a mistake.
|
|
attempt at making these more clear
|
|
Now that til_setting_t.desc is not only a thing, but a thing that
is intended to be refreshed regularly in the course of things
like GUI interactive settings construction, it's not really
appropriate to try even act like this these are const anymore.
|
|
Mechanically replaced ad-hoc til_module_t.destroy_context()
invocations with helper calls.
|
|
|
|
Always only capitalize the first letter, never capitalize like
titles.
|
|
Originally the thinking was that rototiller modules would become
dlopen()ed shared objects, and that it would make sense to let
them be licensed differently.
At this time only some modules I have written were gplv3, Phil's
modules are all gplv2, and I'm not inclined to pivot towards a
dlopen model.
So this commit drops the license field from til_module_t,
relicenses my v3 code to v2, and adds a gplv2 LICENSE file to the
source root dir. As of now rototiller+libtil and all its modules
are simply gplv2, and anything linking in libtil must use a gplv2
compatible license - the expectation is that you just use gplv2.
|
|
This is helpful for forcing underlying setup methods to
redescribe their settings, regardless of what a til_settings_t's
internal state is.
|
|
When integrating libtil into higher order application/gui
toolkits, it's desirable to passthru any unhandled arguments to
the toolkit's initializer.
The specific impetus for adding this is glimmer, which uses
gtk/glib where g_application_run() wants an argv but won't know
what to do with the libtil-recognized args.
|