This needs the EGL_KHR_image_pixmap and the GL_EXT_EGL_image_storage
extensions, which unfortunately aren't available on NVIDIA cards.
Don't add documentation for these, for now.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Since image_dst is in X coordinates, after flipping Y, we need to
subtract the height of the drawing area, to make it the bottom right
corner for OpenGL.
However, this breaks blur. Because we assumed the drawing area is the
same size as the texture, which is not the case for blur. So add the
height of the drawing area as another parameter.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Instead of always using the back texture/fbo. Also use the size of the
source texture, instead of hard coded back buffer size.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This is used to create image masks that can be used to mask out
`compose` regions. For example, this can be used to mask out window body
so shadow won't be painted on them.
This could be more efficient than using rectangular regions for masking,
when there are a large number of rectangles; or more flexible, in the
case of window with rounded corners.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This does not ever happen in practice. But conceptually, the GL backend
holds 2 kinds of images: those in GL coordinate system, and those in X
coordinate system. They are differentiated by the `y_inverted` variable,
and applying alpha to them needs differs in whether y needs to be
inverted. Right now we never invert y, because we only ever call apply
alpha on images in the X coordinate system.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Previously postprocessing is omitted when estimating the color of the
border (e.g. dimming, opacity, inversion, etc.), causing the border to
be drawn with the wrong color.
Related: #770
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
The outer pixels of the corner are drawn with antialiasing, but it color
used for antialiasing is wrong. The estimated border color is used when
there is actually no border.
Related: #770
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
If a window's border_width is bigger than its corner_radius, the inner
radius of the border become less than 0, causing the entire window to be
filled.
Fixes#778
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This is meant to be used to detect GPU resets.
Implemented in the glx backend using the GL_ARB_robustness extension.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Blur-texture sampling has been changed to `CLAMP_TO_EDGE` in commit
4b0ff37b36 and to using the buffer
textures at screen position instead of texture origin in commit
89c18afac6.
When using the above approach, expanding the buffer textures by the same
amount as the damage region is not needed anymore, as we cannot render
more than the screen region anyways. Having larger-than-screen buffer
textures might lead to a slight darkening at the upper and right edges
since we don't necessarily trigger the `CLAMP_TO_EDGE` condition in the
intermediate steps. This becomes apparent when using dual-kawase at large
blur-strengths with light backgrounds.
These changes do not affect the general approach of rendering a
larger-than-window region with the blur to accommodate the necessary
increase in damage region.
Related: 6d646b543f
At least on nvidia, binding the textures from a glx pixmap to a
framebuffer results in `GL_FRAMEBUFFER_UNSUPPORTED`. Instead of using
binding the source texture to a framebuffer and using `glCopyTexImage2D()`
to copy into a new texture, explicitly render the source texture to the
new texture attached to a framebuffer.
Fixes black/invisible windows on nvidia with `frame-opacity != 1`.
see: #647
related: 2a60836a9b
Added more descriptive checks for framebuffer-completeness after adding
attaching textures (for the first time).
Also check for GL errors after `IMAGE_OP_APPLY_ALPHA`.
Currently there is some inconsistency in how image_op is implemented
across backends. The glx backend applies some of the image operations
lazily, and not always in the order the operations were made; while the
xrender backend applies the operations eagerly. This can lead to
different render result in some cases.
Instead of trying to preserving the order of operations, which would be
unnecessary, we re-model the API to better reflect the implementation.
We make it clear that setting the property doesn't change the image
data, and properties are only applied during composition and in a
specific order.
This makes sure the render result looks consistent across backends.
Should also improve the performance of the xrender backend, even if only
slightly.
Also distill out the property management code so they can be shared.
Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
Keep track of the number of elements/indices for the normal blur rects
as well as the resized ones and use the correct number when drawing.
The number of rects can change if resized rects overlap and are reduced
into a single rect.
Fixes#440
Implement the dual-filter kawase blur algorithm for the new OpenGL backend
as seen in kwin [1]. Use with `--blur-method dual_kawase` and set the
desired strength with `--blur-strength level` (1-20).
The dual-filter kawase algorithm produces results close to a traditional
gaussian blur with higher performace, especially at high blur radii. The
supported strength levels provide an effect similar to gauss-radii between
4 and 500 pixels.
As this algorithm relies heavily on the texture-filtering units of a
GPU, there is no support for the xrender backend — at least for now.
[1](https://kwin.kde.narkive.com/aSqRYYw7/d9848-updated-the-blur-method-to-use-the-more-efficient-dual-kawase-blur-algorithm)
**Work-in-Progress**
Split-off kernel-blur specific initialization and rendering from common
OpenGL setup. Add stub functions for dual_kawase-blur initialization and
rendering.
**Work-in-Progress**
Add `dual_kawase` to configuration and argument parsing. Allow `kawase`
for backward compatibility. Add `--blur-strength` parameter for
blur-method `dual_kawase`.
Update documentation to reflect the new blur-method and parameters.
Make use of hardware linear interpolation in a GPU to sample 2 pixels
with a single texture access inside the blur shaders by sampling between
both pixels based on their relative weight.
This is significantly easier for a single dimension as 2D bilinear
filtering would raise additional constraints on the kernels (not single
zero-entries, no zero-diagonals, ...) which require additional checks
with limited improvements. Therfore, only use interpolation along the
larger dimension should be a sufficient improvement.
Using this will effectively half the number of texture accesses and
additions needed for a kernel. E.g. a 1D-pass of the gaussian blur
with radius 15 will only need 16 samples instead of 31.