Matth23u wrote:Is there some really best way to simplify all things "Redraw"?
Matth23u wrote:How would i best make-so redrawing entire interface would be fast and smooth, even when all knobs are automated?
Which would you prefer, "simplify" or "fast and smooth"?
Keeping the amount of redrawing to a minimum does usually take extra work on the schematic - though it's not too hard to build up a little toolbox of sub-components to make it easier.
The general principles are simple enough to explain...
Minimise AreasAlways draw the smallest area that you can get away with. If only part of a control has changed, use area redraws to redraw only that part. If there are two or more smaller parts to draw, the smallest area that will encompass them all can be calculated mathematically, or the
Area Union primitive can help.
Minimise LayeringOnce you're happy with your GUI layout, incorporate static items such as labels into background bitmaps so that the graphics rendering has fewer layers to composite together. Most image editing software will let you work with grid snapping, so getting everything aligned isn't as difficult as you might think. It's also possible to draw to a bitmap within FlowStone - so a control which doesn't change often but contains a lot of drawing components can be 'flattened' into a single layer that doesn't get re-calculated for every single frame as it would otherwise.
Minimise ComplexityBitmap controls are usually more efficient than those drawn by the vector graphics primitives or Ruby commands. If you can avoid re-scaling or rotating them, bitmap pixel data can just be blasted straight into the graphics memory, whereas the vector stuff involves a lot of complex mathematics. Likewise bitmaps of text labels will draw more efficiently than real-time rendered text.
Minimise ReDrawsJust because a parameter value has changed, it doesn't mean that the GUI always needs updating. For example, with bitmap-strip knobs, you only need to redraw when a new animation frame is chosen, not every time the control's float value changes. The
changed primitive is your friend; it will also block redraws when the control is pushed up against its limits.
Restricting the rate of redraw triggers to a maximum number of frames per second can be done quite easily either in primitives or in Ruby; and it can be done per-control, so that you can keep high frame rates where you really need them.
Minimise Ruby JunkWhen using Ruby for drawing, try to avoid constructing new Colors, Brushes, Fonts, etc. within the
draw method. It wastes CPU power on re-creating a whole bunch of identical objects for every single frame, and creates lots of temporary Ruby objects for the Ruby garbage collector to deal with. Create as many of these as you can in the
init method and access them via @instance @variables.
Here's a schematic containing the GUI modules from my Trogz Toolz collection. The modules are mostly sub-components rather than whole controls, but you'll find some of the bitmap rendering and draw rate limiting stuff I've mentioned in there (particularly in the "bitmap strip" modules.)
Ultimately, having nearly every control animated at once will always incur quite a high CPU load in FlowStone, just because of the graphics rendering engine that it uses (i.e. it doesn't use graphics hardware acceleration.) But it can definitely be done better than the standard toolbox controls do it.