PDA

View Full Version : Advice for sharing "contexts" - VBO/PBO/FBO ?



funkmenera
03-30-2009, 01:32 PM
Hi @ all !

First of all, i should mention that i use QT for coding my C/C++ application, because maybe it has sth. to do with the following issue(s).

The point is that i must use several widgets/contexts/windows at the same time. (These windows contain live video streams, 2D- and 3D Plots, etc ...)
But in one "final" MAINwindow the contents of (nearly) all other windows should appear.


The first approach was to use PixelBuffers - the QT-implementation ( just mentioning because i wonder if it makes a difference ? )
So, i created a PixelBuffer for each widget/context and let these PBuffers update the corresponding texture (size=[512, 512]) in a shared Context, the MAINwindow.
On a Core2Duo with a Geforce8800 and Ubuntu that worked - allthough the CPU-usage was pretty high ~50%

But on a Laptop (Core2Duo, Geforce7600Go and with WinXp) it was ... unusable


The second approach was about using Framebuffers. Just the same way as with PBOs. (I think *scapingMyHead* i only gave it a try on the Laptop - with no better result)


Then i thought about not creating a texture to display in the MAINwindow, but passing it some displaylists.
But that's a no go, as the displaylists have to be calculated again and again ... as the data/vertices and stuff change from frame to frame


So, my last approach was to create VBOs (=Vertex Buffer Objects) and pass them, respectivly the identifier of the VBOs to the MAINwindow.

And that's now where I'am stuck ....

After adding glew and having some trouble ... I managed to get it runnning and did a test, to see how far i can go ...
Basically I draw the same VBO ten times at different positions in the scene and the CPU-usage increased to ~60%.
Further i also tried to create and draw ten VBOs with the same data but independent memory - same result
Note: to draw the VBO only once in a scene the CPU-usage was ~0%

I wonder if this a typical behaviour, or if i might do sthg. wrong ?
The VBO is not big .. ~0,2 MB (for ~4000 Vertices)



To make it short: Could anybody please give me an advice of <u>how to draw the contents of several widgets/windows/contexts additionally to there origin windows in a MAINwindow ?</u> - in the fastest and less exhausting way ?!



Hope it got clear what i mean ... if not, please just ask
kind regards,
funki

Dark Photon
04-01-2009, 06:04 AM
It's not at all obvious what you're tripping over. In some parts it sounds like it's some Qtism. In others, that you don't understand FBOs. In others that you're not sure how viewport rendering works.

If you just want to get something up and working, upload a frame of your video to a texture, then render with that texture into a sub-portion of your main window. Rinse. Repeat.

Then you can optimize more for speed. PBOs, maybe shared texture, etc.

funkmenera
04-01-2009, 11:51 AM
Thanks a lot for your reply !

Well, you're right - was a little bit confusing
and yes, i'm not sure what the difference between FBOs and PBOs is ...


I try to make my problem clearer

The point is, as mentioned above, that i want to make the content of some windows of my app visible in another window - the main window.

So the most pleasing result would be to create textures from the visible windows and bind that textures to quads in the scene of the main window.
Therefore i tried to use PBOs - would FBOs be faster for this scenario ?

And the thing with VBOs ... it just was a try, as i didn't get the performance out of my app which i want/need.
Nevertheless i understand that the VBO objects would then be drawn as 3D-Objects ... which lookes in some cases funny/nice - and in others disturbing


So, yesterday i figured out that when i stop painting the horde of windows - but still render to textures using PBOs - i get an performance increasement.
Just meaning that the animation in the main window runs much smoother compared to drawing all windows and all textures.


Therefore i guess the whole mess has something to do with context switching ?!
Or maybe with the way OpenGL is used by the Trolls of QT ?
That brings me to another point i would like to know, as g^^gle isn't my friend in this case. Is there .. or how big is the performance difference between QT and GLUT or other APIs ?

Dark Photon
04-02-2009, 12:35 PM
i'm not sure what the difference between FBOs and PBOs is ...

FBOs - Useful for off-screen rendering (to a texture or renderbuffer)
PBOs - Useful for fast texture uploads to the GPU, or downloads of texture data from the GPU

Sounds like you could render your images to textures (using an FBO), then do multiple renders of those textures, one to each window. OR, you could render to one window, then copy the pixels from the framebuffer into a texture and re-render with that texture into the other window. Both of those could work. What your resolution and antialiasing requirements are might push you toward one or the other.

funkmenera
04-06-2009, 05:07 AM
I gave the FBOs a try - and it works !
At least on one machine - Core2Duo + GeForce 8800GT on Ubuntu
But on my laptop - Core2Duo + Gefroce7600Go + WinXp it doesn't. Seems to me like the driver supports only one FBO ? is that possible ?
And on a third machine - Core2Duo + Quadro(sth.) on Suse 10.2 it works again :D but with a to high cpu-load (nearly 100% of one core) comparde to the other linux machine on which my programm only needs ~20%


So, first of all thanks a lot for the advice !

But as one can guess, i have further questions

First: Why is the "result" on other machines so different ?
Driver issues ? Hardware facts ? OR ... ?

Second: I experience more or less changes in the visual appearence of the contexts - meaning that sometimes the rendering in one window seems to be affected by the values (=GL state variables) set in an other window. So I wonder if there is a way of avoiding that ? Something like setting all values to default at the beginning of a render ? Or should/must i use glPushAttrib ? Or maybe i have to use "mutex"s in order to keep all clean and separated ?

