how to stop the flicker

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

how to stop the flicker

Shaping-3
When switching pluggable presenters, I want to eliminate flicker--unwanted
or unnecessary redrawing of the background of the container.  Where do we
typically disable background repainting?  InvalidateRect?

I'm assuming that Windows is painting each background in positive z-order
(right-handed coordination) from back-to-front--frame, container, pluggable,
in that order.  If my pluggable is rendered in OGL, there is no flicker
because of the double-buffering.  But I still need to kill redraw of the
container and window, so that the white flashes are not seen.  Suggestions
are welcome.


Shaping


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Chris Uppal-3
Shaping wrote:

> When switching pluggable presenters, I want to eliminate flicker--unwanted
> or unnecessary redrawing of the background of the container.  Where do we
> typically disable background repainting?  InvalidateRect?

There are a number of techniques for reducing/eliminating flicker, I don't know
which, if any, are applicable in your case.

1) override View>>onEraseRequired: in your View class to do nothing except
answer 1, thus telling the framework that you are handling the erase yourself.
Only really makes sense for custom views.

2) View>>disableRedraw and #enableRedraw can be used to reduce the amount of
flicker as a view repeatedly repaints itself.

3) Avoid sending #invalidate to a ShellView.  That causes the entire shell,
including its title-bar and borders, to repaint -- and looks /terrible/...

4) Set the background of the container presenter (PlugholePresenter in my
example) to a colour as close to the average/background colour of your
pluggable views as possible.

5) (Pretty dodgy, but I do it anyway ;-)  When you change the Model of a
non-trivial presenter it will (naturally) pass the model over to its View too.
In many cases (in fact without exception, in my code) "interesting" presenters
are connected to container views.  Allowing the container to "see" the new
model causes it to refresh itself needlessly ("needlessly" since it doesn't
actually /use/ the model).  So I sometimes just assign to 'model' directly in
my
presenter's #model: rather than doing a super-send.  I /think/ that there may
be a non-dodgy equivalent by doing something like overriding #viewModel, but
I've never looked into it.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Shaping-3
> There are a number of techniques for reducing/eliminating flicker, I don't
> know
> which, if any, are applicable in your case.

Thanks, for the suggestions, but I can't seem to stop the blanking to white
in containers.  Does anyone else have any success with preventing repainting
of container backgrounds?

>
> 1) override View>>onEraseRequired: in your View class to do nothing except
> answer 1, thus telling the framework that you are handling the erase
> yourself.
> Only really makes sense for custom views.

I tried this in the PresenterPresenter's (PlugholePresenter's) view, but it
still repaints itself white before repainting the contained view.

>
> 2) View>>disableRedraw and #enableRedraw can be used to reduce the amount
> of
> flicker as a view repeatedly repaints itself.

Doesn't this trigger downward to contained views.  In other words, if I
#disableRedraw at the container, will the contained view every be redrawn?

>
> 3) Avoid sending #invalidate to a ShellView.  That causes the entire
> shell,
> including its title-bar and borders, to repaint -- and looks /terrible/...
>
Agreed.

> 4) Set the background of the container presenter (PlugholePresenter in my
> example) to a colour as close to the average/background colour of your
> pluggable views as possible.

I tried this but it doesn't work.  I still get the white flashing, then the
container background redraw, and then the pluggable presenter's view's
background redraw.

>
> 5) (Pretty dodgy, but I do it anyway ;-)  When you change the Model of a
> non-trivial presenter it will (naturally) pass the model over to its View
> too.
> In many cases (in fact without exception, in my code) "interesting"
> presenters
> are connected to container views.  Allowing the container to "see" the new
> model causes it to refresh itself needlessly ("needlessly" since it
> doesn't
> actually /use/ the model).  So I sometimes just assign to 'model' directly
> in
> my
> presenter's #model: rather than doing a super-send.  I /think/ that there
> may
> be a non-dodgy equivalent by doing something like overriding #viewModel,
> but

I cannot comment-out the super send without breaking the present code.  I
will investigate further.


