How to reduce latency using QOpenGLWidget?
-
I'm updating a QOpenGlWidget every 16 ms, by connecting the frameSwapped() signal with update(). On every paintGL i just render a triangle at a different position. This takes less than 16 ms, measured calling glFinish. But there is a significant delay between processing paintGL and the rendered frame actual shown on the monitor. Is there a method to ensure that the next frame is the most recent processed one?
I posted very similar question on Stackoverflow the other day. I will update the questions, if one gets answered. -
There is a lot that can be going on here. You don't provide enough information for us to be much help.
OS and hardware being used?
open source mesa drivers or close-source proprietary driver?
the substance of your render method? -
To be more precise:
The goal of my application is to draw something at the currrent mouse position. Low latency is important. So no frame latency would be perfect, but exactly one frame would be fine as well.
At the moment this is the code i get the best result with:QTimer *Timer = new QTimer(this); connect(Timer, SIGNAL(timeout()), this, SLOT(animate())); Timer->start();
void Widget::animate() { makeCurrent(); QOpenGLFunctions* f = QOpenGLContext::currentContext()->functions(); f->glFinish(); update(); }
void Widget::paintGL() { // Draw Cursor POINT LpPoint; GetCursorPos(&LpPoint); QPoint CursorPos(LpPoint.x, LpPoint.y); CursorPos = mapFromGlobal(CursorPos); QPainter Painter(this); Painter.drawEllipse(CursorPos, 20, 20); }
I'm developing on windows. GPU : NVidia GTX 1070 with the nvidia own drivers.
The problem is that at the moment i can't make any prediction on how my code behaves, when i analyse the frames. I think because of the glFinish sometimes frames get skippes, but without the delay is two frames. -
I think you're underestimating the problem. There are a couple of factors at play here.
First is that you're running this with a timer. This will cause you to miss v-sync every now and then. See my older post explaining it here. To the naked eye it wil look like you're dropping a frame every now and then because you are.
Next is the double buffering and OS and API latency. I touched the topic a bit here.
Last but not least is the fact that mouse input is polled something like 120 to 1000 times a second, while you usually draw only about 60 times per second. This means that if you get the input at the start of your frame, by the time this input is used to draw something at least 16ms will pass (at 60FPS), you'll miss hundreds of input updates and on top of that other types of latency is added.
Low latency input is a very complex topic and simple API like the one Qt provides is probably not gonna be enough to have something that really "sticks to the cursor".
-
Thank you. I connected the frameSwapped signal with the update function to solve the timer problem. I hope that the right way to do it. But i still have some trouble to understand why there's two frames of delay. My paintGL function changes the back buffer and then the buffers get swapped. Why should that cause any latency? I process the mouse position directly after the buffers swapped, because of that there's one frame delay. I tried to overcome this by adding some delay in my animation function, but this didn't change anything. I'm not sure why. At the moment i would be fine with two frames of latency, i just want to understand why.