Remove the legacy backends

This commit is contained in:
Yuxuan Shui 2024-02-10 16:19:54 +00:00
parent 664f8b8b9b
commit aa6943ea88
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
15 changed files with 87 additions and 3894 deletions

View File

@ -57,7 +57,6 @@
#include "config.h"
#include "list.h"
#include "region.h"
#include "render.h"
#include "statistics.h"
#include "types.h"
#include "utils.h"
@ -183,8 +182,6 @@ typedef struct session {
xcb_window_t debug_window;
/// Whether the root tile is filled by us.
bool root_tile_fill;
/// Picture of the root window background.
paint_t root_tile_paint;
/// The backend data the root pixmap bound to
image_handle root_image;
/// A region of the size of the screen.
@ -194,8 +191,6 @@ typedef struct session {
xcb_render_picture_t root_picture;
/// A Picture acting as the painting target.
xcb_render_picture_t tgt_picture;
/// Temporary buffer to paint to before sending to display.
paint_t tgt_buffer;
/// Window ID of the window we register as a symbol.
xcb_window_t reg_win;
#ifdef CONFIG_OPENGL
@ -316,12 +311,6 @@ typedef struct session {
/// Nanosecond offset of the first painting.
long paint_tm_offset;
#ifdef CONFIG_VSYNC_DRM
// === DRM VSync related ===
/// File descriptor of DRI device file. Used for DRM VSync.
int drm_fd;
#endif
// === X extension related ===
/// Event base number for X Fixes extension.
int xfixes_event;

View File

@ -808,7 +808,6 @@ char *parse_config(options_t *opt, const char *config_file, bool *shadow_enable,
// clang-format off
*opt = (struct options){
.backend = BKEND_XRENDER,
.legacy_backends = false,
.glx_no_stencil = false,
.mark_wmwin_focused = false,
.mark_ovredir_focused = false,

View File

@ -102,8 +102,6 @@ typedef struct options {
/// Render to a separate window instead of taking over the screen
bool debug_mode;
// === General ===
/// Use the legacy backends?
bool legacy_backends;
/// Path to write PID to.
char *write_pid_path;
/// The backend in use.

View File

@ -7,8 +7,8 @@ base_deps = [
libev
]
srcs = [ files('picom.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'vsync.c', 'utils.c',
'diagnostic.c', 'string_utils.c', 'render.c', 'kernel.c', 'log.c',
srcs = [ files('picom.c', 'win.c', 'c2.c', 'x.c', 'config.c', 'utils.c',
'diagnostic.c', 'string_utils.c', 'kernel.c', 'log.c',
'options.c', 'event.c', 'cache.c', 'atom.c', 'file_watch.c', 'statistics.c',
'vblank.c') ]
picom_inc = include_directories('.')
@ -52,15 +52,9 @@ if get_option('regex')
deps += [pcre]
endif
if get_option('vsync_drm')
cflags += ['-DCONFIG_VSYNC_DRM']
deps += [dependency('libdrm', required: true)]
endif
if get_option('opengl')
cflags += ['-DCONFIG_OPENGL']
deps += [dependency('epoxy', required: true)]
srcs += [ 'opengl.c' ]
endif
if get_option('dbus')

File diff suppressed because it is too large Load Diff

View File

@ -1,244 +0,0 @@
// SPDX-License-Identifier: MIT
/*
* Compton - a compositor for X11
*
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
*
* Copyright (c) 2011-2013, Christopher Jeffrey
* See LICENSE-mit for more information.
*
*/
#pragma once
#include "common.h"
#include "compiler.h"
#include "log.h"
#include "region.h"
#include "render.h"
#include "win.h"
#include <ctype.h>
#include <epoxy/gl.h>
#include <epoxy/glx.h>
#include <locale.h>
#include <stdlib.h>
#include <string.h>
#include <xcb/render.h>
#include <xcb/xcb.h>
typedef struct {
/// Fragment shader for blur.
GLuint frag_shader;
/// GLSL program for blur.
GLuint prog;
/// Location of uniform "offset_x" in blur GLSL program.
GLint unifm_offset_x;
/// Location of uniform "offset_y" in blur GLSL program.
GLint unifm_offset_y;
/// Location of uniform "factor_center" in blur GLSL program.
GLint unifm_factor_center;
} glx_blur_pass_t;
typedef struct {
/// Fragment shader for rounded corners.
GLuint frag_shader;
/// GLSL program for rounded corners.
GLuint prog;
/// Location of uniform "radius" in rounded-corners GLSL program.
GLint unifm_radius;
/// Location of uniform "texcoord" in rounded-corners GLSL program.
GLint unifm_texcoord;
/// Location of uniform "texsize" in rounded-corners GLSL program.
GLint unifm_texsize;
/// Location of uniform "borderw" in rounded-corners GLSL program.
GLint unifm_borderw;
/// Location of uniform "borderc" in rounded-corners GLSL program.
GLint unifm_borderc;
/// Location of uniform "resolution" in rounded-corners GLSL program.
GLint unifm_resolution;
/// Location of uniform "texture_scr" in rounded-corners GLSL program.
GLint unifm_tex_scr;
} glx_round_pass_t;
/// Structure containing GLX-dependent data for a session.
typedef struct glx_session {
// === OpenGL related ===
/// GLX context.
GLXContext context;
/// Whether we have GL_ARB_texture_non_power_of_two.
bool has_texture_non_power_of_two;
/// Current GLX Z value.
int z;
glx_blur_pass_t *blur_passes;
glx_round_pass_t *round_passes;
} glx_session_t;
/// @brief Wrapper of a bound GLX texture.
typedef struct _glx_texture {
GLuint texture;
GLXPixmap glpixmap;
xcb_pixmap_t pixmap;
GLenum target;
int width;
int height;
bool y_inverted;
} glx_texture_t;
#define CGLX_SESSION_INIT \
{ .context = NULL }
bool glx_dim_dst(session_t *ps, int dx, int dy, int width, int height, int z,
GLfloat factor, const region_t *reg_tgt);
bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx, int dy,
int width, int height, int z, double opacity, bool argb, bool neg,
const region_t *reg_tgt, const glx_prog_main_t *pprogram);
bool glx_init(session_t *ps, bool need_render);
void glx_destroy(session_t *ps);
void glx_on_root_change(session_t *ps);
bool glx_init_blur(session_t *ps);
bool glx_init_rounded_corners(session_t *ps);
#ifdef CONFIG_OPENGL
bool glx_load_prog_main(const char *vshader_str, const char *fshader_str,
glx_prog_main_t *pprogram);
#endif
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 *);
void glx_release_pixmap(session_t *ps, glx_texture_t *ptex);
bool glx_bind_texture(session_t *ps, glx_texture_t **pptex, int x, int y, int width, int height);
void glx_paint_pre(session_t *ps, region_t *preg) attr_nonnull(1, 2);
/**
* Check if a texture is bound, or is bound to the given pixmap.
*/
static inline bool glx_tex_bound(const glx_texture_t *ptex, xcb_pixmap_t pixmap) {
return ptex && ptex->glpixmap && ptex->texture && (!pixmap || pixmap == ptex->pixmap);
}
void glx_set_clip(session_t *ps, const region_t *reg);
bool glx_blur_dst(session_t *ps, int dx, int dy, int width, int height, float z,
GLfloat factor_center, const region_t *reg_tgt, glx_blur_cache_t *pbc);
bool glx_round_corners_dst(session_t *ps, struct managed_win *w,
const glx_texture_t *ptex, int dx, int dy, int width,
int height, float z, float cr, const region_t *reg_tgt);
GLuint glx_create_shader(GLenum shader_type, const char *shader_str);
GLuint glx_create_program(const GLuint *const shaders, int nshaders);
GLuint glx_create_program_from_str(const char *vert_shader_str, const char *frag_shader_str);
unsigned char *glx_take_screenshot(session_t *ps, int *out_length);
/**
* Check if there's a GLX context.
*/
static inline bool glx_has_context(session_t *ps) {
return ps->psglx && ps->psglx->context;
}
/**
* Ensure we have a GLX context.
*/
static inline bool ensure_glx_context(session_t *ps) {
// Create GLX context
if (!glx_has_context(ps)) {
glx_init(ps, false);
}
return glx_has_context(ps);
}
/**
* Free a GLX texture.
*/
static inline void free_texture_r(session_t *ps attr_unused, GLuint *ptexture) {
if (*ptexture) {
assert(glx_has_context(ps));
glDeleteTextures(1, ptexture);
*ptexture = 0;
}
}
/**
* Free a GLX Framebuffer object.
*/
static inline void free_glx_fbo(GLuint *pfbo) {
if (*pfbo) {
glDeleteFramebuffers(1, pfbo);
*pfbo = 0;
}
assert(!*pfbo);
}
/**
* Free data in glx_blur_cache_t on resize.
*/
static inline void free_glx_bc_resize(session_t *ps, glx_blur_cache_t *pbc) {
free_texture_r(ps, &pbc->textures[0]);
free_texture_r(ps, &pbc->textures[1]);
pbc->width = 0;
pbc->height = 0;
}
/**
* Free a glx_blur_cache_t
*/
static inline void free_glx_bc(session_t *ps, glx_blur_cache_t *pbc) {
free_glx_fbo(&pbc->fbo);
free_glx_bc_resize(ps, pbc);
}
/**
* Free a glx_texture_t.
*/
static inline void free_texture(session_t *ps, glx_texture_t **pptex) {
glx_texture_t *ptex = *pptex;
// Quit if there's nothing
if (!ptex) {
return;
}
glx_release_pixmap(ps, ptex);
free_texture_r(ps, &ptex->texture);
// Free structure itself
free(ptex);
*pptex = NULL;
}
/**
* Free GLX part of paint_t.
*/
static inline void free_paint_glx(session_t *ps, paint_t *ppaint) {
free_texture(ps, &ppaint->ptex);
ppaint->fbcfg = (struct glx_fbconfig_info){0};
}
/**
* Free GLX part of win.
*/
static inline void free_win_res_glx(session_t *ps, struct managed_win *w) {
free_paint_glx(ps, &w->paint);
free_paint_glx(ps, &w->shadow_paint);
#ifdef CONFIG_OPENGL
free_glx_bc(ps, &w->glx_blur_cache);
free_texture(ps, &w->glx_texture_bg);
#endif
}

View File

@ -153,7 +153,7 @@ static const struct picom_option picom_options[] = {
"need to be able to see through transparent parts of the window."},
{"blur-method" , required_argument, 328, NULL , "The algorithm used for background bluring. Available choices are: 'none' to "
"disable, 'gaussian', 'box' or 'kernel' for custom convolution blur with "
"--blur-kern. Note: 'gaussian' and 'box' is not supported by --legacy-backends."},
"--blur-kern."},
{"blur-size" , required_argument, 329, NULL , "The radius of the blur kernel for 'box' and 'gaussian' blur method."},
{"blur-deviation" , required_argument, 330, NULL , "The standard deviation for the 'gaussian' blur method."},
{"blur-strength" , required_argument, 331, NULL , "The strength level of the 'dual_kawase' blur method."},
@ -164,20 +164,18 @@ static const struct picom_option picom_options[] = {
{"corner-radius-rules" , required_argument, 340, "RADIUS:COND" , "Window rules for specific rounded corner radii."},
{"clip-shadow-above" , required_argument, 335, NULL , "Specify a list of conditions of windows to not paint a shadow over, such "
"as a dock window."},
{"window-shader-fg" , required_argument, 336, "PATH" , "Specify GLSL fragment shader path for rendering window contents. Does not"
" work when `--legacy-backends` is enabled. See man page for more details."},
{"window-shader-fg" , required_argument, 336, "PATH" , "Specify GLSL fragment shader path for rendering window contents. "
"See man page for more details."},
{"window-shader-fg-rule" , required_argument, 337, "PATH:COND" , "Specify GLSL fragment shader path for rendering window contents using "
"patterns. Pattern should be in the format of SHADER_PATH:PATTERN, "
"similar to --opacity-rule. SHADER_PATH can be \"default\", in which case "
"the default shader will be used. Does not work when --legacy-backends is "
"enabled. See man page for more details"},
"the default shader will be used. See man page for more details"},
// 338 is transparent-clipping-exclude
{"dithered-present" , no_argument , 339, NULL , "Use higher precision during rendering, and apply dither when presenting the "
"rendered screen. Reduces banding artifacts, but might cause performance "
"degradation. Only works with OpenGL."},
// 340 is corner-radius-rules
{"no-frame-pacing" , no_argument , 341, NULL , "Disable frame pacing. This might increase the latency."},
{"legacy-backends" , no_argument , 733, NULL , "Use deprecated version of the backends."},
{"monitor-repaint" , no_argument , 800, NULL , "Highlight the updated area of the screen. For debugging."},
{"diagnostics" , no_argument , 801, NULL , "Print diagnostic information"},
{"debug-mode" , no_argument , 802, NULL , "Render into a separate window, and don't take over the screen. Useful when "
@ -381,9 +379,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
while (-1 != (o = getopt_long(argc, argv, shortopts, longopts, &longopt_idx))) {
switch (o) {
#define P_CASEBOOL(idx, option) \
case idx: \
opt->option = true; \
break
case idx: opt->option = true; break
#define P_CASELONG(idx, option) \
case idx: \
if (!parse_long(optarg, &opt->option)) { \
@ -744,7 +740,6 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
opt->dithered_present = true;
break;
P_CASEBOOL(341, no_frame_pacing);
P_CASEBOOL(733, legacy_backends);
P_CASEBOOL(800, monitor_repaint);
case 801:
opt->print_diagnostics = true;
@ -770,53 +765,22 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
return false;
}
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->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]) {
if (!backend_list[opt->backend]) {
log_error("Backend \"%s\" is only available as part of the legacy "
"backends.",
"backends, which has been removed.",
BACKEND_STRS[opt->backend]);
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);
}
if ((opt->window_shader_fg || opt->window_shader_fg_rules) &&
opt->backend == BKEND_XRENDER) {
log_warn("Shader interface is not supported by the xrender backend.");
opt->window_shader_fg = NULL;
c2_list_free(&opt->window_shader_fg_rules, free);
}
// Range checking and option assignments
@ -830,7 +794,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
opt->shadow_opacity = normalize_d(opt->shadow_opacity);
opt->max_brightness = normalize_d(opt->max_brightness);
if (opt->max_brightness < 1.0) {
if (opt->backend == BKEND_XRENDER || opt->legacy_backends) {
if (opt->backend == BKEND_XRENDER) {
log_warn("--max-brightness is not supported by the %s backend. "
"Falling back to 1.0.",
opt->backend == BKEND_XRENDER ? "xrender" : "legacy glx");
@ -879,10 +843,6 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
"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) {

View File

@ -40,21 +40,17 @@
#include <ev.h>
#include <test.h>
#include "backend/backend.h"
#include "c2.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "diagnostic.h"
#include "err.h"
#include "kernel.h"
#include "picom.h"
#ifdef CONFIG_OPENGL
#include "opengl.h"
#endif
#include "backend/backend.h"
#include "c2.h"
#include "diagnostic.h"
#include "log.h"
#include "picom.h"
#include "region.h"
#include "render.h"
#include "types.h"
#include "utils.h"
#include "win.h"
@ -640,7 +636,6 @@ static void destroy_backend(session_t *ps) {
win_clear_flags(w, WIN_FLAGS_PIXMAP_STALE);
win_release_images(ps->backend_data, w);
}
free_paint(ps, &w->paint);
}
HASH_ITER2(ps->shaders, shader) {
@ -710,71 +705,68 @@ static bool initialize_blur(session_t *ps) {
/// Init the backend and bind all the window pixmap to backend images
static bool initialize_backend(session_t *ps) {
if (!ps->o.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));
if (!ps->backend_data) {
log_fatal("Failed to initialize backend, aborting...");
quit(ps);
return false;
}
ps->backend_data->ops = backend_list[ps->o.backend];
ps->shadow_context = ps->backend_data->ops->create_shadow_context(
ps->backend_data, ps->o.shadow_radius);
if (!ps->shadow_context) {
log_fatal("Failed to initialize shadow context, aborting...");
goto err;
}
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));
if (!ps->backend_data) {
log_fatal("Failed to initialize backend, aborting...");
quit(ps);
return false;
}
ps->backend_data->ops = backend_list[ps->o.backend];
ps->shadow_context = ps->backend_data->ops->create_shadow_context(
ps->backend_data, ps->o.shadow_radius);
if (!ps->shadow_context) {
log_fatal("Failed to initialize shadow context, aborting...");
goto err;
}
if (!initialize_blur(ps)) {
log_fatal("Failed to prepare for background blur, aborting...");
goto err;
}
if (!initialize_blur(ps)) {
log_fatal("Failed to prepare for background blur, aborting...");
goto err;
}
// 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);
// 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);
} else {
if (ps->backend_data->ops->get_shader_attributes) {
shader->attributes =
ps->backend_data->ops->get_shader_attributes(
ps->backend_data, shader->backend_shader);
} else {
shader->attributes = 0;
}
log_debug("Shader %s has attributes %" PRIu64,
shader->key, shader->attributes);
shader->attributes = 0;
}
}
// window_stack shouldn't include window that's
// not in the hash table at this point. Since
// there cannot be any fading windows.
HASH_ITER2(ps->windows, _w) {
if (!_w->managed) {
continue;
}
auto w = (struct managed_win *)_w;
assert(w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED);
// We need to reacquire image
log_debug("Marking window %#010x (%s) for update after "
"redirection",
w->base.id, w->name);
win_set_flags(w, WIN_FLAGS_PIXMAP_STALE);
ps->pending_updates = true;
log_debug("Shader %s has attributes %" PRIu64, shader->key,
shader->attributes);
}
}
// The old backends binds pixmap lazily, nothing to do here
// window_stack shouldn't include window that's
// not in the hash table at this point. Since
// there cannot be any fading windows.
HASH_ITER2(ps->windows, _w) {
if (!_w->managed) {
continue;
}
auto w = (struct managed_win *)_w;
assert(w->state == WSTATE_MAPPED || w->state == WSTATE_UNMAPPED);
// We need to reacquire image
log_debug("Marking window %#010x (%s) for update after "
"redirection",
w->base.id, w->name);
win_set_flags(w, WIN_FLAGS_PIXMAP_STALE);
ps->pending_updates = true;
}
return true;
err:
if (ps->shadow_context) {
@ -802,20 +794,14 @@ static void configure_root(session_t *ps) {
bool has_root_change = false;
if (ps->redirected) {
// On root window changes
if (!ps->o.legacy_backends) {
assert(ps->backend_data);
has_root_change = ps->backend_data->ops->root_change != NULL;
} else {
// Old backend can handle root change
has_root_change = true;
}
assert(ps->backend_data);
has_root_change = ps->backend_data->ops->root_change != NULL;
if (!has_root_change) {
// deinit/reinit backend and free up resources if the backend
// cannot handle root change
destroy_backend(ps);
}
free_paint(ps, &ps->tgt_buffer);
}
ps->root_width = r->width;
@ -843,12 +829,6 @@ static void configure_root(session_t *ps) {
pixman_region32_clear(&ps->damage_ring[i]);
}
ps->damage = ps->damage_ring + ps->ndamage - 1;
#ifdef CONFIG_OPENGL
// GLX root change callback
if (BKEND_GLX == ps->o.backend && ps->o.legacy_backends) {
glx_on_root_change(ps);
}
#endif
if (has_root_change) {
if (ps->backend_data != NULL) {
ps->backend_data->ops->root_change(ps->backend_data, ps);
@ -1155,10 +1135,6 @@ static bool paint_preprocess(session_t *ps, bool *fade_running, bool *animation,
}
void root_damaged(session_t *ps) {
if (ps->root_tile_paint.pixmap) {
free_root_tile(ps);
}
if (!ps->redirected) {
return;
}
@ -1475,10 +1451,9 @@ 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);
return XCB_COMPOSITE_REDIRECT_AUTOMATIC;
}
if (!ps->o.legacy_backends && !backend_list[ps->o.backend]->present) {
if (!backend_list[ps->o.backend]->present) {
// if the backend doesn't render anything, we don't need to take over the
// screen.
return XCB_COMPOSITE_REDIRECT_AUTOMATIC;
@ -1515,12 +1490,8 @@ static bool redirect_start(session_t *ps) {
return false;
}
if (!ps->o.legacy_backends) {
assert(ps->backend_data);
ps->ndamage = ps->backend_data->ops->max_buffer_age;
} else {
ps->ndamage = maximum_buffer_age(ps);
}
assert(ps->backend_data);
ps->ndamage = ps->backend_data->ops->max_buffer_age;
ps->damage_ring = ccalloc(ps->ndamage, region_t);
ps->damage = ps->damage_ring + ps->ndamage - 1;
@ -1529,8 +1500,7 @@ static bool redirect_start(session_t *ps) {
}
ps->frame_pacing = !ps->o.no_frame_pacing && ps->o.vsync;
if ((ps->o.legacy_backends || ps->o.benchmark || !ps->backend_data->ops->last_render_time) &&
ps->frame_pacing) {
if ((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
log_info("Disabling frame pacing.");
@ -1854,11 +1824,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) {
did_render = paint_all_new(ps, bottom);
} else {
paint_all(ps, bottom);
}
did_render = paint_all_new(ps, bottom);
log_verbose("Render end");
ps->first_frame = false;
@ -2018,9 +1984,7 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
// .root_damage = XCB_NONE,
.overlay = XCB_NONE,
.root_tile_fill = false,
.root_tile_paint = PAINT_INIT,
.tgt_picture = XCB_NONE,
.tgt_buffer = PAINT_INIT,
.reg_win = XCB_NONE,
#ifdef CONFIG_OPENGL
.glx_prog_win = GLX_PROG_MAIN_INIT,
@ -2045,10 +2009,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
.last_msc = 0,
#ifdef CONFIG_VSYNC_DRM
.drm_fd = -1,
#endif
.xfixes_event = 0,
.xfixes_error = 0,
.damage_event = 0,
@ -2299,12 +2259,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
}
}
if (ps->o.legacy_backends) {
ps->shadow_context =
(void *)gaussian_kernel_autodetect_deviation(ps->o.shadow_radius);
sum_kernel_preprocess((conv *)ps->shadow_context);
}
rebuild_shadow_exclude_reg(ps);
// Query X Shape
@ -2422,7 +2376,6 @@ 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);
if (backend_list[ps->o.backend]->present) {
// If the backend has `present`, we couldn't be in automatic
@ -2437,12 +2390,6 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root);
apply_driver_workarounds(ps, ps->drivers);
// Initialize filters, must be preceded by OpenGL context creation
if (ps->o.legacy_backends && !init_render(ps)) {
log_fatal("Failed to initialize the backend");
exit(1);
}
if (ps->o.print_diagnostics) {
print_diagnostics(ps, config_file, compositor_running);
free(config_file_to_free);
@ -2456,20 +2403,10 @@ static session_t *session_init(int argc, char **argv, Display *dpy,
free(config_file_to_free);
if (bkend_use_glx(ps) && ps->o.legacy_backends) {
auto gl_logger = gl_string_marker_logger_new();
if (gl_logger) {
log_info("Enabling gl string marker");
log_add_target_tls(gl_logger);
}
}
if (!ps->o.legacy_backends) {
if (ps->o.monitor_repaint && !backend_list[ps->o.backend]->fill) {
log_warn("--monitor-repaint is not supported by the backend, "
"disabling");
ps->o.monitor_repaint = false;
}
if (ps->o.monitor_repaint && !backend_list[ps->o.backend]->fill) {
log_warn("--monitor-repaint is not supported by the backend, "
"disabling");
ps->o.monitor_repaint = false;
}
// Monitor screen changes if vsync_sw is enabled and we are using
@ -2662,19 +2599,12 @@ static void session_destroy(session_t *ps) {
c2_list_free(&ps->o.window_shader_fg_rules, free);
c2_state_free(ps->c2_state);
// Free tgt_{buffer,picture} and root_picture
if (ps->tgt_buffer.pict == ps->tgt_picture) {
ps->tgt_buffer.pict = XCB_NONE;
}
if (ps->tgt_picture != ps->root_picture) {
x_free_picture(&ps->c, ps->tgt_picture);
}
x_free_picture(&ps->c, ps->root_picture);
ps->tgt_picture = ps->root_picture = XCB_NONE;
free_paint(ps, &ps->tgt_buffer);
pixman_region32_fini(&ps->screen_reg);
free(ps->expose_rects);
@ -2700,14 +2630,6 @@ static void session_destroy(session_t *ps) {
free(shader);
}
#ifdef CONFIG_VSYNC_DRM
// Close file opened for DRM VSync
if (ps->drm_fd >= 0) {
close(ps->drm_fd);
ps->drm_fd = -1;
}
#endif
// Release overlay window
if (ps->overlay) {
xcb_composite_release_overlay_window(ps->c.c, ps->overlay);
@ -2735,26 +2657,12 @@ static void session_destroy(session_t *ps) {
ps->damaged_region = XCB_NONE;
}
if (!ps->o.legacy_backends) {
// backend is deinitialized in unredirect()
assert(ps->backend_data == NULL);
} else {
deinit_render(ps);
}
#if CONFIG_OPENGL
if (glx_has_context(ps)) {
// GLX context created, but not for rendering
glx_destroy(ps);
}
#endif
// backend is deinitialized in unredirect()
assert(ps->backend_data == NULL);
// Flush all events
xcb_aux_sync(ps->c.c);
ev_io_stop(ps->loop, &ps->xiow);
if (ps->o.legacy_backends) {
free_conv((conv *)ps->shadow_context);
}
destroy_atoms(ps->atoms);
#ifdef DEBUG_XRC

View File

@ -19,7 +19,6 @@
#include "config.h"
#include "log.h" // XXX clean up
#include "region.h"
#include "render.h"
#include "types.h"
#include "utils.h"
#include "win.h"
@ -84,14 +83,6 @@ static inline bool array_wid_exists(const xcb_window_t *arr, int count, xcb_wind
return false;
}
#ifndef CONFIG_OPENGL
static inline void free_paint_glx(session_t *ps attr_unused, paint_t *p attr_unused) {
}
static inline void
free_win_res_glx(session_t *ps attr_unused, struct managed_win *w attr_unused) {
}
#endif
/**
* Dump an drawable's info.
*/

File diff suppressed because it is too large Load Diff

View File

@ -1,48 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>
#include <xcb/render.h>
#include <xcb/xcb.h>
#ifdef CONFIG_OPENGL
#include "backend/gl/glx.h"
#endif
#include "region.h"
typedef struct _glx_texture glx_texture_t;
typedef struct glx_prog_main glx_prog_main_t;
typedef struct session session_t;
struct managed_win;
typedef struct paint {
xcb_pixmap_t pixmap;
xcb_render_picture_t pict;
glx_texture_t *ptex;
#ifdef CONFIG_OPENGL
struct glx_fbconfig_info fbcfg;
#endif
} paint_t;
typedef struct clip {
xcb_render_picture_t pict;
int x;
int y;
} clip_t;
void render(session_t *ps, int x, int y, int dx, int dy, int w, int h, int fullw,
int fullh, 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);
void paint_one(session_t *ps, struct managed_win *w, const region_t *reg_paint);
void paint_all(session_t *ps, struct managed_win *const t);
void free_paint(session_t *ps, paint_t *ppaint);
void free_root_tile(session_t *ps);
bool init_render(session_t *ps);
void deinit_render(session_t *ps);
int maximum_buffer_age(session_t *);

View File

@ -1,208 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
/// Function pointers to init VSync modes.
#include "common.h"
#include "log.h"
#ifdef CONFIG_OPENGL
#include "backend/gl/glx.h"
#include "opengl.h"
#endif
#ifdef CONFIG_VSYNC_DRM
#include <drm.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#endif
#include "config.h"
#include "vsync.h"
#ifdef CONFIG_VSYNC_DRM
/**
* Wait for next VSync, DRM method.
*
* Stolen from:
* https://github.com/MythTV/mythtv/blob/master/mythtv/libs/libmythtv/vsync.cpp
*/
static int vsync_drm_wait(session_t *ps) {
int ret = -1;
drm_wait_vblank_t vbl;
vbl.request.type = _DRM_VBLANK_RELATIVE, vbl.request.sequence = 1;
do {
ret = ioctl(ps->drm_fd, DRM_IOCTL_WAIT_VBLANK, &vbl);
vbl.request.type &= ~(uint)_DRM_VBLANK_RELATIVE;
} while (ret && errno == EINTR);
if (ret)
log_error("VBlank ioctl did not work, unimplemented in this drmver?");
return ret;
}
/**
* Initialize DRM VSync.
*
* @return true for success, false otherwise
*/
static bool vsync_drm_init(session_t *ps) {
// Should we always open card0?
if (ps->drm_fd < 0 && (ps->drm_fd = open("/dev/dri/card0", O_RDWR)) < 0) {
log_error("Failed to open device.");
return false;
}
if (vsync_drm_wait(ps))
return false;
return true;
}
#endif
#ifdef CONFIG_OPENGL
/**
* Initialize OpenGL VSync.
*
* Stolen from:
* http://git.tuxfamily.org/?p=ccm/cairocompmgr.git;a=commitdiff;h=efa4ceb97da501e8630ca7f12c99b1dce853c73e
* Possible original source: http://www.inb.uni-luebeck.de/~boehme/xvideo_sync.html
*
* @return true for success, false otherwise
*/
static bool vsync_opengl_init(session_t *ps) {
if (!ensure_glx_context(ps)) {
return false;
}
return glxext.has_GLX_SGI_video_sync;
}
static bool vsync_opengl_oml_init(session_t *ps) {
if (!ensure_glx_context(ps)) {
return false;
}
return glxext.has_GLX_OML_sync_control;
}
static inline bool vsync_opengl_swc_swap_interval(session_t *ps, int interval) {
if (glxext.has_GLX_MESA_swap_control) {
return glXSwapIntervalMESA((uint)interval) == 0;
}
if (glxext.has_GLX_SGI_swap_control) {
return glXSwapIntervalSGI(interval) == 0;
}
if (glxext.has_GLX_EXT_swap_control) {
GLXDrawable d = glXGetCurrentDrawable();
if (d == None) {
// We don't have a context??
return false;
}
glXSwapIntervalEXT(ps->c.dpy, glXGetCurrentDrawable(), interval);
return true;
}
return false;
}
static bool vsync_opengl_swc_init(session_t *ps) {
if (!bkend_use_glx(ps)) {
log_error("OpenGL swap control requires the GLX backend.");
return false;
}
if (!vsync_opengl_swc_swap_interval(ps, 1)) {
log_error("Failed to load a swap control extension.");
return false;
}
return true;
}
/**
* Wait for next VSync, OpenGL method.
*/
static int vsync_opengl_wait(session_t *ps attr_unused) {
unsigned vblank_count = 0;
glXGetVideoSyncSGI(&vblank_count);
glXWaitVideoSyncSGI(2, (vblank_count + 1) % 2, &vblank_count);
return 0;
}
/**
* Wait for next VSync, OpenGL OML method.
*
* https://mail.gnome.org/archives/clutter-list/2012-November/msg00031.html
*/
static int vsync_opengl_oml_wait(session_t *ps) {
int64_t ust = 0, msc = 0, sbc = 0;
glXGetSyncValuesOML(ps->c.dpy, ps->reg_win, &ust, &msc, &sbc);
glXWaitForMscOML(ps->c.dpy, ps->reg_win, 0, 2, (msc + 1) % 2, &ust, &msc, &sbc);
return 0;
}
#endif
/**
* Initialize current VSync method.
*/
bool vsync_init(session_t *ps) {
#ifdef CONFIG_OPENGL
if (bkend_use_glx(ps)) {
// Mesa turns on swap control by default, undo that
vsync_opengl_swc_swap_interval(ps, 0);
}
#endif
#ifdef CONFIG_VSYNC_DRM
log_warn("The DRM vsync method is deprecated, please don't enable it.");
#endif
if (!ps->o.vsync) {
return true;
}
#ifdef CONFIG_OPENGL
if (bkend_use_glx(ps)) {
if (!vsync_opengl_swc_init(ps)) {
return false;
}
ps->vsync_wait = NULL; // glXSwapBuffers will automatically wait
// for vsync, we don't need to do anything.
return true;
}
#endif
// Oh no, we are not using glx backend.
// Throwing things at wall.
#ifdef CONFIG_OPENGL
if (vsync_opengl_oml_init(ps)) {
log_info("Using the opengl-oml vsync method");
ps->vsync_wait = vsync_opengl_oml_wait;
return true;
}
if (vsync_opengl_init(ps)) {
log_info("Using the opengl vsync method");
ps->vsync_wait = vsync_opengl_wait;
return true;
}
#endif
#ifdef CONFIG_VSYNC_DRM
if (vsync_drm_init(ps)) {
log_info("Using the drm vsync method");
ps->vsync_wait = vsync_drm_wait;
return true;
}
#endif
log_error("No supported vsync method found for this backend");
return false;
}

View File

@ -1,7 +0,0 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <stdbool.h>
typedef struct session session_t;
bool vsync_init(session_t *ps);

View File

@ -25,7 +25,6 @@
#include "log.h"
#include "picom.h"
#include "region.h"
#include "render.h"
#include "string_utils.h"
#include "types.h"
#include "uthash_extra.h"
@ -36,11 +35,6 @@
#include "dbus.h"
#endif
#ifdef CONFIG_OPENGL
// TODO(yshui) Get rid of this include
#include "opengl.h"
#endif
#include "win.h"
// TODO(yshui) Make more window states internal
@ -1277,7 +1271,6 @@ void win_on_win_size_change(session_t *ps, struct managed_win *w) {
win_release_mask(ps->backend_data, w);
win_release_shadow(ps->backend_data, w);
ps->pending_updates = true;
free_paint(ps, &w->shadow_paint);
}
/**
@ -1454,9 +1447,6 @@ void free_win_res(session_t *ps, struct managed_win *w) {
// finish_unmap_win should've done that for us.
// XXX unless we are called by session_destroy
// assert(w->win_data == NULL);
free_win_res_glx(ps, w);
free_paint(ps, &w->paint);
free_paint(ps, &w->shadow_paint);
// Above should be done during unmapping
// Except when we are called by session_destroy
@ -1603,10 +1593,6 @@ struct win *fill_win(session_t *ps, struct win *w) {
.class_general = NULL,
.role = NULL,
// Initialized during paint
.paint = PAINT_INIT,
.shadow_paint = PAINT_INIT,
.corner_radius = 0,
};
@ -2018,9 +2004,6 @@ void win_update_bounding_shape(session_t *ps, struct managed_win *w) {
win_release_mask(ps->backend_data, w);
win_release_shadow(ps->backend_data, w);
ps->pending_updates = true;
free_paint(ps, &w->paint);
free_paint(ps, &w->shadow_paint);
}
/**
@ -2139,9 +2122,6 @@ static void unmap_win_finish(session_t *ps, struct managed_win *w) {
assert(!w->shadow_image);
}
free_paint(ps, &w->paint);
free_paint(ps, &w->shadow_paint);
// Try again at binding images when the window is mapped next time
win_clear_flags(w, WIN_FLAGS_IMAGE_ERROR);
}

View File

@ -15,7 +15,6 @@
#include "compiler.h"
#include "list.h"
#include "region.h"
#include "render.h"
#include "types.h"
#include "utils.h"
#include "win_defs.h"
@ -23,7 +22,6 @@
struct backend_base;
typedef struct session session_t;
typedef struct _glx_texture glx_texture_t;
#define win_stack_foreach_managed(w, win_stack) \
list_foreach(struct managed_win, w, win_stack, \
@ -33,21 +31,6 @@ typedef struct _glx_texture glx_texture_t;
list_foreach_safe(struct managed_win, w, win_stack, \
base.stack_neighbour) if ((w)->base.managed)
#ifdef CONFIG_OPENGL
// FIXME this type should be in opengl.h
// it is very unideal for it to be here
typedef struct {
/// Framebuffer used for blurring.
GLuint fbo;
/// Textures used for blurring.
GLuint textures[2];
/// Width of the textures.
int width;
/// Height of the textures.
int height;
} glx_blur_cache_t;
#endif
/// An entry in the window stack. May or may not correspond to a window we know about.
struct window_stack_entry {
struct list_node stack_neighbour;
@ -133,8 +116,6 @@ struct managed_win {
bool pixmap_damaged;
/// Damage of the window.
xcb_damage_damage_t damage;
/// Paint info of the window.
paint_t paint;
/// bitmap for properties which needs to be updated
uint64_t *stale_props;
/// number of uint64_ts that has been allocated for stale_props
@ -260,8 +241,6 @@ struct managed_win {
int shadow_width;
/// Height of shadow. Affected by window size and command line argument.
int shadow_height;
/// Picture to render shadow. Affected by window size.
paint_t shadow_paint;
/// The value of _COMPTON_SHADOW attribute of the window. Below 0 for
/// none.
long long prop_shadow;
@ -283,13 +262,6 @@ struct managed_win {
/// The custom window shader to use when rendering.
struct shader_info *fg_shader;
#ifdef CONFIG_OPENGL
/// Textures and FBO background blur use.
glx_blur_cache_t glx_blur_cache;
/// Background texture of the window
glx_texture_t *glx_texture_bg;
#endif
};
/// Process pending updates/images flags on a window. Has to be called in X critical