Shaping


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Chris Uppal-3
Shaping wrote:

> > 2) View>>disableRedraw and #enableRedraw can be used to reduce the
> > amount of
> > flicker as a view repeatedly repaints itself.
>
> Doesn't this trigger downward to contained views.  In other words, if I
> #disableRedraw at the container, will the contained view every be redrawn?

I'm not quite sure what you mean here, so I may be trying to answer the wrong
question.

If you send #disableRedraw to a container view, then (as far as I know) that
view, and all it's subviews will stop repainting themselves until the container
is sent #enableRedraw.  When that happens, it will #invalidate itself
automatically, which will cause Windows to ask it (and hence its subviews) to
repaint themselves.

So you will always get /one/ redraw.  The "value" of the technique is to avoid
flickering if the various views redraw themselves several times during a
re-configuration.


> > 4) Set the background of the container presenter (PlugholePresenter in
> > my example) to a colour as close to the average/background colour of
> > your pluggable views as possible.
>
> I tried this but it doesn't work.  I still get the white flashing, then
> the container background redraw, and then the pluggable presenter's view's
> background redraw.

Maybe you are setting the background to the wrong container ?  I'd try setting
the background of /every/ container to a different colour (and one that is
clearly not white), and see what colour got flashed then.  If it's still white
then at least you know you have to look at a deeper level (maybe at the Windows
level) for a solution.

I've tried technique (4) on my example -- setting the pluggable presenters'
colours to deep blue so that flashing should show up more clearly, and it seems
to work pretty smoothly.  But then, those presenters are so simple that they
can probably paint themselves too quickly to be representative.

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Shaping-3
>
> Maybe you are setting the background to the wrong container ?  I'd try
> setting
> the background of /every/ container to a different colour (and one that is
> clearly not white), and see what colour got flashed then.  If it's still
> white
> then at least you know you have to look at a deeper level (maybe at the
> Windows
> level) for a solution.
>
> I've tried technique (4) on my example -- setting the pluggable
> presenters'
> colours to deep blue so that flashing should show up more clearly, and it
> seems
> to work pretty smoothly.  But then, those presenters are so simple that
> they
> can probably paint themselves too quickly to be representative.
>

Set all of your background colors to black.  That is what I have, and I'm
using your architecture, except I have an OGL presenter at the bottom
instead of a static text field.

