SFML Drawing OpenGL to multiple windows extremely slow - c++

Here is the situation:
I have 4 SFML windows, which are inside a container which I have built. The container calls independent redraw methods for each window, starting with the first and ending with the last.
If each window's drawing code contains the lines drawMyCube() OR glClear(...), then the frame rate becomes slow.
drawMyCube() just draws a cube which rotates depending on the value of an sf::Clock object.
If one window calls (either of) these functions, the frame rate is ~60fps.
If two windows call (either of) these functions, the frame rate is ~30fps.
If three windows call (either of) these functions, the frame rate is ~20fps.
Finally, if all four call (either of) these functions, the frame rate is ~15fps.
This looks like a pattern emerging, so I tried removing the functions from 3 of the windows, and calling them 10 times from one window. I was expecting the frame rate to be ~6fps, but it remained at 60.
Does anyone know why this is happening? There doesn't seem to be any effect if I remove any other functions from the window drawing methods, for example, gluLookAt() doesn't seem to slow it down.
EDIT: Frame rate limit is set to zero and vsync is false.

This sounds exactly like vertical sync. Each of your windows is waiting for vertical refresh, which is why your rate keeps getting cut in half.
I know you said that vsync is off, but it's possible that your video driver is forcing it. Check your driver settings.

Related

How to prevent screen tearing with OpenGL + GLFW?

I am working on a graphical application that supports multiple operating systems and graphical back ends. The window is created with GLFW and the graphics API is chosen at runtime. When running the program on windows and using OpenGL, Vsync seems to be broken. The frame rate is locked at 60 fps, however, screen tearing artifacts appear. Following GLFW documentation, glfwSwapInterval(0); should unlock the frame rate from the default of using VSync. That works as expected. Using glfwSwapInterval(1); should lock the frame rate to match the monitors refresh rate. Not calling glfwSwapInterval(); at all should default to using VSync. While frame rate is correcly locked / unlocked using these calls, I experienced extremely interesting behaviours.
When glfwSwapInterval(); isn't called at all, VSync is set as default. But the wait for the next frame happens at the first draw call! One would think that the delay for the next frame would happen at glfwSwapBuffers(). No screen artifacts are visible what so ever.
When calling glfwSwapInterval(1);, Vsync is set and the delay for the next frame happens at glfwSwapBuffers()! That's great, however, when explicitly setting VSync, screen tearing artifacts appear.
Right now, not calling glfwSwapInterval() for using VSync seems to be a hacky solution, but :
The user wouldn't be able to disable VSync without window reconstruction,
The profiler identifies the first draw call taking way too long, as VSync wait time is somehow happening there.
I have tried fiddling with GPU driver settings and testing the code on multiple machines. The problem is persistent across machines if using windows and OpenGL.
If anyone can make any sense of this, please share, or if I am misunderstanding something, I would greatly appreciate some pointers in the right direction.
EDIT:
Some other detail: the tearing happens at a specific horizontal line. The rest of the frame seems to work properly.
After doing some more tests, it seems that everything is working as intended on integrated graphics. Correct me if I am wrong, but it looks like it is a graphics driver issue.

OpenGL: How to minimize drawing?

My OpenGL screen consists of 2 triangles and 1 texture, nothing else. I'd like to update the screen as little as possible, to save power and limit CPU/GPU usage. Unfortunately, when my draw_scene routine returns early without drawing anything, the OpenGL screen goes black-- even if I never call glutSwapBuffers. My background color is not black by the way. It seems that if I do not draw, the OpenGL window loses its contents. How can I minimize the amount of drawing that is done?
Modern graphics systems assume, that when a redraw is initiated, that the whole contents are redrawn. Furthermore, if you get a redraw event from the graphics system, then that's usually because the contents of the window have become undefined and need to be recreated, so you must redraw in that situation.
To save power you have to disable the idle loop (or just pass over everything that does and immediately yield back to the OS scheduler) and don't have timers create events.

