|
|
Home » Developing U++ » U++ Developers corner » Should we double-buffer by default?
|
|
Re: Should we double-buffer by default? [message #4055 is a reply to message #4053] |
Tue, 18 July 2006 15:56 |
|
luzr wrote on Tue, 18 July 2006 09:23 |
Now reading Qt docs, since Qt4.0 they do doublebuffering as the only option. Should not we too? (OK, this whole message is for Daniel in the first place...
|
Thank you Mirek
Indeed, to answer if double-buffering should be used as default is not easy. Generaly idea is great and it solves many corner issues with painting.
The main problem with double-buffering is speed of drawing, which is depended mainly on graphics card and the screen resolution. Unofrtunately I always had feeling that apps that are working in full screen in double-buffering mode are less responsive (at least when win32 api (gdi) is used) than "classical" painted ones (even if cpu has 1ghz and modern gfx card like gf4 were used).
I will try your new code today evening and then I'll be able to say more. I think that we should make tests in apps working in maximized modes in resolutions 1024x768 and 1280x1024. In smaller windows there should not be any noticeable difference.
|
|
|
|
Re: Should we double-buffer by default? [message #4057 is a reply to message #4056] |
Tue, 18 July 2006 23:43 |
|
luzr wrote on Tue, 18 July 2006 10:36 |
Just a sidenote - while I do not quite like that kind of argument, I have to mention that gf4 is not "modern gfx". 7xxx is "modern". gf4 is 5 years old...
|
Modern in sense of momory bandwitch, speed of drawing 2d primitives - not 3d stuff
From my experince I know that in win32 env gdi work faster (and the double-buffering as well) if memory<->gfx transfers are fast.
Eg p41.7 + gf2mx 32mb was faster (I cosider double-buffering mode in upp and opera that uses qt) than duron 1ghz + gf4200Ti (128MB).
|
|
|
|
|
Re: Should we double-buffer by default? [message #4063 is a reply to message #4060] |
Wed, 19 July 2006 08:09 |
|
luzr wrote on Tue, 18 July 2006 18:42 |
- because scroll is used to scroll window area. Double buffering takes effect later... (yes, I still have "detect Ctrl position change that is scrolled and avoid repainting" in my list. When that will be done, this will disappear).
|
I came to the same conclusion thinking about it later
|
|
|
Re: Should we double-buffer by default? [message #4064 is a reply to message #4058] |
Wed, 19 July 2006 08:34 |
|
luzr wrote on Tue, 18 July 2006 17:57 | I believe that double-buffering does not do memory<->GPU transfers, on decent card with good driver...
|
I've found on usenet:
Quote: |
Bitmaps created by CreateCompatibleBitmap() are managed by the video driver. They may or may not be in video memory.
John - Microsoft Developer Support
|
So if the backbuffer is created in system memory (maybe from unknown reasons on my duron it was) gfx<->memory transfer speed is important.
|
|
|
|
Re: Should we double-buffer by default? [message #4066 is a reply to message #4065] |
Wed, 19 July 2006 10:09 |
|
luzr wrote on Wed, 19 July 2006 03:01 | BTW, any idea how to detect a system that is better to flicker than backbuffer?
I was thinking about measuring time of backbuffer paint routine and when it reaches some threshold (50ms), switch to direct flickering mode.
I am however afraid that random time fluctuation would switch decent system as well...
|
Unfortunately I have no idea how to detect it (if it is detectable at all) Time measuring seems to be a better idea, but instead of doing it in every Paint() and dynamicaly switch the render mode better would be to do some typical tests at the beginning of the application.
Ok, now lets talk a little about problems with double-buffering.
I tested it mainly in my GridTest application. This is simply app with one tab control and two sheets. In first is grid control, in second array control.
What is intersting in debug mode painting is noticeable slower with double buffering (before it was faster). I checked this on 2 computers (app was maximized):
1. Sempron 64 2.1 ghz, gf6600 1280x1024
2. P4 1.7, gf2mx, 1024x768
In release mode on machine 1 speed was very good, on machine 2 refreshing speed was worst (and it was also worst than in "old" upp rendering mode).
I tested mainly column resizeing. On machine 2 in my grid there is significant lag between mouse position and resized column position. In array ctrl is even worst because header scrolls normaly (no lag) but the body is painted 5-8 pixels behind (I guess this is not synchronized and after fixing it the result will be the same as in my grid).
Anyway in both cases we lost the most important thing: responsivity and feeling of "lightweight" ui.
I also noticed that in my grid ScrollView do nothing (it worked before). The grid consist of 4 frames. Top header, left header , scrollbars and the main frame - grid body.
If scroll was detected the OnScroll() routine from main frame was called. And it looks like this:
void GridCtrl::OnScroll()
{
if(!doscroll)
return;
Point newpos(sbx, sby);
Size delta = oldpos - newpos;
scrollxdir = delta.cx == 0 ? scrollxdir : delta.cx < 0 ? 1 : -1;
scrollydir = delta.cy == 0 ? scrollydir : delta.cy < 0 ? 1 : -1;
if(th.drawColLine || lh.drawRowLine)
{
oldpos = newpos;
return;
}
//if(!IsFullRefresh())
{
ScrollView(delta);
if(delta.cx != 0)
{
Size sz = th.GetSize();
th.ScrollView(Rect(fixedWidth, 0, sz.cx, sz.cy), delta.cx, 0);
scrollLeftRight = true;
}
if(delta.cy != 0)
{
lh.ScrollView(0, delta.cy);
}
}
oldpos = newpos;
UpdateCtrlsPos(0, 0, 0, 0, 1);
}
I commented if(!IsFullRefresh) to be sure the header will be scrolled. th is top header lh is left header. Unfortunately
th.ScrollView and lh.ScrollView stopped working. Even if I add
lh/th.Sync() nothing changes. Bug? or there are some important changes I should be aware of?
|
|
|
Re: Should we double-buffer by default? [message #4067 is a reply to message #4066] |
Wed, 19 July 2006 11:01 |
|
mirek
Messages: 13975 Registered: November 2005
|
Ultimate Member |
|
|
OK, I have tested on my SisGX/Sempron1.8 notebook and while the difference is small, I must say there is difference...
Means back to development.... Now I am thinking about some sort of more simple approach to the old problem.... In fact, the real trouble of all this is "sibling Ctrl intersection". That makes all the trouble, if I want really correct algorithm. Anyway, at the same time it is not very often corner case.
So my next idea is to detect this problem and perform non-buffered draw just for ctrls that do not have this problem. Also, maybe we could detect and handle unbuffered just Ctrls that are "big" (say bigger that 200x200 pixels).
I will test these new ideas tommorow or on Friday.
As for GridCtrl scrolling problem, I think I know where to look and I think it is in CtrlDraw.cpp , but sample code would help, if possible..... (upload to ftp, please).
Mirek
|
|
|
Re: Should we double-buffer by default? [message #4070 is a reply to message #4067] |
Wed, 19 July 2006 11:18 |
|
luzr wrote on Wed, 19 July 2006 05:01 | OK, I have tested on my SisGX/Sempron1.8 notebook and while the difference is small, I must say there is difference...
|
Good I'm not alone
Quote: |
Means back to development.... Now I am thinking about some sort of more simple approach to the old problem.... In fact, the real trouble of all this is "sibling Ctrl intersection". That makes all the trouble, if I want really correct algorithm. Anyway, at the same time it is not very often corner case.
So my next idea is to detect this problem and perform non-buffered draw just for ctrls that do not have this problem. Also, maybe we could detect and handle unbuffered just Ctrls that are "big" (say bigger that 200x200 pixels).
|
Could you describe the problem of sibling ctrl intersections more? (if you have time, I would like to think about solution too )
As for unbuffered draw this is some kind of idea. I would also add to this ability to set by hand if control is or isn't double buffered.
Quote: |
As for GridCtrl scrolling problem, I think I know where to look and I think it is in CtrlDraw.cpp , but sample code would help, if possible..... (upload to ftp, please).
|
I will upload it today evenig - no problem.
|
|
|
|
Re: Should we double-buffer by default? [message #4076 is a reply to message #4053] |
Wed, 19 July 2006 15:04 |
mr_ped
Messages: 825 Registered: November 2005 Location: Czech Republic - Praha
|
Experienced Contributor |
|
|
There's another "span buffer" technique also as third option, but it's way too different from single/double buffer.
I was using it with my 2D parallax scrolling engine for one never released 2D shooter game, and it allowed me to do things like 10+ parallax layers with ~30 FPS on 133MHz in 640x480, but you gain performance only if lot of areas are redrawed, what IMHO doesn't seem like the case for ordinary GUI controls.
(except transparent controls, where the span buffer will help partially to detect everything hidden behind solid spans (if some controls do overlap), but in the end you will need to draw the solid background and than run as many passes again as many transparent spans are above the solid one, so there's no performance gain)
Another slight advantage is, that with span buffer you can refresh the content of window from top to down line by line, while double-buffering only single line being processed, so you need less memory on graphics card (1 frame buffer + 1 line), but again U++ is so far used on ordinary PC = plenty of memory. (maybe on PocketPC it can be more interesting option...)
But the main disadvantage is you must render everything with spans, so that would mean SW render of anything. Also antialiasing/cleartype would require lot of thinking and improving of the original simple span buffer. Manageable, but too complex.
One final note... I always use only "rectangle" during window resize, the "resize with content visible" always seems too slow for me.
|
|
|
Re: Should we double-buffer by default? [message #4079 is a reply to message #4071] |
Wed, 19 July 2006 16:25 |
|
luzr wrote on Wed, 19 July 2006 05:47 | Attempt to describe sibling Ctrl intersection problem:
You have opaque Ctrl (can be painted unbuffered) which is intersected by next sibling transparent Ctrl.
|
Lets be more precise. Saying sibling you mean child control or control placed somewhere next to this opaque control (but not involved into parent->child relation).
If you saying intersected you mean that a control is partialy coverd by another control or that another control lies inside a control placed below it or both cases?
Quote: |
(other part of this sibling Ctrl is above either parent Ctrl or worse, can be above ANOTHER opaque sibling)
|
Althought I think I understand it would be nice if you put some screenshot to ilustrate the problem.
Sorry for going so deep into details but I want to be sure that we are speaking the same language and I understand problem correctly.
[Updated on: Wed, 19 July 2006 16:26] Report message to a moderator
|
|
|
|
|
|
|
Goto Forum:
Current Time: Sat Apr 27 19:03:34 CEST 2024
Total time taken to generate the page: 0.02015 seconds
|
|
|