Third: I should explain my current approach
Each widget/windwo/class gets aaccess to a public FBO in the main window class. Eh, voila! the sub-windows/widgets can render to the FBOs in the main window.
If the widget has a own window, the paintGL() function gets called periodically.

Maybe i should try the other approach and call paintGL() wether or not there's a window - to fill the framebuffer of that widget and create a texture from it ...

What would be more advisable when using Antialiasing ?


Further i would like to know, if it's possible to check or estimate how much FBOs are possible ? Rather when do they work and when not ?

Or should i try to make "native GL" instead of using QT's OpenGL abilities for better performance and reliability ?


So, thanks again and i appreciate the time for answering me !
kind regards, funki

Dark Photon
04-06-2009, 04:24 PM
...Core2Duo + GeForce 8800GT on Ubuntu [works]...Core2Duo + Gefroce7600Go + WinXp it doesn't...Core2Duo + Quadro(sth.) ...high cpu-load...

Odd. I only dev GeForce on Linux so I can't help you much with the MSWindow'isms and Quadro'isms. I have heard Win folks on this forum speak about perf quirks with NVidia's multithread driver. The recommendation IIRC was to set "threaded optimization" to OFF in the NVidia control panel and see if that solves it.


...sometimes the rendering in one window seems to be affected by the values (=GL state variables) set in an other window.
Might not be binding your contexts at the right time? But yes, you're responsible for managing the current GL state for each context and making sure it's in the right state before rendering. As you said, glPushAttrib (while slow) can help you debug that.


What would be more advisable when using Antialiasing ?
Depends on what kind you need, if any. You might not. Do you need better geometry resolution (probably not since you're rendering video...)? If so, you can allocate a multisample offscreen render target (GL_framebuffer_multisample), render to it with an FBO, downsample that to a single sample texture (GL_framebuffer_multisample_blit), and then render with that.


Further i would like to know, if it's possible to check or estimate how much FBOs are possible ? Rather when do they work and when not ?
You mean, what texture formats you can render to using an FBO? If so, here's one tool (http://www.vis.uni-stuttgart.de/~klein/fboCheckSupported.tar.gz) I packratted a link to years ago. 'course, you can code something like this up yourself without much trouble too.


Or should i try to make "native GL" instead of using QT's
OpenGL abilities for better performance and reliability ?
Depends. Unless I misunderstand, you're just using Qt to allocate a GL drawable and to manage calling your "paint" method for you, and using it to provide a pretty GUI around the video windows. Nothing I've heard suggests trying to get rid of Qt yet.

funkmenera
04-07-2009, 12:25 PM
Hi ! :)

Well, the thing on Windows was really due to the driver settings. So, thank you very much Mr. Photon for presenting this solution :D
The change was from ~30% cpuload to ~3% !

The thing with the state variables ...
OK, in future i will pay attention ;)
But just one last question concerning that point. May Displaylists influence that behaviour in a unforeseen way ?

And Antialiasing - thanks for the hints ! I will hav a closer look when all is going nice and easy - without antialiasing
But, i'm not only rendering video. In addition i have some 2D-Plots and a 3D-Scene ...


And get rid of QT ? - i don't know - i need it ;) - it's great :D

At the beginning i created several FBOs -twenty at total- with QT.
Then i read somewhere that it's faster to attach a different texture to a FBO, instead of creating/using an other/new FBO.
So i tried this "one FBO way" - first with QT, with which i had no luck and then with "native GL calls" and that worked !

So with this and the driver setup - Windows is close to become a friend (again) - but at the moment i admire Linux ;)


Maybe one last question ?
I know it doesn't really belongs to this thread and there may be a lot of solutions out there.
Nevertheless, i hope to get further hints from a pro no need for a complete solution - just the direction, allthough a complete solution would be nice.
Furthermore this problem is rather QT-specific or Windows-specific, so i maybe should go and read somewhere else :(
Now the point itself ...
The resolution of QTimer(s) is not so good. As a result i had in a project framerates from ~10Hz to ~120Hz, though the content was always the same ... well not completly, but the effort for calculating things in the scene were the same.

So i wonder ... how can i achieve constant framerates ?
with threads ?
Or is there an other way ?
this one ->
http://apsy.gse.uni-magdeburg.de/main/index.psp?sec=1&page=hanke/threadedcube&lang=de
looks like what i searched for ... just wonder if it works with sharing contexts ...

Except this last point, all is done and i'd like to thank you DarkPhoton for helping me out !

Keep on doing this !

Dark Photon
04-08-2009, 03:47 PM
So i wonder ... how can i achieve constant framerates ?

The traditional way is to let the OpenGL driver (specifically the OpenGL window manager API -- glX on Linux, wgl on Windows) gate your redraw loop for you. That is, you leave "sync to vblank" enabled, and essentially when you call glXSwapBuffers (or whatever the wgl analog is -- wglSwapBuffers), then the driver will wait until the next vertical retrace and then swap. If you always take less than this amount of time to render a scene, then magically it appears that your drawing always takes 60Hz, 72Hz, or whatever the vertical retrace interval of your monitor is.

So just let the driver do this. As a bonus, if you do this you don't get nasty tearing artifacts.