How to display smooth video in FireMonkey (FMX, FM3)?

Has anyone figured out how to display smooth video (i.e. a series of bitmaps) in a FireMonkey application, HD or 3D? In VCL you could write to a canvas from a thread and this would work perfectly, but this does not work in FMX. To make things worse, the apparently only reliable way is to use TImage, and that seems to be updated from the main thread (open a menu and video freezes temporarily). All EMB examples I could find all either write to TImage from the main thread, or use Synchronize(). These limitations make FMX unusable for decent video display so I am looking for a hack or possibly bypass of FMX. I use XE5/C++ but welcome any suggestions. Target OS is both Windows 7+ & OS X. Thanks!
How about putting a TPaintbox on your form to hold the video. In the OnPaint method you simply draw the next frame to the paintbox canvas. Now put a TTimer on the form, set the interval to the frame rate required. In the OnTimer event for the timer just write paintbox1.repaint
This should give you regular frames no matter what else the program is doing.
For extra safety, you could increment a frame number in the OnTimer event. Now in the paintbox paint method you know which frame to paint. This means you won't jump frames if something else calls the paint method as well as the timer - you will just end up repainting the same frame for the extra call to OnPaint.
I use this for marching ants selections although I go one step further and use an overlaid canvas so I can draw independently to the selection and the underlying paintbox canvas to remove the need to repaint the main canvas when the selection changes. That requires calls to API but I guess you won't need it unless you are doing videos with a transparent colour.
Further research, including some talks with the Itinerant developer, has unfortunately made it clear that, due to concurrency restrictions, FM has been designed so that all GPU access goes through the main thread and therefore painting will always be limited. As a result I have decided FM is not suitable for my needs and I am re-evaluating my options.

OpenGL window draws fine, but all the windows on top of my OpenGL window go black

I have an app that mixes OpenGL with Motif. The big main window that has OpenGL in it redraws fine. But, the sub windows sitting on top of it all go black. Specifically, just the parts of those subwindows that are right on top of the main window. Those subwindows all have just Motif code in them (except for one).
The app doesn't freeze up or dump core. Data is still flowing, and as text fields, etcetera of various subwindows get updated, those parts redraw. Dragging windows across each other or minimizing/unminimizing also trigger redraws. The timing of the "blackout" is random. I run the same 1-hour dataset every time and sometimes the blackout happens 5 minutes into the run and sometimes 30 minutes in, etc.
I went through the process of turning off sections of code until the problem stopped. Narrowed it down more and more and found it had to do with the use of the depth buffer. In other words, when I comment out the glEnable(GL_ENABLE_DEPTH_TEST), the problem goes away. So the problem seems to have something do with the use of the depth buffer.
As far as I can tell, the depth buffer is being cleared before redrawing is done, as it should. There's if-statements wrapped around the glClear calls, so I put messages in there and confirmed that the glClear of the depth buffer is indeed happening even when the blackout happens. Also, glGetError didn't return anything.
UPDATE 6/30/2014
Looks like there's still at least one person looking at this (thanks, UltraJoe). If I remember correctly, it turned out that it was sometimes swapping buffers without first defining the back buffer and drawing anything to it. It wasn't obvious to me before because it's such a long routine. There were some other minor things I had to clean-up, but I think that was the main cause.
How did you create the OpenGL window/context. Did you just get the X11 Window handle of your Motif main window and created the OpenGL context on that one? Or did you create a own subwindow within that Motif window for OpenGL?
You should not use any window managed by a toolkit directly, unless this was some widget for exclusive OpenGL use. The reason is, that most toolkits don't create a own sub-window for each an every element and also reuse parts of their graphics resources.
Thus you should create a own sub-window for OpenGL, and maybe a further subwindow using glXCreateWindow as well.
This is an old question, I know, but the answer may help someone else.
This sounds like you're selecting a bad visual for your OpenGL window, or you're creating a new colormap that's overriding the default. If at all possible, choose a DirectColor 24-plane visual for everything in your application. DirectColor visuals use read-only color cells, but 24 planes will allow every supported color to be available to every window without having to overwrite color cells.

