Blur effect + buffer transformations
The blur effect works roughly in these three steps:
- before the window to put blur under is painted, it copies the screen content into an fbo with a blit
- it then samples that fbo down to a smaller texture, and samples that back up to a bigger texture. That's where the actual blur happens
- it renders the blur region to the render target and samples the final blur texture while doing that
When a fixed buffer transformation comes into play, this doesn't get very complex either. Everything stays the same, except for:
- both the source and destination rect are transformed
- the region to up- and downsample is transformed
- the transformation is applied to the projection matrix here too
However, problems arise when the transformation changes between invocations of the blur effect:
- with screen rotation, the effect would need to allocate its fbos in the correct size (transposed or not) before it even knows what transformations to apply (because there's no render target yet). This can be fixed by lazily allocating the blur texture, so that (re-)allocations happen when it renders and not when the output changes
- this fix / workaround doesn't work with overlay planes though, which may have a different rotation from the primary plane
- even with only y inversion, there can be different transformations at different times, because effects may want to render the screen into a normal non-inverted texture. The screentransform effect does that for example
In order for different transformations to work like this, we'd need to be able to do different transformations for source and destination rect in step 1, so that the intermediary buffers for up- and downsampling can stay in one fixed transformation. However, fbo blitting only support translation and scaling (scale >= 0) and as such can't handle y inversion and rotations. Alternatives are:
- always use a shadow buffer and render into that without rotation or inversion. Where hardware rotation supports it, use that to flip the image instead
- for drivers that don't support flips, this would reduce efficiency and gaming performance. amdgpu doesn't support it for example, so this is not a good option
- sample from the fbo texture. This works just fine for the wayland and virtual backends, and will work fine for the drm backend with the gbm swapchain modification. With !3507 (merged) it would also work with the x11 windowed backend... so the X11 standalone backend is blocking this.
The most straight forward idea I have is to just assume you never need transformations with the x11 standalone backend, and add a "blit" function that does the blit with transformation in between buffers if possible. I don't really like having such a "doesn't always work" function, so if anyone else has a better idea, that would be great.