Prevent events from accumulating...
I have a high speed camera, and I want to take the incoming video and send it to an OpenGL context as a texture. With each new frame, the code over writes the previous texture buffer. Sadly, Qt can't quite keep up with all these events. So I'm calling the update() event fewer times than I'm uploading textures. So this texture upload is a slot inside my custom QGLWidget, and I want to detect incoming events before calling this slot.
From my reading, update events are filtered by Qt such that multiple events don't build up in the event queue. Does anyone know how to mimic that behavior for other slots so that I never have more than one event sitting in the queue at any one time?
Hi, first of all events and slots are two very different mechanisms. You don't "call" events. You can post an event and Qt will call an event handler and aggregate if they stack up. A call to update() is not the same as posting event. It's a plain function call. There is an event posted somewhere underneath, but that's an implementation detail. Another thing is that for QGLWidget you should call updateGL() when you want to draw, not update() which might involve widget geometry refresh, size hints calculation etc. and can be potentially slower.
As for slots, if threading is not involved, the default connection for signals/slots is a DirectConnection, which is no more expensive than a function call so it should be quite fast.
So please clarify what you're doing. There might be an easy solution, we just need to be on the same page.
In any case there's little point in updating a texture if you can't display it fast enough. It just unnecessarily drains resources. Maybe the problem you see is related to v-sync and not Qt event handling? Maybe you block without realizing it.
A gut feeling is that you're calling update(), which blocks until next v-sync.
I think what you should be doing is either disable v-sync via GL extension (but why would you want to do that?) or draw only when you actually need to.
Let me start over. I have two QObjects running in two different threads. One object emits signals a lot. The other receives the signals and processes it. But each call takes a while. Perhaps object 1 emits signals at 5 to 10 times the rate the object 2 can process them. I'd like to simply skip all accumulated signals and just jump to the most recent signal. How can I tell object 2 to ignore all but the last signal?
Also, updateGL() gives the OpenGL widget priority over all other Qt events. Updating the QGLWidget locks up the rest of the interface. Update() skips a lot of widget refreshes and is then free to answer other QEvents. So the rest of the non-QGLWidget's stay responsive.
You can't really skip signals, but there are few ways to have the same effect.
One would be to set some "dirty flag" eg. a boolean in the slot and start a timer that would "poll" that flag at some constant interval to do the update.
Similarly you can do the inverse. Whenever you start the update you would set a flag and clear it at the end. If a signal comes in between and the flag is set (i.e. it's still working) you would consider the signal accumulating and skip it.