mirror of
https://github.com/yshui/picom.git
synced 2025-04-07 17:44:04 -04:00
backend: prepare to pluginify the backends
Instead of a fixed table, allow an arbitrary number of backends to be registered through `backend_register`. Slightly refactored configuration validation. As a side-effect, you now have to explicitly specify a backend, because due to the dynamic nature of backends, there is no way to choose a default. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
ca12415e22
commit
e512542d71
18 changed files with 396 additions and 222 deletions
|
@ -32,6 +32,7 @@
|
|||
* `override_redirect` in rules now only matches top-level windows that doesn't have a client window. Some window managers (e.g. awesome) set override_redirect for all window manager frame windows, causing this rule to match against everything (#625).
|
||||
* Marginally improve performance when resizing/opening/closing windows. (#1190)
|
||||
* Type and format specifiers are no longer used in rules. These specifiers are what you put after the colon (':') in rules, e.g. the `:32c` in `"_GTK_FRAME_EXTENTS@:32c"`. Now this information is ignored and the property is matched regardless of format or type.
|
||||
* `backend` is now a required option. picom will not start if one is not specified explicitly.
|
||||
|
||||
## Deprecated features
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// SPDX-License-Identifier: MPL-2.0
|
||||
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
|
||||
#include <inttypes.h>
|
||||
#include <xcb/sync.h>
|
||||
#include <xcb/xcb.h>
|
||||
|
||||
|
@ -13,20 +14,69 @@
|
|||
#include "win.h"
|
||||
#include "x.h"
|
||||
|
||||
extern struct backend_operations xrender_ops, dummy_ops;
|
||||
#ifdef CONFIG_OPENGL
|
||||
extern struct backend_operations glx_ops;
|
||||
extern struct backend_operations egl_ops;
|
||||
#endif
|
||||
static struct backend_info {
|
||||
UT_hash_handle hh;
|
||||
const char *name;
|
||||
struct backend_base *(*init)(session_t *ps, xcb_window_t target);
|
||||
bool can_present;
|
||||
} *backend_registry = NULL;
|
||||
|
||||
struct backend_operations *backend_list[NUM_BKEND] = {
|
||||
[BKEND_XRENDER] = &xrender_ops,
|
||||
[BKEND_DUMMY] = &dummy_ops,
|
||||
#ifdef CONFIG_OPENGL
|
||||
[BKEND_GLX] = &glx_ops,
|
||||
[BKEND_EGL] = &egl_ops,
|
||||
#endif
|
||||
};
|
||||
bool backend_register(uint64_t major, uint64_t minor, const char *name,
|
||||
struct backend_base *(*init)(session_t *ps, xcb_window_t target),
|
||||
bool can_present) {
|
||||
if (major != PICOM_BACKEND_MAJOR) {
|
||||
log_error("Backend %s has incompatible major version %" PRIu64
|
||||
", expected %lu",
|
||||
name, major, PICOM_BACKEND_MAJOR);
|
||||
return false;
|
||||
}
|
||||
if (minor > PICOM_BACKEND_MINOR) {
|
||||
log_error("Backend %s has incompatible minor version %" PRIu64
|
||||
", expected %lu",
|
||||
name, minor, PICOM_BACKEND_MINOR);
|
||||
return false;
|
||||
}
|
||||
struct backend_info *info = NULL;
|
||||
HASH_FIND_STR(backend_registry, name, info);
|
||||
if (info) {
|
||||
log_error("Backend %s is already registered", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
info = cmalloc(struct backend_info);
|
||||
info->name = name;
|
||||
info->init = init;
|
||||
info->can_present = can_present;
|
||||
HASH_ADD_KEYPTR(hh, backend_registry, info->name, strlen(info->name), info);
|
||||
return true;
|
||||
}
|
||||
|
||||
struct backend_info *backend_find(const char *name) {
|
||||
struct backend_info *info = NULL;
|
||||
HASH_FIND_STR(backend_registry, name, info);
|
||||
return info;
|
||||
}
|
||||
|
||||
struct backend_base *
|
||||
backend_init(struct backend_info *info, session_t *ps, xcb_window_t target) {
|
||||
return info->init(ps, target);
|
||||
}
|
||||
|
||||
struct backend_info *backend_iter(void) {
|
||||
return backend_registry;
|
||||
}
|
||||
|
||||
struct backend_info *backend_iter_next(struct backend_info *info) {
|
||||
return info->hh.next;
|
||||
}
|
||||
|
||||
const char *backend_name(struct backend_info *info) {
|
||||
return info->name;
|
||||
}
|
||||
|
||||
bool backend_can_present(struct backend_info *info) {
|
||||
return info->can_present;
|
||||
}
|
||||
|
||||
void handle_device_reset(session_t *ps) {
|
||||
log_error("Device reset detected");
|
||||
|
|
|
@ -13,6 +13,10 @@
|
|||
#include "types.h"
|
||||
#include "x.h"
|
||||
|
||||
#define PICOM_BACKEND_MAJOR (1UL)
|
||||
#define PICOM_BACKEND_MINOR (0UL)
|
||||
#define PICOM_BACKEND_MAKE_VERSION(major, minor) ((major) * 1000 + (minor))
|
||||
|
||||
typedef struct session session_t;
|
||||
struct managed_win;
|
||||
|
||||
|
@ -450,12 +454,30 @@ struct backend_operations {
|
|||
|
||||
enum device_status (*device_status)(backend_t *backend_data);
|
||||
};
|
||||
|
||||
extern struct backend_operations *backend_list[];
|
||||
|
||||
struct backend_info;
|
||||
bool backend_execute(struct backend_base *backend, image_handle target, unsigned ncmds,
|
||||
const struct backend_command cmds[ncmds]);
|
||||
|
||||
/// Register a new backend, `major` and `minor` should be the version of the picom backend
|
||||
/// interface. You should just pass `PICOM_BACKEND_MAJOR` and `PICOM_BACKEND_MINOR` here.
|
||||
/// `name` is the name of the backend, `init` is the function to initialize the backend,
|
||||
/// `can_present` should be true if the backend can present the back buffer to the screen,
|
||||
/// false otherwise (e.g. if the backend does off screen rendering, etc.)
|
||||
bool backend_register(uint64_t major, uint64_t minor, const char *name,
|
||||
struct backend_base *(*init)(session_t *ps, xcb_window_t target),
|
||||
bool can_present);
|
||||
struct backend_info *backend_find(const char *name);
|
||||
struct backend_base *
|
||||
backend_init(struct backend_info *info, session_t *ps, xcb_window_t target);
|
||||
struct backend_info *backend_iter(void);
|
||||
struct backend_info *backend_iter_next(struct backend_info *info);
|
||||
const char *backend_name(struct backend_info *info);
|
||||
bool backend_can_present(struct backend_info *info);
|
||||
void log_backend_command_(enum log_level level, const char *func,
|
||||
const struct backend_command *cmd);
|
||||
#define log_backend_command(level, cmd) \
|
||||
log_backend_command_(LOG_LEVEL_##level, __func__, &(cmd));
|
||||
|
||||
/// Define a backend entry point. (Note constructor priority 202 is used here because 1xx
|
||||
/// is reversed by test.h, and 201 is used for logging initialization.)
|
||||
#define BACKEND_ENTRYPOINT(func) static void __attribute__((constructor(202))) func(void)
|
||||
|
|
|
@ -227,3 +227,10 @@ struct backend_operations dummy_ops = {
|
|||
.destroy_blur_context = dummy_destroy_blur_context,
|
||||
.get_blur_size = dummy_get_blur_size,
|
||||
};
|
||||
|
||||
BACKEND_ENTRYPOINT(dummy_register) {
|
||||
if (!backend_register(PICOM_BACKEND_MAJOR, PICOM_BACKEND_MINOR, "dummy",
|
||||
dummy_ops.init, false)) {
|
||||
log_error("Failed to register dummy backend");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -120,6 +120,8 @@ static backend_t *egl_init(session_t *ps, xcb_window_t target) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
log_warn("The egl backend is still experimental, use with care.");
|
||||
|
||||
gd = ccalloc(1, struct egl_data);
|
||||
gd->display = eglGetPlatformDisplayEXT(EGL_PLATFORM_X11_EXT, ps->c.dpy,
|
||||
(EGLint[]){
|
||||
|
@ -389,3 +391,10 @@ void eglext_init(EGLDisplay dpy) {
|
|||
#endif
|
||||
#undef check_ext
|
||||
}
|
||||
|
||||
BACKEND_ENTRYPOINT(egl_register) {
|
||||
if (!backend_register(PICOM_BACKEND_MAJOR, PICOM_BACKEND_MINOR, "egl",
|
||||
egl_ops.init, true)) {
|
||||
log_error("Failed to register egl backend");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -575,3 +575,10 @@ void glxext_init(Display *dpy, int screen) {
|
|||
#endif
|
||||
#undef check_ext
|
||||
}
|
||||
|
||||
BACKEND_ENTRYPOINT(glx_register) {
|
||||
if (!backend_register(PICOM_BACKEND_MAJOR, PICOM_BACKEND_MINOR, "glx",
|
||||
glx_ops.init, true)) {
|
||||
log_error("Failed to register glx backend");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -867,7 +867,12 @@ static void xrender_get_blur_size(void *blur_context, int *width, int *height) {
|
|||
struct backend_operations xrender_ops;
|
||||
static backend_t *xrender_init(session_t *ps, xcb_window_t target) {
|
||||
if (ps->o.dithered_present) {
|
||||
log_warn("\"dithered-present\" is not supported by the xrender backend.");
|
||||
log_warn("\"dithered-present\" is not supported by the xrender backend, "
|
||||
"it will be ignored.");
|
||||
}
|
||||
if (ps->o.max_brightness < 1.0) {
|
||||
log_warn("\"max-brightness\" is not supported by the xrender backend, it "
|
||||
"will be ignored.");
|
||||
}
|
||||
|
||||
auto xd = ccalloc(1, struct xrender_data);
|
||||
|
@ -1043,4 +1048,11 @@ struct backend_operations xrender_ops = {
|
|||
// end
|
||||
};
|
||||
|
||||
BACKEND_ENTRYPOINT(xrender_register) {
|
||||
if (!backend_register(PICOM_BACKEND_MAJOR, PICOM_BACKEND_MINOR, "xrender",
|
||||
xrender_ops.init, true)) {
|
||||
log_error("Failed to register xrender backend");
|
||||
}
|
||||
}
|
||||
|
||||
// vim: set noet sw=8 ts=8:
|
||||
|
|
|
@ -462,7 +462,7 @@ static inline xcb_window_t get_tgt_window(session_t *ps) {
|
|||
* Check if current backend uses GLX.
|
||||
*/
|
||||
static inline bool bkend_use_glx(session_t *ps) {
|
||||
return BKEND_GLX == ps->o.backend || BKEND_XR_GLX_HYBRID == ps->o.backend;
|
||||
return BKEND_GLX == ps->o.legacy_backend || BKEND_XR_GLX_HYBRID == ps->o.legacy_backend;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -635,8 +635,8 @@ void *parse_window_shader_prefix_with_cwd(const char *src, const char **end, voi
|
|||
bool parse_config(options_t *opt, const char *config_file) {
|
||||
// clang-format off
|
||||
*opt = (struct options){
|
||||
.backend = BKEND_XRENDER,
|
||||
.legacy_backends = false,
|
||||
.legacy_backend = BKEND_XRENDER,
|
||||
.use_legacy_backends = false,
|
||||
.glx_no_stencil = false,
|
||||
.mark_wmwin_focused = false,
|
||||
.mark_ovredir_focused = false,
|
||||
|
|
|
@ -158,11 +158,13 @@ typedef struct options {
|
|||
bool debug_mode;
|
||||
// === General ===
|
||||
/// Use the legacy backends?
|
||||
bool legacy_backends;
|
||||
bool use_legacy_backends;
|
||||
/// Path to write PID to.
|
||||
char *write_pid_path;
|
||||
/// The backend in use.
|
||||
int backend;
|
||||
/// Name of the backend
|
||||
struct backend_info *backend;
|
||||
/// The backend in use (for legacy backends).
|
||||
int legacy_backend;
|
||||
/// Log level.
|
||||
int log_level;
|
||||
/// Whether to sync X drawing with X Sync fence to avoid certain delay
|
||||
|
@ -407,7 +409,6 @@ static inline attr_pure int parse_backend(const char *str) {
|
|||
"version will be removed soon.");
|
||||
return BKEND_XR_GLX_HYBRID;
|
||||
}
|
||||
log_error("Invalid backend argument: %s", str);
|
||||
return NUM_BKEND;
|
||||
}
|
||||
|
||||
|
|
|
@ -743,9 +743,10 @@ bool parse_config_libconfig(options_t *opt, const char *config_file) {
|
|||
lcfg_lookup_bool(&cfg, "vsync", &opt->vsync);
|
||||
// --backend
|
||||
if (config_lookup_string(&cfg, "backend", &sval)) {
|
||||
opt->backend = parse_backend(sval);
|
||||
if (opt->backend >= NUM_BKEND) {
|
||||
log_fatal("Cannot parse backend");
|
||||
opt->legacy_backend = parse_backend(sval);
|
||||
opt->backend = backend_find(sval);
|
||||
if (opt->legacy_backend >= NUM_BKEND && opt->backend == NULL) {
|
||||
log_fatal("Invalid backend: %s", sval);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
|
15
src/dbus.c
15
src/dbus.c
|
@ -853,7 +853,6 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg, DBusMessage *reply, DBus
|
|||
dbus_set_error_const(err, DBUS_ERROR_INVALID_ARGS, NULL);
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
assert((size_t)ps->o.backend < sizeof(BACKEND_STRS) / sizeof(BACKEND_STRS[0]));
|
||||
|
||||
#define append(tgt, type, ret) \
|
||||
if (!strcmp(#tgt, target)) { \
|
||||
|
@ -864,6 +863,18 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg, DBusMessage *reply, DBus
|
|||
}
|
||||
#define append_session_option(tgt, type) append(tgt, type, ps->o.tgt)
|
||||
|
||||
if (!strcmp("backend", target)) {
|
||||
assert(!ps->o.use_legacy_backends ||
|
||||
(size_t)ps->o.legacy_backend < ARR_SIZE(BACKEND_STRS));
|
||||
const char *name = ps->o.use_legacy_backends
|
||||
? BACKEND_STRS[ps->o.legacy_backend]
|
||||
: backend_name(ps->o.backend);
|
||||
if (reply != NULL && !cdbus_append_string(reply, name)) {
|
||||
return DBUS_HANDLER_RESULT_NEED_MEMORY;
|
||||
}
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
append(version, string, PICOM_VERSION);
|
||||
append(pid, int32, getpid());
|
||||
append(display, string, DisplayString(ps->c.dpy));
|
||||
|
@ -875,7 +886,7 @@ cdbus_process_opts_get(session_t *ps, DBusMessage *msg, DBusMessage *reply, DBus
|
|||
append(unredir_if_possible_delay, int32, (int32_t)ps->o.unredir_if_possible_delay);
|
||||
append(refresh_rate, int32, 0);
|
||||
append(sw_opti, boolean, false);
|
||||
append(backend, string, BACKEND_STRS[ps->o.backend]);
|
||||
append(backend, string, BACKEND_STRS[ps->o.legacy_backend]);
|
||||
|
||||
append_session_option(unredir_if_possible, boolean);
|
||||
append_session_option(write_pid_path, string);
|
||||
|
|
|
@ -44,17 +44,17 @@ void print_diagnostics(session_t *ps, const char *config_file, bool compositor_r
|
|||
printf("\n### Drivers (inaccurate):\n\n");
|
||||
print_drivers(ps->drivers);
|
||||
|
||||
for (int i = 0; i < NUM_BKEND; i++) {
|
||||
if (backend_list[i] && backend_list[i]->diagnostics) {
|
||||
printf("\n### Backend: %s\n\n", BACKEND_STRS[i]);
|
||||
auto data = backend_list[i]->init(ps, session_get_target_window(ps));
|
||||
if (!data) {
|
||||
printf(" Cannot initialize this backend\n");
|
||||
} else {
|
||||
backend_list[i]->diagnostics(data);
|
||||
backend_list[i]->deinit(data);
|
||||
}
|
||||
for (auto i = backend_iter(); i; i = backend_iter_next(i)) {
|
||||
auto backend_data = backend_init(i, ps, session_get_target_window(ps));
|
||||
if (!backend_data) {
|
||||
printf(" Cannot initialize backend %s\n", backend_name(i));
|
||||
continue;
|
||||
}
|
||||
if (backend_data->ops->diagnostics) {
|
||||
printf("\n### Backend: %s\n\n", backend_name(i));
|
||||
backend_data->ops->diagnostics(backend_data);
|
||||
}
|
||||
backend_data->ops->deinit(backend_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -642,7 +642,7 @@ static inline GLuint glx_gen_texture(GLenum tex_tgt, int width, int height) {
|
|||
*/
|
||||
bool glx_bind_texture(session_t *ps attr_unused, glx_texture_t **pptex, int x, int y,
|
||||
int width, int height) {
|
||||
if (ps->o.backend != BKEND_GLX && ps->o.backend != BKEND_XR_GLX_HYBRID) {
|
||||
if (ps->o.legacy_backend != BKEND_GLX && ps->o.legacy_backend != BKEND_XR_GLX_HYBRID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -698,7 +698,7 @@ bool glx_bind_texture(session_t *ps attr_unused, glx_texture_t **pptex, int x, i
|
|||
*/
|
||||
bool glx_bind_pixmap(session_t *ps, glx_texture_t **pptex, xcb_pixmap_t pixmap, int width,
|
||||
int height, bool repeat, const struct glx_fbconfig_info *fbcfg) {
|
||||
if (ps->o.backend != BKEND_GLX && ps->o.backend != BKEND_XR_GLX_HYBRID) {
|
||||
if (ps->o.legacy_backend != BKEND_GLX && ps->o.legacy_backend != BKEND_XR_GLX_HYBRID) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
279
src/options.c
279
src/options.c
|
@ -298,6 +298,18 @@ store_benchmark_wid(const struct picom_option * /*opt*/, const struct picom_arg
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool store_backend(const struct picom_option * /*opt*/, const struct picom_arg * /*arg*/,
|
||||
const char *arg_str, void *output) {
|
||||
struct options *opt = (struct options *)output;
|
||||
opt->legacy_backend = parse_backend(arg_str);
|
||||
opt->backend = backend_find(arg_str);
|
||||
if (opt->legacy_backend == NUM_BKEND && opt->backend == NULL) {
|
||||
log_error("Invalid backend: %s", arg_str);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define WINDOW_SHADER_RULE \
|
||||
{ .parse_prefix = parse_window_shader_prefix_with_cwd, .free_value = free, }
|
||||
|
||||
|
@ -380,7 +392,7 @@ static const struct picom_option picom_options[] = {
|
|||
"rendered screen. Reduces banding artifacts, but might cause performance "
|
||||
"degradation. Only works with OpenGL."},
|
||||
[341] = {"no-frame-pacing" , DISABLE(frame_pacing) , "Disable frame pacing. This might increase the latency."},
|
||||
[733] = {"legacy-backends" , ENABLE(legacy_backends) , "Use deprecated version of the backends."},
|
||||
[733] = {"legacy-backends" , ENABLE(use_legacy_backends) , "Use deprecated version of the backends."},
|
||||
[800] = {"monitor-repaint" , ENABLE(monitor_repaint) , "Highlight the updated area of the screen. For debugging."},
|
||||
[801] = {"diagnostics" , ENABLE(print_diagnostics) , "Print diagnostic information"},
|
||||
[802] = {"debug-mode" , ENABLE(debug_mode) , "Render into a separate window, and don't take over the screen. Useful when "
|
||||
|
@ -405,7 +417,7 @@ static const struct picom_option picom_options[] = {
|
|||
[259] = {"shadow-blue" , FLOAT(shadow_blue, 0, 1) , "Blue color value of shadow (0.0 - 1.0, defaults to 0)."},
|
||||
[261] = {"inactive-dim" , FLOAT(inactive_dim, 0, 1) , "Dim inactive windows. (0.0 - 1.0, defaults to 0)"},
|
||||
[283] = {"blur-background" , FIXED(blur_method, BLUR_METHOD_KERNEL) , "Blur background of semi-transparent / ARGB windows. May impact performance"},
|
||||
[290] = {"backend" , PARSE_WITH(parse_backend, NUM_BKEND, backend) , "Backend. Possible values are: " BACKENDS},
|
||||
[290] = {"backend" , DO(store_backend) , "Backend. Possible values are: " BACKENDS},
|
||||
[293] = {"benchmark" , INTEGER(benchmark, 0, INT_MAX) , "Benchmark mode. Repeatedly paint until reaching the specified cycles."},
|
||||
[297] = {"active-opacity" , FLOAT(active_opacity, 0, 1) , "Default opacity for active windows. (0.0 - 1.0)"},
|
||||
[302] = {"resize-damage" , INTEGER(resize_damage, INT_MIN, INT_MAX)}, // only used by legacy backends
|
||||
|
@ -483,7 +495,7 @@ static const struct picom_option picom_options[] = {
|
|||
['z'] = {"clear-shadow" , SAY_DEPRECATED(false, CLEAR_SHADOW_DEPRECATION , IGNORE(no_argument))},
|
||||
[272] = {"xinerama-shadow-crop", SAY_DEPRECATED(false, "Use --crop-shadow-to-monitor instead.", ENABLE(crop_shadow_to_monitor))},
|
||||
[287] = {"logpath" , SAY_DEPRECATED(false, "Use --log-file instead." , STRING(logpath))},
|
||||
[289] = {"opengl" , SAY_DEPRECATED(false, "Use --backend=glx instead." , FIXED(backend, BKEND_GLX))},
|
||||
[289] = {"opengl" , SAY_DEPRECATED(false, "Use --backend=glx instead." , FIXED(legacy_backend, BKEND_GLX))},
|
||||
[305] = {"shadow-exclude-reg" , SAY_DEPRECATED(true, "Use --clip-shadow-above instead." , REJECT(required_argument))},
|
||||
|
||||
#undef CLEAR_SHADOW_DEPRECATION
|
||||
|
@ -721,6 +733,143 @@ err:
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool sanitize_options(struct options *opt) {
|
||||
if (opt->use_legacy_backends) {
|
||||
if (opt->legacy_backend == BKEND_EGL) {
|
||||
log_error("The egl backend is not supported with "
|
||||
"--legacy-backends");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->monitor_repaint && opt->legacy_backend != BKEND_XRENDER) {
|
||||
log_warn("For legacy backends, --monitor-repaint is only "
|
||||
"implemented for "
|
||||
"xrender.");
|
||||
}
|
||||
|
||||
if (opt->debug_mode) {
|
||||
log_error("Debug mode does not work with the legacy backends.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->transparent_clipping) {
|
||||
log_error("Transparent clipping does not work with the legacy "
|
||||
"backends");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->max_brightness < 1.0) {
|
||||
log_warn("--max-brightness is not supported by the legacy "
|
||||
"backends. Falling back to 1.0.");
|
||||
opt->max_brightness = 1.0;
|
||||
}
|
||||
|
||||
if (opt->blur_method == BLUR_METHOD_DUAL_KAWASE) {
|
||||
log_warn("Dual-kawase blur is not implemented by the legacy "
|
||||
"backends.");
|
||||
opt->blur_method = BLUR_METHOD_NONE;
|
||||
}
|
||||
|
||||
if (opt->number_of_scripts > 0) {
|
||||
log_warn("Custom animations are not supported by the legacy "
|
||||
"backends. Disabling animations.");
|
||||
for (size_t i = 0; i < ARR_SIZE(opt->animations); i++) {
|
||||
opt->animations[i].script = NULL;
|
||||
}
|
||||
for (int i = 0; i < opt->number_of_scripts; i++) {
|
||||
script_free(opt->all_scripts[i]);
|
||||
}
|
||||
free(opt->all_scripts);
|
||||
opt->all_scripts = NULL;
|
||||
opt->number_of_scripts = 0;
|
||||
}
|
||||
|
||||
if (opt->window_shader_fg || opt->window_shader_fg_rules) {
|
||||
log_warn("The new shader interface is not supported by the "
|
||||
"legacy glx backend. You may want to use "
|
||||
"--glx-fshader-win instead.");
|
||||
opt->window_shader_fg = NULL;
|
||||
c2_list_free(&opt->window_shader_fg_rules, free);
|
||||
}
|
||||
|
||||
if (opt->legacy_backend == BKEND_XRENDER) {
|
||||
bool has_neg = false;
|
||||
for (int i = 0; i < opt->blur_kernel_count; i++) {
|
||||
auto kernel = opt->blur_kerns[i];
|
||||
for (int j = 0; j < kernel->h * kernel->w; j++) {
|
||||
if (kernel->data[j] < 0) {
|
||||
has_neg = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (has_neg) {
|
||||
log_warn("A convolution kernel with negative "
|
||||
"values may not work properly under X "
|
||||
"Render backend.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (opt->backend == NULL) {
|
||||
auto valid_backend_name =
|
||||
backend_find(BACKEND_STRS[opt->legacy_backend]) != NULL;
|
||||
if (!valid_backend_name) {
|
||||
log_error("Backend \"%s\" is only available as part of "
|
||||
"the legacy backends.",
|
||||
BACKEND_STRS[opt->legacy_backend]);
|
||||
} else {
|
||||
// If the backend name is a valid new backend, then
|
||||
// it must not have been specified by the user, because
|
||||
// otherwise opt->backend wouldn't be NULL.
|
||||
log_error("Backend not specified. You must choose one "
|
||||
"explicitly. Valid ones are: ");
|
||||
for (auto i = backend_iter(); i; i = backend_iter_next(i)) {
|
||||
log_error("\t%s", backend_name(i));
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->glx_fshader_win_str) {
|
||||
log_warn("--glx-fshader-win has been replaced by "
|
||||
"\"--window-shader-fg\" for the new backends.");
|
||||
}
|
||||
|
||||
if (opt->max_brightness < 1.0 && opt->use_damage) {
|
||||
log_warn("--max-brightness requires --no-use-damage. "
|
||||
"Falling back to 1.0.");
|
||||
opt->max_brightness = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->write_pid_path && *opt->write_pid_path != '/') {
|
||||
log_warn("--write-pid-path is not an absolute path");
|
||||
}
|
||||
|
||||
// Sanitize parameters for dual-filter kawase blur
|
||||
if (opt->blur_method == BLUR_METHOD_DUAL_KAWASE) {
|
||||
if (opt->blur_strength <= 0 && opt->blur_radius > 500) {
|
||||
log_warn("Blur radius >500 not supported by dual_kawase "
|
||||
"method, "
|
||||
"capping to 500.");
|
||||
opt->blur_radius = 500;
|
||||
}
|
||||
if (opt->blur_strength > 20) {
|
||||
log_warn("Blur strength >20 not supported by dual_kawase "
|
||||
"method, "
|
||||
"capping to 20.");
|
||||
opt->blur_strength = 20;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->resize_damage < 0) {
|
||||
log_warn("Negative --resize-damage will not work correctly.");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process arguments and configuration files.
|
||||
*/
|
||||
|
@ -748,83 +897,22 @@ bool get_cfg(options_t *opt, int argc, char *const *argv) {
|
|||
}
|
||||
|
||||
log_set_level_tls(opt->log_level);
|
||||
if (opt->monitor_repaint && opt->backend != BKEND_XRENDER && opt->legacy_backends) {
|
||||
log_warn("--monitor-repaint has no effect when backend is not xrender");
|
||||
}
|
||||
|
||||
if (opt->window_shader_fg) {
|
||||
scoped_charp cwd = getcwd(NULL, 0);
|
||||
scoped_charp tmp = opt->window_shader_fg;
|
||||
opt->window_shader_fg = locate_auxiliary_file("shaders", tmp, cwd);
|
||||
if (!opt->window_shader_fg) {
|
||||
log_error("Couldn't find the specified window shader file \"%s\"", tmp);
|
||||
log_error("Couldn't find the specified window shader "
|
||||
"file \"%s\"",
|
||||
tmp);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->write_pid_path && *opt->write_pid_path != '/') {
|
||||
log_warn("--write-pid-path is not an absolute path");
|
||||
}
|
||||
|
||||
if (opt->backend == BKEND_EGL) {
|
||||
if (opt->legacy_backends) {
|
||||
log_error("The egl backend is not supported with "
|
||||
"--legacy-backends");
|
||||
return false;
|
||||
}
|
||||
log_warn("The egl backend is still experimental, use with care.");
|
||||
}
|
||||
|
||||
if (!opt->legacy_backends && !backend_list[opt->backend]) {
|
||||
log_error("Backend \"%s\" is only available as part of the legacy "
|
||||
"backends.",
|
||||
BACKEND_STRS[opt->backend]);
|
||||
if (!sanitize_options(opt)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->debug_mode && opt->legacy_backends) {
|
||||
log_error("Debug mode does not work with the legacy backends.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->transparent_clipping && opt->legacy_backends) {
|
||||
log_error("Transparent clipping does not work with the legacy "
|
||||
"backends");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (opt->glx_fshader_win_str && !opt->legacy_backends) {
|
||||
log_warn("--glx-fshader-win has been replaced by "
|
||||
"\"--window-shader-fg\" for the new backends.");
|
||||
}
|
||||
|
||||
if (opt->window_shader_fg || opt->window_shader_fg_rules) {
|
||||
if (opt->backend == BKEND_XRENDER || opt->legacy_backends) {
|
||||
log_warn(opt->backend == BKEND_XRENDER
|
||||
? "Shader interface is not supported by the xrender "
|
||||
"backend."
|
||||
: "The new shader interface is not supported by the "
|
||||
"legacy glx backend. You may want to use "
|
||||
"--glx-fshader-win instead.");
|
||||
opt->window_shader_fg = NULL;
|
||||
c2_list_free(&opt->window_shader_fg_rules, free);
|
||||
}
|
||||
}
|
||||
|
||||
// Range checking and option assignments
|
||||
if (opt->max_brightness < 1.0) {
|
||||
if (opt->backend == BKEND_XRENDER || opt->legacy_backends) {
|
||||
log_warn("--max-brightness is not supported by the %s backend. "
|
||||
"Falling back to 1.0.",
|
||||
opt->backend == BKEND_XRENDER ? "xrender" : "legacy glx");
|
||||
opt->max_brightness = 1.0;
|
||||
} else if (opt->use_damage) {
|
||||
log_warn("--max-brightness requires --no-use-damage. Falling "
|
||||
"back to 1.0.");
|
||||
opt->max_brightness = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// --blur-background-frame implies --blur-background
|
||||
if (opt->blur_background_frame && opt->blur_method == BLUR_METHOD_NONE) {
|
||||
opt->blur_method = BLUR_METHOD_KERNEL;
|
||||
|
@ -846,57 +934,6 @@ bool get_cfg(options_t *opt, int argc, char *const *argv) {
|
|||
CHECK(opt->blur_kernel_count);
|
||||
}
|
||||
|
||||
// Sanitize parameters for dual-filter kawase blur
|
||||
if (opt->blur_method == BLUR_METHOD_DUAL_KAWASE) {
|
||||
if (opt->blur_strength <= 0 && opt->blur_radius > 500) {
|
||||
log_warn("Blur radius >500 not supported by dual_kawase method, "
|
||||
"capping to 500.");
|
||||
opt->blur_radius = 500;
|
||||
}
|
||||
if (opt->blur_strength > 20) {
|
||||
log_warn("Blur strength >20 not supported by dual_kawase method, "
|
||||
"capping to 20.");
|
||||
opt->blur_strength = 20;
|
||||
}
|
||||
if (opt->legacy_backends) {
|
||||
log_warn("Dual-kawase blur is not implemented by the legacy "
|
||||
"backends.");
|
||||
}
|
||||
}
|
||||
|
||||
if (opt->resize_damage < 0) {
|
||||
log_warn("Negative --resize-damage will not work correctly.");
|
||||
}
|
||||
|
||||
if (opt->backend == BKEND_XRENDER) {
|
||||
for (int i = 0; i < opt->blur_kernel_count; i++) {
|
||||
auto kernel = opt->blur_kerns[i];
|
||||
for (int j = 0; j < kernel->h * kernel->w; j++) {
|
||||
if (kernel->data[j] < 0) {
|
||||
log_warn("A convolution kernel with negative "
|
||||
"values may not work properly under X "
|
||||
"Render backend.");
|
||||
goto check_end;
|
||||
}
|
||||
}
|
||||
}
|
||||
check_end:;
|
||||
}
|
||||
|
||||
if (opt->legacy_backends && opt->number_of_scripts > 0) {
|
||||
log_warn("Custom animations are not supported by the legacy "
|
||||
"backends. Disabling animations.");
|
||||
for (size_t i = 0; i < ARR_SIZE(opt->animations); i++) {
|
||||
opt->animations[i].script = NULL;
|
||||
}
|
||||
for (int i = 0; i < opt->number_of_scripts; i++) {
|
||||
script_free(opt->all_scripts[i]);
|
||||
}
|
||||
free(opt->all_scripts);
|
||||
opt->all_scripts = NULL;
|
||||
opt->number_of_scripts = 0;
|
||||
}
|
||||
|
||||
if (opt->fading_enable) {
|
||||
generate_fading_config(opt);
|
||||
}
|
||||
|
@ -918,8 +955,8 @@ void options_postprocess_c2_lists(struct c2_state *state, struct x_connection *c
|
|||
c2_list_postprocess(state, c->c, option->corner_radius_rules) &&
|
||||
c2_list_postprocess(state, c->c, option->focus_blacklist) &&
|
||||
c2_list_postprocess(state, c->c, option->transparent_clipping_blacklist))) {
|
||||
log_error("Post-processing of conditionals failed, some of your rules "
|
||||
"might not work");
|
||||
log_error("Post-processing of conditionals failed, some of your "
|
||||
"rules might not work");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
93
src/picom.c
93
src/picom.c
|
@ -658,18 +658,16 @@ static int mark_pixmap_stale(struct win *w, void *data) {
|
|||
|
||||
/// Init the backend and bind all the window pixmap to backend images
|
||||
static bool initialize_backend(session_t *ps) {
|
||||
if (!ps->o.legacy_backends) {
|
||||
if (!ps->o.use_legacy_backends) {
|
||||
assert(!ps->backend_data);
|
||||
// Reinitialize win_data
|
||||
assert(backend_list[ps->o.backend]);
|
||||
ps->backend_data =
|
||||
backend_list[ps->o.backend]->init(ps, session_get_target_window(ps));
|
||||
backend_init(ps->o.backend, ps, session_get_target_window(ps));
|
||||
if (!ps->backend_data) {
|
||||
log_fatal("Failed to initialize backend, aborting...");
|
||||
quit(ps);
|
||||
return false;
|
||||
}
|
||||
ps->backend_data->ops = backend_list[ps->o.backend];
|
||||
|
||||
if (!initialize_blur(ps)) {
|
||||
log_fatal("Failed to prepare for background blur, aborting...");
|
||||
|
@ -677,24 +675,30 @@ static bool initialize_backend(session_t *ps) {
|
|||
}
|
||||
|
||||
// Create shaders
|
||||
HASH_ITER2(ps->shaders, shader) {
|
||||
assert(shader->backend_shader == NULL);
|
||||
shader->backend_shader = ps->backend_data->ops->create_shader(
|
||||
ps->backend_data, shader->source);
|
||||
if (shader->backend_shader == NULL) {
|
||||
log_warn("Failed to create shader for shader file %s, "
|
||||
"this shader will not be used",
|
||||
shader->key);
|
||||
} else {
|
||||
if (ps->backend_data->ops->get_shader_attributes) {
|
||||
shader->attributes =
|
||||
ps->backend_data->ops->get_shader_attributes(
|
||||
ps->backend_data, shader->backend_shader);
|
||||
if (!ps->backend_data->ops->create_shader && ps->shaders) {
|
||||
log_warn("Shaders are not supported by selected backend %s, "
|
||||
"they will be ignored",
|
||||
backend_name(ps->o.backend));
|
||||
} else {
|
||||
HASH_ITER2(ps->shaders, shader) {
|
||||
assert(shader->backend_shader == NULL);
|
||||
shader->backend_shader = ps->backend_data->ops->create_shader(
|
||||
ps->backend_data, shader->source);
|
||||
if (shader->backend_shader == NULL) {
|
||||
log_warn("Failed to create shader for shader "
|
||||
"file %s, this shader will not be used",
|
||||
shader->key);
|
||||
} else {
|
||||
shader->attributes = 0;
|
||||
if (ps->backend_data->ops->get_shader_attributes) {
|
||||
shader->attributes =
|
||||
ps->backend_data->ops->get_shader_attributes(
|
||||
ps->backend_data,
|
||||
shader->backend_shader);
|
||||
}
|
||||
log_debug("Shader %s has attributes %" PRIu64,
|
||||
shader->key, shader->attributes);
|
||||
}
|
||||
log_debug("Shader %s has attributes %" PRIu64,
|
||||
shader->key, shader->attributes);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -736,7 +740,7 @@ static void configure_root(session_t *ps) {
|
|||
bool has_root_change = false;
|
||||
if (ps->redirected) {
|
||||
// On root window changes
|
||||
if (!ps->o.legacy_backends) {
|
||||
if (!ps->o.use_legacy_backends) {
|
||||
assert(ps->backend_data);
|
||||
has_root_change = ps->backend_data->ops->root_change != NULL;
|
||||
} else {
|
||||
|
@ -779,7 +783,7 @@ static void configure_root(session_t *ps) {
|
|||
ps->damage_ring.cursor = ps->damage_ring.count - 1;
|
||||
#ifdef CONFIG_OPENGL
|
||||
// GLX root change callback
|
||||
if (BKEND_GLX == ps->o.backend && ps->o.legacy_backends) {
|
||||
if (BKEND_GLX == ps->o.legacy_backend && ps->o.use_legacy_backends) {
|
||||
glx_on_root_change(ps);
|
||||
}
|
||||
#endif
|
||||
|
@ -1375,10 +1379,10 @@ uint8_t session_redirection_mode(session_t *ps) {
|
|||
if (ps->o.debug_mode) {
|
||||
// If the backend is not rendering to the screen, we don't need to
|
||||
// take over the screen.
|
||||
assert(!ps->o.legacy_backends);
|
||||
assert(!ps->o.use_legacy_backends);
|
||||
return XCB_COMPOSITE_REDIRECT_AUTOMATIC;
|
||||
}
|
||||
if (!ps->o.legacy_backends && !backend_list[ps->o.backend]->present) {
|
||||
if (!ps->o.use_legacy_backends && !backend_can_present(ps->o.backend)) {
|
||||
// if the backend doesn't render anything, we don't need to take over the
|
||||
// screen.
|
||||
return XCB_COMPOSITE_REDIRECT_AUTOMATIC;
|
||||
|
@ -1415,7 +1419,7 @@ static bool redirect_start(session_t *ps) {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!ps->o.legacy_backends) {
|
||||
if (!ps->o.use_legacy_backends) {
|
||||
assert(ps->backend_data);
|
||||
ps->damage_ring.count = ps->backend_data->ops->max_buffer_age;
|
||||
ps->layout_manager =
|
||||
|
@ -1431,7 +1435,8 @@ static bool redirect_start(session_t *ps) {
|
|||
}
|
||||
|
||||
ps->frame_pacing = ps->o.frame_pacing && ps->o.vsync;
|
||||
if ((ps->o.legacy_backends || ps->o.benchmark || !ps->backend_data->ops->last_render_time) &&
|
||||
if ((ps->o.use_legacy_backends || ps->o.benchmark ||
|
||||
!ps->backend_data->ops->last_render_time) &&
|
||||
ps->frame_pacing) {
|
||||
// Disable frame pacing if we are using a legacy backend or if we are in
|
||||
// benchmark mode, or if the backend doesn't report render time
|
||||
|
@ -1777,7 +1782,7 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
|
|||
static int paint = 0;
|
||||
|
||||
log_verbose("Render start, frame %d", paint);
|
||||
if (!ps->o.legacy_backends) {
|
||||
if (!ps->o.use_legacy_backends) {
|
||||
uint64_t after_damage_us = 0;
|
||||
now = get_time_timespec();
|
||||
auto render_start_us =
|
||||
|
@ -2211,7 +2216,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
}
|
||||
}
|
||||
|
||||
if (ps->o.legacy_backends) {
|
||||
if (ps->o.use_legacy_backends) {
|
||||
ps->shadow_context =
|
||||
(void *)gaussian_kernel_autodetect_deviation(ps->o.shadow_radius);
|
||||
sum_kernel_preprocess((conv *)ps->shadow_context);
|
||||
|
@ -2332,9 +2337,9 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
|
||||
// The old backends doesn't have a automatic redirection mode
|
||||
log_info("The compositor is started in automatic redirection mode.");
|
||||
assert(!ps->o.legacy_backends);
|
||||
assert(!ps->o.use_legacy_backends);
|
||||
|
||||
if (backend_list[ps->o.backend]->present) {
|
||||
if (backend_can_present(ps->o.backend)) {
|
||||
// If the backend has `present`, we couldn't be in automatic
|
||||
// redirection mode unless we are in debug mode.
|
||||
assert(ps->o.debug_mode);
|
||||
|
@ -2348,7 +2353,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
apply_driver_workarounds(ps, ps->drivers);
|
||||
|
||||
// Initialize filters, must be preceded by OpenGL context creation
|
||||
if (ps->o.legacy_backends && !init_render(ps)) {
|
||||
if (ps->o.use_legacy_backends && !init_render(ps)) {
|
||||
log_fatal("Failed to initialize the backend");
|
||||
exit(1);
|
||||
}
|
||||
|
@ -2371,7 +2376,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
|
|||
}
|
||||
}
|
||||
|
||||
if (bkend_use_glx(ps) && ps->o.legacy_backends) {
|
||||
if (bkend_use_glx(ps) && ps->o.use_legacy_backends) {
|
||||
auto gl_logger = gl_string_marker_logger_new();
|
||||
if (gl_logger) {
|
||||
log_info("Enabling gl string marker");
|
||||
|
@ -2618,7 +2623,7 @@ static void session_destroy(session_t *ps) {
|
|||
ps->damage_ring.x_region = XCB_NONE;
|
||||
}
|
||||
|
||||
if (!ps->o.legacy_backends) {
|
||||
if (!ps->o.use_legacy_backends) {
|
||||
// backend is deinitialized in unredirect()
|
||||
assert(ps->backend_data == NULL);
|
||||
} else {
|
||||
|
@ -2635,7 +2640,7 @@ static void session_destroy(session_t *ps) {
|
|||
// Flush all events
|
||||
xcb_aux_sync(ps->c.c);
|
||||
ev_io_stop(ps->loop, &ps->xiow);
|
||||
if (ps->o.legacy_backends) {
|
||||
if (ps->o.use_legacy_backends) {
|
||||
free_conv((conv *)ps->shadow_context);
|
||||
}
|
||||
destroy_atoms(ps->atoms);
|
||||
|
@ -2684,6 +2689,18 @@ static void session_run(session_t *ps) {
|
|||
#define PICOM_MAIN(...) main(__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
/// Early initialization of logging system. To catch early logs, especially
|
||||
/// from backend entrypoint functions.
|
||||
static void __attribute__((constructor(201))) init_early_logging(void) {
|
||||
log_init_tls();
|
||||
log_set_level_tls(LOG_LEVEL_WARN);
|
||||
|
||||
auto stderr_logger = stderr_logger_new();
|
||||
if (stderr_logger != NULL) {
|
||||
log_add_target_tls(stderr_logger);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The function that everybody knows.
|
||||
*/
|
||||
|
@ -2692,16 +2709,6 @@ int PICOM_MAIN(int argc, char **argv) {
|
|||
// correctly
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
// Initialize logging system for early logging
|
||||
log_init_tls();
|
||||
|
||||
{
|
||||
auto stderr_logger = stderr_logger_new();
|
||||
if (stderr_logger) {
|
||||
log_add_target_tls(stderr_logger);
|
||||
}
|
||||
}
|
||||
|
||||
parse_debug_options(&global_debug_options);
|
||||
|
||||
int exit_code;
|
||||
|
|
36
src/render.c
36
src/render.c
|
@ -113,7 +113,8 @@ static inline bool paint_bind_tex(session_t *ps, paint_t *ppaint, int wid, int h
|
|||
* Check if current backend uses XRender for rendering.
|
||||
*/
|
||||
static inline bool bkend_use_xrender(session_t *ps) {
|
||||
return BKEND_XRENDER == ps->o.backend || BKEND_XR_GLX_HYBRID == ps->o.backend;
|
||||
return BKEND_XRENDER == ps->o.legacy_backend ||
|
||||
BKEND_XR_GLX_HYBRID == ps->o.legacy_backend;
|
||||
}
|
||||
|
||||
int maximum_buffer_age(session_t *ps) {
|
||||
|
@ -154,7 +155,7 @@ static inline void xrfilter_reset(session_t *ps, xcb_render_picture_t p) {
|
|||
|
||||
/// Set the input/output clip region of the target buffer (not the actual target!)
|
||||
static inline void attr_nonnull(1, 2) set_tgt_clip(session_t *ps, region_t *reg) {
|
||||
switch (ps->o.backend) {
|
||||
switch (ps->o.legacy_backend) {
|
||||
case BKEND_XRENDER:
|
||||
case BKEND_XR_GLX_HYBRID:
|
||||
x_set_picture_clip_region(&ps->c, ps->tgt_buffer.pict, 0, 0, reg);
|
||||
|
@ -243,7 +244,7 @@ void render(session_t *ps, int x, int y, int dx, int dy, int wid, int hei, int f
|
|||
int fullhei, double opacity, bool argb, bool neg, int cr,
|
||||
xcb_render_picture_t pict, glx_texture_t *ptex, const region_t *reg_paint,
|
||||
const glx_prog_main_t *pprogram, clip_t *clip) {
|
||||
switch (ps->o.backend) {
|
||||
switch (ps->o.legacy_backend) {
|
||||
case BKEND_XRENDER:
|
||||
case BKEND_XR_GLX_HYBRID: {
|
||||
auto alpha_step = (int)(opacity * MAX_ALPHA);
|
||||
|
@ -381,7 +382,7 @@ static inline bool paint_isvalid(session_t *ps, const paint_t *ppaint) {
|
|||
}
|
||||
|
||||
#ifdef CONFIG_OPENGL
|
||||
if (BKEND_GLX == ps->o.backend && !glx_tex_bound(ppaint->ptex, XCB_NONE)) {
|
||||
if (BKEND_GLX == ps->o.legacy_backend && !glx_tex_bound(ppaint->ptex, XCB_NONE)) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
@ -562,7 +563,7 @@ void paint_one(session_t *ps, struct managed_win *w, const region_t *reg_paint)
|
|||
dim_opacity *= window_opacity;
|
||||
}
|
||||
|
||||
switch (ps->o.backend) {
|
||||
switch (ps->o.legacy_backend) {
|
||||
case BKEND_XRENDER:
|
||||
case BKEND_XR_GLX_HYBRID: {
|
||||
auto cval = (uint16_t)(0xffff * dim_opacity);
|
||||
|
@ -656,7 +657,7 @@ static bool get_root_tile(session_t *ps) {
|
|||
ps->root_tile_fill = fill;
|
||||
ps->root_tile_paint.pixmap = pixmap;
|
||||
#ifdef CONFIG_OPENGL
|
||||
if (BKEND_GLX == ps->o.backend) {
|
||||
if (BKEND_GLX == ps->o.legacy_backend) {
|
||||
return paint_bind_tex(ps, &ps->root_tile_paint, 0, 0, true, 0, visual, false);
|
||||
}
|
||||
#endif
|
||||
|
@ -775,7 +776,8 @@ win_paint_shadow(session_t *ps, struct managed_win *w, region_t *reg_paint) {
|
|||
bool should_clip =
|
||||
(w->corner_radius > 0) && (!ps->o.wintype_option[w->window_type].full_shadow);
|
||||
if (should_clip) {
|
||||
if (ps->o.backend == BKEND_XRENDER || ps->o.backend == BKEND_XR_GLX_HYBRID) {
|
||||
if (ps->o.legacy_backend == BKEND_XRENDER ||
|
||||
ps->o.legacy_backend == BKEND_XR_GLX_HYBRID) {
|
||||
uint32_t max_ntraps = to_u32_checked(w->corner_radius);
|
||||
xcb_render_trapezoid_t traps[4 * max_ntraps + 3];
|
||||
uint32_t n = make_rounded_window_shape(
|
||||
|
@ -913,7 +915,7 @@ win_blur_background(session_t *ps, struct managed_win *w, xcb_render_picture_t t
|
|||
factor_center = pct * 8.0 / (1.1 - pct);
|
||||
}
|
||||
|
||||
switch (ps->o.backend) {
|
||||
switch (ps->o.legacy_backend) {
|
||||
case BKEND_XRENDER:
|
||||
case BKEND_XR_GLX_HYBRID: {
|
||||
// Normalize blur kernels
|
||||
|
@ -1043,14 +1045,14 @@ void paint_all(session_t *ps, struct managed_win *t) {
|
|||
}
|
||||
}
|
||||
|
||||
if (BKEND_GLX != ps->o.backend) {
|
||||
if (BKEND_GLX != ps->o.legacy_backend) {
|
||||
ps->tgt_buffer.pict = x_create_picture_with_visual_and_pixmap(
|
||||
&ps->c, ps->c.screen_info->root_visual, ps->tgt_buffer.pixmap,
|
||||
0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (BKEND_XRENDER == ps->o.backend) {
|
||||
if (BKEND_XRENDER == ps->o.legacy_backend) {
|
||||
x_set_picture_clip_region(&ps->c, ps->tgt_picture, 0, 0, ®ion);
|
||||
}
|
||||
|
||||
|
@ -1170,7 +1172,7 @@ void paint_all(session_t *ps, struct managed_win *t) {
|
|||
|
||||
#ifdef CONFIG_OPENGL
|
||||
// If rounded corners backup the region first
|
||||
if (w->corner_radius > 0 && ps->o.backend == BKEND_GLX) {
|
||||
if (w->corner_radius > 0 && ps->o.legacy_backend == BKEND_GLX) {
|
||||
const int16_t x = w->g.x;
|
||||
const int16_t y = w->g.y;
|
||||
auto const wid = to_u16_checked(w->widthb);
|
||||
|
@ -1193,7 +1195,7 @@ void paint_all(session_t *ps, struct managed_win *t) {
|
|||
#ifdef CONFIG_OPENGL
|
||||
// Rounded corners for XRender is implemented inside render()
|
||||
// Round window corners
|
||||
if (w->corner_radius > 0 && ps->o.backend == BKEND_GLX) {
|
||||
if (w->corner_radius > 0 && ps->o.legacy_backend == BKEND_GLX) {
|
||||
auto const wid = to_u16_checked(w->widthb);
|
||||
auto const hei = to_u16_checked(w->heightb);
|
||||
glx_round_corners_dst(ps, w, w->glx_texture_bg, w->g.x,
|
||||
|
@ -1237,7 +1239,7 @@ void paint_all(session_t *ps, struct managed_win *t) {
|
|||
|
||||
auto rwidth = to_u16_checked(ps->root_width);
|
||||
auto rheight = to_u16_checked(ps->root_height);
|
||||
switch (ps->o.backend) {
|
||||
switch (ps->o.legacy_backend) {
|
||||
case BKEND_XRENDER:
|
||||
if (ps->o.monitor_repaint) {
|
||||
// Copy the screen content to a new picture, and highlight the
|
||||
|
@ -1375,7 +1377,7 @@ static bool init_alpha_picts(session_t *ps) {
|
|||
}
|
||||
|
||||
bool init_render(session_t *ps) {
|
||||
if (ps->o.backend == BKEND_DUMMY) {
|
||||
if (ps->o.legacy_backend == BKEND_DUMMY) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1400,7 +1402,7 @@ bool init_render(session_t *ps) {
|
|||
}
|
||||
|
||||
// Initialize window GL shader
|
||||
if (BKEND_GLX == ps->o.backend && ps->o.glx_fshader_win_str) {
|
||||
if (BKEND_GLX == ps->o.legacy_backend && ps->o.glx_fshader_win_str) {
|
||||
#ifdef CONFIG_OPENGL
|
||||
if (!glx_load_prog_main(NULL, ps->o.glx_fshader_win_str, &ps->glx_prog_win)) {
|
||||
return false;
|
||||
|
@ -1429,7 +1431,7 @@ bool init_render(session_t *ps) {
|
|||
ccalloc(ps->o.blur_kernel_count, struct x_convolution_kernel *);
|
||||
|
||||
bool ret = false;
|
||||
if (ps->o.backend == BKEND_GLX) {
|
||||
if (ps->o.legacy_backend == BKEND_GLX) {
|
||||
#ifdef CONFIG_OPENGL
|
||||
ret = glx_init_blur(ps);
|
||||
#else
|
||||
|
@ -1465,7 +1467,7 @@ bool init_render(session_t *ps) {
|
|||
}
|
||||
|
||||
// Initialize our rounded corners fragment shader
|
||||
if (ps->o.corner_radius > 0 && ps->o.backend == BKEND_GLX) {
|
||||
if (ps->o.corner_radius > 0 && ps->o.legacy_backend == BKEND_GLX) {
|
||||
#ifdef CONFIG_OPENGL
|
||||
if (!glx_init_rounded_corners(ps)) {
|
||||
log_error("Failed to init rounded corners shader.");
|
||||
|
|
7
src/x.c
7
src/x.c
|
@ -832,11 +832,18 @@ void x_create_convolution_kernel(const conv *kernel, double center,
|
|||
buf[1] = DOUBLE_TO_XFIXED(kernel->h);
|
||||
|
||||
double sum = center;
|
||||
bool has_neg = false;
|
||||
for (int i = 0; i < kernel->w * kernel->h; i++) {
|
||||
if (i == kernel->w * kernel->h / 2) {
|
||||
// Ignore center
|
||||
continue;
|
||||
}
|
||||
sum += kernel->data[i];
|
||||
if (kernel->data[i] < 0 && !has_neg) {
|
||||
has_neg = true;
|
||||
log_warn("A X convolution kernel with negative values may not "
|
||||
"work properly.");
|
||||
}
|
||||
}
|
||||
|
||||
// Note for floating points a / b != a * (1 / b), but this shouldn't have any real
|
||||
|
|
Loading…
Add table
Reference in a new issue