Skip to content

Commit

Permalink
Merge branch 'yshui:next' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
pijulius authored May 20, 2024
2 parents fcc32ee + 167c3ff commit fc39512
Show file tree
Hide file tree
Showing 38 changed files with 2,778 additions and 707 deletions.
12 changes: 12 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github: yshui
patreon:
open_collective:
ko_fi:
tidelift:
community_bridge:
liberapay:
issuehunt:
lfx_crowdfunding:
polar:
buy_me_a_coffee:
custom:
9 changes: 8 additions & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install libconfig 1.7
run: |
wget https://hyperrealm.github.io/libconfig/dist/libconfig-1.7.3.tar.gz
tar -xvf libconfig-1.7.3.tar.gz
cd libconfig-1.7.3
./configure --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu/
sudo make install
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
Expand All @@ -27,7 +34,7 @@ jobs:
languages: ${{ matrix.language }}

# Install dependencies
- run: sudo apt update && sudo apt install libconfig-dev libdbus-1-dev libegl-dev libev-dev libgl-dev libpcre2-dev libpixman-1-dev libx11-xcb-dev libxcb1-dev libxcb-composite0-dev libxcb-damage0-dev libxcb-dpms0-dev libxcb-glx0-dev libxcb-image0-dev libxcb-present-dev libxcb-randr0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-shape0-dev libxcb-util-dev libxcb-xfixes0-dev libxext-dev meson ninja-build uthash-dev
- run: sudo apt update && sudo apt install libdbus-1-dev libegl-dev libev-dev libgl-dev libpcre2-dev libpixman-1-dev libx11-xcb-dev libxcb1-dev libxcb-composite0-dev libxcb-damage0-dev libxcb-dpms0-dev libxcb-glx0-dev libxcb-image0-dev libxcb-present-dev libxcb-randr0-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-shape0-dev libxcb-util-dev libxcb-xfixes0-dev libxext-dev meson ninja-build uthash-dev
if: ${{ matrix.language == 'cpp' }}

# Autobuild
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## New features

* `@include` directives in config file now also search in `$XDG_CONFIG_HOME/picom/include` and `$XDG_CONFIG_DIRS/picom/include`, in addition to relative to the config file's parent directory.
* Allow `corner-radius-rules` to override `corner-radius = 0`. Previously setting corner radius to 0 globally disables rounded corners. (#1170)
* New `picom-inspect` tool, which lets you test out your picom rules. Sample output:

Expand Down Expand Up @@ -49,7 +50,7 @@

* picom now uses some OpenGL 4.3 features.
* picom now optionally depends on `rtkit` at runtime to give itself realtime scheduling priority.
* `libconfig` is now a mandatory dependency.
* `libconfig` is now a mandatory dependency, with a minimal supported version of 1.7.

# v11.2 (2024-Feb-13)

Expand Down
2 changes: 2 additions & 0 deletions man/picom.1.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,8 @@ CONFIGURATION FILES
-------------------
picom could read from a configuration file if libconfig support is compiled in. If *--config* is not used, picom will seek for a configuration file in `$XDG_CONFIG_HOME/picom.conf` (`~/.config/picom.conf`, usually), then `$XDG_CONFIG_HOME/picom/picom.conf`, then `$XDG_CONFIG_DIRS/picom.conf` (often `/etc/xdg/picom.conf`), then `$XDG_CONFIG_DIRS/picom/picom.conf`.
When `@include` directive is used in the config file, picom will first search for the included file in the parent directory of `picom.conf`, then in `$XDG_CONFIG_HOME/picom/include/`, then in `$XDG_CONFIG_DIRS/picom/include`.
picom uses general libconfig configuration file format. A sample configuration file is available as `picom.sample.conf` in the source tree. Most of commandline switches can be used as options in configuration file as well. For example, *--vsync* option documented above can be set in the configuration file using `vsync = `. Command line options will always overwrite the settings in the configuration file.
Window-type-specific settings are exposed only in configuration file and has the following format:
Expand Down
5 changes: 5 additions & 0 deletions src/backend/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,9 @@ struct backend_blit_args {
/// will be normalized so that the maximum brightness is
/// this value.
double max_brightness;
/// Scale factor for the horizontal and vertical direction (X for horizontal,
/// Y for vertical).
vec2 scale;
/// Corner radius of the source image. The corners of
/// the source image will be rounded.
double corner_radius;
Expand All @@ -139,6 +142,8 @@ struct backend_blit_args {
bool color_inverted;
};

static const vec2 SCALE_IDENTITY = {1.0, 1.0};

enum backend_image_format {
/// A format that can be used for normal rendering, and binding
/// X pixmaps.
Expand Down
22 changes: 11 additions & 11 deletions src/backend/gl/blur.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,18 +344,18 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
}

// Original region for the final compositing step from blur result to target.
auto coord = ccalloc(nrects * 16, GLint);
auto coord = ccalloc(nrects * 16, GLfloat);
auto indices = ccalloc(nrects * 6, GLuint);
gl_mask_rects_to_coords(origin, nrects, rects, coord, indices);
gl_mask_rects_to_coords(origin, nrects, rects, SCALE_IDENTITY, coord, indices);
if (!target->y_inverted) {
gl_y_flip_target(nrects, coord, target->height);
}

// Resize region for sampling from source texture, and for blur passes
auto coord_resized = ccalloc(nrects_resized * 16, GLint);
auto coord_resized = ccalloc(nrects_resized * 16, GLfloat);
auto indices_resized = ccalloc(nrects_resized * 6, GLuint);
gl_mask_rects_to_coords(origin, nrects_resized, rects_resized, coord_resized,
indices_resized);
gl_mask_rects_to_coords(origin, nrects_resized, rects_resized, SCALE_IDENTITY,
coord_resized, indices_resized);
pixman_region32_fini(&reg_blur_resized);
// FIXME(yshui) In theory we should handle blurring a non-y-inverted source, but
// we never actually use that capability anywhere.
Expand All @@ -375,9 +375,9 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
indices, GL_STREAM_DRAW);
glEnableVertexAttribArray(vert_coord_loc);
glEnableVertexAttribArray(vert_in_texcoord_loc);
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
glVertexAttribPointer(vert_coord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, NULL);
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat) * 4, (void *)(sizeof(GLfloat) * 2));

