Multiple Qt widgets depicting different OpenSceneGraph nodes without performance loss - c++

We are currently facing the following problem: We have an application that needs to display a multitude of separate OpenSceneGraph scenes in different Qt widgets. For example, we might have one Qt widget depicting a sphere, while another widget depicts an icosahedron. Since we are using OpenSceneGraph 3.0.1, we followed the osgViewerQt example from the official documentation for implementing this.
The example code uses a QTimer in order to force updates for the viewer widget:
connect( &_timer, SIGNAL(timeout()), this, SLOT(update()) );
_timer.start( 10 );
The problems now begin when we want to create and show multiple widgets. Since each widget comes with its own timer, performance rapidly decreases with the number of open widgets. Not only is the interaction with the OSG widgets very slow, also the interaction with other Qt widgets noticeably lags. Even a halfway recent quad-core system is almost overwhelmed when approximately 5 windows are open. This issue is definitely not related to our graphics hardware. Other applications may render much larger scenes (Blender, Meshlab etc.) without any negative performance impact.
So, to summarize: What would be the best way of creating multiple Qt widgets showing different OpenSceneGraph scenes without a performance impact?
What we already tried:
We already considered using a single osgViewer::CompositeViewer for
rendering all scene objects. However, we discarded this idea for
now because it will probably make interactions with a single widget
very complicated.
We tried putting the rendering portion of each osgViewer::CompositeViewer in a separate thread as detailed by the osgQtWidgets example.
Our second try (using threads) looked roughly like this:
class ViewerFrameThread : public OpenThreads::Thread
{
public:
ViewerFrameThread(osgViewer::ViewerBase* viewerBase):
_viewerBase(viewerBase) {}
~ViewerFrameThread()
{
cancel();
while(isRunning())
{
OpenThreads::Thread::YieldCurrentThread();
}
}
int cancel()
{
_viewerBase->setDone(true);
return 0;
}
void run()
{
int result = _viewerBase->run();
}
osg::ref_ptr<osgViewer::ViewerBase> _viewerBase;
};
However, this also resulted in a remarkable performance decrease. Each thread still requires much CPU time (which is not surprising as the basic interaction is still handled with a timer). The only advantage of this approach is that at least interaction with other Qt widgets remain possible.
The ideal solution for us would be a widget that only fires redraw requests whenever the user interacts with it, for example by clicking, double-clicking, scrolling etc. More precisely, this widget should remain idle until there is a need for an update. Is something akin to this possible at all? We would welcome any suggestions.

Having tried out several models for this problem, I am happy to report that I found one that is working perfectly. I am using a QThread (similar to the thread described above) that essentially wraps an osgViewer::ViewerBase object and simply calls viewer->run().
The trick to keep CPU usage low is to force OpenSceneGraph to render on demand only. Having tried out the various options, I found the following two settings to work best:
viewer->setRunFrameScheme( osgViewer::ViewerBase::ON_DEMAND );
viewer->setThreadingModel( osgViewer::ViewerBase::CullDrawThreadPerContext );
A viewer that is modified like this will not use spurious CPU cycles for continuous updates while still using multiple threads for culling and drawing. Other threading models might of course perform better in some cases, but for me, this was sufficient.
If any one else attempts a similar solution, be warned that some operations now require explicit redraw requests. For example, when handling interactions with OSG objects or when you are writing your own CameraManipulator class, it doesn't hurt to call viewer->requestRedraw() after changing viewer settings. Else, the viewer will only refresh when the widget requires a repaint.
In short, here's what I learned:
Don't use timers for rendering
Don't give up on multiple threads just yet
Nothing beats reading the source code (the official OSG examples were sometimes scarce on details, but the source never lies...)

It should be possible. I can't believe they used a timer running at 100Hz to update the widgets -- it's really not the right way to do it.
I don't know about OSG's architecture, but you need to figure a way to obtain a callback from OSG when the data has been changed. In the callback, you simply queue an update event to the appropriate widget like so:
void OSGCallbackForWidgetA()
{
QCoreApplication::postEvent(widgetA, new QEvent(QEvent::UpdateRequest),
Qt::LowEventPriority);
}
This callback code is thread safe and you can invoke it in any thread, whether it has been started by QThread or not. The event will be compressed, that means that it acts like a flag. Posting it sets the flag, and the flag will be reset when the widget finishes with the update. Posting it multiple times when the update is pending does not add any events to the event queue, and does not imply multiple updates.

