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
No known key found for this signature in database
GPG Key ID: 37C999F617EA1A47
10 changed files with 123 additions and 44 deletions

View File

@ -43,57 +43,46 @@ jobs:
<<: *defaults
steps:
- build:
build-config: -Dbuild_docs=true -Dnew_backends=true
build-config: -Dbuild_docs=true
minimal:
<<: *defaults
steps:
- build:
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false -Dnew_backends=true
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false
nogl:
<<: *defaults
steps:
- build:
build-config: -Dopengl=false -Dnew_backends=true
build-config: -Dopengl=false
noregex:
<<: *defaults
steps:
- build:
build-config: -Dregex=false -Dnew_backends=true
build-config: -Dregex=false
clang_basic:
<<: *defaults
steps:
- build:
cc: clang-6.0
build-config: -Dnew_backends=true
build-config:
clang_minimal:
<<: *defaults
steps:
- build:
cc: clang-6.0
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false -Dnew_backends=true
build-config: -Dopengl=false -Ddbus=false -Dregex=false -Dconfig_file=false
clang_nogl:
<<: *defaults
steps:
- build:
cc: clang-6.0
build-config: -Dopengl=false -Dnew_backends=true
build-config: -Dopengl=false
clang_noregex:
<<: *defaults
steps:
- build:
cc: clang-6.0
build-config: -Dregex=false -Dnew_backends=true
clang_basic_nonew:
<<: *defaults
steps:
- build:
cc: clang-6.0
build-config:
basic_nonew:
<<: *defaults
steps:
- build:
build-config:
build-config: -Dregex=false
workflows:
all_builds:
@ -104,8 +93,6 @@ workflows:
- clang_minimal
- nogl
- clang_nogl
- clang_basic_nonew
- basic_nonew
# - test-xvfb
# vim: set sw=2 ts=8 et:

View File

@ -76,6 +76,9 @@ OPTIONS
*--log-file*::
Set the log file. If *--log-file* is never specified, logs will be written to stderr. Otherwise, logs will to writeen to the given file, though some of the early logs might still be written to the stderr. When setting this option from the config file, it is recommended to use an absolute path.
*--experimental-backends*::
Use the new, reimplemented version of the backends. The new backends are HIGHLY UNSTABLE at this point, you have been warned. This option is not available in the config file.
*--show-all-xerrors*::
Show all X errors (for debugging).

View File

@ -11,6 +11,4 @@ option('xrescheck', type: 'boolean', value: false, description: 'Enable X resour
option('build_docs', type: 'boolean', value: false, description: 'Build documentation and man pages')
option('new_backends', type: 'boolean', value: false, description: 'Does not really do anything right now')
option('modularize', type: 'boolean', value: false, description: 'Build with clang\'s module system')

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) {
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;
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,7 +272,8 @@ 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:

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
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
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);
//log_trace("free out dated pict");
}
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;
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;
}
if (!ps->o.experimental_backends) {
free_win_res(ps, w);
}
// Drop w from all prev_trans to avoid accessing freed memory in
// repair_win()