Unsolved Qt Text Rendering is extremely slow... any way to speed up?
-
On which os are you working ?
On OS X you can start XCode Developer Tool called Instruments (Time Profiler).
There you can exactly see whats is responsible for the slow execution time.On the first look i'm also @kshegunov opinion. Resizing the widget in the paint event should never be done !!
As he mentioned it causes implicit an update of your widget which then results in another paint event.
Did you get that ? In your case there are 3 times more paint events than normal (which of course makes the execution slower)So try it out...without the setMinimumSize and resize calls it will be faster !
-
Resizing the control is necessary because it is on a scrollable surface.
It may very well be necessary, but it shouldn't happen when drawing. Issue the resize from outside (i.e. the containing object) and in the
paintEvent
override only do the painting.Please explain to me how it is "terrible".
Nothing to do with the looks. Your code style is good and clearly understandable, your design choice is what I was referring to. From the short snippet you provided it appears you've jumped through all kinds of hoops to couple you objects up. For one, they all use something called
GlobalData
which is suspicious by itself. What's the reason for it? Why areCoordinates
painting, it doesn't make sense? AreCoordinates
coordinates, or are theyCoordinatesRenderer
, or something else? And whyCoordinates
have any knowledge that there's such a thing asLabMapWidget
?! Same reasoning for modes, a mode shouldn't care at all that there's such a thing as painting, much less do the painting ... -
@kshegunov
LOL. Ok. Now I get it. The reason for your objection is because you don't understand the nature of the application. FYI... this is NOT the big application I am talking about in my post in the general lounge about the commercial cost. This is a second major application that I decided to convert to C++ because that is the target language anyway.The purpose of this application is to come up with a very complex algorithm for creating realistic maps in a gaming environment. I am a "civfanatic" and a map "fetishist" (I have been obsessed with maps since I was bout 6-7 years old; I became the navigator for family trips are around 10.). I also was an Earth science teacher for 5 years. Here are the list of constraints I put on myself for this program after working with my first version in pure C#.
-
This version of application must be able to deal with more than one type of tile because of the up and coming release of Civ 6 (as well as Civ 5). Currently both squares and hexes are supported.. eventually I will hopefully introduce an ISEA (Isocohedral Equal Area) grid on a true spherical globe (made of a combination of hexes and pentagrams. A soccer ball is an example of a kind of ISEA grid. The "Cell Format" is the interface that deals with this particular aspect of the program.
-
"Modes" DO take care of the painting if that is the whole point of the "mode." Since much of what I am doing is based on intuition and trial and error in addition to research and my training, I need to be able to view a long list of points of data and be able to switch between them instantly; even superimpose them. (A few dozen already exist... think elevation, temperature, shore distance, precipitation, etc...). Superimposing the text itself is unlikely considering the time it would take... but I have already done it with color.
I decided to consolidate code by using a "data" class which is what I am referring to by mode. The "coordinates" data mode is the mod that is chosen when I need to see the plot coordinates on the screen. Before, adding new drawing/data modes was an annoyingly lengthy process that involved changing several sections of code (switch case statements etc...) I have simplified the process tremendously. All data points now inherit a template class interface that handles the retrieval of data (using a typed delegate/callback... hence the need for a template) and "rendering" it on the map. The class is fairly simple and only involves creating a constructor, a render method (that was originally stuck in at least one case in switch case statements), and adding a single line for creating the single class instance. "Main mode' refers to the primary data that is being colored. The "data mode" refers to the data being printed (or illustrated in the case of wind/current direction). Eventually I will add at least one more "secondary" mode that will be color blended with the primary mode.
- Global Data is a class of static/global data that needs to be shared with all classes.
Let me show you PART of an image exported by the previous version of the application to give you an idea of the nature of the program. Here is a strip from a world map image exported by the original program. The current "data mode' is global wind direction (with the size of the arrow based on relative wind speed). The current "main mode" (coloration) is plot type (blue = ocean, light blue = coast, green = plains, yellow = hills, orange = mountains). No mixing here so there is no secondary mode selected. Perhaps I should use another word besides "mode"... but hopefully you get the idea.
Just in case you are curious about details regarding the project, there are several threads I started on Civfanatics that revolve around this engine. The main one is here.
-
-
Interesting background ! That shed some lights for other suggestions. You should then maybe avoid doing it with widgets and go for the Graphics View framework. It looks like it should be more suited for your needs.
On a side note, maybe the Marble project could be of interest.
-
@SGaist
I remember you mentioning this or something similar when I was asking questions about combining views (i.e. "layers"; now that you have an understanding of the goal, I can be specific... I was talking about combining the primary/main view with the secondary and possibly more views).I will go ahead and give the framework a shot to see if text rendering is faster there.
-
@kshegunov and @euchkatzl
Yeah you're right about the resizing... bad idea. I am surprised it doesn't do a recursive call then. I don't think it will change the non-recursive number of times the paint method is called for a zoom in/out event but it was simply a bad move. -
@primem0ver said:
I am surprised it doesn't do a recursive call then.
Qt tries to be, and in many cases succeeds in being, smart about events (input and window events especially) and their dispatching. The paint event is not issued immediately but is put in the event queue and is also sometimes subject to compression.
-
@primem0ver said:
@SGaist
I remember you mentioning this or something similar when I was asking questions about combining views (i.e. "layers"; now that you have an understanding of the goal, I can be specific... I was talking about combining the primary/main view with the secondary and possibly more views).I will go ahead and give the framework a shot to see if text rendering is faster there.
Don't be too disappointed, though. Rendering of glyphs is a complex task, and neither Widgets nor GraphicsView makes use of the GPU or even multiple threads.
However, GraphicsView makes it pretty easy to cache painted items: Unless you change the text or looks of an item, there's no need to re-render the glyphs every time.
-
@Asperamanca so basically you're saying it won't change the text rendering speed? That would be rather annoying after spending a day and a half of changing my code to work with the graphics view. (Close to being done)
Another question that I have about the QGraphicsView. I need to change the way it detects zoom events. If the mouse is scrolled normally I want to scroll the picture down. If the shift is held down while the mouse is scrolled, THEN I want it to zoom.
-
@SGaist and everyone else interested...
The QGraphicsView does speed up drawing text enough that the control is usable in that regard. However, there are three issues with it (in order of importance).
- Scrolling horizontally causes white lines to appear, Not sure why. They appear to be made of cached text from the "text" layer of objects that are being drawn on top of the picture. They clear when I scroll vertically but unless I do that it makes the view unusable.
- It takes a substantial amount of time to create the view.
- It takes a horrendous amount of time to destruct the view.
I believe the time issue stems from the fact that there are so many objects to create and destroy (rather than simply drawing them manually).