How to avoid flickering? (in patched OO.o Math)

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

How to avoid flickering? (in patched OO.o Math)

Jonas Finnemann Jensen
Hi,

I'm working on creating a visual formula editor in OO.o Math for
Go-OO as part of Google Summer of Code 2010. So far it's going pretty
good, but run into some minor flickering issues when redrawing often,
which is why I'm posting here...

In OO.o Math I need to redraw then entire formula whenever the the
caret moves or the formula is changed. The widget is drawn in
SmGraphicWindow::Paint. To redraw the widget I call Invalidate().

Now I would expect that some kind of double buffering to happen
around the call to SmGraphicWindow::Paint. But as far as I can see
the widget (SmGraphicWindow) is at times completely blank, this is
very brief, but enough to be visible and course flickering.

How is Window::Paint supposed to be implemented to avoid flickering?
Is the drawing in Window::Paint double buffered? If not why? And how
should I implement double buffering?
 - I haven't found much in terms of documentation, so if there's any
please throw it at me...

If anybody wants to try it out (I doubt that's necessary) I've attached a
patch that makes it easy to reproduce the issue by clicking the formula
and hitting some keys.
The patch will make any key course the formula to be redrawn, so it's
easy to make it redraw as fast as it would if the user entered text...

The patch is against ooo320-m17 (with go-oo patches), but it's only
two lines show if it doesn't apply it's easy to copy-paste.

Anyway, I hope you can help me resolve this problem...

--
Regards Jonas Finnemann Jensen.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

starmath-flickering.diff (1002 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: How to avoid flickering? (in patched OO.o Math)

Philipp Lohmann
Hi,

painting is not double buffered in vcl Windows (including
SmGraphicWindow) - and currently there is no method to have that
automatically. The notable excpetion is the Mac, where drawing is double
buffered just above the system level.

In places where you want to avoid flickering through constant redrawing
the usual solution is to draw to a VirtualDevice (see vcl/virdev.hxx)
created with the Window as reference (to get bit depth and other
properties right), then draw that using the DrawOutDev call on the
Window to copy the contents of said VirtualDevice. This will flicker the
least amount since it paints only once instead of first painting the
background, then content to the window.

This works easiest if your Window is fully opaque (no transparencies
involved), in which case you know your background. I assume this is the
case for the math window. If your Window is transparent, you need to
copy the window background before drawing on it - which is somewhat
cumbersome and can be error prone.

Kind regards, pl

P.S.: Yes, double buffering would be a very nice feature on a per window
basis and basically every other toolkit than creaky old vcl has that. Sorry.

On 6/14/10 11:23 PM, Jonas Finnemann Jensen wrote:

> Hi,
>
> I'm working on creating a visual formula editor in OO.o Math for
> Go-OO as part of Google Summer of Code 2010. So far it's going pretty
> good, but run into some minor flickering issues when redrawing often,
> which is why I'm posting here...
>
> In OO.o Math I need to redraw then entire formula whenever the the
> caret moves or the formula is changed. The widget is drawn in
> SmGraphicWindow::Paint. To redraw the widget I call Invalidate().
>
> Now I would expect that some kind of double buffering to happen
> around the call to SmGraphicWindow::Paint. But as far as I can see
> the widget (SmGraphicWindow) is at times completely blank, this is
> very brief, but enough to be visible and course flickering.
>
> How is Window::Paint supposed to be implemented to avoid flickering?
> Is the drawing in Window::Paint double buffered? If not why? And how
> should I implement double buffering?
>   - I haven't found much in terms of documentation, so if there's any
> please throw it at me...
>
> If anybody wants to try it out (I doubt that's necessary) I've attached a
> patch that makes it easy to reproduce the issue by clicking the formula
> and hitting some keys.
> The patch will make any key course the formula to be redrawn, so it's
> easy to make it redraw as fast as it would if the user entered text...
>
> The patch is against ooo320-m17 (with go-oo patches), but it's only
> two lines show if it doesn't apply it's easy to copy-paste.
>
> Anyway, I hope you can help me resolve this problem...
>
> --
> Regards Jonas Finnemann Jensen.
>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]


--
"If the designers of X-window built cars, there would be no fewer than
  five steering wheels hidden about the cockpit, none of which followed
  the same principles -- but you'd be able to shift gears with your
  car stereo. Useful feature, that."
                 -- From the programming notebooks of a heretic, 1990.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: How to avoid flickering? (in patched OO.o Math)

Jonas Finnemann Jensen
Hi,

Thanks for you quick reply... I've played with VirtualDevice for a few
days now...
I assume what you suggest is:

SmGraphicWindow::Paint(const Rectangle&)
{
    size = ...
    VirtualDevice vDev(*this, 0, 0);
    vDev.SetOutputSize(size);
    rDoc.Draw(vDev, aPoint); //The drawing code...
    DrawOutDev(Point(0,0), size, Point(0,0), size, vDev);
}

I've tried this... But it doesn't solve the flickering, and it somehow
disables anti-alias... I've also tried to do the actual drawing on
vDev in PrePaint (not a great place I know, but might work),
nevertheless this didn't solve the issue either...

I guess the problem is the Erase() call in Window::ImplCallPaint()...
Anyway, this issue isn't important (yet), so I'll work on something
that is. And post back here if I get back to playing with this issue
again...

Again, thanks for your reply...

--
Regards Jonas Finnemann Jensen.



On Tue, Jun 15, 2010 at 09:27, Philipp Lohmann <[hidden email]> wrote:

> Hi,
>
> painting is not double buffered in vcl Windows (including SmGraphicWindow) -
> and currently there is no method to have that automatically. The notable
> excpetion is the Mac, where drawing is double buffered just above the system
> level.
>
> In places where you want to avoid flickering through constant redrawing the
> usual solution is to draw to a VirtualDevice (see vcl/virdev.hxx) created
> with the Window as reference (to get bit depth and other properties right),
> then draw that using the DrawOutDev call on the Window to copy the contents
> of said VirtualDevice. This will flicker the least amount since it paints
> only once instead of first painting the background, then content to the
> window.
>
> This works easiest if your Window is fully opaque (no transparencies
> involved), in which case you know your background. I assume this is the case
> for the math window. If your Window is transparent, you need to copy the
> window background before drawing on it - which is somewhat cumbersome and
> can be error prone.
>
> Kind regards, pl
>
> P.S.: Yes, double buffering would be a very nice feature on a per window
> basis and basically every other toolkit than creaky old vcl has that. Sorry.
>
> On 6/14/10 11:23 PM, Jonas Finnemann Jensen wrote:
>>
>> Hi,
>>
>> I'm working on creating a visual formula editor in OO.o Math for
>> Go-OO as part of Google Summer of Code 2010. So far it's going pretty
>> good, but run into some minor flickering issues when redrawing often,
>> which is why I'm posting here...
>>
>> In OO.o Math I need to redraw then entire formula whenever the the
>> caret moves or the formula is changed. The widget is drawn in
>> SmGraphicWindow::Paint. To redraw the widget I call Invalidate().
>>
>> Now I would expect that some kind of double buffering to happen
>> around the call to SmGraphicWindow::Paint. But as far as I can see
>> the widget (SmGraphicWindow) is at times completely blank, this is
>> very brief, but enough to be visible and course flickering.
>>
>> How is Window::Paint supposed to be implemented to avoid flickering?
>> Is the drawing in Window::Paint double buffered? If not why? And how
>> should I implement double buffering?
>>  - I haven't found much in terms of documentation, so if there's any
>> please throw it at me...
>>
>> If anybody wants to try it out (I doubt that's necessary) I've attached a
>> patch that makes it easy to reproduce the issue by clicking the formula
>> and hitting some keys.
>> The patch will make any key course the formula to be redrawn, so it's
>> easy to make it redraw as fast as it would if the user entered text...
>>
>> The patch is against ooo320-m17 (with go-oo patches), but it's only
>> two lines show if it doesn't apply it's easy to copy-paste.
>>
>> Anyway, I hope you can help me resolve this problem...
>>
>> --
>> Regards Jonas Finnemann Jensen.
>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: [hidden email]
>> For additional commands, e-mail: [hidden email]
>
>
> --
> "If the designers of X-window built cars, there would be no fewer than
>  five steering wheels hidden about the cockpit, none of which followed
>  the same principles -- but you'd be able to shift gears with your
>  car stereo. Useful feature, that."
>                -- From the programming notebooks of a heretic, 1990.
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [hidden email]
> For additional commands, e-mail: [hidden email]
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: How to avoid flickering? (in patched OO.o Math)

Philipp Lohmann
Hi,

On 6/18/10 7:58 PM, Jonas Finnemann Jensen wrote:

> Hi,
>
> Thanks for you quick reply... I've played with VirtualDevice for a few
> days now...
> I assume what you suggest is:
>
> SmGraphicWindow::Paint(const Rectangle&)
> {
>      size = ...
>      VirtualDevice vDev(*this, 0, 0);
>      vDev.SetOutputSize(size);
>      rDoc.Draw(vDev, aPoint); //The drawing code...
>      DrawOutDev(Point(0,0), size, Point(0,0), size, vDev);
> }
>
> I've tried this... But it doesn't solve the flickering, and it somehow
> disables anti-alias... I've also tried to do the actual drawing on
> vDev in PrePaint (not a great place I know, but might work),
> nevertheless this didn't solve the issue either...

You can enable antialiasing with SetAntialias (call and flags in
vcl/outdev.hxx).

> I guess the problem is the Erase() call in Window::ImplCallPaint()...
> Anyway, this issue isn't important (yet), so I'll work on something
> that is. And post back here if I get back to playing with this issue
> again...

Good point. If you draw fully opaque, you can disable the Erase by
setting no background at all calling SetBackground() (the method without
wallpaper).

Just my 2 cents, pl


--
"If the designers of X-window built cars, there would be no fewer than
  five steering wheels hidden about the cockpit, none of which followed
  the same principles -- but you'd be able to shift gears with your
  car stereo. Useful feature, that."
                 -- From the programming notebooks of a heretic, 1990.

---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]