Skip to content

backends/drm: port away from gbm_surface and remove the need for a shadow buffer

Xaver Hugl requested to merge work/zamundaaa/gbm-swapchain into master

This provides several benefits:

  • we're guaranteed to have the minimum amount of buffers to cycle through, which should improve efficiency a tiny bit
  • removing the shadow buffer removes the fullscreen copy that's been done with screen rotations so far, which should noticably improve efficiency on mobile, where hardware rotation is usually not available or only very limited (for example according to drmdb the Snapdragon 845 can only do 180° rotation but not 90° or 270°). We also haven't enabled hardware rotation by default yet, so it should help on PCs with rotated screens too
  • we only have to allocate one buffer and do no painting when doing atomic tests, which should cut down the time needed for said tests and by extension for starting KWin
  • we can allocate an arbitrary amount of buffers if we like. In some cases this could allow us to implement proper zero copy screen casting (or I guess single copy, if you count compositing as a copy)
  • the gbm swapchain I created isn't bound to a graphics API, which makes some simplifications of the drm backend possible and allows it to be used with Vulkan later on

Doing this also inverts the y axis vs what gbm_surface provides though, so this MR also adds the APIs needed to make having a transformed buffer work with the scene and effects. For most effects this was trivial, only the blur effect was a bit more complicated. It now "blits" from the main framebuffer with transformations if needed, so that the blur texture is always without rotations. It also uses a set of textures per screen instead of a combined one for all, which in hindsight isn't really necessary anymore, but as it simplifies the effect code and reduces VRAM usage I'd like to keep it that way. As another simplification, instead of creating multiple sets of geometries with just different scaling applied and undoing that with a different projection matrix per rendering step, the effect now uses one blur geometry and one projection matrix for the up- and downsampling.

There are some remaining issues however:

  • the drm backend now calls glFlush() after rendering. I have no clue why that's needed, but whenever we render into a shadow buffer of some sort (-> revert the last commit & use a rotated screen, or use QtQuick effects) there's very weird visible glitches. This glFlush isn't ideal, as we then may block for multiple milliseconds on the CPU side.
    • for #134 (closed) and #124 we'd need to asynchronously wait for rendering to complete before committing buffers anyways, so once we do that, calling glFlush should become unnecessary
    • we might be able to fix this more easily for the short term by creating a fence and setting the IN_FENCE_FD drm property. While almost all drivers support this, we'd still need a fallback for the radeon driver... I guess a if (!supported) glFlush() wouldn't be that bad though
  • with the last commit, screen recording of rotated outputs is broken. This is fixable (just pass the transformation of the buffer along in OpenGLBackend::textureForOutput and take that into account when doing the copy to the screen recording buffer) but I haven't implemented that yet
  • while we never show any buffer with atomic modesetting before rendering to it, legacy modesets directly throw newly allocated buffers on the screen. Mesa seems to allocate a black buffer by default, but I'm not sure if that just works by chance on my hardware. If it isn't the same on all other hardware or otherwise not guaranteed, we need to either
    • bind the buffer before doing said modesets and clear it with OpenGL. I don't like this option though, part of the motivation for this change is to get rid of graphics API calls when doing buffer allocations
    • delay the modesets with legacy. Also not necessarily pretty, but it would allow us to skip the connector<->crtc combination tests with legacy, where they don't make a ton of sense anyways

In general, if others could test this MR as well that would be very helpful. I think I tested all the effects and different options, but it's always possible that I missed something

Edited by Xaver Hugl

Merge request reports