I met similar problem when I have multiple OSG viewers in one Qt application, where one of them works well, while the rest are very "slow".
By turning on the rendering stats (press "s" on the viewer), I found that the "slow" actually is not caused by the rendering, actually the rendering is fast.
The reason why the viewers are "slow" is that many gui events are not handled. For example, whey you drag the scene, many drag events are generated by Qt, but only few are passed to the OSG viewer, so the viewers response "slowly".
The events dropping actually is due to that the rendering is too fast...in Viewer::eventTraversal(), only those relative new events are processed, and the "relative new" is measured by cutOffTime = _frameStamp->getReferenceTime(). So if Qt generates the events slower than the rendering, many events will be cut off, and thus not processed.
And finally, after I found the root cause, the solution is easy. Let's cheat a bit on the reference time of _frameStamp used in the Viewer::eventTraversal():
class MyViewer : public osgViewer::Viewer
{
...
virtual void eventTraversal();
...
}
void MyViewer::eventTraversal()
{
double reference_time = _frameStamp->getReferenceTime();
_frameStamp->setReferenceTime(reference_time*100);
osgViewer::Viewer::eventTraversal();
_frameStamp->setReferenceTime(reference_time);
return;
}

I spent also quite some time to figure out how to make this work.
I think that the answer from Gnosophilon cannot work with Qt5, as the rules for switching context thread are more strict than with Qt4 (ie, a call to moveToThread() is required on the OpenGL context object). At time of writing, OSG doesn't satisfy this rules.
(At least I couldn't make it work)
I haven't figure out how to do it in a separate thread, however, to render the scene smoothly in the UI thread, without use of fixed interval timer, one may do the following
viewer_->setRunFrameScheme(osgViewer::ViewerBase::ON_DEMAND);
viewer_->setThreadingModel(osgViewer::CompositeViewer::SingleThreaded);
osgQt::initQtWindowingSystem();
osgQt::setViewer(viewer_.get());
osgQt::setViewer() handle with global variables, so only one viewer at a time can be used.
(which can be a CompositeViewer of course)

Related

Communication between objects (in C++)

I am currently coding my biggest C++ program, using multiple objects to manage a windows (using Windows API functions), a 3D engine (DirectX), and other objects all having to work together to accomplish their task.
I have some problems to organize my objects so they can interact with each other intelligently.
When an object has to perform operations, or worse, pass parameters to another object, I struggle to define the best solution to harmonise and organize my code.
Here is an excellent example:
As I said, in my program I have 2 objects: (1) "windowManager" which handles all the operations related to the window itself, and (2) "rendererManager" which handles all my DirectX operations, from the initialisation to the rendering of every frame.
When the window get resized, DirectX has to be reset to adjust the drawing area, otherwise the image gets stretched, so "windowManager" has to be able to order "rendererManager" to reset.
I could not think of a better solution than to create a "rendererManager.Reset()" method, then 2 methods for the window manager "windowManager.GetRequestRendererReset()" and "windowManager.SetRequestRendererReset(bool reset)"
When my window get resized, the object "windowManager" calls its own method "windowManager.SetRequestRendererReset(true)" to change one of his arguments that can be queried from a "get method".
With this, in my main cycle (in the infinite loop in the main) I applied some verification such as:
if (windowManager.GetRequestRendererReset()) { // The window has been resized, we need to reset DirectX
rendererManager.Reset(windowManager.GetWindow());
windowManager.SetRequestRendererReset(false);
}
This feels very sub-optimal and I feel that there is a better solution.
In addition to this, I now need to send more complex information to my object "rendererManager", such as text to write in the image at specific location, and without an intelligent organization my whole code might become swampy.
Is there some guidelines on how to optimise interactions and communications between objects?
Do you have a good lesson/tutorial about this, or do you have examples of good practices?

SDL2 events on mobile

I've fought for a couple of hours with a bug due to a behavior of SDL2 of which I didn't know anything.
In particular, I didn't know that, on mobile, whenever the user touches the screen, two events are sent:
The first one was quite obvious to me: a finger down event.
The second one was indeed less obvious: a mouse button down event.
The same applies for the finger up/mouse button up events.
Because of them, an internal command was thrown twice giving me an headache.
The target is to support both mobile and desktop environments for reasons that are beyond the purpose of the question.
Also, I can guess SDL2 works like that in order to support smooth migration of already existent codebase.
Anyway, is there a (let me say) SDL2-way to inhibit the mouse related events on mobile?
Honestly, they don't make much sense from my point of view and I would like to get rid of them, unless the software is executed on a desktop environment.
Also, I don't want neither to use compile time parameters nor to have dedicated parts of code the aim of which is to suppress those events on mobile.
The code is quite simple. Below a (maybe) meaningful, reduced example:
SDL_Event ev;
while(SDL_PollEvent(&ev)) {
switch(event.type) {
case SDL_FINGERDOWN:
// read it and throw an internal event E
break;
case SDL_MOUSEBUTTONDOWN:
// read it and throw an internal event E
break;
}
}
Unfortunately, both the events above are read when the user touches the screen, as explained.
* EDIT *
I didn't mention that I was testing my application on an Android device and I'm far to be sure that the same problem arises on iOS.
See the response below. It seems indeed that the issue (that so far I've understood it is not exactly an issue) is mainly due to the way SDL2 treats by default finger events on Android.
Even though I really like the idea of Christophe to add an event filter, I've found that SDL2 already gives support for this problem in terms of an hint on Android.
In particular, there exists the hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH.
One can set it by means of the function SDL_SetHint. See here for further details.
It's as simple as:
SDL_SetHint(SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH, "1");
As from the documentation of the hint, by default it is set to 0 and that means that:
mouse events will be handled as touch events and touch will raise fake mouse events
That's true, it was my problem, but by setting it to 1 we can get what follows:
mouse events will be handled separately from pure touch events
So, no longer fake mouse events on Android devices.
The reason behind the default value is not so clear to me, but this one sounds really like the right way to achieve it.
EDIT (more details)
This change seems to be recent.
Here is a link to the libsdl forum where they were discussing the issues that arose as a consequence of the patch that introduced this behavior.
Someone had the same problem I had and some others were trying also to explain why the patch had been accepted.
EDIT: alternative solution
The hint SDL_HINT_ANDROID_SEPARATE_MOUSE_AND_TOUCH is available since SDL v2.0.4, so it seems that the only viable solution for lower versions of SDL2 is to use an event filter.
Anyway, I discourage to query the platform by using SDL_GetPlatform in order to decide if to set or not to set an event filter.
Instead, as from the documentation of both SDL_MouseMotionEvent and SDL_MouseButtonEvent, there exists the which parameter that:
[...] may be SDL_TOUCH_MOUSEID, for events that were generated by a touch input device, and not a real mouse. You might want to ignore such events, if your application already handles SDL_TouchFingerEvent.
Because of that, I suggest to set an event filter no matter of what's the underlying platform, thus to queue the events or to filter them if needed.
Unfortunately, there is no such platform specific deactivation parameter.
The cleanest way to do it would hence be in the initialisation code to query for the platform with SDL_GetPlatform() and, if mobile, set an eventfilter with SDL_SetEventFilter() which prevents the mouse events from being queued.
It's not exactly the answer you expect, but I see no other sdl alternative.
A simpler approach, if you control the code of your event loop, would be to set a flag instead of an event filter, and if the flag is set do nothing on the mouse event. This second approach is however not so clean, as you have to take care of platform specific behaviour in all your code, whereas it's much more isolated in the first alternative.

Synchronous single file download - is it the right approach in a GUI Qt application?

I'm developing an updater for my application in Qt, primarily to get to know the framework (I realize there are multiple ready-made solutions available, that's not relevant here). It is a basic GUI application using a QMainWindow subclass for its main window and an MyAppUpdater class to perform the actual program logic.
The update information (version, changelog, files to be downloaded) is stored on my server as an XML file. The first thing the updater should do after it sets up the UI is query that server, get the XML file, parse it and display info to the user. Here's where I have a problem though; coming from a procedural/C background, I'd initiate a synchronous download, set a timeout of maybe 3 seconds, then see what happens - if I manage to download the file correctly, I'll parse it and carry on, otherwise display an error.
However, seeing how inconvenient something like that is to implement in Qt, I've come to believe that its network classes are designed in a different way, with a different approach in mind.
I was thinking about initiating an asynchronous download in, say, InitVersionInfoDownload, and then connecting QNetworkReply's finished signal to a slot called VersionInfoDownloadComplete, or something along these lines. I'd also need a timer somewhere to implement timeout checks - if the slot is not invoked after say 3 seconds, the update should be aborted. However, this approach seems overly complicated and in general inadequate to the situation; I cannot proceed without retrieving this file from the server, or indeed do anything while waiting for it to be downloaded, so an asynchronous approach seems inappropriate in general.
Am I mistaken about that, or is there a better way?
TL;DR: It's the wrong approach in any GUI application.
how inconvenient something like that is to implement in Qt
It's not meant to be convenient, since whenever I see a shipping product that behaves that way, I have an urge to have a stern talk with the developers. Blocking the GUI is a usability nightmare. You never want to code that way.
coming from a procedural/C background, I'd initiate a synchronous download, set a timeout of maybe 3 seconds, then see what happens
If you write any sort of machine or interface control code in C, you probably don't want it to be synchronous either. You'd set up a state machine and process everything asynchronously. When coding embedded C applications, state machines make hard things downright trivial. There are several solutions out there, QP/C would be a first class example.
was thinking about initiating an asynchronous download in, say, InitVersionInfoDownload, and then connecting QNetworkReply's finished signal to a slot called VersionInfoDownloadComplete, or something along these lines. I'd also need a timer somewhere to implement timeout checks - if the slot is not invoked after say 3 seconds, the update should be aborted. However, this approach seems overly complicated
It is trivial. You can't discuss such things without showing your code: perhaps you've implemented it in some horribly verbose manner. When done correctly, it's supposed to look lean and sweet. For some inspiration, see this answer.
I cannot proceed without retrieving this file from the server, or indeed do anything while waiting for it to be downloaded
That's patently false. Your user might wish to cancel the update and exit your application, or resize its window, or minimize/maximize it, or check the existing version, or the OS might require a window repaint, or ...
Remember: Your user and the environment are in control. An application unresponsive by design is not only horrible user experience, but also makes your code harder to comprehend and test. Pseudo-synchronous spaghetti gets out of hand real quick. With async design, it's trivial to use signal spy or other products to introspect what the application is doing, where it's stuck, etc.

User Interface doesn't update output with position data

I am creating a user interface using (Qt) and I am attaching it to my C/C++ motion application using shared memory as my form of Inter Process Communication.
I currently have a class which I created in my motion application that has many members. Most of these members are used to update data on the UI and some of them get updated about 20 to 50 times a second, so it is pretty fast (the reason being because it is tracking motion). My problem is that the data is not getting updated on the UI frequently. It gets updated every few seconds. I was able to get it work using other variables made in structures from my application by using "volatile" however it does not seem to be working for members of my class. I know that the problem is not on the UI (Qt) side, because I saw that the actual member data was not being updated in my application, even though I have commands every cycle to update the data.
I was pretty sure the problem is that some optimization is occurring since I do not have my members declared as volatile as in my structures, but when I made them volatile it still did not work. I found that when I through a comment to print out in the function that updates my motion data within my motion application, the UI updates much more frequently as if the command to print out the comment deters the compiler form optimizing out some stuff.
Has anyone experienced this problem or have a possible solution?
Your help is greatly appreciated. Thanks ahead of time!
EDIT:
The interface does not freeze completely. I just updates every few seconds instead of continuously as I intended for it to do. Using various tests I know that the problem is not on the GUI or shared memory side. The problem lies strictly on the motion application side. The function that I am calling is below: int
`motionUpdate(MOTION_STAT * stat)
{
positionUpdate(&stat->traj);
}
`
where
positionUpdate(){stat->Position = motStatus.pos_fb;}
Position is a class member that contains x, y, and z. The function does not seem to update the position values unless I put a printed out comment before positionUpdate(). I don't track the change in shared memory to update the UI, but instead just update the UI every cycle.
Especially Given you are using Qt, I would strongly advise not using "native" shared memory, but to use signals instead. Concurrency using message-passing (signals/slots is one such way) is much, much easier to reason about and debug than trying to share memory.
I would expect your problem with updating is that the UI isn't being called enough of the time, so there is a backlog of updating to do.
Try putting in some code that throws away updates if they happen less than 0.3 seconds apart and see if that helps. You may wish to tune that number but start at the larger end.
Secondly, make sure there aren't any "notspots" in your app, in which the GUI thread is not being given the chance to run. If there are, consider putting code into another thread or, alternatively, calling processEvents() within that part of the code.
If the above really isn't what's happening, I would suggest adding more info about the architecture of your program.

Qt's state machine as a node graph?

I am trying to figure out how to use a node graph for processing a set of data.
It is for an application that manipulates sound data, much like if you had a bunch of pedals for your guitar.
You have some nodes with predefined procedures connected to each other in a directed graph.
Each takes a turn to process the data, and when one is finished it gives a signal to the next node to do it's thing. The idea is you piece these nodes together using the ui.
I am using Qt for creating the UI, and as such I was looking through it's documentation to see if there was something I could use for the above mentioned problem. And I found the Qt state machine, from what I can read it seems to do what I need, a state is entered, you do some processing, when it is done a finished signal is given, and the next state in the graph is started. Also the fact that you could nest states, giving me the ability to create new nodes by combining existing ones, seems like an attractive idea.
However the state machine was created for changing the attributes of widgets (changing their state) and not for wrapping procedures. For example, a button is pressed and the state machine changes the state of another widget, and e.g. if the button is released the state is swapped back.
So, anyone with more experience, with Qt, the state machine, or processing by node graphs, who could give me a hint whether or not tweaking the state machine to wrap my procedures will work. Or, if there is something else in the Qt library I could use?
I used QStateMachine for online message processing (online in the sense of online algorithm) and it worked fine, there weren't restrictions just because the original idea was to modify widgets.
However, personally I would not use it for your project because a state machine is not exactly what you describe. It might be possible to bend it to your needs but it would certainly be weird. A better solution would be to make a nice polymorphic OO model with your "effects" having a base class and a decoupled graph implementation to connect them. You can use Qt signals to signal finishing the the graph to take the next step. It is also easier to build your custom graph from data than create the states and transitions for the state machine dynamically.