summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2022-04-19til_fb: introduce til_fb_fragment_fill()Vito Caputo
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()
2022-04-15til_threads: propagate threaded til_fb_fragment.zeroedVito Caputo
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.
2022-04-14til_fb: copy zeroed in til_fb_fragment_tile_single()Vito Caputo
Oversight from when zeroed tracking was introduced in d9db26.
2022-04-14modules/*: remove srand() initializationsVito Caputo
Just rely on til_init()'s srand() ensuring things are fresh.
2022-04-14til: seed srand in til_init()Vito Caputo
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.
2022-04-13til_fb: put back til_fb_context() accessorVito Caputo
This was removed before, despite being left in the header by mistake. Putting back for glimmer's sake.
2022-04-01til_settings: make res_{desc,setting} optionalVito Caputo
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.
2022-04-01modules/*: instantiate and use setupsVito Caputo
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.
2022-03-30*: wire up context-specific setup instancesVito Caputo
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
2022-03-30*: use til_module_create_context() in more placesVito Caputo
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.
2022-03-30til_settings: fix empty values in til_settings_new()Vito Caputo
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.
2022-03-30til_settings: remove vestigial return missed by 7ff8efVito Caputo
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.
2022-03-29build: make sdl2 and rototiller bin optionalVito Caputo
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.
2022-03-28modules/swarm: add lines drawing styleVito Caputo
Introduce drawing styles, adding a line style in addition to the existing points. Settings are style={points,lines}, default is now lines.
2022-03-28modules/swarm: remove extra ticks multiply on leader radsVito Caputo
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.
2022-03-28til_settings: provide a user_data pointer w/til_setting_tVito Caputo
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.
2022-03-25modules/compose: -EINVAL on empty layers settingVito Caputo
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.
2022-03-19modules/sparkler: clarify BSP-tree setting descsVito Caputo
attempt at making these more clear
2022-03-19*: de-constify til_setting_t throughoutVito Caputo
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.
2022-03-19*: use til_module_destroy_context()Vito Caputo
Mechanically replaced ad-hoc til_module_t.destroy_context() invocations with helper calls.
2022-03-19til: add til_module_destroy_context() helperVito Caputo
2022-03-19*: normalize setting description capitalizationsVito Caputo
Always only capitalize the first letter, never capitalize like titles.
2022-03-19*: drop til_module_t.licenseVito Caputo
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.
2022-03-19til_settings: introduce til_settings_reset_descs()Vito Caputo
This is helpful for forcing underlying setup methods to redescribe their settings, regardless of what a til_settings_t's internal state is.
2022-03-14til_args: introduce til_args_pruned_parse() variantVito Caputo
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.
2022-03-12til_settings: always describe relevant settingsVito Caputo
The existing iterative *_setup() interface only described settings not found, quietly accepting usable settings already present in the til_settings_t. This worked fine for the existing interactive text setup thing, but it's especially problematic for providing a GUI setup frontend. This commit makes it so the *_setup() methods always describe undescribed settings they recognize, leaving the setup frontend loop calling into the *_setup() methods to both apply the description validation if wanted and actually tie the description to respective setting returned by the _setup() methods as being related to the returned description. A new helper called til_settings_get_and_describe_value() has been introduced primarily for use of module setup methods to simplify this nonsense, replacing the til_settings_get_value() calls and surrounding logic, but retaining the til_setting_desc_t definitions largely verbatim. This also results in discarding of some ad-hoc til_setting_desc_check() calls, now that there's a centralized place where settings become "described" (setup_interactively in the case of rototiller). Now a GUI frontend (like glimmer) would just provide its own setup_interactively() equivalent for constructing its widgets for a given *_setup() method's chain of returned descs. Whereas in the past this wasn't really feasible unless there was never going to be pre-supplied settings. I suspect the til_setting_desc_check() integration into setup_interactively() needs more work, but I think this is good enough for now and I'm out of spare time for the moment.
2022-03-11main: move til_init() to start of mainVito Caputo
Currently this was done rather late for vestigial pre-libtil reasons; it used to be a local function for specifically "create rendering threads" purpose. But it's rather awkward now to see such an initializer called late after myriad other til_* API is being used, and there's nothing gauranteeing til_init() will continue to strictly create rendering threads. Nothing is actually changing in what til_init() does here, it's just a cosmetic movement of the call site and s/librototiller/libtil/ in the error message.
2022-03-11main: simplify setup_from_args()Vito Caputo
Just removing some copy pasta from the error paths, nothing functionally different.
2022-02-15modules/flui2d: introduce settable decay factorVito Caputo
The existing simulation would always accumulate, eventually filling the volume with density. This adds a decay to diminish the density, with the default less quickly filling the volume vs. before.
2022-02-15modules/*: remove inappropriate 'f' numeric suffixesVito Caputo
These are making it into the settings strings, it's benign only because regexps aren't currently being enforced. Fix it up anyways.
2021-10-03args: move argument parsing/help output to libtilVito Caputo
This is totally opt-in for libtil callers, but is a step towards enabling uniform cli invocations across frontends. The help side of this is particularly janky, but since what's appropriate there is directly related to the args parsing it seems appropriate to bring along. The janky part is the implicit output formatting assumptions being made, as-is it doesn't really lend itself well to being augmented into broader frontend help output. Alas, this is rototiller playground, so let's just go easy and assume frontends will largely spit out whatever this provides - or completely replace it if appropriate.
2021-10-01*: librototiller->libtilVito Caputo
Largely mechanical rename of librototiller -> libtil, but introducing a til_ prefix to all librototiller (now libtil) functions and types where a rototiller prefix was absent. This is just a step towards a more libized librototiller, and til is just a nicer to type/read prefix than rototiller_.
2021-02-18fb: fix comment braino: s/invalid/inactive/Vito Caputo
2021-02-18modules/rtv: fix "none" snow to actually blankVito Caputo
This manifests in the current unconfigured rtv glimmer shows, since the default is a the "none" module when no settings are applied. But it turns out this isn't just a glimmer problem, "none" is advertised in the settings as a blanking alternative to snow. So it's actually broken in rototiller as well. This fixes it by detecting the nil "none" module's lack of any prepare_frame or render_fragment methods, and open coding the blanker with a fb_fragment_zero() inline.
2021-02-18fb: introduce fb_rebuild()Vito Caputo
When an fb has been resized, all the pages can be forced to go through a backend free->alloc cycle by calling this function. This process gets queued and realized as the pages pass through the inactive state. This does mean that whatever pages are already queued as ready still get displayed, so it's not exactly without racing/flickering at the fringes on window growth. It's possible to do something with the pages in the ready queue to combat this, but for now I'm just leaving them be to keep it simple. The ready pages could be stretched or something...
2021-02-18fb: remember the page count in fb_tVito Caputo
Adds fb_t.n_pages member, we need the number of pages for queueing rebuilds.
2021-02-18fb: make inactive pages list doubly-linkedVito Caputo
This introduces a previous pointer to _fb_page_t, but it's only used on the inactive list. This is a preparatory commit to facilitate adding inactive pages at the head and consuming inactive pages off the tail, without having to always iterate the list for the new tail. Rebuilding pages on resize needs to happen somewhere, and the inactive list seems like the right place to do it. And to do it with a simple per-fb pages-needing-rebuild counter requires turning the inactive list into a FIFO queue.
2021-02-17threads: make more of this API cancellation safeVito Caputo
It's desirable to be able to cancel a rendering loop thread used in librototiller callers, which will necessarily use these functions. When the cancellation originates from a GUI thread, which then joins on the rendering loop thread being cancelled, this blocks the GUI thread until the rendering loop thread realizes the cancellation and exits. But the GUI thread is likely party to the machinery of consuming fb pages being produced by librototiller, throwing them on-screen, and making previously visible pages available for reuse. The rendering loop thread blocks on waiting for that making pages available step, to have space for rendering a new frame into. This creates a circular dependency, and when the GUI thread is stuck in the cancel+join of the render loop thread, this establishes potential for deadlock when there's no extra page already available, and the GUI thread can't service its event loop to flip a page. Thread cancellation is the escape hatch for such situations, which is why cancellation can't be disabled across the critical section of librototiller calls and reenabled+polled at the top of the render loop thread. We *need* cancellation to wake up and break out of all the cancellation points within that critical section, so they don't deadlock in this scenario. They need to wake up, cleanup any held locks, and the calling thread exit so the join may finish and life goes on. Hence, put these unlocks in cleanup handlers so callers can cancel them without leaking held locks.
2021-02-17rototiller: add rototiller_quiesce()Vito Caputo
This is a wrapper around threads_wait_idle(), so the caller can easily synchronize with outstanding work before tearing things down or otherwise rejiggering the world.
2021-02-17fb,settings: return NULL from _free() methodsVito Caputo
and ignore NULL parameters as benign
2021-02-16*fb: plumb outer fb_t down to fb_ops_t methodsVito Caputo
None of the existing fb_ops_t implementations need this, but due to how GTK+ works, the GTK+ frontend using librototiller will likely want to wire up calling fb_flip() on the fb from behind fb_ops.
2021-02-14*: split rototiller.[ch] into lib and mainVito Caputo
This is a first approximation of separating the core modules and threaded rendering from the cli-centric rototiller program and its sdl+drm video backends. Unfortunately this seemed to require switching over to libtool archives (.la) to permit consolidating the per-lib and per-module .a files into the librototiller.a and linking just with librototiller.a to depend on the aggregate of libs+modules+librototiller-glue in a simple fashion. If an alternative to .la comes up I will switch over to it, using libtool really slows down the build process. Those are implementation/build system details though. What's important in these changes is establishing something resembling a librototiller API boundary, enabling creating alternative frontends which vendor this tree as a submodule and link just to librototiller.{la,a} for all the modules+threaded rendering of them, while providing their own fb_ops_t for outputting into, and their own settings applicators for driving the modules setup.
2021-02-14compose,montage,rtv: drop author and license fieldsVito Caputo
These modules are meta modules, and the only place this information is presented currently is in the rtv module captions overlaying the visual output of unrelated modules. So it's rather misleading to put the meta module's author and license on-screen when what's being shown is arguably just a tiny fraction of the meta module's contribution. Rather than bother with constructing license and author lists at runtime from the modules incorporated by these meta modules, let's instead adopt a policy of meta modules omit any declaration of license or authorship outside of the source. This is a simple solution for now, it can be revisited later if necessary. Changing the .author member of rototiller_module_t to an .authors() function pointer wouldn't be difficult. But it does open up something of a can of worms when considering recursive dependencies and needing to construct unique authors and licenses lists from things like nested meta modules. Obviously there can't be infinite recursion as that would manifest in the rendering path as well, but what I'm more concerned about is properly handling potentialy quite long lists. It's already annoying when rtv has to deal with a long settings string, which I believe currently is just truncated. The same would have to be done with long authors/licenses I guess. In any case, I think it's probably fine to just leave authorship and license ambiguous when a meta module is shown in rtv. It's certainly preferable to vcaputo@pengaru.com getting credit for everything shown in the three meta modules currently implemented, or more specifically, the two shown in rtv; compose and montage. Note this required making rtv tolerante of NULL .license and .author rototiller_module_t members.
2021-02-14*fb: improve error propagation out of setup/initVito Caputo
A lot of errors were being conflated as ENOMEM due to the lazy use of NULL pointer returns for errors. This commit reworks a handful of those return paths to instead return an errno-style int, storing the results on success at a supplied result pointer. It's kind of ugly, and I make some assumptions about libdrm setting errno on failure - it too uses this lazy API of returning NULL pointers on failure. Hopefully errno is always set by an underlying ioctl failing. The SDL error API is also pretty gross, being cross-platform it defines its own error codes so I try vaguely map these to errno values. I'm considering this a first approximation at fixing this up, but there are probably bugs as I did it real fast and nasty. It at least seems to all still work OK here in the non-error paths I tested. So it doesn't seem more broken than before at a glance.
2021-02-14drm_fb,sdl_fb: staticify all functionsVito Caputo
Some omissions, nothing in these is public outside of what's explicitly plumbed out via fb_ops_t.
2021-02-08modules/*: normalize description capitalizationVito Caputo
Minor cosmetic consistency fixup
2021-02-08modules/swarm: implement a particles swarm moduleVito Caputo
Just a fun little swarm based loosely on 80s-era boids It would be interesting to make stuff like the # of particles and the weights runtime configurable, or exposed as knobs. Using a Z-buffer for occlusions and perhaps shading by depth might make a significant improvement on the visual quality. It might also be interesting to draw the particles as lines connecting their current position with their previous, instead as pixels. Or fat pixels like stars...
2021-02-07modules/plasma: normalize plasma dimensionsVito Caputo
This is a quick and dirty jab at normalizing the plasma size to be independent of the frame size. I kind of hate this module as-is, it's tempting to discard all the fixed point stuff and just redo it using floats.. the plasma itself isn't that attractive as-is either. But I have other things to work on currently, just wanted to make it so the plasma doesn't look like a solid color in the montage tile.
2021-02-07modules/plasma: trivial cleanupsVito Caputo
- move LUT initialization to context create - minor syntactic changes
2021-01-18modules/drizzle: low-hanging fruit optimizationsVito Caputo
- switch puddle_sample() to 0..1 coordinates to avoid some pointless extra arithmetic on every pixel - avoid redundant ->w multiplies in puddle_sample() - avoid multiplies in inner loops of drizzle_render_fragment() by accumulating coordinates w/addition instead I noticed full-screen 'compose' was struggling to keep a full frame rate on my laptop when testing with the new 'plato' layer. valgrind profiles showed drizzle as the big hog, mostly the puddle_sample() function. These changes help but it's still not great, getting much better will likely become invasive and crufty. It would be nice to cache the vertical lerp results and reuse them across puddle_sample() calls when valid, that might be a useful TODO. The runner-up is spiro, prolly some low-hanging fruit there as well, I haven't looked yet.
© All Rights Reserved