Merge pull request #109 from yshui/integrate-new-backends

Integrate new backends
This commit is contained in:
yshui 2019-02-20 17:55:03 +00:00 committed by GitHub
commit 72a921da2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 123 additions and 44 deletions

View File

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

View File

@ -76,6 +76,9 @@ OPTIONS
*--log-file*:: *--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. 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-xerrors*::
Show all X errors (for debugging). 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('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') 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) void *(*prepare_win)(void *backend_data, session_t *ps, win *w)
__attribute__((nonnull(1, 2, 3))); __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) void (*release_win)(void *backend_data, session_t *ps, win *w, void *win_data)
__attribute__((nonnull(1, 2, 3))); __attribute__((nonnull(1, 2, 3)));

View File

@ -1,8 +1,5 @@
# enable xrender # enable xrender
srcs += [ files('backend_common.c') ] srcs += [ files('backend_common.c', 'xrender.c', 'backend.c') ]
if get_option('new_backends')
srcs += [ files('xrender.c', 'backend.c') ]
endif
# enable opengl # enable opengl
if get_option('opengl') if get_option('opengl')

View File

@ -46,6 +46,7 @@
#include "types.h" #include "types.h"
#include "c2.h" #include "c2.h"
#include "log.h" #include "log.h"
#include "backend/backend.h"
#ifdef CONFIG_DBUS #ifdef CONFIG_DBUS
#include "dbus.h" #include "dbus.h"
#endif #endif
@ -738,6 +739,7 @@ repair_win(session_t *ps, win *w) {
add_damage(ps, &parts); add_damage(ps, &parts);
pixman_region32_fini(&parts); pixman_region32_fini(&parts);
} }
static void static void
restack_win(session_t *ps, win *w, xcb_window_t new_above) { restack_win(session_t *ps, win *w, xcb_window_t new_above) {
xcb_window_t old_above; xcb_window_t old_above;
@ -802,8 +804,17 @@ restack_win(session_t *ps, win *w, xcb_window_t new_above) {
void void
configure_win(session_t *ps, xcb_configure_notify_event_t *ce) { configure_win(session_t *ps, xcb_configure_notify_event_t *ce) {
// On root window changes // On root window changes
auto root_change_fn = backend_list[ps->o.backend]->root_change;
if (ce->window == ps->root) { 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); free_paint(ps, &ps->tgt_buffer);
}
ps->root_width = ce->width; ps->root_width = ce->width;
ps->root_height = ce->height; 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) if (BKEND_GLX == ps->o.backend)
glx_on_root_change(ps); glx_on_root_change(ps);
#endif #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); force_repaint(ps);
return; return;
@ -1948,11 +1965,26 @@ redir_start(session_t *ps) {
// Map overlay window. Done firstly according to this: // Map overlay window. Done firstly according to this:
// https://bugzilla.gnome.org/show_bug.cgi?id=597014 // https://bugzilla.gnome.org/show_bug.cgi?id=597014
if (ps->overlay) if (ps->overlay) {
xcb_map_window(ps->c, ps->overlay); xcb_map_window(ps->c, ps->overlay);
}
xcb_composite_redirect_subwindows(ps->c, ps->root, XCB_COMPOSITE_REDIRECT_MANUAL); 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: // Unredirect GL context window as this may have an effect on VSync:
// < http://dri.freedesktop.org/wiki/CompositeSwap > // < http://dri.freedesktop.org/wiki/CompositeSwap >
@ -1979,6 +2011,7 @@ static void
redir_stop(session_t *ps) { redir_stop(session_t *ps) {
if (ps->redirected) { if (ps->redirected) {
log_debug("Screen unredirected."); log_debug("Screen unredirected.");
backend_info_t *bi = backend_list[ps->o.backend];
// Destroy all Pictures as they expire once windows are unredirected // Destroy all Pictures as they expire once windows are unredirected
// If we don't destroy them here, looks like the resources are just // If we don't destroy them here, looks like the resources are just
// kept inaccessible somehow // kept inaccessible somehow
@ -1992,7 +2025,18 @@ redir_stop(session_t *ps) {
} }
// `w` might be freed by win_check_fade_finished // `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); free_paint(ps, &w->paint);
} }
} }
@ -2002,6 +2046,12 @@ redir_stop(session_t *ps) {
if (ps->overlay) if (ps->overlay)
xcb_unmap_window(ps->c, 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 // Must call XSync() here
x_sync(ps->c); 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 the screen is unredirected, free all_damage to stop painting
if (ps->redirected && ps->o.stoppaint_force != ON) { if (ps->redirected && ps->o.stoppaint_force != ON) {
static int paint = 0; static int paint = 0;
if (ps->o.experimental_backends) {
paint_all_new(ps, t, false);
} else {
paint_all(ps, t, false); paint_all(ps, t, false);
}
paint++; paint++;
if (ps->o.benchmark && paint >= ps->o.benchmark) 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(ps->o.glx_fshader_win_str);
free_xinerama_info(ps); free_xinerama_info(ps);
deinit_render(ps);
#ifdef CONFIG_VSYNC_DRM #ifdef CONFIG_VSYNC_DRM
// Close file opened for DRM VSync // Close file opened for DRM VSync
if (ps->drm_fd >= 0) { if (ps->drm_fd >= 0) {
@ -2863,6 +2915,13 @@ session_destroy(session_t *ps) {
ps->reg_win = XCB_NONE; 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 // Flush all events
x_sync(ps->c); x_sync(ps->c);
ev_io_stop(ps->loop, &ps->xiow); ev_io_stop(ps->loop, &ps->xiow);

View File

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

View File

@ -79,6 +79,8 @@ typedef struct options_t {
bool monitor_repaint; bool monitor_repaint;
bool print_diagnostics; bool print_diagnostics;
// === General === // === General ===
/// Use the experimental new backends?
bool experimental_backends;
/// Path to write PID to. /// Path to write PID to.
char *write_pid_path; char *write_pid_path;
/// The backend in use. /// 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); bool *fading_enable, bool *hasneg, win_option_mask_t *winopt_mask);
#endif #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 /// Parse a configuration file is that is enabled, also initialize the winopt_mask with
/// default values /// default values
/// Outputs and returns: /// Outputs and returns:

View File

@ -440,6 +440,7 @@ static const struct option longopts[] = {
{"log-file", required_argument, NULL, 322}, {"log-file", required_argument, NULL, 322},
{"reredir-on-root-change", no_argument, NULL, 731}, {"reredir-on-root-change", no_argument, NULL, 731},
{"glx-reinit-on-root-change", no_argument, NULL, 732}, {"glx-reinit-on-root-change", no_argument, NULL, 732},
{"experimental-backends", no_argument, NULL, 733},
{"monitor-repaint", no_argument, NULL, 800}, {"monitor-repaint", no_argument, NULL, 800},
{"diagnostics", no_argument, NULL, 801}, {"diagnostics", no_argument, NULL, 801},
// Must terminate with a NULL entry // 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(319, no_x_selection);
P_CASEBOOL(731, reredir_on_root_change); P_CASEBOOL(731, reredir_on_root_change);
P_CASEBOOL(732, glx_reinit_on_root_change); P_CASEBOOL(732, glx_reinit_on_root_change);
P_CASEBOOL(733, experimental_backends);
P_CASEBOOL(800, monitor_repaint); P_CASEBOOL(800, monitor_repaint);
case 801: opt->print_diagnostics = true; break; case 801: opt->print_diagnostics = true; break;
default: usage(1); break; default: usage(1); break;

View File

@ -24,6 +24,7 @@
#include "log.h" #include "log.h"
#include "types.h" #include "types.h"
#include "region.h" #include "region.h"
#include "backend/backend.h"
#include "render.h" #include "render.h"
#ifdef CONFIG_DBUS #ifdef CONFIG_DBUS
@ -609,7 +610,12 @@ void calc_win_size(session_t *ps, win *w) {
calc_shadow_geometry(ps, w); calc_shadow_geometry(ps, w);
w->flags |= WFLAG_SIZE_CHANGE; w->flags |= WFLAG_SIZE_CHANGE;
// Invalidate the shadow we built // 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); 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); win_rounded_corners(ps, w);
// Window shape changed, we should free old wpaint and shadow pict // 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->paint);
free_paint(ps, &w->shadow_paint); free_paint(ps, &w->shadow_paint);
//log_trace("free out dated pict"); }
win_on_factor_change(ps, w); win_on_factor_change(ps, w);
} }
@ -1321,8 +1339,17 @@ finish_unmap_win(session_t *ps, win **_w) {
w->state = WSTATE_UNMAPPED; w->state = WSTATE_UNMAPPED;
w->flags = 0; 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->paint);
free_paint(ps, &w->shadow_paint); free_paint(ps, &w->shadow_paint);
}
} }
static void static void
@ -1347,7 +1374,9 @@ finish_destroy_win(session_t *ps, win **_w) {
ps->active_win = NULL; ps->active_win = NULL;
} }
if (!ps->o.experimental_backends) {
free_win_res(ps, w); free_win_res(ps, w);
}
// Drop w from all prev_trans to avoid accessing freed memory in // Drop w from all prev_trans to avoid accessing freed memory in
// repair_win() // repair_win()