Original report by email, that describe the problem along with logs from both Wayland, Qt and our code. These are intermixed client/server logs
Hi Pat & Kyle,
Apologies if I’m going about this the wrong way – but we require a bit of urgent technical support.
Mostly our Wayland implementation is working well – but we have one issue that is causing us some grief. At first glance it seems like a cosmetic issue, but in our application it is quite an ugly one, so it needs to be fixed.
The problem is this: When we show a Wayland window after it has been hidden, we see a couple of frames from the client from before it was hidden. Since our framerate is not particularly fast, this is quite noticeable to the user. It seems that when the window is hidden, Wayland prevents the client from rendering frames (this is good) but somewhere a couple of frames are queued up and these are rendered after the window is shown again.
Is there any way of avoiding this? We are using Qt5.12.2 on the compositor side, and Qt5.12.4 on the client side (the difference in versions is because the client is supplied by a third party).
The log below shows what we see when we Hide the wayland window, then wait a few seconds, then show the window. We want the user to see an “Engines” page before the window is hidden, then while it is hidden the client should switch to an “idle” page, then when it is shown the user will see the idle page until the client can load a new page (in the case below, the “Naviop Home” page. Note the problem only happens if we use an OpenGL surface for rendering on the client. If we use raster / shared memory on the client, then the client appears to continue rendering even when hidden, and the problem doesn’t occur. Unfortunately, it is not practical for us to use raster rendering on the client for performance reasons.
Some things we think may fix the issue for us:
· In our case we’d actually be OK if the client continued rendering even when hidden (since we have other ways to control the client to make sure it doesn’t use up too much CPU). Therefore, if we could make the client continue rendering, even when hidden, we think it would work OK (this is what happens when we use a raster surface on the client, and it works OK).
· It seems the client detects that it is hidden if it doesn’t receive a frame callback within 100uS. In our case, this is not enough time for the client to switch to the “idle” frame, which is what we need it to do. If we could extend this timeout to, say, 1s, it would probably work, as well
· The behaviour doesn’t seem right in a general sense. If the Wayland system could avoid rendering “stale” frames when a window is shown (in our case we see frames that are many seconds old) then this would also fix our problem.
Client commits engine frame, then server receives the commit, then Navico FB renders the frame (Swap, then blit)
Now the window gets hidden. MFDApp sends out-of-band “Application-switch” message to client
Client hasn’t received the application-switch message yet, so renders and commits another engine frame
Client still hasn’t received the application-switch message, so starts rendering another engine frame. Note that this time the Wayland plugin detects that the window has been hidden. It still commits the frame, though.
NDesign now receives the application-switch message, and changes to the “idle” page
Wayland Server sees the previous commit – note this is an engine frame – not the idle page yet. Potentially the server now has 2 engine frames queued up that it hasn’t rendered.
NDesign continues process of loading Idle Page. Wayland plugin knows that the window is hidden, so doesn’t commit anything.
After a few seconds, the user presses “Naviop” icon, and MFDApp shows the Wayland panel, and sends another out-of-band application-switch message.
Wayland compositor flushes out any frames it has in its queue. Note that there are potentially two frames – both engine frames. It seems that there is some kind of bug here, because it does swap-swap-blit-blit rather than swap-blit-swap-blit. In any case, it is an engine page frame that ends up on the screen. Not the idle page – despite the fact that we told the client process to change to the idle page over 3 seconds ago.
Note sure what this log message means
Client renders the idle page…
NDesign receives application-switch message to render Naviop home page.
Client commits the idle page…
NDesign finishes loading Naviop home page
Client renders Naviop home page
Server receives idle page commit.
NavicoFB renders idle page – 0.5s after the show event – eg. The screen has been showing engines page for 0.5s.
Client commits Naviop home page
NavicoFB continues rendering the idle page.
NavicoFB receives commit for the Naviop home page
NavicoFB renders the Naviop home page – finally. Life is now good, but 0.5s of engines page has made our UI look very unprofessional.
|For Gerrit Dashboard: QTBUG-77520|
|270898,1||WIP: Don't change window exposure on frame callback timeout||5.12||qt/qtwayland||Status: NEW||-2||0|