Background blur for layer surfaces and translucent windows - #3
Open
wayne-tbl wants to merge 7 commits into
Open
Conversation
The blur request needs somewhere to live. Adding it to zphoc_layer_shell_effects_v1 would mean editing a protocol phoc owns: our version 4 and any version 4 phoc later defines would be two different things under one name, and a client could not tell them apart. So define zphoc_furios_layer_shell_effects_v1 instead, in a file of our own, with get_blur_layer_surface and the zphoc_furios_blur_layer_surface_v1 it hands back. phoc's protocol is left exactly as it is. Signed-off-by: wayne <wayne@furilabs.com>
Signed-off-by: wayne <wayne@furilabs.com>
Mirrors PhocAlphaLayerSurface: same lifecycle, same listeners, pending radius applied on commit. Changing the radius damages the whole output, since blurred pixels do not follow the surface's own damage. The request arrives on our own global rather than phoc's, so this binds zphoc_furios_layer_shell_effects_v1 alongside the existing one and leaves zphoc_layer_shell_effects_v1 at version 3, exactly as phoc defines it. Signed-off-by: wayne <wayne@furilabs.com>
Take the maximum over the mapped TOP and OVERLAY surfaces. While anything asks for blur the whole output is damaged: the filter spreads pixels sideways, so a partial redraw leaves the blurred content disagreeing with what is around it. Signed-off-by: wayne <wayne@furilabs.com>
A dual-Kawase pyramid over plain GL textures and framebuffers. The source is the output's own framebuffer, copied with glCopyTexSubImage2D from inside the render pass. That shape is forced by the hardware rather than chosen: on the android renderer a wlr_allocator buffer cannot back a render target -- no dmabuf import, no native window -- and an earlier revision that rendered into one produced incomplete framebuffers and aborted the compositor at startup. phoc says as much itself, in the "Do not use wlr_allocator on android" path of phoc_renderer_render_view_to_buffer(). The pyramid halves resolution per level rather than widening the tap offset, because past roughly a texel of separation the samples stop overlapping and read as discrete copies -- on diagonal taps, a visible star pattern. Application windows are blurred without asking, decided from their opaque region, since a toplevel has no way to request it over the layer shell effects protocol. Nothing is blurred unless a surface asks for it, so that request is the opt in; PHOC_BLUR=0 switches the whole thing off for a session, for a device whose GL path misbehaves. Signed-off-by: wayne <wayne@furilabs.com>
Blur is on by default and a surface only gets it by asking over the layer shell effects protocol, but a device whose GL path misbehaves needs a way to switch the effect off without downgrading the compositor. Read at startup and followed while phoc runs; the backdrop is captured from the render pass, so nothing frosts or clears until a frame is asked for. Signed-off-by: wayne <wayne@furilabs.com>
Covers the request and that a blurred surface still renders correctly. The GL path itself only runs on a device: the suite forces WLR_RENDERER=pixman and no gles2 renderer can be created under Xvfb, so what runs here is the protocol plumbing and the fallback when blur is unavailable. Signed-off-by: wayne <wayne@furilabs.com>
Author
|
Blur cost, measured. FLX1s (720x1600), six runs, two per configuration. phoc, % of one core:
Zero at idle, roughly double during animation, peak near half a core. phosh unaffected. Repeat runs of the same configuration reproduce phoc to 0.3-6% on drawer and app grid, so the doubling sits well outside noise. Governor pinned to performance, background package activity killed, every run started from the same temperature. Caveats: the FLX1 has 2.3x the pixels and is not yet measured, and this is CPU only. The kawase pass is GPU work and was not measured. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background blur for layer surfaces that ask for it, and for translucent
application windows.
layer-shell-effects: add a background blur request— bumpszphoc_layer_shell_effects_v1to version 4 and addsget_blur_layer_surface. The radius is double buffered and takes effect onwl_surface.commit, following the alpha surface it is modelled on.layer-surface: track a background blur radiuslayer-shell-effects: implement the blur layer surface— mirrorsPhocAlphaLayerSurface: same lifecycle, same listeners.output: report the blur radius of mapped layer surfaces— the maximum overmapped TOP and OVERLAY. While anything asks for blur the whole output is
damaged, since the filter spreads pixels sideways and a partial redraw leaves
blurred content disagreeing with what is around it.
renderer: blur the backdrop of translucent surfacestests: exercise the blur layer surfaceThe renderer commit is the large one and does not split further — the filter,
the capture and the two call sites are one mechanism. Its shape is forced by the
hardware rather than chosen: on the android renderer a
wlr_allocatorbuffercannot back a render target (no dmabuf import, no native window), and an earlier
revision that rendered into one produced incomplete framebuffers and aborted the
compositor at startup. phoc says as much itself, in the "Do not use
wlr_allocator on android" path of
phoc_renderer_render_view_to_buffer(). Sothe dual-Kawase pyramid runs on plain GL textures and FBOs, with the source
copied out of the output's own framebuffer with
glCopyTexSubImage2Dfrominside the render pass. The pyramid halves resolution per level rather than
widening the tap offset: past roughly a texel of separation the samples stop
overlapping and read as discrete copies — a visible star pattern on diagonal
taps.
Application windows are blurred without asking, decided from their opaque
region, since a toplevel has no way to request it over the layer shell effects
protocol.
Nothing is blurred unless a surface asks for it, so that request is the opt-in.
On top of that the
blurgsetting switches the whole effect off, for a devicewhose GL path misbehaves, without downgrading the compositor. It defaults to
on, is read at startup and followed while phoc runs -- the same shape as the
touch-pointskey in thescreen-capturePR, damaging the outputs on changebecause the backdrop is captured from the render pass. An earlier revision of
this branch used a
PHOC_BLURenvironment variable for that; it has beenreplaced by the setting at review request, and is gone.
On testing: the GL path only runs on a device. The suite forces
WLR_RENDERER=pixmanand no gles2 renderer can be created under Xvfb, so whatthe new test covers is the protocol plumbing and the fallback when blur is
unavailable. The renderer itself has been exercised on an FLX1 (Halium/hybris,
Mali-G68) across many boots, including rotation.
How it reaches the GPU
Nothing is read back to the CPU anywhere in this path -- there is no
glReadPixelsand no buffer mapping.phoc_renderer_capture_blur()runs inside the output's existingwlr_render_pass, called fromrender_layer()just before a surface thatasked for blur is drawn. It does not begin a render pass of its own, and that
is deliberate: the android renderer has no dmabuf import and no native window
for an offscreen
wlr_allocatorbuffer, so a second render target is notavailable here --
phoc_renderer_render_view_to_buffer()already says as much.glCopyTexSubImage2Dcopies the output framebuffer, as itstands at that moment, into a GL texture. Driver-side blit.
up-sample shaders drawing a 4-vertex triangle strip. The pyramid starts at
quarter resolution, cutting the fill rate of every iteration by 16.
Depth follows the radius:
levels = round(log2(max(radius, 8) / 8)), clampedto 0..4, so radius 8 is one level and each doubling buys one more.
render_blur_backdrop()draws the result as a raw GL quadunder the surface.
PhocBlurStateper output (capture texture, five pyramidtextures and their FBOs) in a hashtable on
PhocRenderer, dropped byphoc_renderer_forget_output(). Allocated once per output, not per frame.The FBO binding and surrounding GL state are saved and restored, since this
borrows wlroots' render pass rather than owning it.
Cost when idle is nil, because
phoc_output_draw()renders no frame at allwhen nothing is damaged. The cost that is real: when blur is active and the
damage ring is non-empty the whole output is damaged, since a blurred pixel
depends on a hundred pixels around it and partial redraw artifacts. So anything
that damages a small region every frame now repaints the whole output. A CPU
comparison against stock phoc is still outstanding;
gsettings set sm.puri.phoc blur falsegives a live A/B on the same device.Pairs with FuriLabs/phosh#4, which requests the blur. phosh binds this
protocol only if the compositor offers it and is deliberately outside its
"lacks needed globals" fatal check, so it still starts against a stock phoc and
simply gets no blur. The two can land in either order.
7 commits, off
forky.