Poor performance with DrawText on Win7 x64

I noticed in an MFC application I'm developing that while dragging the scroll bar to smoothly scroll down the document, the framerate drops to choppy levels when a block containing about a paragraph of text is on screen, but silky smooth when it's offscreen. Investigating the performance, I found the single CDC::DrawText call for the paragraph of text responsible. This is in an optimised release build.
I used QueryPerformanceCounter to get a high-resolution measurement of just the DrawText call, like this:
QueryPerformanceCounter(...);
pDC->DrawText(some_cstring, some_crect, DT_WORDBREAK);
QueryPerformanceCounter(...);
The text is unicode, lorem-ipsum style filler, 865 characters long and wraps over 7-and-a-bit lines given the rectangle and font (Segoe UI, lfHeight = -12, a standard body text size). From my measurements, that call alone takes on average 7.5 ms, with the odd peak at 21ms. (Note to keep up with a 60Hz monitor you get about 16ms to render each update.)
I tried making some changes to improve the performance:
Removing the DT_WORDBREAK improves performance to about 1ms (about 7 times faster), but given only one line of text is making it to the screen, and there were just over 7 lines with word breaking, this seems to suggest to me the bottleneck is elsewhere.
I was drawing text in transparent mode (SetBkMode(TRANSPARENT)). So I tried opaque mode with a solid background fill. No improvement.
I thought ClearType rendering might be to blame. I changed the font lfQuality from CLEARTYPE_QUALITY to NONANTIALIASED_QUALITY. It looked like crap with sharp edges and all, and no improvement.
As per a comment suggestion, I was using a CMemDC, but I got rid of it and did direct drawing. It flickered like mad, and no improvement.
This is running on a Windows 7 64-bit laptop with an Intel Core 2 Duo P8400 # 2.26 GHz and 4 GB RAM - I don't think it counts as a slow system.
I'm calling DrawText() every time it draws and this obviously hammers the performance with such a slow function, especially if several of those text-blocks are visible at once. It's enough to make the experience feel sluggish. However, Firefox can render a page like this one in ClearType with much more text, and seems to cope just fine. What am I doing wrong? How can I get around the poor performance of an actual DrawText call?
Drawing the text at every refresh is wasteful. Use double buffering, that is, draw in an offscreen bitmap and just blit it to the screen. Then, for scrolling, just copy most of the bitmap up or down or sideways as necessary, then draw only the invalidated area (before blitting the result to the screen).
If even that turns out to be too slow, keep also the drawn text in an off-screen bitmap, and blit instead of draw.
Cheers & hth.,
According to this german blogpost, the issue has to do with support for asian language fonts. If you enable those in XP you get the same perf hit. In Vista/7, they are default enabled and you can't turn them off.
EDIT: Just maybe, using a different font might help.. (one that does not contain asian characters).
Users can't read text at 7 lines in 7 milliseconds, so the call itself is fast enough.
The 60 Hz refresh rate of the monitor is entirely irrelevant. You don't need to re-render the same text for every frame. The videocard will happily send the same pixels to the screen again.
So, I thibk you have another problem. Are you perhaps wondering about scrolling text? Please ask about the problem you really have, instead of assuming DrawText is the culprit.
In order to break the text on word breaks, DrawText needs to repeatedly try to get the width of a block of text to see if it will fit, then take the remainder and do it over. It will need to do this at every call. If your text is unchanging, this is an unnecessary overhead. As a workaround, you could measure the text yourself and insert temporary line breaks and remove the DT_WORDBREAK flag.
Have you considered Direct2D/DirectWrite?
Anyway it should work better if you just draw the text once to its own mem dc and blit that over to whatever dc you want it painted on with each iteration.