Age | Commit message (Collapse) | Author |
|
This introduces a concept of a stream's module context, which is
used to render the stream via til_stream_render().
The context is set using til_stream_set_module_context(), but at
this time no reference is taken - it just puts the context into
the stream for use by the render calls. The caller is
responsible for ensuring it persist as long as the stream uses
it.
This is a preparatory commit for implementing pre/post render
module contexts that get hooked into a stream. The impetus for
this is supporting background music via modules like playit,
without requiring stuff like rkt scenes to always include the bgm
context in the scene's module context heirarchy.
Nothing is functionally different here, the commit only adds the
new interfaces for setting the context and rendering via stream
instead of til_module_render() of the context you'd now set on
the stream.
|
|
I noticed the sdl_fb backend seemed to often have significantly
better FPS in fullscreen use vs. drm_fb fullscreen. Looking at
the libdrm api I saw this PREFER_SHADOW capability and noticed my
laptop's gpu driver sets it... With this change, despite the
additional memcpy(), the drm fullscreen FPS seems significantly
better.
A subsequent commit will make this an overridable runtime setting
|
|
There's already a pause triggered here, but the audio wasn't
getting paused as well.
|
|
Replace vestigial casted setup dereferences with already present
local typed setup variable.
|
|
Until now everything interested in audio just used a plain getter
on the stream to get at the context.
But with how things work currently, audio is always left in a
paused state until explicitly unpaused. This works fine with
modules/rkt, which manages pause/unpause explicitly. When
there's nothing like modules/rkt in charge though, the audio just
sits stuck paused. Meaning if you do some simple thing like
--module=playit, it won't ever get unpaused.
With this commit, something like modules/rkt takes control of the
stream's audio context, in a way that prevents anything else from
taking control of the same context on the same stream. That
enables having main try take control of the audio context after
creating the module contexts, then in the rendering thread ensure
the audio is unpaused if main is in control of the audio context
and something's queueing audio frames.
For now there's no mechanism for releasing control of the audio
context. It doesn't seem appropriate to make this more elaborate
than necessary. There's basically just two use cases WRT audio:
1. Something like rkt, which takes control once for the process
and stays in control until process exit.
2. Something far simpler where nothing's taking control like
rkt, and main just needs to get things unpaused when
needed because something's generating audio frames.
|
|
- til_audio_seek() when Rocket sets the row
- til_audio_{pause,unpause}() when Rocket (un)pauses
This is of limited use as-is, rkt probably needs a sister concept
of scenes for songs, which similarly to scenes would be selected
by index in a discrete Rocket track.
As-is to make music work one must always incorporate something
like a modules/playit context into the current scene so it always
gets rendered alongside the visuals. That's quite cumbersome and
annoying.
Another possibility would be introducing something like a
"register" built-in that, like "ref", takes a context path, and
maybe something like a pre/post setting. That would put it in
the rendering path of the stream before or after any explicit
renders... Then all one would need is to register a
modules/playit context with the song of interest to have it play,
and create that as any other rkt "scene", and reference its
context from "register" which could bind a tap for controlling
the registered/unregistered state. It needs more fleshing out,
but what's here seems worth merging as-is for now.
|
|
Rudimentary .IT file music playback via libplayit.
When seekable=on, the file is 100% pre-rendered at context
create, then simply copied into the audio queue @ render_audio.
When seekable=off, the file is mixed incrementally per-frame @
render_audio in max of bufsize=N_frames increments. The bufsize
here basically just determines the maximum time spent rendering
audio in a single go, and how much tolerance of frame delays due
to slow rendering there will be before dropouts occur.
|
|
More preparatory work for adding an .IT file playback module
|
|
Preparatory commit for implementing an .IT file playback module
|
|
Simple audio rendering modules need a way to render their audio
without affecting the fragment's state. By providing a
til_module_t.render_audio() a module indicates it's only an audio
renderer, and its render won't trigger an implicit clear of the
frame's fragment.
There might be a new flag added to indicate when modules are
audio modules, but this is good enough for now.
|
|
Preliminary means of making the audio context available to
modules.
|
|
This is an early implementation of something resembling an audio
backend for rototiller/libtil.
The assumption for now is that everything will use signed 16-bit
native-endian stereo output @ 44.1khz.
|
|
Defaults to on, controls inclusion of SDL_RENDERER_PRESENTVSYNC
in the flags passed to SDL_CreateRenderer().
Useful for obesrving how high FPS can be with the overhead of the
GPU upload, unlike --video=mem which tells you how fast FPS can
be entirely headless.
|
|
Preparatory commit for a vsync setting sharing these values.
|
|
Preparatory commit for introducing c->renderer_flags to allow
vsync configure at runtime.
|
|
Some trivial error handling improvements for compose...
til_module_t.create_context() should really return -errno
instead, since some modules try do stuff like opening files or
network connections @ create_context().
|
|
Trivial cleanup. These are unnecessary nowadays since
til_setup_free() won't invoke the free_func() on a NULL setup,
and everything uses til_setup_free() to free a til_setup_t.
|
|
Becomes til_rgb_to_uint32(). Nothing functionally changed, just
making this generally available for anything wanting to parse an
rgb hex string into a uint32 packed pixel in a setup_func.
|
|
Preparatory commit for implementing nonblocking connects in
modules/rkt, shouldn't change anything by itself.
|
|
Been ignoring this mess for too long, just whitespace changes -
nothing functionally different.
This makes diffs far easier to read when libs or modules get
added/removed etc.
Some of the other Makefile.am files could use similar tidying,
but these are the most commonly messed with in the course of
rototiller development.
|
|
Intended as a bootstrap for new module creation, particularly
aimed at new contributors. No module context, fragmenting, taps,
or settings are implemented, to keep things as simple as
possible.
|
|
The lack of support for fractional multipliers prevents pixbounce
from drawing anything in small frame scenarios, like as a
checkers fill_module.
You can easily reproduce this by doing:
--module=pixbounce,pixmap_size=0.8,pixmap=err --video=sdl,size=64x64 --defaults --go
Which after this commit works...
While here I did a minor optimization removing some divides, and
fixed up the assumption that fragment->{width,height} ==
fragment->frame_{width,height} in pixbounce_prepare_frame().
It should have been using .frame_{width,height}.
|
|
This is vestigial from pre-everything's-til_setting_t days, where
the local setting values were just the bare char* value,
requiring getting at the related til_setting_t via *res_setting.
Now that's unnecessary since the local texture variable is now a
til_setting_t*, so clean this bit up.
|
|
In the pre-threaded blinds days these were tiny functions, not
anymore.
Plus it's not like there's very many blinds ever anyways so the
number of calls isn't huge, making the syntactic sugar aspect of
"inline suggests hot" a bit misleading here.
|
|
Minor oversight when this was written, this fragmenter is private
to checkers.
|
|
This deviates from the established pattern of all built-in
modules being in til_builtins.c, but that's ok.
The main impetus for this is to just get asc out of rotation for
randomized compose layers, since it's so uninteresting. But it's
also valid as a built-in since it's primarily for diagnostic
purposes anyways.
|
|
justify= now supports "aligned" and "offsetted", justify=aligned
being the existing behavior where you would specify
halign={left,right,center} and valign={top,bottom,center}.
When justify=offsetted is specified however, {valign=,halign=}
are unused and instead {hoffset=,voffset=} are expected, as
either hoffset=auto/voffset=auto for automagic offsetting
according to the x/y coords, or explicit offsetting using -1..+1
normalized fractional values serving as coordinates within the
rendered text's rectangle where to anchor the x/y coordinate.
By using halign=auto,valign=auto one can carelessly vary the x/y
coordinates using the taps (i.e. via rkt) without having to deal
with justification concerns (modulo large texts that can't
possibly fit), as the offsets will automatically adapt according
to the coordinates.
|
|
Instead of rigid txt_align_t enums to specify how the text is
aligned relative to the x/y coordinates, you specify float
offsets in normalized coordinates -1..+1 allowing fine-grained
control of the offsets.
modules/asc will use this to automatically adjust the offsets
when requested, so x/y coordinates may be varied dynamically
using taps with the text automagically adjusting its offset to
try stay in-fragment.
|
|
Mechanical rename to txt_render_fragment_aligned(), updating all
existing call sites accordingly.
This is a preparatory commit for introducing an offsetted variant
of txt_render_fragment() (txt_render_fragment_offsetted()).
No functional difference, purely naming changes.
|
|
Nothing terribly exciting, the string can now be moved
dynamically via taps in the usual manner. When nobody's driving
the taps they just use the setting, still defaulting to 0,0
(centered).
|
|
Just removing a spurious newline noticed while grabbing some
taps boilerplate for asc...
|
|
This just binds the simple libs/txt/txt.c stuff to a rendering
module, exposing the minimal options as settings.
It's handy for testing libs/txt/txt.c, and introduces a module
requiring free-form strings potentially including newlines be
handled properly as settings values. This latter aspect is
important for improving settings syntax, any improvements must
handle these more complicated scenarios and now there's a good
test case for exercising those nuances.
I suppose there might also be use in the creative process if you
want a text element but haven't got around to hacking up a
prettier module for it yet. Just use this one temporarily.
See commit for some remaining TODO items.
|
|
Silly oversight preventing some haligns from working right if the
string doesn't have a newline... uncovered while testing a new
txt module's alignment settings.
|
|
Mechanical transition from checkers_value_to_pos() to the now
libtil-provided equivalent of identical implementation.
|
|
This copies from checkers_value_to_pos() turning it into a libtil
helper. It's a common operation in setup_funcs to map a setting
value to a numeric position in the list of values.
|
|
When using the blank builtin for profiling purposes it can be
necessary to ensure it actually incurs the cost of clearing.
|
|
Writing this down so it doesn't completely fall off my radar.
|
|
s->count isn't always perfectly divisable by n_cpus, which is why
ctxt->n_elements is computed from n_cpus * elements_per_cpu in
the transition to threaded rendering for flow.
That's all fine and dandy, but the ctxt->elements initialization
loop was still using the vestigial s->count from the pre-threaded
implementation. So on core counts where ctxt->n_elements was
smaller than s->count, initialization scribbled.
Thanks Sketch for assistance in chasing this down w/ASAN enabled
on a box that exhibited crashing w/rtv,channels=flow.
|
|
57bae7 removed the default from the settings list when bumping the counts,
oops!
|
|
The convention has been to label threaded modules in their
description.
|
|
Now that there's threaded rendering, handling larger counts
without bogging down the frame rate on anything remotely modern
is feasible.
|
|
While optimizing the threaded rendering in commit 6d6c141, the
pos.{xy} expanding from 0-1 to -1..+1 were eliminated from the
inner loops in favor of just having the positions always in
-1..+1 coordinates. But I missed that it was only the x/y
coordinates which were being expanded, with .z being left in the
0-1 space, which had a desirable aesthetic effect of condensing
the Z space, flattening everything.
This commit undoes that, without reintroducing the expansion to
the inner loops. It's a bit crufty because now .z is treated
exceptionally throughout as 0..1 while {.x,.y} are in -1..+1, but
it's fine for now.
|
|
This exploits the just added multipass rendering support.
In the first pass, the flow-field is sampled and applied to the
elements, with every thread operating on its own subset of the
elements list. Since the flow-field sampling is all read-only,
it's perfectly safe too do in parallel. Nothing is drawn in the
first pass, it's only the elements updating according to the
flow-field which is performed.
In the second pass, the elements are rendered in parallel using
the slice_per_cpu fragmenter. Since the elements are kept on a
simple array, with no spatial indexing, every thread must visit
every element.
Since the fragmenter used divides the frame into horizontal
slices, every thread needing to reject elements not overlapping
its region can take some shortcuts in easily identifying elements
entirely outside its region. But the whole 3d->2d projection
step must still be performed for every element's current position
and +n_iters final position for the frame, which does have a
divide unfortunately.
Nonetheless, this change improves frame rates substantially on my
2c/4t i7 X230 as benchmarked w/--video=mem,1366x768:
--seed=0x64fa9508 '--module=rtv,channels=flow,duration=3,context_duration=3,caption_duration=0,log_channels=on,snow_duration=0,snow_module=none' '--video=mem,size=1366x768'
rtv channel settings: 'flow,size=4,count=40000,speed=.8'
FPS: 261
FPS: 265
rtv channel settings: 'flow,size=4,count=1000,speed=.9'
FPS: 1153
FPS: 3204
FPS: 2934
rtv channel settings: 'flow,size=8,count=5000,speed=.9'
FPS: 2923
FPS: 1634
FPS: 1592
rtv channel settings: 'flow,size=2,count=50000,speed=.4'
FPS: 1006
FPS: 219
FPS: 268
rtv channel settings: 'flow,size=16,count=30000,speed=.8'
FPS: 304
FPS: 350
FPS: 343
rtv channel settings: 'flow,size=16,count=30000,speed=.02'
FPS: 379
FPS: 503
FPS: 472
rtv channel settings: 'flow,size=8,count=1000,speed=.16'
FPS: 1393
FPS: 3822
FPS: 3876
---
Prior to this commit:
--seed=0x64fa9508 '--module=rtv,channels=flow,duration=3,context_duration=3,caption_duration=0,log_channels=on,snow_duration=0,snow_module=none' '--video=mem,size=1366x768'
rtv channel settings: 'flow,size=4,count=40000,speed=.8'
FPS: 53
FPS: 53
rtv channel settings: 'flow,size=4,count=1000,speed=.9'
FPS: 426
FPS: 1366
FPS: 1335
rtv channel settings: 'flow,size=8,count=5000,speed=.9'
FPS: 1097
FPS: 368
FPS: 367
rtv channel settings: 'flow,size=2,count=50000,speed=.4'
FPS: 279
FPS: 73
FPS: 74
rtv channel settings: 'flow,size=16,count=30000,speed=.8'
FPS: 71
FPS: 71
FPS: 70
rtv channel settings: 'flow,size=16,count=30000,speed=.02'
FPS: 136
FPS: 305
FPS: 305
rtv channel settings: 'flow,size=8,count=1000,speed=.16'
FPS: 972
FPS: 2593
FPS: 2634
|
|
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.
|
|
This is intended to perhaps be of use for threaded rendering that
don't actually produce pixels during their render phase, but
still need n_cpus fragments to dispatch the parallel work keying
off the fragment.number.
Such a renderer might then put its pixels on-screen serially @
finish_frame(), or maybe the rendering functions will get a
return value to trigger multi-pass rendering on the same tick.
|
|
Nothing too crazy here, the speed= setting still controls the
speed in lieu of something driving the tap.
|
|
Remove strobe_update_taps() redundant assignment if already zero
|
|
The ad-hoc sys-based probe of cpus works fine on Linux, but it's
not really preferable when Linux's sysconf supports
_SC_NPROCESSORS_ONLN, and there's a chance non-Linux's will
support it too.
Supposedly even Emscripten supports this, and will report the
number of available WebWorkers through this interface, even with
pthreads emulation. I'm curious if that actually works, getting
wasm builds of rototiller demos could be fun.
|
|
This is too aggressive and produces some undesirable visible
artifacts on the periphery, especially for slow-moving
small-size fields.
In such scenarios the elements near the edges would be
excessively pruned when the direction wandered off-screen, then
leaving an overly sparse region when the direction inevitably
wandered back.
This is still an issue but it's far less prominent when only
clipping to the flow field boundaries... since the FOV doesn't
quite encompass the edges of the flow field. Now the elements
can survive wandering a bit off-screen, and re-enter.
|
|
Phil tripped over this when his TV powered off in the midst of
playing with rototiller over hdmi output.
The NULL mode/connector was being supplied as the
til_setting_spec_t.preferred value throwing an assert in
til_setting_desc_new().
Just detect this exception and return an error.
|