I'm using three different QGLWidgets in the same main thread, preferably rendered at 60fps but I cannot achieve more than 20fps. It seems that this is caused by Vsync as each widget probably tries to synchronize with the refresh rate independently and therefore they lock somehow. If I only use two widgets I achieve 30fps. Or if I fix the update rate of one widget to, let's say 10fps, I reach 25fps on the others (10+25+25=60). swapInterval() always returns 0, independent of the value I set with setSwapInterval(int). Any ideas? Can I disable Vsync? Or might the problem be caused by something different?
It seems that its currently the bug from Qt 5.0 - https://bugreports.qt.io/browse/QTBUG-29073
Turning the Vsync off will solve the problem with dividing update rate between QGLWidgets, your graphics card will render to screen as fast as you tell it to or as fast as it can. But you must disable the VSync in graphics card settings. Just setting fmt.setSwapInterval(0) will do nothing.
Unfortunately another problem raises, if you are painting video that contains horizontal moves, tearing will appear.
Hopefully the Qt 5.3 shall fix this bug.
For those who are still struggling with this issue, my short answer is: before trying anything else: install Qt 5.4.
Longer answer:
I never had any issue to disable VSync with Qt 4.8.
Using Qt 5.3.1 (in Kubuntu 14.04 64bit), I have never been able to force my QGLWidget not to sync at VBlank, which means that swapBuffers() was blocking no matter what. I disabled VSync both in the "Desktop effect" panel and the NVidia control panel, and setSwapInterval(0) to no avail. Therefore my fps have always been clamped to 60fps/numOfQGLWidget (unless I used SingleBuffering, but the flickering was not tolerable in my applications). Using multi-threading, it should theoretically be possible to have VSync enabled (hence no tearing), and achieve 60fps for multiple QGLWidget, but I failed to have that working as well.
Today, I just installed Qt 5.4, and it magically solved the issue: I can successfully have a non-blocking swapBuffers(), as I used to in Qt 4.8. I think Qt 5.3 forced VSync somehow no matter what you driver settings were. But it is no longer the case in Qt 5.4, at least in my configuration. It seemed the Qt team did a lot of work to improve OpenGL for Qt 5.4 (notably, they introduced the QOpenGLWidget class), so my advice to anyone using OpenGL with Qt would be to make the update to Qt 5.4, it will likely make your life easier.
Related
I'm trying to get Qt and EGL to work together. I'm working on a program that uses EGL to draw, and I have to use Qt to create a GUI overlay.
The current solution was to turn a QWidget into a native window, and pass it's window handle to EGL. This works, but it's difficult to work with. Qt isn't aware that the widget is being drawn in by something else. So when another widget is overlaid, even if it's transparent, the image drawn by EGL is erased. The only way to get them to work is if I jigsaw the buttons and other GUI elements in a way that they don't overlap the parts of the native window I want to show. However this means that I can't use layouts or QML or any of the tools that would make creating different GUIs easy.
So my question is, how can I draw with EGL into Qt in a more usable way.
I'm working with Qt 5.4.2 by the way. If absolutely necessary, I might be able to upgrade to 5.5, but newer versions won't work.
I was looking into QOpenGLContext, and ways to make it use the context created by EGL, but I can't seem to find any good examples on how to actually go about doing this.
Other than trying to manually, re-write everything to mimic the tooblar graphics and the size transition animation when moving between pages, Is there a better way to do this?
Amazingly I can't find ANY resources covering this, or even someone asking for this.
http://qt-project.org/doc/qt-5.1/qtwidgets/qtwidgets-index.html#styles
The window animations may already work as is... You may want to specify Native Windowing, so that the Mac Windowing system is aware of your Qt windows:
http://qt-project.org/doc/qt-5.1/qtwidgets/qwidget.html#native-widgets-vs-alien-widgets
Native Widgets vs Alien Widgets
Introduced in Qt 4.4, alien widgets
are widgets unknown to the windowing system. They do not have a native
window handle associated with them. This feature significantly speeds
up widget painting, resizing, and removes flicker. Should you require
the old behavior with native windows, you can choose one of the
following options:
Use the QT_USE_NATIVE_WINDOWS=1 in your
environment.
Set the Qt::AA_NativeWindows attribute on your
application. All widgets will be native widgets.
Set the
Qt::WA_NativeWindow attribute on widgets: The widget itself and all of
its ancestors will become native (unless
Qt::WA_DontCreateNativeAncestors is set).
Call QWidget::winId to
enforce a native window (this implies 3).
Set the Qt::WA_PaintOnScreen
attribute to enforce a native window (this implies 3).
See also
QEvent, QPainter, QGridLayout, and QBoxLayout.
And this link has more information on the styling in Qt than I have ever seen before today!
http://qt-project.org/doc/qt-5.1/qtwidgets/style-reference.html
Hope that helps.
I have a Qwidget inside of which, I have multiple children in the form of QmlApplicationViewer objects, each pointing to a different qml file.
Problem is, when I use mouse, all the qml files take events, but when I try to use the touch screen, only some of them does.
Can someone give a direction as to where the problem might be ? Will appreciate and sort of possible causes which might cause this issue.
Platform : Ubuntu 12.04 - Qt 4.8 - 32 bit
There really is not enough information here to even begin to answer this question. The most obvious answer that comes to mind is some of your qml files are not correctly defining the TouchArea within the qml. If you want more help you need to post code.
I tried using the EG-Touch touch drivers for my platform, which are supposed to have some issues on 12.04(as per some forums). I reverted back to Ubuntu 11.04 and used the e-Galax touch drivers instead, and things are working fine now.
P.S. : If someone finds a working driver for 12.04 or any other work around, please update. I will accept a better answer. Closing this for now.
I work on a QML-based UI where some elements are implemented in C++ plugin.
Everything worked fine so far in WinXP 32bit and Win7 32bit. Last week I got new laptop with Win7 64bit on board, and my code does not work properly there. Several seconds after start-up application behaves nicely, but then suddenly view stops redrawing. Neither QML-initiated events, nor plug-in calls to QDeclarativeItem::update() work. In plugin I am 100% sure that update() is called, but then I know, that calls to overriden QGraphicsItem::paint() do not happen as expected. The view only gets redrawn when window gets/looses focus.
I have quickly verified my application on a desktop running Win7 and had no problems there. This leads my to suspect that there is something different about how Windows 7 requests window update on my laptop and on other computers, however I am unable to figure out the difference right now.
Can someone help me out to understand what is going on there?
Thanks in advance!
p.s. Unfortunately my primitive mock-ups did not exhibit same problem, and I cannot share production code. If I will find a way to reproduce this problem in a prototype before actual solution will be found, I will post it.
Add a qapp->processEvents() after your update() call, it will probably work.
(I've come across a similar problem, but it happens on all platforms, hopefully this solution will work for you)
The answer to my question lays in something I overlooked initially in my problem description. The QDeclarativeItem::update() function was called from a non-Qt thread (certainly not GUI thread). I re-routed the call through Qt event loop and the problem was gone.
I was on Qt 4.7/4.8 at that time and cannot say how it'd behave in Qt 5.x.
I have enabled qt+OpenGl+SimpleGl on one of the ARM platform and was able to run opengl example programs.
I also has a qt+Webkit, which is working with a graphic plugin.
I wanted to use simpleGl context for every thing, instead of using the normal graphic screen. So, when I try to run Qt+Webkit with simpleGl, I just get a blank screen.
Does QT support this? If so how can we make it?
Yes, this is correct. OpenGL draws directly to the framebuffer. The simplegl driver doesn't handle what is drawn using the raster paint engine of the QWS, so you may see only black.
Using simplegl for "everything" means you want everything to be drawn using OpenGL in your EGL full-screen window? This is possible under some assumptions. You have to write all your applications to be rendered using the Qt OpenGL paint engine (using the opengl graphics system is not supported under Qt/E). This is possible also for QtWebKit, I'm doing it now. Note that this does not mean that everything is rendered using hardware acceleration. You'll have to write your applications "the right way" to get all actually hardware accelerated. Consider that you'll have to handle the mouse pointer some other way in this case.
The other way is to just modify the simplegl driver to allow for the use of Qt applications using the raster paint engine. This is possible as well with some limitations. Qt can use blit to place its own windows over OpenGL. Look for the framebuffer driver inside the Qt source tree to know how to do this. You can then have common Qt applications and OpenGL Qt applications some way. I'm doing this as well. Not everything can be done anyway.
EDIT: I'm sure you already did, but in case, give this http://doc.qt.io/qt-4.8/qt-embeddedlinux-opengl.html much attention.
Unfortunately I don't know anything about SimpleGL, but I do know that there is a way to render a standard Qt widget in a QGLWidget. Maybe have a look at this Qt Quarterly which I think is somewhat related to your question:
http://doc.qt.nokia.com/qq/qq26-openglcanvas.html