glBindVertexArray(vao[1]);
glBindBuffer(GL_ARRAY_BUFFER, bo[2]);
Expand All @@ -389,9 +389,9 @@ bool gl_blur(struct backend_base *base, ivec2 origin, image_handle target_,
GL_STREAM_DRAW);
glEnableVertexAttribArray(vert_coord_loc);
glEnableVertexAttribArray(vert_in_texcoord_loc);
glVertexAttribPointer(vert_coord_loc, 2, GL_INT, GL_FALSE, sizeof(GLint) * 4, NULL);
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_INT, GL_FALSE,
sizeof(GLint) * 4, (void *)(sizeof(GLint) * 2));
glVertexAttribPointer(vert_coord_loc, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 4, NULL);
glVertexAttribPointer(vert_in_texcoord_loc, 2, GL_FLOAT, GL_FALSE,
sizeof(GLfloat) * 4, (void *)(sizeof(GLfloat) * 2));

int vao_nelems[2] = {nrects * 6, nrects_resized * 6};

Expand Down
94 changes: 53 additions & 41 deletions src/backend/gl/gl_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -366,10 +366,10 @@ struct gl_vertex_attribs_definition {
};

static const struct gl_vertex_attribs_definition gl_blit_vertex_attribs = {
.stride = sizeof(GLint) * 4,
.stride = sizeof(GLfloat) * 4,
.count = 2,
.attribs = {{GL_INT, vert_coord_loc, NULL},
{GL_INT, vert_in_texcoord_loc, ((GLint *)NULL) + 2}},
.attribs = {{GL_FLOAT, vert_coord_loc, NULL},
{GL_FLOAT, vert_in_texcoord_loc, ((GLfloat *)NULL) + 2}},
};

