summaryrefslogtreecommitdiff
path: root/src/modules/checkers
AgeCommit message (Collapse)Author
2023-10-11modules/checkers: staticify checkers_fragment_tile_single()Vito Caputo
Minor oversight when this was written, this fragmenter is private to checkers.
2023-10-02modules/checkers: adopt til_value_to_pos() helperVito Caputo
Mechanical transition from checkers_value_to_pos() to the now libtil-provided equivalent of identical implementation.
2023-09-04til: support multi-pass renderingVito Caputo
Modules can now use the til_module_t.finish_frame() return value to trigger re-rendering by returning 1, returning 0 finishes the frame. A smattering of til_module_t.finish_frame() implementations were largely mechanically updated to match this change by returning 0, since nothing actually uses multi-pass rendering yet. The impetus for this is experimenting with the flow module doing two passes of threaded rendering per frame. A first pass to sample the flow field and update the elements, per-cpu, but drawing nothing. Then a second pass to render the elements in a tiled manner.
2023-08-31modules/*: use til_setup_free_with_ret_err() where aproposVito Caputo
Just some more res_setup baking failure path cleanups, largely mechanical change.
2023-08-30modules/checkers: handle baking errors in checkers_setup()Vito Caputo
More setup_func conversion to returning the failed setting on errors during res_setup baking.
2023-08-12modules/checkers: fix clipping bug in fragmenterVito Caputo
The existing code wasn't clipping correctly to the right/bottom edges of the incoming fragment when the xoff/yoff was 0 but xshift/yshift non-zero. In that case the incoming fragment bound was unintentionally being enlarged, resulting in an overrun when the such a cell was filled/cleared. It was discovered watching montage under rtv, which stumbled across running checkers w/size=128 on a montage tile of 128x96. The height/y coords of the single checker cell filling the whole montage tile weren't getting clamped properly down to the 96-tall tile. The shifting for centering checkers introduced some really annoying arithmetic in this fragmenter.
2023-08-12modules/checkers: minor cosmetic changes to fragmenterVito Caputo
Trivial changes to improve some naming / scoping, done while investigating a bug. Nothing functionally changed
2023-08-07modules/checkers: ensure all fill_module_contexts renderVito Caputo
There's potential for some of the per-cpu fill_module_contexts to go unused for an entire frame. When this occurs, depending on the fill_module in use, it can lead to their context's state diverging. To mitigate this possibility, add a tidying up pass in checkers_finish_frame() where such straggler contexts are identified and forced to render once into a cell-sized waste_fb of off-screen memory. This ensures all contexts see all frames/ticks that any participated in, preserving their clone status across the board. Prior to this you could see jittering in something like '--module=checkers,fill_module=roto' as the roto contexts diverged on the r/rr variables when some didn't get in on the action of some frames. See large TODO comment for why this approach is used instead of something less wasteful of cpu time. If this approach is kept, it might make sense to do the waste rendering in parallel. Systems with large numbers of cores could end up with many stragglers, depending on how many cells there are vs. cpus. I don't have any such systems so it's difficult to test any efforts in that vein.
2023-08-05modules/checkers: til_module_setup_full() for fill_module=Vito Caputo
Switch to the generic til_module_setup_full() and rely on the "none" builtin's NULL res_setup on finalize to indicate when no fill_module is desired. This gets rid of the need for a separate til_module_t* handle for the fill_module, since til_setup_t.creator can be used for that, and the NULL til_setup_t* to indicate no fill_module. Basically discards some busy work style code, there's more cleanups needed surrounding this stuff though.
2023-08-05til_setup,*: add til_setup_t.creator pointerVito Caputo
Particularly with nested modules it's annoying to have to stow the module separate from the setup during the setup process. If the baked setup included the module pointer in the non-module-specific-setup part of the setup, then nested settings could finalize using the generic module setup wrapper and just rely on this til_setup_t.creator pointer to contain the appropriate module. Which should enable tossing out a bunch of copy-n-pasta surrounding nested modules setup. Note this has to be a void* since til_setup_t is a generic thing used equally by both the fb code and the module code. Hence why this is called "creator" and not "module", as well as the void* as opposed to til_module_t*. Also if rototiller ever grows a sound backend, the setup machinery will be reused there as well, and it'll be yet another creator handle that isn't an til_fb_ops_t or a til_module_t. It's assumed that the callers producing these setups won't be trying to pass them to the wrong places i.e. a module setup getting passed to an fb backend and vice versa. I'm mildly annoyed about having to move the various til_module_t blocks to above the module's foo_setup(), but it seemed like the least annoying option. This may be revisited.
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-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-04modules/*: return invalid setting on -EINVAL in setupVito Caputo
In the interests of improving error handling of interactive setups, return the setting that was invalid when setup returns -EINVAL. For now this is only supported for non-finalized/non-baking setup calls, i.e. (!res_setup). In the future I want this also supported for finalizing when res_setup is set. A lot of the -EINVAL returns are actually during that stage (or need to be added) due to that being when the more sensitive parsing occurs going from strings to native numeric types and such. The main reason it's not already being done in this commit is it'll churn quite a bit to get there, since the setup funcs don't generally have the setting pointers onhand at that phase. It'll require changing the string-value-centric local variables to instead all be the til_setting_t* holding those values. And if setup funcs aren't going to be so value-centric, the settings API will likely change to not even return the values directly anymore and only return the full-blown til_settings_t as the main return pointer, perhaps rid of their res_setting use even. Anyway, while here I did some random little cleanups too.
2023-06-13modules/checkers: return -EINVAL on invalid module nameVito Caputo
Not sure why this was -ENOMEM, module lookups don't allocate anything...
2023-06-13*: smattering of random small fixes to silence -WallVito Caputo
I thought the build was already using -Wall but that seems to not be the case, maybe got lost somewhere along the line or messed up in configure.ac After forcing a build with -Wall -Werror, these showed up. Fixed up in the obvious way, nothing too scary.
2023-06-13modules/checkers: introduce clear=,clear_color= settingsVito Caputo
Similar to fill= and fill_color=, these influence how to treat the "clear" cells. Until now "clear" cells would unconditionally just be cleared via til_fb_fragment_clear(). Now they can also be filled w/color,sampled,textured, and maybe in the future a clear_module= will also be introduced. Note that for now I've left the clear_color randomizer disabled, see code comments. Having this setting also makes me wonder if the "filled" cells should be optionally cleared using the "clear" setting first. Imagine a scenario where you have fill_module=shapes, and you want the color around the shape to match the clear color, for instance... Especially once you can pass a color down to the fill_module, controlling these things becomes more critical. There's definitely more work to do here.
2023-06-13modules/checkers: prefix fill_ to fill color+flagsVito Caputo
Preparatory commit for introducing equivalents for the "clear" cells. This renamed the color= setting to fill_color=, in addition to the internal naming.
2023-06-05modules/checkers: use til_module_create_contexts() for fill_moduleVito Caputo
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...
2023-05-30til,*: pivot to til_setup_t for context pathsVito Caputo
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.
2023-05-30modules/*: utilize til_module_setup_finalize()Vito Caputo
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.
2023-05-28til_setup,*: note settings path in til_setup_tVito Caputo
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.
2023-05-26til_settings: add til_setting_spec_t.as_labelVito Caputo
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.
2023-05-26modules/checkers: desc the fill_module's name settingVito Caputo
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.
2023-05-23modules/checkers: add seed to randomized pattern,dynamicsVito Caputo
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.
2023-05-23modules/checkers: fix transposed seed,ticks argumentsVito Caputo
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.
2023-05-19modules/checkers: also set texture->frame_{width,height}Vito Caputo
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.
2023-05-11modules/checkers: settings-ize fill_moduleVito Caputo
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.
2023-05-11modules/*: stop storing setup by value in contextsVito Caputo
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.
2023-05-11til_module_context: reference setup from module contextVito Caputo
This just does the obvious pulling in of til_setup_t, holding the reference throughout the lifetime of the module context.
2023-05-11modules/*: remove use of static default setupsVito Caputo
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.
2023-05-11til_settings: introduce til_setting_spec_t concept vs. descVito Caputo
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.
2023-01-20til: pass module to .context_create()/til_module_context_new()Vito Caputo
Let's make it so til_module_context_t as returned from til_module_context_new() can immediately be freed via til_module_context_free(). Previously it was only after the context propagated out to til_module_context_create() that it could be freed that way, as that was where the module member was being assigned. With this change, and wiring up the module pointer into til_module_t.create_context() as well for convenient providing to til_module_context_new(), til_module_t.create_context() error paths can easily cleanup via `return til_module_context_free()` But this does require the til_module_t.destroy_context() be able to safely handle partially constructed contexts, since the mid-create failure freeing won't necessarily have all the members initialized. There will probably be some NULL derefs to fix up, but at least the contexts are zero-initialized @ new.
2023-01-11* turn til_fb_fragment_t.stream into a discrete parameterVito Caputo
This was mostly done out of convenience at the expense of turning the fragment struct into more of a junk drawer. But properly cleaning up owned stream pipes on context destroy makes the inappropriateness of being part of til_fb_fragment_t glaringly apparent. Now the stream is just a separate thing passed to context create, with a reference kept in the context for use throughout. Cleanup of the owned pipes on the stream supplied to context create is automagic when the context gets destroyed. Note that despite there being a stream in the module context, the stream to use is still supplied to all the rendering family functions (prepare/render/finish) and it's the passed-in stream which should be used by these functions. This is done to support the possibility of switching out the stream frame-to-frame, which may be interesting. Imagine doing things like a latent stream and a future stream and switching between them on the fly for instance. If there's a sequencing composite module, it could flip between multiple sets of tracks or jump around multiple streams with the visuals immediately flipping accordingly. This should fix the --print-pipes crashing issues caused by lack of cleanup when contexts were removed (like rtv does so often).
2023-01-10*: introduce paths for module contextsVito Caputo
There needs to be a way to address module context instances by name externally, in a manner complementary to settings and taps. This commit adds a string-based path to til_module_context_t, and modifies til_module_create_context() to accept a parent path which is then concatenated with the name of the module to produce the module instance's new path. The name separator used in the paths is '/' just like filesystem paths, but these paths have no relationship to filesystems or files. The root module context creation in rototiller's main simply passes "" as the parent path, resulting in a "/" root as one would expect. There are some obvious complications introduced here however: - checkers in particular creates a context per cpu, simply using the same seed and setup to try make the contexts identical at the same ticks value. With this commit I'm simply passing the incoming path as the parent for creating those contexts, but it's unclear to me if that will work OK. With an eye towards taps deriving their parent path from the context path, I guess these taps would all get the same parent and hash to the same value despite being duplicated. Maybe it Just Works, but one thing is clear - there won't be any way to address the per-cpu taps as-is. Maybe that's desirable though, there's probably not much use in trying to control the taps at the CPU granularity. - when the recursive settings stuff lands, it should bring along the ability to explicitly name settings blocks. Those names should override the module name in constructing the path. I've noted as such in the code. - these paths probably need to be hashed @ initialization time so there needs to be a hash function added to til, and a hash value accompanying the name in the module context. It'd be dumb to keep recomputing the hash when these paths get used for hash table lookups multiple times per frame... there's probably more I'm forgetting right now, but this seems like a good first step. fixup root path
2022-09-04til: fixup til_fb_fragment_t.texture fragmentingVito Caputo
Until now when fragmenting with a texture present the texture pointer was simply copied through to the new logical fragment. The problem with that is when sampling pixels from the texture in a nested frame scenario, the locations didn't align with the placement of the logical fragment. With this change when the incoming fragment has a texture, the output fragment gets some uninitialized memory attached in the outgoing fragment's texture pointer. Then the fragmenter is expected to do the same populating of res_fragment->texture it already did for res_fragment, just relative to fragment->texture->{buf,stride,pitch} etc. It's a bit hairy/janky because til_fb_fragment_t.texture is just a pointer to another til_fb_fragment_t. So the ephemeral/logical fragments fragmenting/tiling produces which tend to just be sitting on the stack need to get another til_fb_fragment_t instance somewhere and made available at the ephemeral til_fb_fragment_t's .texture member. We don't want to be allocating and freeing these things constantly, so for now I'm just ad-hoc stowing the pointer of an adjacent on-stack texture fragment in the .texture member when the incoming fragment has a texture. But this is gross because the rest of the fragment contents don't get initialized _at_all_, and currently if the incoming fragment has no texture the res_fragment->texture member isn't even initialized. The fragmenters aren't really supposed to be expecting anything sensible in *res_fragment, but now we're making use of res_fragment->texture *if* fragment->texture is set. This is just gross. So there's a bunch of asserts sprinkled around to help police this fragility for now, but if someone writes new fragmenters there's a good chance this will trip them up.
2022-08-07til: til_fb_fragment_t **fragment_ptr all the thingsVito Caputo
Preparatory commit for enabling cloneable/swappable fragments There's an outstanding issue with the til_fb_page_t submission, see comments. Doesn't matter for now since cloning doesn't happen yet, but will need to be addressed before they do.
2022-07-24modules/checkers: center unaligned checkers scenariosVito Caputo
This introduces a bespoke fragmenter for checkers. The generic til_fb tiler isn't concerned with aesthetics so it doesn't particularly care if clipped tiles are asymmetrically distributed. It worked fine to get checkers developed and working, but it's really unattractive to have the whole be off-centered when the checkers don't perfectly align with the frame size. There's some gross aspects like leaving the frame_{width,height} to be corrected at render time so render_fragment can access the incoming frame_width for cell state determination.
2022-07-20modules/checkers: one more rand/rand_r conversionVito Caputo
wired up to til_module_context.seed
2022-07-18til: wire seed up to til randomizersVito Caputo
til_setting_desc_t.random() and til_module_randomize_setup() now take seeds. Note they are not taking a pointer to a shared seed, but instead receive the seed by value. If a caller wishes the seed to evolve on every invocation into these functions, it should simply insert a rand_r(&seed) in producing the supplied seed value. Within a given randomizer, the seed evolves when appropriate. But isolating the effects by default seems appropriate, so callers can easily have determinism within their respective scope regardless of how much nested random use occurs.
2022-06-10modules/checkers: experimenting with fill modesVito Caputo
this introduces a color= setting syntax: color=#rrggbb color=0xrrggbb color=rrggbb where rrggbb is case-insensitive html-style hexadecimal also introduces a fill= setting: fill=color fill=sampled fill=textured fill=random fill=mixed sampled draws the color from the incoming fragment when layered, textured draws the pixels from the texture when available, random randomizes the choice from color,sampled,textured. mixed isn't implemented fully and is just aliased to random currently. The thinking for mixed is to allow specifying proportions for color,sampled,textured which would then be applied as weights when randomizing the selection from the three at every filled checker. the current implementation is just calling rand() when randomized, but should really be like the other dynamics in checkers with rate control and hash-based. and introduces a fill_module= setting: this is a first stab at employing other modules for filling the filled cells. Note since checkers is already a threaded module, the fill module context gets created per-cpu but with an n_cpus=1. This is kind of the first time module contexts are being rendered manifold for the same frame, and that's illuminating some shortcomings which needed to be dealt with. Some modules automatically advance a phase/T value on every render which gets persisted in their context struct. With how checkers is using contexts, it's desirable for multiple renders of the same context using the same ticks to produce the same output. So modules need to be more careful about time and determine "dt" (delta-time) values, and animate proportional to ticks elapsed. When ticks doesn't change between renders, dt is zero, and nothing should change. For now this is using a hard-coded list of modules to choose from, you specify the module by name or "none" for no fill_module (solid checker fill). ex: "fill_module=shapes" There's a need for something like fragment color and flag overrides to allow til_module_render() to be treated as more of a brush where the caller gets to specify what colors to use, or if texturing should be allowed. For now, when fill_module=$module is employed, the color determination stuff within checkers doesn't get applied. That will need to be fixed in the future.
2022-06-10til: introduce til_frame_plan_t and .cpu_affinityVito Caputo
modules/checkers w/fill_module=$module requires a consistent mapping of cpu to fragnum since it creates a per-cpu til_module_context_t for the fill_module. The existing implementation for threaded rendering maximizes performance by letting *any* scheduled to run thread advance fragnum atomically and render the acquired fragnum indiscriminately. A side effect of this is any given frame, even rendered by the same module, will have a random mapping of cpus/threads to fragnums. With this change, the simple til_module_t.prepare_frame() API of returning a bare fragmenter function is changed to instead return a "frame plan" in til_frame_plan_t. Right now til_frame_plan_t just contains the same fragmenter as before, but also has a .cpu_affinity member for setting if the frame requires a stable relationship of cpu/thread to fragnum. Setting .cpu_affinity should be avoided if unnecessary, and that is the default if you don't mention .cpu_affinity at all when initializing the plan in the ergonomic manner w/designated initializers. This is because the way .cpu_affinity is implemented will leave threads spinning while they poll for *their* next fragnum using atomic intrinsics. There's probably some room for improvement here, but this is good enough for now to get things working and correct.
2022-06-10til: add ticks to til_module_context_tVito Caputo
Also wire this up to the til_module_context_new() helper and all its callers. This is in preparation for modules doing more correct delta-T derived animation.
2022-05-29*: pivot to til_module_context_tVito Caputo
- modules now allocate their contexts using til_module_context_new() instead of [cm]alloc(). - modules simply embed til_module_context_t at the start of their respective private context structs, if they do anything with contexts - modules that do nothing with contexts (lack a create_context() method), will now *always* get a til_module_context_t supplied to their other methods regardless of their create_context() presence. So even if you don't have a create_context(), your prepare_frame() and/or render_fragment() methods can still access seed and n_cpus from within the til_module_context_t passed in as context, *always*. - modules that *do* have a create_context() method, implying they have their own private context type, will have to cast the til_module_context_t supplied to the other methods to their private context type. By embedding the til_module_context_t at the *start* of their private context struct, a simple cast is all that's needed. If it's placed somewhere else, more annoying container_of() style macros are needed - this is strongly discouraged, just put it at the start of struct. - til_module_create_context() now takes n_cpus, which may be set to 0 for automatically assigning the number of threads in its place. Any non-zero value is treated as an explicit n_cpus, primarily intended for setting it to 1 for single-threaded contexts necessary when embedded within an already-threaded composite module. - modules like montage which open-coded a single-threaded render are now using the same til_module_render_fragment() as everything else, since til_module_create_context() is accepting n_cpus. - til_module_create_context() now produces a real type, not void *, that is til_module_context_t *. All the other module context functions now operate on this type, and since til_module_context_t.module tracks the module this context relates to, those functions no longer require both the module and context be passed in. This is especially helpful for compositing modules which do a lot of module context creation and destruction; the module handle is now only needed to create the contexts. Everything else operating on that context only needs the single context pointer, not module+context pairs, which was unnecessarily annoying. - if your module's context can be destroyed with a simple free(), without any deeper knowledge or freeing of nested pointers, you can now simply omit destroy_context() altogether. When destroy_context() is missing, til_module_context_free() will automatically use libc's free() on the pointer returned from your create_context() (or on the pointer that was automatically created if you omitted create_context() too, for the bare til_module_context_t that got created on your behalf anyways). For the most part, these changes don't affect module creation. In some ways this eases module creation by making it more convenient access seed and n_cpus if you had no further requirement for a context struct. In other ways it's slightly annoying to have to do type-casts when you're working with your own context type, since before it was all void* and didn't require casts when assigning to your typed context variables. The elimination for requiring a destroy_context() method in simple free() of private context scenarios removes some boilerplate in simple cases. I think it's a wash for module writers, or maybe a slight win for the simple cases.
2022-05-25*: normalize on all case-insensitive comparisonsVito Caputo
I don't think rototiller is an appropriate place for being so uncooperative, if someone gets the case wrong anywhere just make it work. We should avoid making different things so subtly different that case alone is the distinction anyways, so I don't see this creating any future namespace collision problems.
2022-05-21til: supply a seed to til_module_t.create_context()Vito Caputo
In the recent surge of ADD-style rtv+compose focused development, a bunch of modules were changed to randomize initial states at context_create() so they wouldn't be so repetitive. But the way this was done in a way that made it impossible to suppress the randomized initial state, which sometimes may be desirable in compositions. Imagine for instance something like the checkers module, rendering one module in the odd cells, and another module into the even cells. Imagine if these modules are actually the same, but if checkers used one seed for all the odd cells and another seed for all the even cells. If the modules used actually utilized the seed provided, checkers would be able to differentiate the odd from even by seeding them differently even when the modules are the same. This commit is a step in that direction, but rototiller and all the composite modules (rtv,compose,montage) are simply passing rand() as the seeds. Also none of the modules have yet been modified to actually make use of these seeds. Subsequent commits will update modules to seed their pseudo-randomized initial state from the seed value rather than always calling things like rand() themselves.
2022-05-01til_fb: add draw flags for controlling texturabilityVito Caputo
Just adds TIL_FB_DRAW_FLAG_TEXTURABLE so callers can granularly inhibit texturing if desired.
2022-05-01modules/*: make use of generic fragmentersVito Caputo
Just one case, modules/submit, was using 32x32 tiles and is now using 64x64. I don't expect it to make any difference. While here I fixed up the num_cpus/n_cpus naming inconsistencies, normalizing on n_cpus.
2022-05-01til: wire n_cpus up to the fragmenter functionVito Caputo
Fragmenting is often dimensioned according to the number of cpus, and by not supplying this to the fragmenter it was made rather common for module contexts to plumb this themselves - in some cases incorporating a context type/create/destroy rigamarole for the n_cpus circuit alone. So just plumb it in libtil, and the prepare_frame functions can choose to ignore it if they have something more desirable onhand. Future commits will remove a bunch of n_cpus from module contexts in favor of this.
2022-04-25modules/*: set TIL_MODULE_OVERLAYABLE where appropriateVito Caputo
In the interests of facilitating randomized automagic layered compositing, tell the world when you're overlay-appropriate.
2022-04-24*: s/void */til_setup_t */Vito Caputo
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.
© All Rights Reserved