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:
Yuxuan Shui
2019-02-09 15:52:40 +00:00
parent 62d4c0cbdb
commit b0c5db9f5a
10 changed files with 123 additions and 44 deletions

View File

@ -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)));

View File

@ -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')

View File

@ -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);

View File

@ -13,6 +13,7 @@
#include <X11/Xutil.h>
#include "common.h"
#include "backend/backend.h"
#include "win.h"
#include "x.h"
#include "c2.h"

View File

@ -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.

View File

@ -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;

View File

@ -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()