mirror of https://github.com/yshui/picom.git
Compare commits
7 Commits
651dd73560
...
fa42eac7a5
Author | SHA1 | Date |
---|---|---|
Maxim Solovyov | fa42eac7a5 | |
Yuxuan Shui | d6e3335cfd | |
Yuxuan Shui | c5e58da1ba | |
Yuxuan Shui | e5e618fb50 | |
Yuxuan Shui | 09b58035f4 | |
Yuxuan Shui | 4aa283df98 | |
Yuxuan Shui | cf08a3b7a5 |
|
@ -72,7 +72,7 @@ jobs:
|
|||
executor: e
|
||||
steps:
|
||||
- build:
|
||||
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false
|
||||
build-config: -Dopengl=false -Ddbus=false -Dregex=false
|
||||
release:
|
||||
executor: e
|
||||
steps:
|
||||
|
@ -104,7 +104,7 @@ jobs:
|
|||
steps:
|
||||
- build:
|
||||
cc: clang
|
||||
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false
|
||||
build-config: -Dopengl=false -Ddbus=false -Dregex=false
|
||||
clang_nogl:
|
||||
executor: e
|
||||
steps:
|
||||
|
|
|
@ -40,6 +40,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.
|
||||
|
||||
# v11.2 (2024-Feb-13)
|
||||
|
||||
|
|
|
@ -39,8 +39,8 @@ Assuming you already have all the usual building tools installed (e.g. gcc, pyth
|
|||
* xcb-present
|
||||
* xcb-glx
|
||||
* pixman
|
||||
* libconfig
|
||||
* libdbus (optional, disable with the `-Ddbus=false` meson configure flag)
|
||||
* libconfig (optional, disable with the `-Dconfig_file=false` meson configure flag)
|
||||
* libGL, libEGL, libepoxy (optional, disable with the `-Dopengl=false` meson configure flag)
|
||||
* libpcre2 (optional, disable with the `-Dregex=false` meson configure flag)
|
||||
* libev
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
option('sanitize', type: 'boolean', value: false, description: 'Build with sanitizers enabled (deprecated)')
|
||||
option('config_file', type: 'boolean', value: true, description: 'Enable config file support')
|
||||
option('regex', type: 'boolean', value: true, description: 'Enable regex support in window conditions')
|
||||
|
||||
option('vsync_drm', type: 'boolean', value: false, description: 'Enable support for using drm for vsync')
|
||||
|
|
|
@ -371,12 +371,6 @@ static image_handle
|
|||
glx_bind_pixmap(backend_t *base, xcb_pixmap_t pixmap, struct xvisual_info fmt) {
|
||||
GLXPixmap *glxpixmap = NULL;
|
||||
auto gd = (struct _glx_data *)base;
|
||||
// Retrieve pixmap parameters, if they aren't provided
|
||||
if (fmt.visual_depth > OPENGL_MAX_DEPTH) {
|
||||
log_error("Requested depth %d higher than max possible depth %d.",
|
||||
fmt.visual_depth, OPENGL_MAX_DEPTH);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fmt.visual_depth < 0) {
|
||||
log_error("Pixmap %#010x with invalid depth %d", pixmap, fmt.visual_depth);
|
||||
|
|
3
src/c2.c
3
src/c2.c
|
@ -416,9 +416,6 @@ c2_lptr_t *c2_parse(c2_lptr_t **pcondlst, const char *pattern, void *data) {
|
|||
}
|
||||
|
||||
TEST_CASE(c2_parse) {
|
||||
log_init_tls();
|
||||
// log_add_target_tls(stderr_logger_new());
|
||||
|
||||
char str[1024];
|
||||
c2_lptr_t *cond = c2_parse(NULL, "name = \"xterm\"", NULL);
|
||||
struct atom *atoms = init_mock_atoms();
|
||||
|
|
|
@ -70,9 +70,6 @@
|
|||
#define US_PER_SEC 1000000L
|
||||
#define MS_PER_SEC 1000
|
||||
|
||||
/// @brief Maximum OpenGL FBConfig depth.
|
||||
#define OPENGL_MAX_DEPTH 32
|
||||
|
||||
/// @brief Maximum OpenGL buffer age.
|
||||
#define CGLX_MAX_BUFFER_AGE 5
|
||||
|
||||
|
@ -199,6 +196,9 @@ typedef struct session {
|
|||
paint_t root_tile_paint;
|
||||
/// The backend data the root pixmap bound to
|
||||
image_handle root_image;
|
||||
/// The root pixmap generation, incremented everytime
|
||||
/// the root pixmap changes
|
||||
uint64_t root_image_generation;
|
||||
/// A region of the size of the screen.
|
||||
region_t screen_reg;
|
||||
/// Picture of root window. Destination of painting in no-DBE painting
|
||||
|
@ -271,8 +271,6 @@ typedef struct session {
|
|||
/// Render command builder
|
||||
struct command_builder *command_builder;
|
||||
struct renderer *renderer;
|
||||
/// Whether the root image has been changed since last render
|
||||
bool root_damaged;
|
||||
/// Whether all windows are currently redirected.
|
||||
bool redirected;
|
||||
/// Pre-generated alpha pictures.
|
||||
|
|
|
@ -887,15 +887,7 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
|
|||
// clang-format on
|
||||
|
||||
char *ret = NULL;
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
ret = parse_config_libconfig(opt, config_file, shadow_enable, fading_enable,
|
||||
hasneg, winopt_mask);
|
||||
#else
|
||||
(void)config_file;
|
||||
(void)shadow_enable;
|
||||
(void)fading_enable;
|
||||
(void)hasneg;
|
||||
(void)winopt_mask;
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -17,9 +17,7 @@
|
|||
|
||||
#include "uthash_extra.h"
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
#include <libconfig.h>
|
||||
#endif
|
||||
|
||||
#include "compiler.h"
|
||||
#include "kernel.h"
|
||||
|
@ -311,7 +309,6 @@ void parse_debug_options(struct debug_options *);
|
|||
*/
|
||||
bool condlst_add(c2_lptr_t **, const char *);
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
const char *xdg_config_home(void);
|
||||
char **xdg_config_dirs(void);
|
||||
|
||||
|
@ -326,7 +323,6 @@ char **xdg_config_dirs(void);
|
|||
char *
|
||||
parse_config_libconfig(options_t *, const char *config_file, bool *shadow_enable,
|
||||
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||
#endif
|
||||
|
||||
void set_default_winopts(options_t *, win_option_mask_t *, bool shadow_enable,
|
||||
bool fading_enable, bool blur_enable);
|
||||
|
|
|
@ -3,13 +3,5 @@
|
|||
|
||||
#pragma once
|
||||
#include <xcb/xcb.h>
|
||||
#include "compiler.h"
|
||||
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
int inspect_main(int argc, char **argv, const char *config_file);
|
||||
#else
|
||||
static inline int inspect_main(int argc attr_unused, char **argv attr_unused,
|
||||
const char *config_file attr_unused) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -11,7 +11,7 @@ srcs = [ files('picom.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.
|
|||
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c',
|
||||
'options.c', 'event.c', 'cache.c', 'atom.c', 'file_watch.c', 'statistics.c',
|
||||
'vblank.c', 'transition.c', 'wm.c', 'renderer/layout.c', 'renderer/command_builder.c',
|
||||
'renderer/renderer.c', 'renderer/damage.c') ]
|
||||
'renderer/renderer.c', 'renderer/damage.c', 'config_libconfig.c', 'inspect.c') ]
|
||||
picom_inc = include_directories('.')
|
||||
|
||||
cflags = []
|
||||
|
@ -34,6 +34,7 @@ endforeach
|
|||
foreach i : required_xcb_packages
|
||||
base_deps += [dependency(i, version: '>=1.12.0', required: true)]
|
||||
endforeach
|
||||
base_deps += [dependency('libconfig', version: '>=1.4', required: true)]
|
||||
|
||||
if not cc.has_header('uthash.h')
|
||||
error('Dependency uthash not found')
|
||||
|
@ -41,12 +42,6 @@ endif
|
|||
|
||||
deps = []
|
||||
|
||||
if get_option('config_file')
|
||||
deps += [dependency('libconfig', version: '>=1.4', required: true)]
|
||||
|
||||
cflags += ['-DCONFIG_LIBCONFIG']
|
||||
srcs += [ 'config_libconfig.c', 'inspect.c' ]
|
||||
endif
|
||||
if get_option('regex')
|
||||
pcre = dependency('libpcre2-8', required: true)
|
||||
cflags += ['-DCONFIG_REGEX_PCRE']
|
||||
|
@ -97,9 +92,7 @@ if get_option('unittest')
|
|||
test('picom unittest', picom, args: [ '--unittest' ])
|
||||
endif
|
||||
|
||||
if get_option('config_file')
|
||||
install_symlink('picom-inspect', install_dir: 'bin', pointing_to: 'picom')
|
||||
endif
|
||||
install_symlink('picom-inspect', install_dir: 'bin', pointing_to: 'picom')
|
||||
|
||||
if cc.has_argument('-fsanitize=fuzzer')
|
||||
c2_fuzz = executable('c2_fuzz', srcs + ['fuzzer/c2.c'],
|
||||
|
|
|
@ -746,11 +746,6 @@ bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap,
|
|||
log_error("Failed to query info of pixmap %#010x.", pixmap);
|
||||
return false;
|
||||
}
|
||||
if (r->depth > OPENGL_MAX_DEPTH) {
|
||||
log_error("Requested depth %d higher than %d.", depth,
|
||||
OPENGL_MAX_DEPTH);
|
||||
return false;
|
||||
}
|
||||
depth = r->depth;
|
||||
width = r->width;
|
||||
height = r->height;
|
||||
|
|
|
@ -34,9 +34,7 @@ struct picom_option {
|
|||
// clang-format off
|
||||
static const struct option *longopts = NULL;
|
||||
static const struct picom_option picom_options[] = {
|
||||
#ifdef CONFIG_LIBCONFIG
|
||||
{"config" , required_argument, 256, NULL , "Path to the configuration file."},
|
||||
#endif
|
||||
{"help" , no_argument , 'h', NULL , "Print this help message and exit."},
|
||||
{"shadow-radius" , required_argument, 'r', NULL , "The blur radius for shadows. (default 12)"},
|
||||
{"shadow-opacity" , required_argument, 'o', NULL , "The translucency for shadows. (default .75)"},
|
||||
|
|
12
src/picom.c
12
src/picom.c
|
@ -1189,12 +1189,12 @@ void root_damaged(session_t *ps) {
|
|||
|
||||
ps->root_image = ps->backend_data->ops->v2.bind_pixmap(
|
||||
ps->backend_data, pixmap, x_get_visual_info(&ps->c, visual));
|
||||
ps->root_image_generation += 1;
|
||||
if (!ps->root_image) {
|
||||
err:
|
||||
log_error("Failed to bind root back pixmap");
|
||||
}
|
||||
}
|
||||
ps->root_damaged = true;
|
||||
}
|
||||
|
||||
// Mark screen damaged
|
||||
|
@ -1846,7 +1846,7 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
|
|||
auto render_start_us =
|
||||
(uint64_t)now.tv_sec * 1000000UL + (uint64_t)now.tv_nsec / 1000;
|
||||
layout_manager_append_layout(
|
||||
ps->layout_manager, ps->wm,
|
||||
ps->layout_manager, ps->wm, ps->root_image_generation,
|
||||
(struct geometry){.width = ps->root_width,
|
||||
.height = ps->root_height});
|
||||
bool succeeded = renderer_render(
|
||||
|
@ -2888,3 +2888,11 @@ int PICOM_MAIN(int argc, char **argv) {
|
|||
|
||||
return ret_code;
|
||||
}
|
||||
|
||||
#ifdef UNIT_TEST
|
||||
static void unittest_setup(void) {
|
||||
log_init_tls();
|
||||
// log_add_target_tls(stderr_logger_new());
|
||||
}
|
||||
void (*test_h_unittest_setup)(void) = unittest_setup;
|
||||
#endif
|
||||
|
|
|
@ -147,9 +147,8 @@ void layout_manager_damage(struct layout_manager *lm, unsigned buffer_age,
|
|||
pixman_region32_init(&scratch_region);
|
||||
pixman_region32_clear(damage);
|
||||
if (past_layout->size.width != curr_layout->size.width ||
|
||||
past_layout->size.height != curr_layout->size.height) {
|
||||
// We might be able to do better for blur size change, but currently we
|
||||
// don't even support changing that.
|
||||
past_layout->size.height != curr_layout->size.height ||
|
||||
past_layout->root_image_generation != curr_layout->root_image_generation) {
|
||||
pixman_region32_union_rect(damage, damage, 0, 0,
|
||||
(unsigned)curr_layout->size.width,
|
||||
(unsigned)curr_layout->size.height);
|
||||
|
|
|
@ -26,9 +26,6 @@ struct layout_manager {
|
|||
unsigned current;
|
||||
/// Mapping from window to its index in the current layout.
|
||||
struct layer_index *layer_indices;
|
||||
/// Output render plan.
|
||||
struct render_plan *plan;
|
||||
unsigned plan_capacity;
|
||||
struct list_node free_indices;
|
||||
|
||||
// internal
|
||||
|
@ -110,8 +107,6 @@ struct layout_manager *layout_manager_new(unsigned max_buffer_age) {
|
|||
planner->max_buffer_age = max_buffer_age + 1;
|
||||
planner->current = 0;
|
||||
planner->layer_indices = NULL;
|
||||
planner->plan_capacity = 0;
|
||||
planner->plan = NULL;
|
||||
list_init_head(&planner->free_indices);
|
||||
pixman_region32_init(&planner->scratch_region);
|
||||
for (unsigned i = 0; i <= max_buffer_age; i++) {
|
||||
|
@ -133,11 +128,7 @@ void layout_manager_free(struct layout_manager *lm) {
|
|||
list_remove(&i->free_list);
|
||||
free(i);
|
||||
}
|
||||
for (unsigned i = 0; i < lm->plan_capacity; i++) {
|
||||
pixman_region32_fini(&lm->plan[i].render);
|
||||
}
|
||||
pixman_region32_fini(&lm->scratch_region);
|
||||
free(lm->plan);
|
||||
free(lm);
|
||||
}
|
||||
|
||||
|
@ -152,11 +143,13 @@ void layout_manager_free(struct layout_manager *lm) {
|
|||
// above.
|
||||
|
||||
void layout_manager_append_layout(struct layout_manager *lm, struct wm *wm,
|
||||
struct geometry size) {
|
||||
uint64_t root_pixmap_generation, struct geometry size) {
|
||||
auto prev_layout = &lm->layouts[lm->current];
|
||||
lm->current = (lm->current + 1) % lm->max_buffer_age;
|
||||
auto layout = &lm->layouts[lm->current];
|
||||
command_builder_command_list_free(layout->commands);
|
||||
layout->root_image_generation = root_pixmap_generation;
|
||||
|
||||
unsigned nlayers = wm_stack_num_managed_windows(wm);
|
||||
if (nlayers > layout->capacity) {
|
||||
struct layer *new_layers =
|
||||
|
|
|
@ -71,6 +71,8 @@ struct layer {
|
|||
/// Layout of windows at a specific frame
|
||||
struct layout {
|
||||
struct geometry size;
|
||||
/// The root image generation, see `struct session::root_image_generation`
|
||||
uint64_t root_image_generation;
|
||||
/// Number of layers in `layers`
|
||||
unsigned len;
|
||||
/// Capacity of `layers`
|
||||
|
@ -88,11 +90,6 @@ struct layout {
|
|||
struct backend_command *commands;
|
||||
};
|
||||
|
||||
struct render_plan {
|
||||
region_t render;
|
||||
const struct layer *layer;
|
||||
};
|
||||
|
||||
struct wm;
|
||||
struct layout_manager;
|
||||
|
||||
|
@ -101,7 +98,7 @@ struct layout_manager;
|
|||
/// layouts, with its size chosen at creation time. Calling this will push at new layout
|
||||
/// at the end of the ring buffer, and remove the oldest layout if the buffer is full.
|
||||
void layout_manager_append_layout(struct layout_manager *lm, struct wm *wm,
|
||||
struct geometry size);
|
||||
uint64_t root_image_generation, struct geometry size);
|
||||
/// Get the layout `age` frames into the past. Age `0` is the most recently appended
|
||||
/// layout.
|
||||
struct layout *layout_manager_layout(struct layout_manager *lm, unsigned age);
|
||||
|
|
|
@ -421,6 +421,32 @@ static bool renderer_prepare_commands(struct renderer *r, struct backend_base *b
|
|||
return true;
|
||||
}
|
||||
|
||||
void renderer_ensure_monitor_repaint_ready(struct renderer *r, struct backend_base *backend) {
|
||||
if (!r->monitor_repaint_pixel) {
|
||||
r->monitor_repaint_pixel = backend->ops->v2.new_image(
|
||||
backend, BACKEND_IMAGE_FORMAT_PIXMAP, (struct geometry){1, 1});
|
||||
BUG_ON(!r->monitor_repaint_pixel);
|
||||
backend->ops->v2.clear(backend, r->monitor_repaint_pixel,
|
||||
(struct color){.alpha = 0.5, .red = 0.5});
|
||||
}
|
||||
if (!r->monitor_repaint_copy) {
|
||||
r->monitor_repaint_copy = ccalloc(r->max_buffer_age, image_handle);
|
||||
for (int i = 0; i < r->max_buffer_age; i++) {
|
||||
r->monitor_repaint_copy[i] = backend->ops->v2.new_image(
|
||||
backend, BACKEND_IMAGE_FORMAT_PIXMAP,
|
||||
(struct geometry){.width = r->canvas_size.width,
|
||||
.height = r->canvas_size.height});
|
||||
BUG_ON(!r->monitor_repaint_copy[i]);
|
||||
}
|
||||
}
|
||||
if (!r->monitor_repaint_region) {
|
||||
r->monitor_repaint_region = ccalloc(r->max_buffer_age, region_t);
|
||||
for (int i = 0; i < r->max_buffer_age; i++) {
|
||||
pixman_region32_init(&r->monitor_repaint_region[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// @return true if a frame is rendered, false if this frame is skipped.
|
||||
bool renderer_render(struct renderer *r, struct backend_base *backend,
|
||||
image_handle root_image, struct layout_manager *lm,
|
||||
|
@ -448,29 +474,7 @@ bool renderer_render(struct renderer *r, struct backend_base *backend,
|
|||
}
|
||||
|
||||
if (monitor_repaint) {
|
||||
if (!r->monitor_repaint_pixel) {
|
||||
r->monitor_repaint_pixel = backend->ops->v2.new_image(
|
||||
backend, BACKEND_IMAGE_FORMAT_PIXMAP, (struct geometry){1, 1});
|
||||
BUG_ON(!r->monitor_repaint_pixel);
|
||||
backend->ops->v2.clear(backend, r->monitor_repaint_pixel,
|
||||
(struct color){.alpha = 0.5, .red = 0.5});
|
||||
}
|
||||
if (!r->monitor_repaint_copy) {
|
||||
r->monitor_repaint_copy = ccalloc(r->max_buffer_age, image_handle);
|
||||
for (int i = 0; i < r->max_buffer_age; i++) {
|
||||
r->monitor_repaint_copy[i] = backend->ops->v2.new_image(
|
||||
backend, BACKEND_IMAGE_FORMAT_PIXMAP,
|
||||
(struct geometry){.width = r->canvas_size.width,
|
||||
.height = r->canvas_size.height});
|
||||
BUG_ON(!r->monitor_repaint_copy[i]);
|
||||
}
|
||||
}
|
||||
if (!r->monitor_repaint_region) {
|
||||
r->monitor_repaint_region = ccalloc(r->max_buffer_age, region_t);
|
||||
for (int i = 0; i < r->max_buffer_age; i++) {
|
||||
pixman_region32_init(&r->monitor_repaint_region[i]);
|
||||
}
|
||||
}
|
||||
renderer_ensure_monitor_repaint_ready(r, backend);
|
||||
}
|
||||
|
||||
command_builder_build(cb, layout, force_blend, blur_frame, inactive_dim_fixed,
|
||||
|
|
|
@ -85,6 +85,8 @@ TEST_CASE(mstrextend) {
|
|||
/// Parse a floating point number of form (+|-)?[0-9]*(\.[0-9]*)
|
||||
double strtod_simple(const char *src, const char **end) {
|
||||
double neg = 1;
|
||||
bool succeeded = false;
|
||||
*end = src;
|
||||
if (*src == '-') {
|
||||
neg = -1;
|
||||
src++;
|
||||
|
@ -95,6 +97,7 @@ double strtod_simple(const char *src, const char **end) {
|
|||
double ret = 0;
|
||||
while (*src >= '0' && *src <= '9') {
|
||||
ret = ret * 10 + (*src - '0');
|
||||
succeeded = true;
|
||||
src++;
|
||||
}
|
||||
|
||||
|
@ -104,13 +107,17 @@ double strtod_simple(const char *src, const char **end) {
|
|||
while (*src >= '0' && *src <= '9') {
|
||||
frac += mult * (*src - '0');
|
||||
mult *= 0.1;
|
||||
succeeded = true;
|
||||
src++;
|
||||
}
|
||||
ret += frac;
|
||||
}
|
||||
|
||||
*end = src;
|
||||
return ret * neg;
|
||||
if (succeeded) {
|
||||
*end = src;
|
||||
return ret * neg;
|
||||
}
|
||||
return NAN;
|
||||
}
|
||||
|
||||
TEST_CASE(strtod_simple) {
|
||||
|
@ -126,6 +133,10 @@ TEST_CASE(strtod_simple) {
|
|||
result = strtod_simple("+.5", &end);
|
||||
TEST_EQUAL(result, 0.5);
|
||||
TEST_EQUAL(*end, '\0');
|
||||
|
||||
result = strtod_simple("+.", &end);
|
||||
TEST_TRUE(safe_isnan(result));
|
||||
TEST_EQUAL(*end, '+');
|
||||
}
|
||||
|
||||
const char *trim_both(const char *src, size_t *length) {
|
||||
|
|
Loading…
Reference in New Issue