summaryrefslogtreecommitdiff
path: root/src/til_fb.h
AgeCommit message (Collapse)Author
2023-08-29til_fb: return queue delay from til_fb_page_get()Vito Caputo
til_fb is triple buffered, but when rendering lags behind the queue is empty making present-to-delay intervals smaller than when rendering is keeping up and the queue is kept full. This returns the duration of the returned pages last submit-to-present delay, effectively measuring how long a page can expect to wait to be flipped to/presented currently. A subsequent commit will apply this delay value to the ticks supplied to rendering.
2023-08-13til_fb: introduce til_fb_halt()Vito Caputo
This makes it so til_fb_page_get() will return NULL when the fb has been "halted". If til_fb_page_get() is already waiting for a page to become available, it will be woken up by til_fb_halt(). Preparatory commit for eliminating the reliance on pthread_cancel() to terminate rototiller_thread() on shutdown. Cancellation is always a PITA, especially cross-platform, but in general it's so easy to have subtle bugs when using it.
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-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-05-19til_fb: clip get_pixel_clipped() to fragmentVito Caputo
til_fb_fragment_get_pixel_clipped() was clipping to the frame bounds, which are actually just a logical dimension for placing and scaling fragments within a frame. drizzle in particular is leaning on this clipped-get to prevent accessing outside of the fragment's backing buffer. Let's just clip it to the fragment bounds instead, see comment added for more information.
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-07til_fb: introduce til_fb_fragment_t.streamVito Caputo
This adds an optional stream member and type for introducing some persistent potentially cross-fragment state bound to the logical frame being rendered to by the fragment. It's a preparatory commit for adding things like arbitrary stream-bound state modules can create/read/modify for passing non-pixel information between modules bound to the fragment's frame that may vary frame to frame, but may also only be updated occasionally within a stream while still being accessible by every frame for the lifetime of the stream. This may evolve to encompass the fragment's texture member, turning the texture into just another arbitrary thingy tied to the stream which modules/rendering primitives may lookup and make use of if present. This commit only adds the type and member though, no implementation yet.
2022-08-07modules/drizzle: add a mapped overlay styleVito Caputo
this introduces a style= setting with values: style=mask simple alpha mask overlay style=map displacement mapped overlay I might add a lighting option for the style=map mode with a moving light source or something like that, but it's already pretty slow as-is. This is mostly just for more testing of the snapshotting, but there's some interesting compositions enabled like: module=compose,layers=submit:moire:drizzle or just moire:drizzle, when style=map happens.
2022-08-07til: experimentally fragment-centric page apiVito Caputo
It seems like it might be most ergonomic and convenient for everything to just use til_fb_fragment_t and rely on ops.submit to determine if the fragment is a page or not, and if it is how to submit it. This commit brings things into that state of the world, it feels kind of gross at the til_fb_page_*() API. See the large comment in til_fb.c added by this commit for more information. I'm probably going to just run with this for now, it can always get cleaned up later. What's important is to get the general snapshotting concept and functionality in place so modules can make use of it. There will always be things to cleanup in this messy tangle of a program.
2022-08-07til_fb: introduce til_fb_fragment_t.opsVito Caputo
There's a need for the ability to efficiently snapshot fragments via buffer swapping when possible, for modules that want to do overlay effects which sample the input fragment at arbitrary pixels other than the one being written to, while producing output pixels. Without first making a stable snapshot of the input fragment's contents, you can't implement such algorithms because you destroy the input fragment while writing the output pixels. A simple solution would be to just allocate memory and copy the input fragment's contents into the allocation, then sample the copy while writing to the input (now output) fragment's memory. But when the input fragment represents the entire framebuffer page/window, it's technically practical to instead simply swap out the input fragment for a fresh fragment acquired from the framebuffer/window provider. Then just sample from the original fragment while writing to the freshly acquired one now taking the original's place. Simple enough. Except til_fb_fragment_t is also used to describe subfragments within a larger buffer, and these can't be made discontiguous and swapped out. For these fragments there's no escaping the need for a copy to be made of the contents. So there needs to be a way for the fragment itself to furnish an appropriate snapshotting mechanism, and when what the cloning mechanism returns can vary. Depending on the snapshotting mechanism's implementation, there's also a need for the fragment to furnish an appropriate free method. If the snapshot is an entire page from the native video backend, the backend must free it. If it's just libc heap-allocated memory, then a plain old free() suffices. If for some reason the memory can't be freed, then a NULL free() method would be appropriate to simply do nothing. So this commit introduces such free() and snapshot() methods in the form of a til_fb_fragment_ops_t struct. There's no implementations or use of these as of yet, this is purely preparatory. In addition to free() and snapshot(), a submit() method has also been introduced for submitting ready frames to be displayed. Not all fragments may be submitted, only "root" fragments which represent an entire page from the video backend. It's these fragments which will have a non-NULL submit() method, which the video backend will have initialized appropriately in returning the page's root fragment. This is a preparatory change in anticipation of removing the til_fb_page_t type altogether, replacing it with a simple til_fb_fragment_t having the ops.submit() method set.
2022-07-15til_fb: switch til_fb_ops_t.init() to use til_setup_tVito Caputo
Until now the fb init has been receiving a til_settings_t to access its setup. Now that there's a til_setup_t for representing the fully baked setup, let's bring the fb stuff up to speed so their init() behaves more like til_module_t.create_context() WRT settings/setup. This involves some reworking of how settings are handled in {drm,sdl}_fb.c but nothing majorly different. The only real funcitonal change that happened in the course of this work is I made it possible now to actually instruct SDL to do a more legacy SDL_WINDOW_FULLSCREEN vs. SDL_WINDOW_FULLSCREEN_DESKTOP where SDL will attempt to switch the video mode. This is triggered by specifying both a size=WxH and fullscreen=on for video=sdl. Be careful though, I've observed some broken display states when specifying goofy sizes, which look like Xorg bugs.
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-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-27til_fb: fix til_fb_fragment_fill() memset() misuseVito Caputo
This braino wasn't actually showing itself in any output since it was always being used to fill either 0xffffffff or 0x00000000. But if an actual pixel having distinct RGB values were supplied, it wouldn't have worked right as just the low char was being written to the destination buffer's bytes. Additionally I think the til_fb_fragment_t.{pitch,stride} members should probably change to the number of pixels (uint32_t) vs. bytes. The thinking initially was to facilitate describing fragments having rows split up with arbitrary numbers of bytes. Having a constraint of requiring the pixels always be 32-bit aligned ensures dword-at-a-time optimized copies can always succeed without something like SIGBUS occurring. When such a constraint is respected, the pitch/stride will always be 32-bit aligned so they should just describe numbers of pixels. Except, one can imagine scenarios where writing bytes at a time instead of uint32_t's at a time can produce interesting color-staggerring effects, and introducing a deliberate offset in the pitch/stride making it unaligned can be interesting. I'm leaving it all alone for now, but there's already assumptions being made about doing uint32_t-grained operations on the fragment's buf. Even the til_fb_fragment_t.buf's type is a uint32_t* already, and it forces us to use a void* or char* version of the pointer to apply pitch/stride as in this commit.
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.
2022-04-19*: s/til_fb_fragment_zero/til_fb_fragment_clear/Vito Caputo
Mechanical renaming of "zero" to "clear" throughout for this context.
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-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-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-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.
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_.
© All Rights Reserved