summaryrefslogtreecommitdiff
path: root/src
AgeCommit message (Collapse)Author
2023-08-03til_settings: introduce til_setting_t.nocheckVito Caputo
This adds a setting value syntax for bypassing checks; ':' prefix e.g. --module=:experimental_module Would result in the value experimental_module added, and no verification performed of its presence in the module setting's values list. Two new til_settings api functions are introduced as well for setting and getting the raw values including any prefix syntax: til_setting_get_raw_value() til_setting_set_raw_value() these are needed because the til_setting_t.value member will continue to point at the "cooked" form of the value with the prefix stripped out, so the general cases of needing the value won't have to worry about the presence of prefixes. They have the til_setting_t.nocheck member to see if the setting was a nocheck-prefixed value. The nocheck prefix is preserved across serialization as well. So using a serialized form to seed a derivative settings instance won't spuriously start failing checks because the ':' prefixes are gone where they were necessary. They'll be kept wherever they were previously. There will probably be some more random fixes needed here and there where code is directly manipulating til_setting_t.value and must now go through the "raw" getter/setter api.
2023-08-01modules/rkt: make the default base= "rkt"Vito Caputo
The "tiller" base (base being a Rocket concept) was always a bit spurious. Maybe "til" would make more sense, but "rkt" is more contextually specific. I think when I originally picked "tiller" I was prioritizing picking something unlikely to collide with another directory name. But the way Rocket is naming the directory in the filesystem it gets suffixed with an _ anyways.
2023-08-01modules/rkt: make "blank" default scenes=Vito Caputo
The "compose,compose,compose,compose" default was never intended to be permanent, but gave a set of scenes to test the Rocket integrations like scene selection and scene-specific tracks without any additional effort. Now that there's scener for easily adding/editing scenes, and things are just generally more mature, I think it makes sense to just go back to something minimal here. I'd really rather just have it be "", but that's not handled well presently. There isn't really a way to start with an empty scenes set for rkt. Which is awkward, but "blank" is close. It'd just be nice to start with an altogether blank slate rather than having to always edit the default first scene when starting anew...
2023-07-31modules/rkt: remove TIL_MODULE_EXPERIMENTAL flagVito Caputo
Now that the "scener" interface seems to be semi usable and capable of editing... things are looking more complete in the sense that there's no huge gaping holes and a lot of the dust has settled. It's also looking pretty good for this sticking around long-term, so I'm removing the experimental flag making this more discoverable and visible in general. There's still work to be done surrounding GNU Rocket the library, like getting it using non-blocking connects, and there's a need for forgetting tracks which the protocol doesn't support currently. But it'd be silly to wait on getting those things upstream before making rkt more visible.
2023-07-31modules/signals: experimental signals moduleVito Caputo
Playing with libs/sig in 2D, this isn't really an interesting module by itself in terms of visual output. But it might have utility as a diagnostic thing if libs/sig becomes a more used thing. At the very least, for now, it's useful for observing affects of and iterating on libs/sig development. So I'm merging this, just gated behind TIL_MODULE_EXPERIMENTAL so it's not in rtv rotation or presented as something in the usual modules list.
2023-07-30modules/rkt: first stab at scene editing for scenerVito Caputo
This augments the NEWSCENE_SETUP state to also handle editing existing settings, which is slightly different but actually overlaps with the already implemented invalid input stuff. There's still work to do, and the UX is kind of awkward at best. But this takes us from having no ability to edit existing scenes, to being able to actually make edits interactively while it's all live... with a modicum of interactive guidance via the setup machinery. It basically behaves just like creating a new scene, except instead of the <enter>-accepted "preferred" values, you accept the existing relevant setting. So as-is, when editing, you have no shortcut for getting back the "preferred" value for a given setting. That's been replaced with the existing value for that setting. You also get seemingly spurious redundant queries for module names in things like compose::layers, but they're really not the same since the first time you get asked it's actually the full settings string you're getting an opportunity to specify wholesale, but can accept to seed the layer's settings as-is, which you will then be given an opportunity to edit piecemeal. It's that subsequent piecemeal editing of the individual settings within the nested instance that can feel like a spurious duplication, especialy when a given layer has just a bare-value module name and no subsequent settings.. like "plasma". You'd be asked if you want "plasma" for the layers/[N], then asked if you want "plasma" _again_ for the layers/[N]/[0] since the module name is an unnamed setting at position 0 within the layers/[N] instance. It was tempting to try streamline that a bit, but there's actually utility in having an opportunity to paste in a full settings string for the layers/[N] if you have a serialized scene onhand you want to dump in there. Then after that, you can juts smash enter as much as necessary to accept what you pasted in without editing those in the piecemeal phase. Or, if there was actually something in what you pasted you did want to change, change it during that piecemeal phase. I think it at least kind of works.
2023-07-30modules/checkers: add blurb about context clonesVito Caputo
There's an outstanding issue surrounding the need for context clones, and I'd just like to write something down somewhere before it falls off my radar. Presently it's just checkers that exercises this need, so it makes sense to put it here for now, until I get around to actually taking action on the issue.
2023-07-28modules/*: use til_fragmenter_slice_per_cpu_x16() where applicableVito Caputo
Mechanical change switching til_fragmenter_slice_per_cpu() users over to til_fragmenter_slice_per_cpu_x16(), except sparkler where it's quite detrimental to performance.
2023-07-28til: add til_fragmenter_slice_per_cpu_x16() variantVito Caputo
This restores the original til_fragmenter_slice_per_cpu() while adding an explicit x16 variant for what til_fragmenter_slice_per_cpu() had become. The impetus for this is realizing the x16 multiplier is terrible for sparkler's crappy threading, and it really need strictly n_cpus slices for the threading to be beneficial. So I'm just getting rid of the hidden x16 in favor of making it explicit in an _x16 variant. Subsequent commit will pivot all the non-sparkler callers to til_fragmenter_slice_per_cpu_x16().
2023-07-28modules/rkt: minor error message formatting fixVito Caputo
Better spearate the generic error line from surrounding text with an extra newline
2023-07-28modules/rkt: s/_EDITSCENE/_SCENE/Vito Caputo
This was a bit of an aspirational misnomer, editing scenes isn't actually implemented yet. What the EDITSCENE state currently implements is the per-scene dialog+prompt, which originally was going to just be the scene editing flow but became more of a "view a specified scene's details" with a prompt of its own. Nothing functionally changes, just mechanical internal renames.
2023-07-28til_settings: add til_settings_get_label() getterVito Caputo
Preparatory commit for rkt_scener scenes editing, which will be replacing the current scene's settings instance with a newly constructed one. This enables simply duplicating the existing scene setting's positional label, which will be identical in the replacement.
2023-07-28til_settings: filter til_settings_as_arg() resultsVito Caputo
Most of the time if there are undescribed settings in the settings hierarchy, they're just noise in the serialized as_arg form. So change til_settings_as_arg() to always skip undsecribed entries, and introduce til_settings_as_arg_unfiltered() for any use cases that actually want everything included. The unfiltered variant may just go the way of the dodo if nothing ever makes use of it.
2023-07-28til: use til_module_render_limited() in "ref" builtinVito Caputo
Since "ref" renders using arbitrary foreign contexts, it must explicitly limit their rendering concurrency to its own.
2023-07-28til: introduce til_module_render_limited() variantVito Caputo
With the introduction of discoverable on-stream contexts, with the intention of modules finding them at runtime for nested rendering, relying exclusively on limiting n_cpus @ til_module_create_context() is no longer adequate. When the nested rendering makes use of a context created elsewhere, it can't make any assumptions about what its n_cpus is, nor should it be attempting to change that value for its use. So this variant just adds a max_cpus parameter for setting an upper bound to whatever is found in the context's n_cpus. The impetus for this is to fix the ref builtin, which you can currently trick into deadlock by performing a nested threaded render within a threaded render. What the ref module should be doing is propagating its own context's n_cpus down as the upper bound, via this new render variant.
2023-07-25modules/rkt: fix vestigial til_str_newf() useVito Caputo
This is leftover from development when it used a fmt string in combination with the key, before the desc path was getting properly appended.
2023-07-21modules/shapes: drop atan2_approx()Vito Caputo
With the addition of the "radcache" in b6362c, the need for a faster approximate atan2f() is largely eliminated. And there seems to be a bug in the implementation as-is taken from https://mazzo.li/posts/vectorized-atan2.html You can see the bug as vertical line artifact around the center where the X coordinate would be 0. Rather than debug what's wrong with this approximation's implementation surrounding its quadrant adjustments, let's just resume using atan2f() and let the cache keep things quick.
2023-07-17main: fix UAF bug on shutdownVito Caputo
When introducing the **fragment_ptr model in 5a0776f, the rototiller_thread() introduced a local place to put the pointer to point at when rendering. But this pointer then ends up outliving the thread on shutdown within any queued frames until quiescent. Fixed in the obvious way by sticking it in rototiller_t instead.
2023-07-17modules/rkt: limit Rocket reconnect frequency to 2HZVito Caputo
On Linux I don't notice a significant affect on anything letting rkt try connect every frame when offline but in creative mode. On Windows however, Dan reported significant latencies in the Scener prompt responsiveness and visible slowdowns in this condition. I suspect the WIN32 Rocket library's sync_tcp_connect() code is the real problem here. But for now I can ameliorate things a bit by just hammering on that code path less when unconnected.
2023-07-16modules/rkt: pause on entering scene 99999Vito Caputo
This is only relevant to creative mode. Stops RocketEditor from continuing playback endlessly until user intervention beyond the current end of the demo.
2023-07-16modules/rkt: track last scene in ctxt->last_sceneVito Caputo
Prepartory commit for pausing playback upon entering 99999 scene It needs to trigger only on the edge of entering the scene to permit RocketEditor to unpause playback even if still in scene 99999, if that's what the user is trying to do. It'd be annoying to have it just keep asserting a paused state until the scene idx leaves 99999... But this also enables triggering anything on scene change edges, for future stuff.
2023-07-16modules/rkt: cleanup Rocket track namesVito Caputo
- strip off the leading /path/to/rkt/module prefix - separate taps from their scene context path with ':' vs. '/' RocketEditor doesn't currently support recursive grouping, so this is as good as it gets. Note this commit will break the existing tracks for alphazed, so you'll have to use a newer .zip for track data if building your rototiller from source. Or build from a prior commit.
2023-07-16module/rkt: pull rkt_context_t to sync_get_trackfVito Caputo
Preparatory commit for rewriting track paths a bit to better group things in RocketEditor. I'll need access to rkt_context_t.til_module_context_t.setup->path for prefix matching purposes..
2023-07-15modules/roto: implement fill_module= settingVito Caputo
This makes it possible to tiled+rotate the output of another module in the same manner checkers::fill_module fills cells with module output. The default stays "none" for the classic roto with the psychedelic color cycling. When !"none" the color cycling doesn't get applied currently. It might be interesting to try support that in the future though.
2023-07-14modules/rkt: remove vestigial "/scenes" path appendVito Caputo
During rkt_scener development this append was at one time needed, as there was no retained reference to the scenes_settings for deriving paths from. Now that the path is derived from the actual scenes setting instance it's just resulting in a double trailing /scenes in the "/module/rkt/scenes/scenes:" heading Purely cosmetic fix
2023-07-13til_args,*_fb: introduce --title= and wire up to til_fb_tVito Caputo
For meta-demo use cases like alphazed is experimenting with, it's desirable to change the window title from "rototiller" to "alphazed" or whatever if in windowed mode. This adds a way to do that in the obvious fashion... --title="alphazed" etc.
2023-07-13sdl_fb: hide cursor when fullscreenVito Caputo
2023-07-13til_stream: update tap ptr in til_stream_tap new pipe caseVito Caputo
The tap->ptr indirection must always be updated even when we're the driver on a fresh pipe created by us. This bug only triggers when the caller's tap was already on-stream, without being the driver, and the driving tap/context has since exited the stream, untapping itself which removed the associated pipes - even the ones it didn't own but was driving. In that scenario when pipe is created by the previously non-driving tap on its first update since the driver exited, its tap->ptr still points at the stale driver. This manifested as a UAF bug in that case. The fix is a simple matter of always updating tap->ptr to reflect the driving tap. This also fixes the real bug causing 468c78e3 to crash, such that the syncronous gc performed there shouldn't really be necessary to prevent crashing. It was the awkward overlapping existence of contexts at the same path which produced the triggering lifecycle pattern WRT driving taps at that path.
2023-07-13modules/rkt: '=' for current Rocket scene in scenerVito Caputo
Pressing '=' at either prompts now makes scener's current scene the current Rocket scene. While you could already do this manually by just looking at the scenes list for the one with the '*' in the Rocket column while either watching a production and pressing <enter> repeatedly to keep refreshing the scenes list... that's cumbersome and annoying, now just use this shortcut. Since this just copies Rocket's scene to the Scener scene index, it needed to properly handle scene 99999... hence the previous commits.
2023-07-13modules/rkt: include EXITED [99999] in scenes listVito Caputo
While there's no actual context for 99999, it's a state we need to represent visibly somehow.. so just make it appear like an epilogue scene off the end. I've included the Rocket/Scener/Pinned status columns consistently as well so you at least still get a visible indication when you've done something like pinned 99999 somehow (not that this is possible presently, but with future changes there will be more ways to copy the Rocket idx into Scener's idx)
2023-07-13modules/rkt: add 99999 exit scene defineVito Caputo
rkt_scener needs to know this value so define it in rkt.h and switch over all the existing 99999 instances.
2023-07-12modules/rtv: perform gc immediately in cleanup_channel()Vito Caputo
Until channel context paths are distinct it's buggy to let the contexts linger while constructing the next channel's contexts. Originally when the gc was added here the intention was to support stuff like the "ref" module and get the channels settings wired up immediately with more focus on rtv's details in this area. Supporting stuff like contexts backing some layers persisting across channels, while the others were swapped out, seemed potentially interesting (and it still is). But the rkt stuff became prioritized as rtv is more like a fuzzer than anything despite being the default module. And rkt related activities will continue for now, so let's just get rtv less likely to crash. A reliable repro for triggering an ASAN UAF bug without this commit is: --seed=0x64af3b05 '--module=rtv,duration=1,context_duration=1,channels=compose,caption_duration=2,snow_duration=0,snow_module=none,log_channels=on' '--video=sdl,fullscreen=off,size=640x480' A few channels in blinds will UAF while updating taps stored in a freed context, because the previous channel has a blinds in the same layer as the newly setup channel, putting the contexts at exactly the same paths on-stream. There's probably another bug in here that I need to dig into, but coexisting contexts at the same path on-stream was never the intention. The syncronous immediate gc ensures nothing remains of the previous channel before constructing the new one at the same path.
2023-07-12modules/rtv: fix settings path for channel settingsVito Caputo
The channel module name was being used as the settings instance name, which is redundant to the entries[0] "value as label" behavior with the module name also @ entries[0]. The resulting paths resembled: /module/rtv/compose/compose/layers/[N]/... /module/rtv/compose/compose/texture/... Now they are: /module/rtv/channel/compose/layers/[N]/... /module/rtv/channel/compose/texture/... There's still work to be done in this area of rtv. It's unclear if even a static "/module/rtv/channel" is correct, or if it should show the subscript of the channels[] entry currently being used when that becomes a proper nested settings situation, i.e. /module/rtv/channels/[0]/compose/layers/[N]/... ... /module/rtv/channels/[1]/spiro ... /module/rtv/channels/[2]/roto ... for a "channels=compose,spiro,roto" kind of hypothetical another option which might make sense is to have the channel path more like an auto-increment identifier so the channel contexts have unique paths and don't collide on the stream. This could be important for scenarios utilizing the "ref" module and trying to reuse parts of the context from one channel to the next. When the paths collide things tend to break in weird ways presently. this area needs more thought
2023-07-12til_stream: loop gc passes until nothing gets freedVito Caputo
Due to how meta-modules reference other modules from within their context, they pin the related refcounts until their gc is performed. So repeat the gc passess until nothing gets freed, to gc those recursive references immediately. Fortunately this isn't intended to be done at perf-sensitive times...
2023-07-12til_stream: clarify c->n_contexts reuseVito Caputo
til_stream_register_module_contexts() reuses the container when c->n_contexts is sufficiently large, and deliberately leaves c->n_contexts as-is to potentially accomodate a larger set in the future. The excess was NULLified in prepping for reuse so it should be fine, just add a blurb about it so it doesn't look like an oversight.
2023-07-12modules/blinds: update taps in prepare_frameVito Caputo
Silly and unnecessarily racy to do this in render_fragment now that blinds is threaded
2023-07-11modules/blinds: make blinds threadedVito Caputo
This is a first stab at threading blinds, while here I got rid of the reliance on _checked() put_pixel for clipping. This could be better, things like using a block put/copy instead of put_pixel would be a huge advantage for blinds due to its naturally contiguous blocks per-blind. While this module when non-threaded wasn't especially slow, any module leaving cores idle is depriving other potentially threaded modules of utilizing them for the duration of the non-threaded render. So now that rototiller is being used for compositions and increasingly becoming something of a meta-demo, it's become important to make everything as threaded as possible.
2023-07-11modules/blinds: update taps at context create tooVito Caputo
Especially since taps are established on first use, it's desirable to get them online immediately so they show in things like --print-pipes and modules::rkt/RocketEditor and not spuriously once the context becomes actively rendered... This kind of thing will be done for all modules eventually
2023-07-11modules/shapes: cache per-pixel atan2 resultsVito Caputo
computing the angle for every pixel coordinate from the origin is costly, even with the approximate method added by c690303. An easy speedup is to only do this once for a given frame dimensions, and cache those results. In the form of a 32-bit float, it's equivalent to caching a full page of pixel data. This is slightly complicated by needing to be an effectively global cache and the potential for multiple shapes contexts rendering concurrently when part of a composition. I think this particular situation highlights a need for something equivalent generalized on-stream where modules can register discoverable caches of costly to compute information, having a high probability of being useful to others. In this particular case it was alphazed's use of shapes in two layers that made it an obvious win, even without any other modules needing atan2() per-pixel with a centered origin. With this commit: Configured settings as flags: --seed=0x64adabae '--module=compose,layers=blank\,shapes\\\,type\\\=pinwheel\\\,scale\\\=.9\\\,pinch\\\=.25\\\,pinch_spin\\\=.1\\\,pinches\\\=7\\\,points\\\=19\\\,spin\\\=.01\,shapes\\\,type\\\=pinwheel\\\,scale\\\=.9\\\,pinch\\\=1\\\,pinch_spin\\\=-.25\\\,pinches\\\=8\\\,points\\\=5\\\,spin\\\=0,texture=moire\,centers\=3' '--video=mem,size=1366x768' FPS: 73 FPS: 74 FPS: 73 Without: Configured settings as flags: --seed=0x64adb857 '--module=compose,layers=blank\,shapes\\\,type\\\=pinwheel\\\,scale\\\=.9\\\,pinch\\\=.25\\\,pinch_spin\\\=.1\\\,pinches\\\=7\\\,points\\\=19\\\,spin\\\=.01\,shapes\\\,type\\\=pinwheel\\\,scale\\\=.9\\\,pinch\\\=1\\\,pinch_spin\\\=-.25\\\,pinches\\\=8\\\,points\\\=5\\\,spin\\\=0,texture=moire\,centers\=3' '--video=mem,size=1366x768' FPS: 55 FPS: 54 FPS: 54 So it's significant, and in alphazed there's also a transition from one scene with two full-screen shapes layers into a checkered scene with shapes as the fill_module. Further amplifying the payoff.. infact whenever shapes is used for a fill_module in checkers, there's n_cpus shapes contexts created because checkers is threaded. All of those would be benefitting from the cache.
2023-07-10til_fb: fast-path til_fb_fragment_clear() a bitVito Caputo
What this really should have is a general memset32() implementation, but for now it's a small improvement at least for clearing since that's known to be a 0-pixel case where memset() is applicable. memset() isn't usable for actual RGBA pixels since it operates strictly on bytes. There's some hacks for using memmove() to get closer where you store the first four bytes, then memove the start of the buffer to the remaining, doubling the size of the move each time for log(n) calls to memmove. Maybe that makes sense as a stop-gap for the general case, it needs implementing+benchmarking first. This commit is dead simple though and an obvious little FPS gain for clearing.
2023-07-10til: introduce "noop" builtinVito Caputo
When profiling compositions it's convenient to suppress some modules in the settings to see how their omission affects the FPS. There's already a "blank" builtin which clears the fragment, but there's no way to turn the cost to ~zero. This "noop" builtin does just that, absolutely nothing - it won't even trigger the implicit "til_fb_fragment_t.cleared = 1" update so whatever rendering follows will still find an uncleared fragment if that's what came into the noop.
2023-07-09til: introduce til_module_setup_full()Vito Caputo
This moves the core til_module_setup() functionality out into a more composable helper with an eye towards all meta-modules using it for doing their module setup instead of all the ad-hoc stuff occurring presently. Since til_module_setup_full() needs more paramaters to influence its behavior, it's not directly usable as a "setup_func". But is trivially wrapped into one, which is what til_module_setup() has now become. It's in the wrapper that users are expected to do specify what's necessary for influencing til_module_setup_full() to do what's appropriate for their needs.
2023-07-09modules/spiro: skip color math+packing if texturedVito Caputo
The color stuff as-is isn't cheap and doesn't even get used if there's a texture present, so don't bother with it at all. This is especially significant since this module isn't threaded, so it ties up all the cores leaving most of them idle when part of a composition. Also since spiro doesn't clamp its coordinates to the fragment dimensions, only considering the frame dimensions, it must continue using the "checked" put_pixel variant...
2023-07-08modules/rkt: pile of __WIN32__ concessionsVito Caputo
This seems to make things work well enough for mingw+wine Will probably revisit in the future. Adding an ewouldblock helper rather than duplicating the ifdeffery seems likely Let's just leave it like this for now and find out if a real windows test succeeds
2023-07-08modules/rkt: switch to inet_addr()Vito Caputo
This is available in win32, unlike inet_aton()
2023-07-08til: add timersub macro for __WIN32__Vito Caputo
just quick and nasty hacking to make win32 build again
2023-07-08til: measure til_module_render() durationsVito Caputo
This stows the duration (in ticks (which are ms for now)) of a given module context's most recent, as well as tracking the max, in til_module_context_t. For now it's also added to --print-module-contexts output, but this is still rather primitive and nearly inscrutible in practice... that output is a flickery and unsorted mess during playback. But this is just a start. Ticks may need to move up to microseconds if it'll also be the units for measuring timings. Right now things are slow enough that the low-hanging fruit stand out as multiple if not dozens of milliseconds so it's still useful for now.
2023-07-08modules/checkers: stop setting til_frame_plan_t.cpu_affinityVito Caputo
In the early days of checkers when I introduced fill_module= with the per-cpu contexts to still allow threaded rendering, the whole seed passing to contexts thing wasn't as well sorted out. This meant the contexts often produced vastly different outputs despite being the same module, same seed, and same settings. The consequence of that was that w/fill_module checkers would produce crazy randomized output when you expected the same output in the filled cells. But by using .cpu_affinity (which I had to implement just for this use case actually) at least the different outputs would become stable. It was a band-aid over a different problem that still needed sorting out. Nowadays, it seems like this is improved enough at least for alphazed to look correct without the affinity hack, so I'm removing it because it really kills checkers threaded performance. Whatever modules remain uncooperative WRT seed reproducibility, they'll just need to be fixed up.
2023-07-08modules/shapes: use new approximate atan2 functionVito Caputo
While here also did more minor optimizations moving things out of the inner loops that were only there out of laziness...
2023-07-08modules/shapes: introduce an approximate atan2f()Vito Caputo
Taken from this excellent post: https://mazzo.li/posts/vectorized-atan2.html While I haven't gone full vectorized, just getting rid of the regular atan2f() call will be a big improvement. This just adds the functionality, nothing is calling it yet.
© All Rights Reserved