picom
picom copied to clipboard
Custom shader for new backends
Creating a new PR because I want to preserve @tryone144's original PR (#507) as a reference.
Codecov Report
Merging #851 (35b403a) into next (896acab) will decrease coverage by
0.19%
. The diff coverage is51.38%
.
@@ Coverage Diff @@
## next #851 +/- ##
==========================================
- Coverage 39.22% 39.02% -0.20%
==========================================
Files 46 46
Lines 9753 9977 +224
==========================================
+ Hits 3826 3894 +68
- Misses 5927 6083 +156
Impacted Files | Coverage Δ | |
---|---|---|
src/backend/backend.c | 60.34% <ø> (ø) |
|
src/backend/backend_common.c | 39.09% <0.00%> (-0.66%) |
:arrow_down: |
src/backend/gl/gl_common.h | 30.95% <ø> (+0.71%) |
:arrow_up: |
src/backend/gl/glx.c | 36.89% <ø> (-0.33%) |
:arrow_down: |
src/common.h | 75.00% <ø> (-3.27%) |
:arrow_down: |
src/config.h | 23.52% <ø> (ø) |
|
src/win.h | 78.12% <ø> (ø) |
|
src/picom.c | 67.99% <28.88%> (-3.53%) |
:arrow_down: |
src/options.c | 21.79% <36.36%> (+0.22%) |
:arrow_up: |
src/backend/gl/gl_common.c | 16.10% <54.36%> (+1.28%) |
:arrow_up: |
... and 15 more |
This should be ready for prime time. Only thing left is to document the shader interface.
Can you have a look, @tryone144 ?
Ah, I forgot to set projection for custom shaders.
Update: fixed.
Also, the time parameter is kinda useless unless we have an option to force picom to redraw every frame.
I propose adding a force-redraw = bool;
option and a force-redraw-rule = [];
option.
Can you have a look, @tryone144 ?
I will try to get around to this week.
Also, the time parameter is kinda useless unless we have an option to force picom to redraw every frame.
I propose adding a
force-redraw = bool;
option and aforce-redraw-rule = [];
option.
I initially though about force-redrawing every window with a custom shader, but that is overkill performance wise. And I don't think autodetecting the use of time
is reliable enough.
force-redraw
and force-redraw-rule
should be fine. Maybe even add a force-blend-rule
option while we are at it?
These options however, leave the user responsible to ensure correct behaviour of their shaders (for animations and transparency).
hmm, actually i think we can detect use of time
automatically. glGetUniformLocation
would return -1 if the variable isn't used.
@tryone144 Thanks for the review! I will try to get to it ASAP
The create_shader() backend operation could return a bool
Yes. I am also thinking maybe add a get_shader_property
function with the only property being ANIMATED
for now. I think this API is conceptually nicer, but I don't know if it's overkill. What other properties could a shader have?
@tryone144 I think I resolved most of the complaints :+1:
@tryone144 i think this PR is complete.
Another thing that just came to mind: While it might be intuitive that redrawing the animated shaders continuously will inevitably increase the CPU load, we could add a short note to the docs.
Are we re-drawing with the screen refresh-rate when vsync is enabled (even on nvidia that has problems with glFinish()
)? Or do we re-draw as fast as the idle-loop permits?
A short test supports the assumption we draw at the vsync limit (i.e. vsync = false
results in 100% utilization).
A short test supports the assumption we draw at the vsync limit (i.e. vsync = false results in 100% utilization).
Hmm, it's an interesting question. But I think this is more or less expected behavior. I tried glxgears
, and it does the same sort of thing if I disable vsync.
Where can I find documentation on how to use this myself? Can it be used to create rounded corners also, or work at the same time as them? I want to try to use it to implement #824 as a shader
@LoganDark see man picom
, the SHADER INTERFACE section. Yes, it's possible to implement rounded corners in your custom shaders.
Will it be possible to separate the post processing passes in the future? Like apply the color adjustments and then my own filter and then the vanilla rounded corners?
@LoganDark you can copy the default_post_processing code if you want.
I see, it looks like rewriting / copying all the code is the only option, well I suppose this is fine for an initial release, thank you :)
Hope that more modular/granular options are added in the future
Is it possible for a shader to change the opacity of the background-blur? So outside of the window is not blurred if the window has rounded corners?
Is it also possible for a shader to sample behind the window so things like color filters can be implemented?
Should I open issues for these?
@LoganDark No, this option is for custom foreground shaders, hence the fg
in the name. You can open a feature request for background shaders if you want.
Hmm, I try to start picom like this: picom --config ~/.config/picom/picom.conf --window-shader-fg ~/.config/picom/shader.glsl
(the config is the sample one from the source tree, with backend = "xrender";
), but I get the following:
[ 08/27/2022 11:25:49.881 get_cfg WARN ] The new window shader interface does not work with the legacy glx backend.
I've tried explicitly adding a --backend xrender
arg, but the result is the same.
The picom version is vgit-e0758
and the shader is:
#version 330
in vec2 texcoord; // texture coordinate of the fragment
uniform float opacity; // opacity of the window (0.0 - 1.0)
uniform float dim; // dimming factor of the window (0.0 - 1.0, higher means more dim)
uniform float corner_radius; // corner radius of the window (pixels)
uniform float border_width; // estimated border width of the window (pixels)
uniform bool invert_color; // whether to invert the color of the window
uniform sampler2D tex; // texture of the window
uniform sampler2D brightness; // estimated brightness of the window, 1x1 texture
uniform float max_brightness; // configured maximum brightness of the window (0.0 - 1.0)
uniform float time; // time in milliseconds, counting from an unspecified starting point
vec4 default_post_processing( vec4 c );
vec4 window_shader() {
vec4 c = texelFetch(tex, ivec2(texcoord), 0);
mix( c, vec4(.5, 1.0, .5, 1.0), .5 ); // just for feedback that the shader works
return default_post_processing(c);
}
Any idea what's going wrong?
I've tried explicitly adding a
--backend xrender
arg, but the result is the same.
The OpenGL shader only work with a gl compatible backend — only glx
for now.
The xrender backend can't use shaders directly.
Thank you, with glx it works great! (For some reason I thought the glx backend was the legacy one...)
By the way, do you know if it's possible to make the shader apply to the whole screen (and not specific windows) with the shader conditions? I'm trying to make a CRT-ish shader (scanlines, curvature, etc). I'm using bspwm, if that makes any difference. I tried --window-shader-fg-rule ~/.config/picom/retro.glsl:'wmwin'
, but that condition seems to be the wrong one for what I'm trying to achieve.
edit:
If there were a window offset uniform available, then I could use that to convert the texcoord to a screen space UV and correctly calculate the curvature, displacement, etc for any shaded window's fragments, but I don't currently see a way of achieving this. Any suggestions?
@Falkgaard I guess it's a bit confusing. There are the legacy backends and the new backends. Each set of backends has its own glx and xrender backend. You were using the legacy backend, because you probably are not using the latest commit and didn't pass --experiment-backends
.
The new backends are now the default thus if you use the latest git commit you don't need that option anymore.
shader apply to the whole screen
This is better achieved with a overall shader, the per-window shader isn't suited for this job.
I see. Updated to the latest commit. Cheers!
This is better achieved with a overall shader, the per-window shader isn't suited for this job.
Mm, makes sense. Does Picom support overall shaders or just per-window shaders?
(And if not, if anyone knows of some software that allows this when running a tiling WM, I'd love to hear about it.)
curvature
Keep in mind this would cause the cursor to no longer be accurate, because picom doesn't render the cursor itself
CRT
Would you mind sharing your shader with us? I've been looking for an accurate CRT shader for PICOM, I found one, but its not accurate at all. I tried porting zfast-crt but failed