Forum: wxRuby paint_buffered

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C9622ef018be71cb8d03ed361c4f660c?d=identicon&s=25 Anton Hornquist (antonhornquist)
on 2008-11-03 17:35
Hello,

In order to reduce flicker in my paint-intense app I've switched from
paint |dc| to paint_buffered |dc|. Unfortunately, there is no difference
after switching. Does anyone know why? Are there any other workarounds
for this?

I'm on winxp, ruby 1.8.4, wxruby 1.9.9 (i've tried wxruby 1.9.8 but the
result is the same)

/Anton
B47879f66d76dead1801327e1e6985e8?d=identicon&s=25 John Kennedy (Guest)
on 2008-11-03 17:58
(Received via mailing list)
This is something that I've spent *many* days ripping my hair out over.
Eventually, I found that I was calling 'paint' when I should have used
'refresh'.
Could you supply us with some code so we could take a look?
06f6780c99d4a8dd71f2b474082ea9ce?d=identicon&s=25 Alex Fenton (Guest)
on 2008-11-03 18:53
(Received via mailing list)
Anton Hörnquist wrote:
> In order to reduce flicker in my paint-intense app I've switched from
> paint |dc| to paint_buffered |dc|. Unfortunately, there is no difference
> after switching. Does anyone know why? Are there any other workarounds
> for this?
>
> I'm on winxp, ruby 1.8.4, wxruby 1.9.9 (i've tried wxruby 1.9.8 but the
> result is the same)
>
Avoiding flicker in GUI apps is unfortunately not as easy as using
paint_buffered, although it helps in a lot of cases.

It would be good to see some code that we can actually run, and more
information about the app - eg is the refreshing event-driven (the user
doees something, the display changes) or time-driven? To what extent can
future drawing be predicted? Is the drawing itself complex, or is there
a lot of computationally intensive non-drawing code in paint? Does
everything change at once?

Depending on this different things might help - eg preparing drawing in
idle time, only updating voided parts of the canvas, etc

alex
C9622ef018be71cb8d03ed361c4f660c?d=identicon&s=25 Anton Hornquist (antonhornquist)
on 2008-11-04 00:38
Attachment: memu.rb (4 KB)
Alex Fenton wrote:
> It would be good to see some code that we can actually run, and more
> information about the app - eg is the refreshing event-driven (the user
> doees something, the display changes) or time-driven? To what extent can
> future drawing be predicted? Is the drawing itself complex, or is there
> a lot of computationally intensive non-drawing code in paint? Does
> everything change at once?
>
> Depending on this different things might help - eg preparing drawing in
> idle time, only updating voided parts of the canvas, etc

Sure! Find memu.rb attached. It's a little hack, a monome emulator. You
will need rosc by hans fugal for it to work - hans.fugal.net/src/rosc/.
See www.monome.org for details about the actual device.

The MemuWindow is refreshed when a user presses or releases one of the
buttons on the virtual device (mouse cursor and
evt_left_down/evt_left_up). The box around the button is thickened.
Also, when certain osc parameters are received, the leds within the
buttons are lit up!

There is really no complex drawing going on, just a bunch of rectangles
:), but it's rather important that the stuff is updated in realtime.
Perhaps Ruby aint the ideal language for this.

/Anton
06f6780c99d4a8dd71f2b474082ea9ce?d=identicon&s=25 Alex Fenton (Guest)
on 2008-11-04 02:01
(Received via mailing list)
Anton Hörnquist wrote:
> Alex Fenton wrote:
>
>> It would be good to see some code that we can actually run, and more
>> information about the app - eg is the refreshing event-driven (the user
>> doees something, the display changes) or time-driven?
> Sure! Find memu.rb attached. It's a little hack, a monome emulator. You
> will need rosc by hans fugal for it to work - hans.fugal.net/src/rosc/.
> See www.monome.org for details about the actual device.

Thanks, looks interesting although I have only a hazy idea what it's
about. Please don't take this the wrong way, but if you're sending in
code for advice it's much preferred that the code is self-contained (as
yours is) and doesn't have external dependencies that need to be
installed (as yours does). I and others on this list are really happy to
try things out and advise, but it's too much to expect people to
download, compile and install third-party libs to do that.
>> Depending on this different things might help - eg preparing drawing in
>> idle time, only updating voided parts of the canvas, etc
>
>
> The MemuWindow is refreshed when a user presses or releases one of the
> buttons on the virtual device (mouse cursor and
> evt_left_down/evt_left_up). The box around the button is thickened.
> Also, when certain osc parameters are received, the leds within the
> buttons are lit up!
>
I haven't tried it out, but from reviewing your script perhaps I can
make a few suggestions:

First, and most important, it looks like you're repainting the whole 64
buttons when, for any given event, only one has changed state. An
alternate and more efficient approach might be to make each LED a
separate widget, an instance of a class inheriting from Wx::Window. It
knows its state, and draws its own rectangle. The TargetControl class in
the events.rb sample would be an example to look at for this.

You could then layout the buttons using a 8x8 Wx::GridSizer, store them
in a two dimensional array (faster lookup than your buttons.detect
method), then when an event is received, change the state of the
relevant button and call refresh (or update) on it alone. This means
that a much smaller amount of drawing has to be done for each change. It
would also make your handling of left-down and left-up simpler as you
wouldn't have to test which LED might have been hit.

Second, you might see whether, if each LED has only an on and off state
and these look the same, whether it is faster to cache an image for each
state and do draw_bitmap for each button. It may or may not be faster
than drawing each one with primitives like draw_rectangle.

Third, you could try playing around with, instead of having the server
in a different ruby thread, polling it for messages in evt_idle or
directly in a timer (Wx::Timer.every(20) { server.serve }). Also, is it
possible to have update the UI based only on server messages - ie
evt_left_down only notifies the server of change of state, and the
server notifies back to update the GUI? This design is generally more
scalable, in my experience, than having the state-changing event handler
also update the UI.
> There is really no complex drawing going on, just a bunch of rectangles
> :), but it's rather important that the stuff is updated in realtime.
> Perhaps Ruby aint the ideal language for this.
Ruby's certainly slow, and while wxRuby's a decently fast GUI toolkit,
the SWIG wrapping has significant overhead to each method call. That
said, I used Jay McGavren's Zyps library, which draws a lot of
primitives from scratch on a timed basis, and was able to get pretty
smooth animation (definitely more than 20fps I think). You might find
those wxruby-users threads in Dec 2007 / Jan 2008 of interest.

hth
alex
This topic is locked and can not be replied to.