Page 1 of 1

Strange redraw problem under Windows 7

Posted: Sun Dec 13, 2009 2:20 am
by mpthompson
I'm a bit stumped with a redraw problem under Windows 7 and I'm hoping to get some suggestions on where I might look further to resolve the issue.

I have been creating an interactive drawing application under Windows XP with wxWidgets 2.8.10 and everything seemed to be working fine for quite a while. Recently I've updated my development environment to Windows 7 and I'm now getting strange redraw issues.

In my application I have a number of Refresh() and Update() call sequences to immediately invalidate a region of the window while user is interacting objects within the application. Occasionally the redraws fail -- the code is executing as I can trace with debug statements through the OnDraw() method, it is just that nothing is painted into the dc/window. There is no pattern that I can tell on when the redraw fails or not -- it happens about 1/5th of the time. The strangest thing is that when a redraw fails if I move the mouse to another application window or over the minimize/maximize/close icons in the windows is immediately updated with what should have been drawn. It's as if the repaint was made into a buffer and the actual update of the window from the buffer is being deferred -- however I'm not doing any double buffering within my code.

If I bring an executable compiled under Windows XP to my Windows 7 system it exhibits the same redraw problem. Likewise, if I bring an executable compiled under Windows 7 to my Windows XP system it no longer displays this repaint issue. This would seem eliminate any differences in my build environments causing this issue.

I've been trying to nail down what might be wrong for over a day now and I've run out of ideas. Could it be a driver problem?

I'm using wxWidgets 9.8.10, Windows 7 and Visual C++ 2008 Express Edition.

Any suggestions would be sincerely appreciated.

Posted: Sun Dec 13, 2009 2:28 am
by mpthompson
Just a quick follow up. On a hunch I set my Windows 7 system to use the "Windows Classic" theme and the redraw problem went away. This would imply that the issue is related the Windows 7 Aero theme being activated. I wonder if Aero implements some sort of buffering interfering with the windows updates via Refresh() and Update().

I guess it's something more for me too look through on these forums.

Posted: Sun Dec 13, 2009 8:31 am
by Frank
Hmmm, I'm using Windows7 for some weeks now and never had drawing any problems. Not with my own (wxWidgets-)apps nor any other app.

There is of course a difference in Aeoro. It has realtime thumbs as a mouseover for the tasklist (okay, that's not really new, it's a feature since Vista). These thumbnails are not rendered when using the classic theme. So maybe it has something to do with this...

Posted: Sun Dec 13, 2009 8:25 pm
by mpthompson
Using Google I'm learning a lot more about Aero and the Desktop Window Manager (DWM) utilized by Vista/Windows 7. Apparently they utilize some form of double buffering implemented by the GPU that is transparent to the underlying applications for the fancy visual effects of the desktop. Under normal situations, this double buffering is completely transparent to typical GDI based applications, but apparently there are instances where the refresh of the screen becomes confused and leads to display issues such as I'm running into.

Looking further into this, in my situation after calling Refresh() and Update() I'm then calling SetVirtualSize() on the wxScrolledWindow derived subclass to adjust the window size around the objects contained within the window. Apparently calling these three function calls in this sequence triggers a situation where the Aero/DWM double buffering scheme fails to properly update the window. Causing the DWM to refresh the display from cache (i.e. clicking in another window) is enough for the buffer to properly shown on the display.

I'm reworking the repaint code in my application to change this sequence of calls to avoid the specific repaint issue.[/url]

Posted: Mon Dec 14, 2009 8:29 am
by mpthompson
Turns out the function call to SetVirtualSize() was a Red Herring, but I did find a solution to my problem.

There is undocumented Windows function called DwmFlush() that seems to allow a GDI based application to force the Desktop Windows Manager (DWM) to synchronize it's buffers for the application with the display hardware. By placing calls to DwmFlush() in specific locations in my application I was able to eliminate the display issues in Windows 7 with the Aero theme enabled.

It seems that in 99.99% of the cases Microsoft got the reworked GDI calls functioning smoothly with DWM, but in the few instances where the cache and physical display get out of sync, the call DwmFlush() takes care of the issue. At least it has for me.

Re: Strange redraw problem under Windows 7

Posted: Wed Aug 24, 2011 2:00 pm
by remi
Hi all

I have a problem which seems to be very close. But, inversly it happens on vista and seven when ***the classic windows theme is enabled***, It doesn't appear when the default transparent theme is enabled. The problem doesn't exist also on our OSX version.

The symptom appears when the user drag and click mouse on my glcanvas windows. At a moment, after a impredictible number of mouse manipulation (it is impossible to get the precise repro steps), the glwindow stop refreshing, like if the sequence :

Code: Select all

glFlush();
SwapBuffers();
does nothing.

Then I added a

Code: Select all

DwmFlush();
to the previous sequence, it ***seems*** to work (until I discover it is not...)

Is it possible to have more information/experiences about this ?


Config :
wxWidgets 2.8.11 I have the same problem with the 2.9.2
Visual C++ 2008 + SP1
Vista 64 / seven 64

Re: Strange redraw problem under Windows 7

Posted: Fri Sep 02, 2011 8:46 am
by remi
Hi

I made more tests, and the add of

Code: Select all

DwmFlush();
change nothing. The problem remains.

I repeat, the problem appears occasionaly when the "classic window theme" is set, when the "window vista" is set, there is no display problem at all.

Also, I found that If I resize the window of my app, (so that the glcanvas windows are resized also), the display refresh is made.

Any idea ?

best

Re: Strange redraw problem under Windows 7

Posted: Thu Mar 14, 2013 4:04 pm
by mxwwx
Hi,
we eliminated the problem by manually issuing

InvalidateRect( GetHwnd(), NULL, true );

instead of ( or additionaly to ) Refresh()

best