Let old/new backends co-exist
Now both the old and the new backends are compiled in, the user can choose which one to use with a command line switch. Lower the barrier for testing. Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
@ -115,7 +115,7 @@ typedef struct backend_info {
|
||||
void *(*prepare_win)(void *backend_data, session_t *ps, win *w)
|
||||
__attribute__((nonnull(1, 2, 3)));
|
||||
|
||||
/// Free resources allocated by prepare()
|
||||
/// Free resources allocated by prepare_win()
|
||||
void (*release_win)(void *backend_data, session_t *ps, win *w, void *win_data)
|
||||
__attribute__((nonnull(1, 2, 3)));
|
||||
|
||||
|
@ -1,8 +1,5 @@
|
||||
# enable xrender
|
||||
srcs += [ files('backend_common.c') ]
|
||||
if get_option('new_backends')
|
||||
srcs += [ files('xrender.c', 'backend.c') ]
|
||||
endif
|
||||
srcs += [ files('backend_common.c', 'xrender.c', 'backend.c') ]
|
||||
|
||||
# enable opengl
|
||||
if get_option('opengl')
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "types.h"
|
||||
#include "c2.h"
|
||||
#include "log.h"
|
||||
#include "backend/backend.h"
|
||||
#ifdef CONFIG_DBUS
|
||||
#include "dbus.h"
|
||||
#endif
|
||||
@ -738,6 +739,7 @@ repair_win(session_t *ps, win *w) {
|
||||
add_damage(ps, &parts);
|
||||
pixman_region32_fini(&parts);
|
||||
}
|
||||
|
||||
static void
|
||||
restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||
xcb_window_t old_above;
|
||||
@ -802,8 +804,17 @@ restack_win(session_t *ps, win *w, xcb_window_t new_above) {
|
||||
void
|
||||
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||
// On root window changes
|
||||
auto root_change_fn = backend_list[ps->o.backend]->root_change;
|
||||
if (ce->window == ps->root) {
|
||||
free_paint(ps, &ps->tgt_buffer);
|
||||
if (ps->o.experimental_backends) {
|
||||
if (!root_change_fn) {
|
||||
// deinit/reinit backend if the backend cannot handle root change
|
||||
backend_list[ps->o.backend]->deinit(ps->backend_data, ps);
|
||||
ps->backend_data = NULL;
|
||||
}
|
||||
} else {
|
||||
free_paint(ps, &ps->tgt_buffer);
|
||||
}
|
||||
|
||||
ps->root_width = ce->width;
|
||||
ps->root_height = ce->height;
|
||||
@ -838,7 +849,13 @@ configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
|
||||
if (BKEND_GLX == ps->o.backend)
|
||||
glx_on_root_change(ps);
|
||||
#endif
|
||||
|
||||
if (ps->o.experimental_backends) {
|
||||
if (root_change_fn) {
|
||||
root_change_fn(ps->backend_data, ps);
|
||||
} else {
|
||||
ps->backend_data = backend_list[ps->o.backend]->init(ps);
|
||||
}
|
||||
}
|
||||
force_repaint(ps);
|
||||
|
||||
return;
|
||||
@ -1948,11 +1965,26 @@ redir_start(session_t *ps) {
|
||||
|
||||
// Map overlay window. Done firstly according to this:
|
||||
// https://bugzilla.gnome.org/show_bug.cgi?id=597014
|
||||
if (ps->overlay)
|
||||
if (ps->overlay) {
|
||||
xcb_map_window(ps->c, ps->overlay);
|
||||
}
|
||||
|
||||
xcb_composite_redirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL);
|
||||
|
||||
x_sync(ps->c);
|
||||
|
||||
if (ps->o.experimental_backends) {
|
||||
// Reinitialize win_data
|
||||
backend_info_t *bi = backend_list[ps->o.backend];
|
||||
assert(bi);
|
||||
ps->backend_data = bi->init(ps);
|
||||
for (win *w = ps->list; w; w = w->next) {
|
||||
if (w->a.map_state == XCB_MAP_STATE_VIEWABLE) {
|
||||
w->win_data = bi->prepare_win(ps->backend_data, ps, w);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// Unredirect GL context window as this may have an effect on VSync:
|
||||
// < http://dri.freedesktop.org/wiki/CompositeSwap >
|
||||
@ -1979,6 +2011,7 @@ static void
|
||||
redir_stop(session_t *ps) {
|
||||
if (ps->redirected) {
|
||||
log_debug("Screen unredirected.");
|
||||
backend_info_t *bi = backend_list[ps->o.backend];
|
||||
// Destroy all Pictures as they expire once windows are unredirected
|
||||
// If we don't destroy them here, looks like the resources are just
|
||||
// kept inaccessible somehow
|
||||
@ -1992,7 +2025,18 @@ redir_stop(session_t *ps) {
|
||||
}
|
||||
|
||||
// `w` might be freed by win_check_fade_finished
|
||||
if (w) {
|
||||
if (!w) {
|
||||
continue;
|
||||
}
|
||||
if (ps->o.experimental_backends) {
|
||||
assert(bi);
|
||||
if (w->state == WSTATE_MAPPED) {
|
||||
bi->release_win(ps->backend_data, ps, w, w->win_data);
|
||||
w->win_data = NULL;
|
||||
} else {
|
||||
assert(!w->win_data);
|
||||
}
|
||||
} else {
|
||||
free_paint(ps, &w->paint);
|
||||
}
|
||||
}
|
||||
@ -2002,6 +2046,12 @@ redir_stop(session_t *ps) {
|
||||
if (ps->overlay)
|
||||
xcb_unmap_window(ps->c, ps->overlay);
|
||||
|
||||
if (ps->o.experimental_backends) {
|
||||
// deinit backend
|
||||
bi->deinit(ps->backend_data, ps);
|
||||
ps->backend_data = NULL;
|
||||
}
|
||||
|
||||
// Must call XSync() here
|
||||
x_sync(ps->c);
|
||||
|
||||
@ -2079,7 +2129,11 @@ _draw_callback(EV_P_ session_t *ps, int revents) {
|
||||
// If the screen is unredirected, free all_damage to stop painting
|
||||
if (ps->redirected && ps->o.stoppaint_force != ON) {
|
||||
static int paint = 0;
|
||||
paint_all(ps, t, false);
|
||||
if (ps->o.experimental_backends) {
|
||||
paint_all_new(ps, t, false);
|
||||
} else {
|
||||
paint_all(ps, t, false);
|
||||
}
|
||||
|
||||
paint++;
|
||||
if (ps->o.benchmark && paint >= ps->o.benchmark)
|
||||
@ -2836,8 +2890,6 @@ session_destroy(session_t *ps) {
|
||||
free(ps->o.glx_fshader_win_str);
|
||||
free_xinerama_info(ps);
|
||||
|
||||
deinit_render(ps);
|
||||
|
||||
#ifdef CONFIG_VSYNC_DRM
|
||||
// Close file opened for DRM VSync
|
||||
if (ps->drm_fd >= 0) {
|
||||
@ -2863,6 +2915,13 @@ session_destroy(session_t *ps) {
|
||||
ps->reg_win = XCB_NONE;
|
||||
}
|
||||
|
||||
if (ps->o.experimental_backends) {
|
||||
// backend is deinitialized in redir_stop
|
||||
assert(ps->backend_data == NULL);
|
||||
} else {
|
||||
deinit_render(ps);
|
||||
}
|
||||
|
||||
// Flush all events
|
||||
x_sync(ps->c);
|
||||
ev_io_stop(ps->loop, &ps->xiow);
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include <X11/Xutil.h>
|
||||
#include "common.h"
|
||||
#include "backend/backend.h"
|
||||
#include "win.h"
|
||||
#include "x.h"
|
||||
#include "c2.h"
|
||||
|
@ -79,6 +79,8 @@ typedef struct options_t {
|
||||
bool monitor_repaint;
|
||||
bool print_diagnostics;
|
||||
// === General ===
|
||||
/// Use the experimental new backends?
|
||||
bool experimental_backends;
|
||||
/// Path to write PID to.
|
||||
char *write_pid_path;
|
||||
/// The backend in use.
|
||||
@ -270,13 +272,14 @@ 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);
|
||||
void set_default_winopts(options_t *, win_option_mask_t *, bool shadow_enable,
|
||||
bool fading_enable);
|
||||
/// Parse a configuration file is that is enabled, also initialize the winopt_mask with
|
||||
/// default values
|
||||
/// Outputs and returns:
|
||||
/// same as parse_config_libconfig
|
||||
char *parse_config(options_t *, const char *config_file, bool *shadow_enable,
|
||||
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||
bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
|
||||
|
||||
/**
|
||||
* Parse a backend option argument.
|
||||
|
@ -440,6 +440,7 @@ static const struct option longopts[] = {
|
||||
{"log-file", required_argument, NULL, 322},
|
||||
{"reredir-on-root-change", no_argument, NULL, 731},
|
||||
{"glx-reinit-on-root-change", no_argument, NULL, 732},
|
||||
{"experimental-backends", no_argument, NULL, 733},
|
||||
{"monitor-repaint", no_argument, NULL, 800},
|
||||
{"diagnostics", no_argument, NULL, 801},
|
||||
// Must terminate with a NULL entry
|
||||
@ -770,6 +771,7 @@ void get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
|
||||
P_CASEBOOL(319, no_x_selection);
|
||||
P_CASEBOOL(731, reredir_on_root_change);
|
||||
P_CASEBOOL(732, glx_reinit_on_root_change);
|
||||
P_CASEBOOL(733, experimental_backends);
|
||||
P_CASEBOOL(800, monitor_repaint);
|
||||
case 801: opt->print_diagnostics = true; break;
|
||||
default: usage(1); break;
|
||||
|
43
src/win.c
43
src/win.c
@ -24,6 +24,7 @@
|
||||
#include "log.h"
|
||||
#include "types.h"
|
||||
#include "region.h"
|
||||
#include "backend/backend.h"
|
||||
#include "render.h"
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
@ -609,7 +610,12 @@ void calc_win_size(session_t *ps, win *w) {
|
||||
calc_shadow_geometry(ps, w);
|
||||
w->flags |= WFLAG_SIZE_CHANGE;
|
||||
// Invalidate the shadow we built
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
if (ps->o.experimental_backends) {
|
||||
backend_list[ps->o.backend]->release_win(ps->backend_data, ps, w, w->win_data);
|
||||
w->win_data = backend_list[ps->o.backend]->prepare_win(ps->backend_data, ps, w);
|
||||
} else {
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1228,9 +1234,21 @@ void win_update_bounding_shape(session_t *ps, win *w) {
|
||||
win_rounded_corners(ps, w);
|
||||
|
||||
// Window shape changed, we should free old wpaint and shadow pict
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
//log_trace("free out dated pict");
|
||||
if (ps->o.experimental_backends) {
|
||||
//log_trace("free out dated pict");
|
||||
// Window shape changed, we should free win_data
|
||||
if (ps->redirected && w->state == WSTATE_MAPPED) {
|
||||
// Note we only do this when screen is redirected, because
|
||||
// otherwise win_data is not valid
|
||||
backend_info_t *bi = backend_list[ps->o.backend];
|
||||
bi->release_win(ps->backend_data, ps, w, w->win_data);
|
||||
w->win_data = bi->prepare_win(ps->backend_data, ps, w);
|
||||
//log_trace("free out dated pict");
|
||||
}
|
||||
} else {
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
}
|
||||
|
||||
win_on_factor_change(ps, w);
|
||||
}
|
||||
@ -1321,8 +1339,17 @@ finish_unmap_win(session_t *ps, win **_w) {
|
||||
w->state = WSTATE_UNMAPPED;
|
||||
w->flags = 0;
|
||||
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
if (ps->o.experimental_backends) {
|
||||
// We are in unmap_win, we definitely was viewable
|
||||
if (ps->redirected) {
|
||||
assert(w->win_data);
|
||||
backend_list[ps->o.backend]->release_win(ps->backend_data, ps, w, w->win_data);
|
||||
w->win_data = NULL;
|
||||
}
|
||||
} else {
|
||||
free_paint(ps, &w->paint);
|
||||
free_paint(ps, &w->shadow_paint);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1347,7 +1374,9 @@ finish_destroy_win(session_t *ps, win **_w) {
|
||||
ps->active_win = NULL;
|
||||
}
|
||||
|
||||
free_win_res(ps, w);
|
||||
if (!ps->o.experimental_backends) {
|
||||
free_win_res(ps, w);
|
||||
}
|
||||
|
||||
// Drop w from all prev_trans to avoid accessing freed memory in
|
||||
// repair_win()
|
||||
|
Reference in New Issue
Block a user