summaryrefslogtreecommitdiff
path: root/src/modules/blinds/blinds.c
AgeCommit message (Collapse)Author
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-22modules/blinds: add taps for T,step,countVito Caputo
Part of me wants to give the blinds arbitrary angle instead of the vert/horiz options. But part of the beauty of blinds is the jaggy-free aliasing-free sharp edges by virtue of always being orthonormal using whole pixels. Maybe in the future there could be a orientation setting where you pick horiz/vert/angular. Then only when angular does it get a theta tap and use angled blinds with anti-aliased imperfect edges...
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-05modules/blinds: use til_ticks_to_rads(ticks)Vito Caputo
This gets rid of the static accumulator hack used for the blinds phase.
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-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-06-10modules/blinds: use til_fb_put_pixel_checked()Vito Caputo
While testing an experimental checkers w/fill_module=blinds with ASAN it became clear this module is making flawed assumptions about fragment->frame_{width,height} and fragment->{width,height} being equal. When used by checkers for filling cells, there are situations where the edge cell fragments need to describe a frame slightly larger than the drawn area, because the cell size doesn't align perfectly to the overall window/screen dimensions. So in these cases the synthesized frame will still be a full cell's dimensions while the width,height serve to clip within that area. If modules aren't properly clipping their rendering, instead just using frame_{width,height}, then they will have to use the _checked() variants to ensure clipping occurs properly on a per-pixel (slower) basis.
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-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-01til_fb: introduce a fragment texture sourceVito Caputo
Idea here is to provide texture sources for obtaining pixel colors at the til_fb_put_pixel/fill drawing API, making it possible for at least overlayable modules to serve as mask/stencil operators where their drawn areas are populated by the contents of another fragment produced dynamically, potentially by other modules altogether. This commit adds a texture=modulename option to the compose module for specifying if a texture should be used when compositing, excepting and defaulting to "none" for disabling texturing. A future commit should expand this compose option to accept a potential list of modules for composing the texture in the same way as the main layers= list functions. Something this all immediately makes clear is the need for a better settings syntax, probably in the form of all module setting specifiers optionally being followed by a squence of settings, with support for escaping to handle nested situations.
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-04-27til_fb: til_fb_fragment_t.{pitch,stride} uint32_t unitsVito Caputo
Originally it seemed sensible to make these units of bytes, for flexibility reasons. But it's advantageous for everything to be able to assume pixels are always 4-byte/32-bit aligned. Having the stride/pitch be in bytes of units made it theoretically possible to produce unaligned rows of pixels, which would break that assumption. I don't think anything was ever actually producing such things, and I've added some asserts to the {sdl,drm}_fb.c page acquisition code to go fatal on such pages. This change required going through all the modules and get rid of their uint32_t vs. void* dances and other such 1-byte vs. 4-byte scaling arithmetic. Code is simpler now, and probably faster in some cases. And now allows future work to just assume things cna always occur 4-bytes at a time without concern for unaligned accesses.
2022-04-25modules/blinds: add count and orientation settingsVito Caputo
This adds count=N and orientation={horizontal,vertical} settings. Which was precipitated by the introduction of a vertical blinds mode. e.g.: --module=blinds,count=32,orientation=vertical or for a quick tour of the possibilities: --module=rtv,channels=blinds,duration=1,context_duration=1,snow_duration=0 weeeee
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-19modules/blinds: add simple 80s-aesthetic window blindsVito Caputo
This isn't super interesting but I might just start adding simplistic overlay style modules for compositing/transition use.
© All Rights Reserved