The flicker is almost gone.  I got about 80% (estimating) of the "white
duration" to go away, simply by using a BorderLayout in my
PresenterPresenter and setting arrangement to #center for the pluggable.  I
had left this nil, thinking that the pluggable would fit perfectly inside of
the container, because they are the same exact size.  This didn't happen.  I
got a 5 to 10 pixel gap on the left and top.  This went away when I made the
change, and so did much of the flicker (which I don't understand).  The
remaining flicker is very short and seems to be in either MyPagePresenter
(the pluggable) or in the OGL presenter inside of that.  I think the
flickering is near the bottom of the view hierarchy because the short
flicker occurs very late in the switching cycle (from one OGL presenter to
the next), after plugging and just before OGL rendering.  I will try to make
a simple example of this to help find the problem.


Shaping


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Chris Uppal-3
Shaping wrote:

> Set all of your background colors to black.That is what I have,

Oooh!   Very Goth...

I tried that, and also thought to maximise the test shell, and I could then see
a /slight/ (but nonetheless irritating) flicker -- about 1/2 to 1/4 of the
black area would flicker white as the plugin changed.  On investigation it
turned out that I'd missed one of the container views' backgrounds.
Specifically (to my example) the container view used by PlugholePageAbstract to
hold the two static texts.  With that fixed, I'm seeing no flicker at all.
(And I'm not using any of the other techniques I mentioned).

That suggests that the problem is either that you also have missed one of the
container views, or that the flicker is inherent in your OGL component.  Or
that something else is amiss, but I can't imagine what...

    -- chris


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Shaping-3
> Oooh!   Very Goth...

Gothic.

>
> I tried that, and also thought to maximise the test shell, and I could
> then see
> a /slight/ (but nonetheless irritating) flicker -- about 1/2 to 1/4 of the
> black area would flicker white as the plugin changed.  On investigation it
> turned out that I'd missed one of the container views' backgrounds.
> Specifically (to my example) the container view used by
> PlugholePageAbstract to
> hold the two static texts.  With that fixed, I'm seeing no flicker at all.
> (And I'm not using any of the other techniques I mentioned).
>
> That suggests that the problem is either that you also have missed one of
> the
> container views, or that the flicker is inherent in your OGL component.
> Or
> that something else is amiss, but I can't imagine what...
>

Yes, I too missed one.  There are four:  container view in shell;
presenterHolder (formerly PresenterPresenter); MyPage; and the generic OGL
presenter inside of it.  All are black now, and the rendering has a mostly
solid black background, but there is a narrow horizontal band of white that
sometimes flickers.  It is one-sixth to one-third the height of the view.
It seems to happen when I /rush/ the switching of the pages, but even this
doesn't not happen consistently.  Sometimes I see the flash only one in ten
tries.  Overall, it looks very good.  I would like to get to the bottom of
it, though.


Shaping


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Shaping-3
Hi Blair.

I've investigated almost every possible cause of the flicker still remaining
in the pluggable presenter architecture that Chris and I have been working
through.  I need to solve this problem.  This is what I know:

All of my backgrounds are black.

The flicker is intermittent and usually occupies a narrow vertical band in
the subview.  Occasionally, the "band" occupies the whole subview.

The problem is not OpenGL vertical synchronization, lack of which is
reported to produce a similar problem.  I tried sync-ing on two machines
with different models of ATI card, and both times failed to eliminate the
flicker.

I have seen the flicker go away when OpenGL renders to the main window's
client area (I've done much of this mode myself, and prefer it, but you have
to role everything yourself).  I have seen the flicker problem in a
subview/subwindow on both Dolphin and in an MFC app involving a dialog with
a static subview as the OGL viewport.

So my only remaining thought is whether there is a default white background
brush registered by the class associated with the static or whatever window
is being used by Dolphin as the ContainerView.  Any thoughts?


Shaping



 "Shaping" <[hidden email]> wrote in message
news:[hidden email]...

>> Oooh!   Very Goth...
>
> Gothic.
>
>>
>> I tried that, and also thought to maximise the test shell, and I could
>> then see
>> a /slight/ (but nonetheless irritating) flicker -- about 1/2 to 1/4 of
>> the
>> black area would flicker white as the plugin changed.  On investigation
>> it
>> turned out that I'd missed one of the container views' backgrounds.
>> Specifically (to my example) the container view used by
>> PlugholePageAbstract to
>> hold the two static texts.  With that fixed, I'm seeing no flicker at
>> all.
>> (And I'm not using any of the other techniques I mentioned).
>>
>> That suggests that the problem is either that you also have missed one of
>> the
>> container views, or that the flicker is inherent in your OGL component.
>> Or
>> that something else is amiss, but I can't imagine what...
>>
>
> Yes, I too missed one.  There are four:  container view in shell;
> presenterHolder (formerly PresenterPresenter); MyPage; and the generic OGL
> presenter inside of it.  All are black now, and the rendering has a mostly
> solid black background, but there is a narrow horizontal band of white
> that sometimes flickers.  It is one-sixth to one-third the height of the
> view. It seems to happen when I /rush/ the switching of the pages, but
> even this doesn't not happen consistently.  Sometimes I see the flash only
> one in ten tries.  Overall, it looks very good.  I would like to get to
> the bottom of it, though.
>
>
> Shaping
>


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Blair McGlashan-3
"Shaping" <[hidden email]> wrote in message
news:[hidden email]...

> Hi Blair.
>
> I've investigated almost every possible cause of the flicker still
> remaining in the pluggable presenter architecture that Chris and I have
> been working through.  I need to solve this problem.  ...
>...
> So my only remaining thought is whether there is a default white
> background brush registered by the class associated with the static or
> whatever window is being used by Dolphin as the ContainerView.  Any
> thoughts?

The single DolphinWindow class used for all Dolphin's Views (not the
ControlViews of course) does have a background brush to erase to
COLOR_WINDOW, however this is usually overridden from the image by the
implementation of WM_ERASEBKGND. For a standard view it is used if no
background colour is configured for the view (see View>>onEraseRequired:
where comments explain this adequately). This would be the implementation
inherited by ContainerView. Any view that completely paints its client area
(and which does not therefore require erasing) would normally override
#onEraseRequired: to suppress the default behaviour by returning 1 or true.
An example in the standard image is DoubleBufferedView. I also posted an
interesting example to the group recently of how to implement a
MultilineTextEdit with a background image and this did the same. You might
want to try creating a ContainerView subclass that doesn't erase the
background and suppresses the default beavhiour (i.e. override
#onEraseRequired: to return true), or just modify ContainerView itself
temporarily.

You could also try without a class brush by modifying View
class>>winClassBrush to return 0. It will probably have undesirable effects
in some apps, but might help your investigation. As I say though, this won't
be used unless the DefWindowProc is called, and that will only happen if the
#onEraseRequired: implementation returns nil/self rather than true/1.

Regards

Blair


Reply | Threaded
Open this post in threaded view
|

Re: how to stop the flicker

Shaping-3
>> I've investigated almost every possible cause of the flicker still
>> remaining in the pluggable presenter architecture that Chris and I have
>> been working through.  I need to solve this problem.  ...
>>...
>> So my only remaining thought is whether there is a default white
>> background brush registered by the class associated with the static or
>> whatever window is being used by Dolphin as the ContainerView.  Any
>> thoughts?
>
> The single DolphinWindow class used for all Dolphin's Views (not the
> ControlViews of course) does have a background brush to erase to
> COLOR_WINDOW, however this is usually overridden from the image by the
> implementation of WM_ERASEBKGND. For a standard view it is used if no
> background colour is configured for the view (see View>>onEraseRequired:
> where comments explain this adequately). This would be the implementation
> inherited by ContainerView. Any view that completely paints its client
> area (and which does not therefore require erasing) would normally
> override #onEraseRequired: to suppress the default behaviour by returning
> 1 or true. An example in the standard image is DoubleBufferedView. I also
> posted an interesting example to the group recently of how to implement a
> MultilineTextEdit with a background image and this did the same. You might
> want to try creating a ContainerView subclass that doesn't erase the
> background and suppresses the default beavhiour (i.e. override
> #onEraseRequired: to return true), or just modify ContainerView itself
> temporarily.

I tried placing the true-returning #onEraseRequired: in ContainerView.  That
made the flashing worse, meaning that the whole view was clearly turning
white very briefly.

>
> You could also try without a class brush by modifying View
> class>>winClassBrush to return 0. It will probably have undesirable
> effects in some apps, but might help your investigation. As I say though,
> this won't be used unless the DefWindowProc is called, and that will only
> happen if the #onEraseRequired: implementation returns nil/self rather
> than true/1.

I tried this too, but there was no change.  The flashing almost never occurs
sometimes.  You can go through five or more page changes with no flashing,
and then suddenly, there is a narrow band of white, usually  1/8 to 1/4 of
the vertical size of the view, near the bottom or top of the view.

This doesn't really look like an erase-background issue, because when the
background is being erased, it is very clearly and uniformly being
erased--you can't miss it.  I'm thinking that this must be a GDI
aberration/weirdness/bug.

I will post to the OpenGL group about this.  My only other thought is to use
a WinDIB section for rendering, as I did in my VW OGL stuff, in much the
same manner as Jun OpenGL does.  This approach seems cleaner than the more
conventional rendering to the back buffer and then swapping it to window.
With the DIBSection you are rendering to the DIB, and then blitting it to
the dc.  I never had any flicker problems, but I never used a proper Windows
window, except at the top level, where I rendered everything with OGL in the
client area, often at full-screen...


Shaping