News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Flicker reduction drawing strategy

Started by Biterider, May 25, 2021, 04:02:46 AM

Previous topic - Next topic

Biterider

Hi
I want to share the result of a flicker reduction strategy for normal windows.
When experimenting with dynamic layouts, I've found that dialogs flicker a lot less when they are resized than regular windows. It seems that dialogs have a smarter implementation to redraw the background. Unfortunately, this feature doesn't seem to be available for regular windows. That said, if you want better flicker behaviour, you'll have to write your own code.  :badgrin:

A common painting strategy in coding examples is to paint the entire background first, and then paint any remaining child windows. This is fine for immutable windows, but when they have to be changed and redrawn frequently, such as resizing, the poor design quickly becomes apparent.

In this situation, the goal is to paint the background only where it is needed and avoid painting over the areas covered by child windows. This requires the creation of a dynamic array of rectangular areas, starting with the client window and excluding all areas of the child windows.  :biggrin:

I wrote the code in the form of a WndBackground object (derived from DataCollection) to do this job. The result is impressive; the window practically no longer flickers!

Regions were candidates for the implementation, but they lack the ability to exclude other regions, so I went with a collection of RECT structures. Maybe a linked list of RECTs would be a better performance choice, but for the moment, I use a DataCollection, that is easier to handle.

Attached the source code and a demo binary from a project I'm working on.

To see the impact of the implementation, run one of the binaries and create an MDI child by pressing Ctrl+N. Now change the size by dragging the border.
Compare the visual result with the other binary.

Have fun!  :cool:

Biterider

HSE

Hi Biterider!

Fantastic  :thumbsup:

Now that MDI child is not flickering we can clearly  see that, dragging superior border, statusbar jump like crazy  :biggrin: :biggrin: :biggrin:

Have fun!

HSE.
Equations in Assembly: SmplMath

Biterider

Hi HSE
You mean that dragging the upper border of the MDI child, its Statusbar is jumping?
I can not see that here (Win10). What OS do you have? Both binaries are doing the same thing?


Biterider

HSE

Biterider:

Quote from: Biterider on May 25, 2021, 05:31:42 AM
You mean that dragging the upper border of the MDI child, its Statusbar is jumping?
Yes. Resizing using upper border, status bar is moved upward or downward (I think) and redraw again in his position, that look like increasing and decreasing height.

Quote from: Biterider on May 25, 2021, 05:31:42 AM
What OS do you have? Both binaries are doing the same thing?
Same thing in 7-32 and 7-64, both files. Child flickering attract a little more attention, removing flickering you note better this behaviour.
HSE
Equations in Assembly: SmplMath

Biterider

Hi HSE
There are 2 Statusbars. One in the frame Window (below the client window) and another in the MDI child. I think you mean the first. Right?

Biterider

HSE

Equations in Assembly: SmplMath

jj2007

I'm afraid the demo flickers a lot here on my Win7-64 machine. Virtually everything flickers when resizing, even the menu!

For comparison I attach a small editor demo (some functions don't work yet). On my machine, it remains pretty calm, with the exception of the three controls (2x edit, one static) embedded into the toolbar in the upper right corner.

HSE

Quote from: jj2007 on May 25, 2021, 07:16:42 AM
On my machine, it remains pretty calm
There is a problem here, the background is greenish!!  :biggrin:

Very interesting the resizing problem with upper border is similar, but also with lower border. I addition you can see a green band at right when enlarging from left or right.
Equations in Assembly: SmplMath

jj2007

Quote from: HSE on May 25, 2021, 08:23:00 AM
There is a problem here, the background is greenish!!  :biggrin:
:tongue:

QuoteVery interesting the resizing problem with upper border is similar, but also with lower border. I addition you can see a green band at right when enlarging from left or right.

On my machine I have no flicker at all when resizing vertically. In contrast, horizontal resizing makes the three embedded controls in the upper right corner flicker a bit.

The menu remains always calm. In contrast, biterider's demo shows flicker in the menu, which is quite odd :cool:

HSE

Quote from: jj2007 on May 25, 2021, 08:52:47 AM
horizontal resizing makes
The scroll box is oscillating between two different sizes and positions when horizontal resizing   :rolleyes:
Equations in Assembly: SmplMath

jj2007

You are right :thumbsup:

Very weird, it really jumps up and down. With vertical resizing it remains very smooth. I don't have control over this behaviour, it's a standard RichEdit "feature", apparently. Toggling word wrap has no effect (this was my suspicion) :sad:

@Biterider: Your demo really flickers. The menu, the toolbar, the tree control - everything. I suppose it's really the background erasing that goes haywire. But why the menu??? That is NC background.

HSE

Quote from: jj2007 on May 25, 2021, 09:14:38 AM
it's a standard RichEdit "feature"

Usually I use MoveWindow, but help say:
QuoteTo resize the control, you can use the SetWindowPos function.

Equations in Assembly: SmplMath

jj2007

Tested, no effect. I bet that SetWindowPos uses MoveWindow under the hood :cool:

jj2007

P.S.: The "jumping scrollbar" in my demo does not appear in my WinXP VM. It behaves normally, although there is generally much more flicker than on Win7.

If I take away the vertical scrollbar by omitting WS_VSCROLL from the style during CreateWindowEx, and then enable it afterwards with SetWindowLong, I get a smooth scrollbar - no jumps, see attachment!

  gcStyleEdit= WS_BORDER or ES_LEFT or ES_AUTOVSCROLL or ES_MULTILINE or 0*WS_VSCROLL
  GuiControl MyEdit, "richedit", bcol RgbCol(222, 255, 240)
 
  invoke GetWindowLong, hMyEdit, GWL_STYLE
  or eax, WS_VSCROLL
  invoke SetWindowLong, hMyEdit, GWL_STYLE, eax


So it seems the built-in RichEdit scrollbar has a little problem - I've added it to the RichEd20.dll bugs thread :sad:

LiaoMi

Hi Biterider,

on my machine, I didn't notice any difference  :undecided: I think the best way would be to measure the performance metric and display it as data.

The Linux perf GUI for performance analysis - https://github.com/KDAB/hotspot and https://github.com/KDAB/hotspot#screenshots
Library of ImGui controls for displaying performance metrics - https://github.com/GameTechDev/MetricsGui
Performance counter monitoring GUI - https://github.com/numascale/perf-gui

By synchronizing data objects in each test, you can determine where the problem area is. You can create a set of tests for both cases, and then measure the timings that affect the desynchronization of rendering to the screen.