D23105: WIP: [platforms/x11] Cleanup GLX backend, revise compositing

Roman Gilg noreply at phabricator.kde.org
Mon Aug 19 21:34:51 BST 2019


romangg added inline comments.

INLINE COMMENTS

> fredrik wrote in glxbackend.cpp:718
> > Ok and in other case the back buffer also has what's currently on the front buffer and we can paint it partly over and then swap?
> 
> No, but the buffer age extension makes it possible to query the number of frames that have elapsed since the current back buffer was the front buffer. Based on that we can calculate how much we need to repaint to bring it up-to-date.
> 
> See  `void OpenGLBackend::addToDamageHistory(const QRegion &region)` and `QRegion OpenGLBackend::accumulatedDamageHistory(int bufferAge) const`
> 
> > Related to that do you know why we present() in prepareRenderingFrame (in DRM backend as well) and not after the actual paint in endRenderingFrame?
> 
> This code was written based on the idea that SwapBuffers() blocks until the swap is complete, which also means that it blocks until the next vblank.
> 
> The logic can be illustrated with the following pseudo code:
> 
>   while (true) {
>       SwapBuffers(); // For the previous frame
>       renderTimer.start();
>       paint();
>       glFlush();
>   
>       // Sleep until just before the next vblank
>       int timeSinceLastVBlank = renderTimer.elapsed();
>       sleep(vblankInterval - timeSinceLastVBlank);
>   }
> 
> In practice we don't call sleep of course; instead we start the composite timer with the timeout set to just before the next vblank, and return to the event loop.
> 
> But the only driver where SwapBuffers() behaves like this is the NVIDIA driver, and its not the default behavior. It's enabled by setting __GL_MaxFramesAllowed to 1 before initializing OpenGL.
> 
> The reason the next frame is rendered immediately after the buffer swap instead of doing it as late as possible is to avoid missing the vblank when there is a sudden increase in render time. Also if we miss the vblank by one millisecond, the main thread will be blocked in SwapBuffers for 15 milliseconds, which is less than ideal.
> 
> But there's obviously a trade-off here between smoothness and latency.

> The logic can be illustrated with the following pseudo code: [...]

Thank you very much for the comprehensive explanation. I see the logic behind it now when the SwapBuffers call is assumed to be blocking. When it's not it seems just unnecessary complicated to me. Just do the SwapBuffers directly after paint() for the next frame at some point before the upcoming vblank. Then on buffer swap event or vblank interval timer timeout repeat for the next frame.

> Also if we miss the vblank by one millisecond, the main thread will be blocked in SwapBuffers for 15 milliseconds, which is less than ideal.

But only if the driver blocks on SwapBuffers and as you said no current driver behaves like this per default, right? Otherwise if we miss we "just" have a delay of one frame for the next paint result on screen (what we have with the current code on master all the time).

REPOSITORY
  R108 KWin

REVISION DETAIL
  https://phabricator.kde.org/D23105

To: romangg, #kwin, fredrik
Cc: nicolasfella, alexeymin, kwin, LeGast00n, The-Feren-OS-Dev, sbergeron, jraleigh, fbampaloukas, GB_2, mkulinski, ragreen, jackyalcine, Pitel, iodelay, crozbo, bwowk, ZrenBot, ngraham, himcesjf, lesliezhai, ali-mohamed, hardening, romangg, jensreuterberg, abetts, sebas, apol, mart
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.kde.org/pipermail/kwin/attachments/20190819/65f632c0/attachment-0001.html>


More information about the kwin mailing list