I have a Qt application that is built around a QGraphicsView/Scene. The graphical performance is fine, animations are extremely smooth and a simple high res timer says the frames are drawing as fast as 400 fps. However, the application is always using 15% cpu according to task manager. I have run performance analysis on it in Visual Studio 2012 and it is showing that most of the samples are being taken in the QApplication::notify function.
I have set the viewport to render with a QGLWidget in hopes that offloading the drawing functions to the GPU would help, but that had no impact at all on CPU usage.
Is this normal? Is there something I can do to reduce CPU usage?
Well, there you have it - 400 FPS framerates. That loads one of your cores at 100%. There is a reason people usually cap framerates. The high framerates are putting a strain on the Qt event system which is driving the graphics.
Limit your frame rate to 60 FPS and problem solved.
I'm not updating the view unless an event occurs that updates an
individual graphicswidget
Do not update the scene for each and every scene element change. This is likely the cause of the overhead. You can make multiple scene item changes, but render the scene at a fixed rate.
Also, I notice you said graphicswidget - which I assume is QGraphicsWidget - this might be problematic too. QObject derived classes are a little on the heavy side, and the Qt event system comes with overheads too, which is the reason the regular QGraphicsItem is not QObject derived. If you use graphics widgets excessively, that might be a source of overhead, so see if you can get away with using the lighter QGraphicsItem class and some lighter mechanism to drive your scene.
Related
Actually I do have a big problem with performance in my game and also I have checked a lot of resources and I did what they said about this topic but unfortunately I still have a problem with that.
Also, I did all of these subjects below to solve my issue, but nothing happened
mapping(I set all of my GameObjects as static object)
re-size all of textures in the game
customize all of my Audio
used low poly objects in game
baking
checking profiler
on medium range phone frame rate is around 30-40 fps
also I de-active all of my objects in runtime (such as UI , 3D Models , Terrian and etc. ... ) just for testing to get know what the problem is ?
But the funny part is:
when I de-active them, my frame rate is still 35-45 FPS.
I'm really confused about that !!
update :
Also my game is for android platform
I uploaded some pictures of my game profiler
Cpu Profiler picture
Rendering Profiler picture
Cpu Timeline Profiler picture
Audio Profiler picture
UI Profiler picture
Physic Profiler picture
Global Illumination Profiler picture
The UWP version of our app runs with a much slower framerate (6 fps vs 24 fps) compared to the desktop equivalent. Note that both versions were tested on the same hardware.
Both versions are built using SharpDX, the only difference is how the RenderTargets are set up. The Windows app uses an HwndRenderTarget, and the UWP app uses a SurfaceImageSource brush that paints into a Rectangle.
We've narrowed the main culprit (on the CPU side at least) to FillGeometry, which consumes a lot of the time on UWP.
Is there a reason why FillGeometry would take much longer in the above UWP configuration compared to desktop?
Note: The rendering code is identical on both, so avoid suggestions which impact both implementations equally, such as using GeometryRealization instead of Geometry. We're looking for the reason for the difference between the rendering performance on UWP and desktop.
If there are factors other than Geometry that might be affecting performance, it would be useful to know those as well, since our profiling tools might not be altogether precise.
One of the factors seems to be that internal Direct2D clipping works differently in these cases.
Our scene has hundreds of geometries, and our initial code did not clip to the viewport, and relied instead on Direct2D doing the clipping. This resulted in the differences in frame rates mentioned in the original post.
When explicit clipping was added, the frame rate for the UWP version increased to around 16fps (still less than that of the desktop app) while the frame rate of the desktop version was not affected much.
So at this point it is a hypothesis that different clipping routines are at work in these two cases.
This isn't fully solved, as we still have a significant difference in frame rates. But it's a start.
I'm working with Cocos2d-x to port my PC game to Android.
For the sprites part, I wanted to optimize the rendering process so I decided to dynamically create sprites sheets that contain the frames for all the sprites.
Unfortunately, this makes the rendering process about 10-15 times slower than using small textures containing only the frames for the current sprite (on mobile device, on Windows everything runs smoothly).
I initially thought it could be related to the switching between the sheets (big textures like 4096*4096) when the rendering process would display one sprite from one sheet, then another from another sheet and so on... making a lot of switches between huge textures.
So I sorted the sprites before "putting" their frames in the sprites sheets, and I can confirm that the switches are now non-existent.
After a long investigation, profiling, tests etc... I finally found that one Open GL function takes all the time:
glBufferData(GL_ARRAY_BUFFER, sizeof(_quadVerts[0]) * _numberQuads * 4, _quadVerts, GL_DYNAMIC_DRAW);
Calling this function takes a long time (profiler says more than 20 ms per call) if I use the big texture, quite fast if I use small ones (about 2 ms).
I don't really know Open GL, I'm using it because Cocos2d-x uses it, and I'm not at ease to try to debug/optimize the engine because I really think they are far better than me for that :)
I might be misunderstanding something and I'm stuck on this since several days and I have no idea of what I can do now.
Any clues ?
Note: I'm talking about glBufferData but I have the same issue with glBindFramebuffer, very slow with big textures. I assume this is all the same topic.
Thanks
It is normally a costly call to do as glBufferData involves CPU to GPU transfer.
But the logic behind Renderer::drawBatchedQuads is to flush the quads that have been buffered in a temporary array. The more quads you have to render, the more data have to be transferred.
Since the quads properties (positions, texture, colors) are likely to change each frame, a CPU to GPU transfer is required every frame as hinted by the flag GL_DYNAMIC_DRAW.
According to specs:
GL_DYNAMIC_DRAW: The data store contents will be modified repeatedly and used many times as the source for GL drawing command.
There are possible alternatives to glBufferData such as glMapBuffer or glBufferSubData that could be used for comparison.
We built an application which uses QT WebEngine to test WebGL functionality, it worked however the CPU utilization was very high (>30%) for rendering some sine waveforms, the root file system was provided by QT Enterprise as described here for IMX6
http://doc.qt.digia.com/QtEnterpriseEmbedded/qtee-preparing-hardware-imx6sabresd.html
On inspecting the root file system we found that there were no GPU drivers (usually libVivante.so and libVivante.ko for IMX6), so it looks like all the GL rendering is being done by CPU instead of GPU and thats the reason for high CPU Utilization, Does anybody know any other ways to enable hardware acceleration for WebGL in the QT WebEngine?
Qt WebEngine requires hardware acceleration to composite the layers of the page and you would probably not be able to see anything on the screen without it.
Chromium, behind Qt WebEngine, is quite a beast and is more designed for perceived smoothness than to yield CPU cycles; it will use all the resources it can to achieve this.
Any JavaScript WebGL call will go from the main render thread, then to the GPU process main thread to be decoded into GL calls to the driver. Each different WebGL canvas will trigger a different FBO to be used and bound, requiring GL context switching, and as often as possible, the latest state will trigger the Chromium compositor to kick in, send all the delegated scene to the browser process, to finally end in QtQuick's scene graph thread to be composited.
All this to say that a single JavaScript WebGL call triggers a much bigger machine than just telling OpenGL to draw those geometries. A CPU usage of 30% on this kind of device doesn't seem anormal to me, though there might be a way to avoid bottle necks.
The most efficient this could get is by having a custom QtQuick Scene Graph geometry as shown in this example: http://qt-project.org/doc/qt-5/qtquick-scenegraph-customgeometry-example.html, but even then I wouldn't expect a CPU usage under 10% on that device.
I am developing a small game for Windows Phone which is based on silverlight animation.
Some animations are using silverlight animation framework like Trandforms API and some animations are frame based. What I am doing is, I am running a Storyboard having very small duration and when it;s completed event fires, I am changing image frame there. So images get replaced every time completed event get fired. But I think it is causing memory leakage in my game and memory footprint is increasing with time.
I want to ask is it a right way to do frame base animations or is there any better way to do this in silverlight???
What I can do to reduce memory consumption so that it does not increase with time.
As a general rule, beware animating anything which can't be GPU accelerated or bitmap cached. You haven't given enough information to tell if this is your issue but start by monitoring the frame rate counters, redraw regions and cache visualisation.
You can detect memory leaks with the built in profiling tools.
See DEBUG > Start Windows Phone Application Analysis