/**
Expand All @@ -384,7 +384,7 @@ static const struct gl_vertex_attribs_definition gl_blit_vertex_attribs = {
* @param nuniforms number of uniforms for `shader`
* @param uniforms uniforms for `shader`
*/
static void gl_blit_inner(GLuint target_fbo, int nrects, GLint *coord, GLuint *indices,
static void gl_blit_inner(GLuint target_fbo, int nrects, GLfloat *coord, GLuint *indices,
const struct gl_vertex_attribs_definition *vert_attribs,
const struct gl_shader *shader, int nuniforms,
struct gl_uniform_value *uniforms) {
Expand Down Expand Up @@ -475,26 +475,29 @@ static void gl_blit_inner(GLuint target_fbo, int nrects, GLint *coord, GLuint *i
gl_check_err();
}

void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLint *coord,
GLuint *indices) {
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, vec2 scale,
GLfloat *coord, GLuint *indices) {
for (ptrdiff_t i = 0; i < nrects; i++) {
// Rectangle in source image coordinates
rect_t rect_src = region_translate_rect(rects[i], ivec2_neg(origin));
// Rectangle in target image coordinates
rect_t rect_dst = rects[i];

// clang-format off
memcpy(&coord[i * 16],
((GLint[][2]){
{rect_dst.x1, rect_dst.y1}, // Vertex, bottom-left
{rect_src.x1, rect_src.y1}, // Texture
{rect_dst.x2, rect_dst.y1}, // Vertex, bottom-right
{rect_src.x2, rect_src.y1}, // Texture
{rect_dst.x2, rect_dst.y2}, // Vertex, top-right
{rect_src.x2, rect_src.y2}, // Texture
{rect_dst.x1, rect_dst.y2}, // Vertex, top-left
{rect_src.x1, rect_src.y2}, // Texture
((GLfloat[][2]){
// Interleaved vertex and texture coordinates, starting with vertex.
{(GLfloat)rect_dst.x1, (GLfloat)rect_dst.y1}, // bottom-left
{(GLfloat)(rect_src.x1 / scale.x), (GLfloat)(rect_src.y1 / scale.y)},
{(GLfloat)rect_dst.x2, (GLfloat)rect_dst.y1}, // bottom-right
{(GLfloat)(rect_src.x2 / scale.x), (GLfloat)(rect_src.y1 / scale.y)},
{(GLfloat)rect_dst.x2, (GLfloat)rect_dst.y2}, // top-right
{(GLfloat)(rect_src.x2 / scale.x), (GLfloat)(rect_src.y2 / scale.y)},
{(GLfloat)rect_dst.x1, (GLfloat)rect_dst.y2}, // top-left
{(GLfloat)(rect_src.x1 / scale.x), (GLfloat)(rect_src.y2 / scale.y)},
}),
sizeof(GLint[2]) * 8);
// clang-format on

GLuint u = (GLuint)(i * 4);
memcpy(&indices[i * 6],
Expand All @@ -509,13 +512,13 @@ void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLin
/// @param[in] nrects number of rectangles
/// @param[in] coord OpenGL vertex coordinates
/// @param[in] texture_height height of the source image
static inline void gl_y_flip_texture(int nrects, GLint *coord, GLint texture_height) {
static inline void gl_y_flip_texture(int nrects, GLfloat *coord, GLint texture_height) {
for (ptrdiff_t i = 0; i < nrects; i++) {
auto current_rect = &coord[i * 16]; // 16 numbers per rectangle
for (ptrdiff_t j = 0; j < 4; j++) {
// 4 numbers per vertex, texture coordinates are the last two
auto current_vertex = &current_rect[j * 4 + 2];
current_vertex[1] = texture_height - current_vertex[1];
current_vertex[1] = (GLfloat)texture_height - current_vertex[1];
}
}
}
Expand All @@ -524,7 +527,7 @@ static inline void gl_y_flip_texture(int nrects, GLint *coord, GLint texture_hei
/// shader, and uniforms.
static int
gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_args *args,
GLint **coord, GLuint **indices, struct gl_shader **shader,
GLfloat **coord, GLuint **indices, struct gl_shader **shader,
struct gl_uniform_value *uniforms) {
auto img = (struct gl_texture *)args->source_image;
int nrects;
Expand All @@ -534,9 +537,9 @@ gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_a
// Nothing to paint
return 0;
}
*coord = ccalloc(nrects * 16, GLint);
*coord = ccalloc(nrects * 16, GLfloat);
*indices = ccalloc(nrects * 6, GLuint);
gl_mask_rects_to_coords(origin, nrects, rects, *coord, *indices);
gl_mask_rects_to_coords(origin, nrects, rects, args->scale, *coord, *indices);
if (!img->y_inverted) {
gl_y_flip_texture(nrects, *coord, img->height);
}
Expand All @@ -558,11 +561,13 @@ gl_lower_blit_args(struct gl_data *gd, ivec2 origin, const struct backend_blit_a
border_width = 0;
}
// clang-format off
auto tex_sampler = vec2_eq(args->scale, SCALE_IDENTITY) ?
gd->samplers[GL_SAMPLER_REPEAT] : gd->samplers[GL_SAMPLER_REPEAT_SCALE];
struct gl_uniform_value from_uniforms[] = {
[UNIFORM_OPACITY_LOC] = {.type = GL_FLOAT, .f = (float)args->opacity},
[UNIFORM_INVERT_COLOR_LOC] = {.type = GL_INT, .i = args->color_inverted},
[UNIFORM_TEX_LOC] = {.type = GL_TEXTURE_2D,
.tu = {img->texture, gd->samplers[GL_SAMPLER_REPEAT]}},
.tu = {img->texture, tex_sampler}},
[UNIFORM_EFFECTIVE_SIZE_LOC] = {.type = GL_FLOAT_VEC2,
.f2 = {(float)args->effective_size.width,
(float)args->effective_size.height}},
Expand Down Expand Up @@ -613,7 +618,7 @@ bool gl_blit(backend_t *base, ivec2 origin, image_handle target_,
return false;
}

GLint *coord;
GLfloat *coord;
GLuint *indices;
struct gl_shader *shader;
struct gl_uniform_value uniforms[NUMBER_OF_UNIFORMS] = {};
Expand Down Expand Up @@ -678,9 +683,9 @@ static bool gl_copy_area_draw(struct gl_data *gd, ivec2 origin,
return true;
}

auto coord = ccalloc(16 * nrects, GLint);
auto coord = ccalloc(16 * nrects, GLfloat);
auto indices = ccalloc(6 * nrects, GLuint);
gl_mask_rects_to_coords(origin, nrects, rects, coord, indices);
gl_mask_rects_to_coords(origin, nrects, rects, SCALE_IDENTITY, coord, indices);
if (!target->y_inverted) {
gl_y_flip_target(nrects, coord, target->height);
}
Expand Down Expand Up @@ -856,6 +861,17 @@ uint64_t gl_get_shader_attributes(backend_t *backend_data attr_unused, void *sha
return ret;
}

static const struct {
GLint filter;
GLint wrap;
} gl_sampler_params[] = {
[GL_SAMPLER_REPEAT] = {GL_NEAREST, GL_REPEAT},
[GL_SAMPLER_REPEAT_SCALE] = {GL_LINEAR, GL_REPEAT},
[GL_SAMPLER_BLUR] = {GL_LINEAR, GL_CLAMP_TO_EDGE},
[GL_SAMPLER_EDGE] = {GL_NEAREST, GL_CLAMP_TO_EDGE},
[GL_SAMPLER_BORDER] = {GL_NEAREST, GL_CLAMP_TO_BORDER},
};

bool gl_init(struct gl_data *gd, session_t *ps) {
if (!epoxy_has_gl_extension("GL_ARB_explicit_uniform_location")) {
log_error("GL_ARB_explicit_uniform_location support is required but "
Expand Down Expand Up @@ -965,20 +981,16 @@ bool gl_init(struct gl_data *gd, session_t *ps) {
gd->back_image.height = ps->root_height;

glGenSamplers(GL_MAX_SAMPLERS, gd->samplers);
for (int i = 0; i < GL_MAX_SAMPLERS; i++) {
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
glSamplerParameterf(gd->samplers[GL_SAMPLER_EDGE], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameterf(gd->samplers[GL_SAMPLER_EDGE], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BLUR], GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BORDER], GL_TEXTURE_WRAP_S,
GL_CLAMP_TO_BORDER);
glSamplerParameterf(gd->samplers[GL_SAMPLER_BORDER], GL_TEXTURE_WRAP_T,
GL_CLAMP_TO_BORDER);
for (size_t i = 0; i < ARR_SIZE(gl_sampler_params); i++) {
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MIN_FILTER,
gl_sampler_params[i].filter);
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_MAG_FILTER,
gl_sampler_params[i].filter);
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_WRAP_S,
gl_sampler_params[i].wrap);
glSamplerParameteri(gd->samplers[i], GL_TEXTURE_WRAP_T,
gl_sampler_params[i].wrap);
}

gd->logger = gl_string_marker_logger_new();
if (gd->logger) {
Expand Down Expand Up @@ -1100,9 +1112,9 @@ image_handle gl_new_image(backend_t *backend_data attr_unused,
bool gl_apply_alpha(backend_t *base, image_handle target, double alpha, const region_t *reg_op) {
auto gd = (struct gl_data *)base;
static const struct gl_vertex_attribs_definition vertex_attribs = {
.stride = sizeof(GLint) * 4,
.stride = sizeof(GLfloat) * 4,
.count = 1,
.attribs = {{GL_INT, vert_coord_loc, NULL}},
.attribs = {{GL_FLOAT, vert_coord_loc, NULL}},
};
if (alpha == 1.0 || !pixman_region32_not_empty(reg_op)) {
return true;
Expand All @@ -1115,7 +1127,7 @@ bool gl_apply_alpha(backend_t *base, image_handle target, double alpha, const re
int nrects;
const rect_t *rect = pixman_region32_rectangles(reg_op, &nrects);

auto coord = ccalloc(nrects * 16, GLint);
auto coord = ccalloc(nrects * 16, GLfloat);
auto indices = ccalloc(nrects * 6, GLuint);

struct gl_uniform_value uniforms[] = {
Expand Down
19 changes: 11 additions & 8 deletions src/backend/gl/gl_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@ struct gl_texture {
};

enum gl_sampler {
/// A sampler that repeats the texture, with nearest filtering.
GL_SAMPLER_REPEAT = 0,
/// A sampler that repeats the texture, with linear filtering.
GL_SAMPLER_REPEAT_SCALE,
/// Clamp to edge
GL_SAMPLER_EDGE,
/// Clamp to border, border color will be (0, 0, 0, 0)
Expand Down Expand Up @@ -126,13 +129,13 @@ void gl_prepare(backend_t *base, const region_t *reg);
/// @param[in] rects mask rectangles, in mask coordinates
/// @param[out] coord OpenGL vertex coordinates, suitable for creating VAO/VBO
/// @param[out] indices OpenGL vertex indices, suitable for creating VAO/VBO
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, GLint *coord,
GLuint *indices);
/// Like `gl_mask_rects_to_coords`, but with `origin` and `mask_origin` set to 0. i.e. all
/// coordinates are in the same space.
void gl_mask_rects_to_coords(ivec2 origin, int nrects, const rect_t *rects, vec2 scale,
GLfloat *coord, GLuint *indices);
/// Like `gl_mask_rects_to_coords`, but with `origin` is (0, 0).
static inline void gl_mask_rects_to_coords_simple(int nrects, const rect_t *rects,
GLint *coord, GLuint *indices) {
return gl_mask_rects_to_coords((ivec2){0, 0}, nrects, rects, coord, indices);
GLfloat *coord, GLuint *indices) {
return gl_mask_rects_to_coords((ivec2){0, 0}, nrects, rects, SCALE_IDENTITY,
coord, indices);
}

GLuint gl_create_shader(GLenum shader_type, const char *shader_str);
Expand Down Expand Up @@ -210,13 +213,13 @@ static inline GLuint gl_bind_image_to_fbo(struct gl_data *gd, image_handle image
/// @param[in] nrects number of rectangles
/// @param[in] coord OpenGL vertex coordinates
/// @param[in] target_height height of the target image
static inline void gl_y_flip_target(int nrects, GLint *coord, GLint target_height) {
static inline void gl_y_flip_target(int nrects, GLfloat *coord, GLint target_height) {
for (ptrdiff_t i = 0; i < nrects; i++) {
auto current_rect = &coord[i * 16]; // 16 numbers per rectangle
for (ptrdiff_t j = 0; j < 4; j++) {
// 4 numbers per vertex, target coordinates are the first two
auto current_vertex = &current_rect[j * 4];
current_vertex[1] = target_height - current_vertex[1];
current_vertex[1] = (GLfloat)target_height - current_vertex[1];
}
}
}
Expand Down
Loading

0 comments on commit fc39512

Please sign in to comment.