1
0
Fork 0
mirror of https://github.com/yshui/picom.git synced 2025-04-07 17:44:04 -04:00

misc: general chores

Organize files into folders, move some code around. Remove unnecessary
`#include`s. And fix some missing copyright declarations.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-06-03 17:10:42 +01:00
parent 1fa8e70906
commit 270bcc45ac
No known key found for this signature in database
GPG key ID: D3A4405BE6CC17F4
82 changed files with 591 additions and 584 deletions

View file

@ -9,9 +9,9 @@
#include <uthash.h>
#include "compiler.h"
#include "list.h"
#include "log.h"
#include "utils.h"
#include "utils/list.h"
#include "utils/misc.h"
struct backend_plugins {
UT_hash_handle hh;

View file

@ -1,13 +1,16 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <string.h>
#include <uthash.h>
#include <xcb/xcb.h>
#include "atom.h"
#include "cache.h"
#include "common.h"
#include "compiler.h"
#include "log.h"
#include "utils.h"
#include "utils/cache.h"
#include "utils/misc.h"
struct atom_entry {
struct cache_handle entry;
@ -163,4 +166,4 @@ struct atom *init_mock_atoms(void) {
abort();
}
#endif
#endif

View file

@ -1,8 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <string.h>
#include <xcb/xcb.h>
#include "cache.h"
#include "meta.h"
#include "utils/meta.h"
// clang-format off
// Splitted into 2 lists because of the limitation of our macros
@ -79,4 +82,4 @@ void destroy_atoms(struct atom *a);
/// secutive integers as atoms, starting from 1. Calling get_atom_name with atoms
/// previously seen will result in the string that was used to create the atom; if
/// the atom was never returned by get_atom, it will abort.
struct atom *init_mock_atoms(void);
struct atom *init_mock_atoms(void);

View file

@ -6,15 +6,16 @@
#include <picom/types.h>
#include "backend/backend.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "region.h"
#include "win.h"
#include "wm/win.h"
#include "x.h"
#include "backend.h"
static struct backend_info {
UT_hash_handle hh;
const char *name;

View file

@ -6,15 +6,16 @@
#include <xcb/xcb_image.h>
#include <xcb/xcb_renderutil.h>
#include "backend/backend_common.h"
#include "common.h"
#include "config.h"
#include "kernel.h"
#include "log.h"
#include "utils.h"
#include "win.h"
#include "utils/kernel.h"
#include "utils/misc.h"
#include "wm/win.h"
#include "x.h"
#include "backend_common.h"
/**
* Generate a 1x1 <code>Picture</code> of a particular color.
*/

View file

@ -6,12 +6,12 @@
#include <xcb/randr.h>
#include <xcb/xcb.h>
#include "backend/backend.h"
#include "backend/driver.h"
#include "common.h"
#include "compiler.h"
#include "log.h"
#include "driver.h"
/// Apply driver specified global workarounds. It's safe to call this multiple times.
void apply_driver_workarounds(struct session *ps, enum driver driver) {
if (driver & DRIVER_NVIDIA) {

View file

@ -8,7 +8,7 @@
#include <xcb/xcb.h>
#include "config.h"
#include "utils.h"
#include "utils/misc.h"
struct session;
struct backend_base;

View file

@ -10,8 +10,8 @@
#include "config.h"
#include "log.h"
#include "region.h"
#include "uthash_extra.h"
#include "utils.h"
#include "utils/misc.h"
#include "utils/uthash_extra.h"
#include "x.h"
struct dummy_image {

View file

@ -1,8 +1,7 @@
#include <locale.h>
#include <stdbool.h>
#include <backend/backend.h>
#include <backend/backend_common.h>
#include "backend/backend_common.h"
#include "gl_common.h"

View file

@ -11,16 +11,17 @@
#include "backend/backend.h"
#include "backend/backend_common.h"
#include "backend/gl/egl.h"
#include "backend/gl/gl_common.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "picom.h"
#include "utils.h"
#include "utils/misc.h"
#include "x.h"
#include "egl.h"
#include "gl_common.h"
struct egl_data {
struct gl_data gl;
EGLDisplay display;

View file

@ -7,11 +7,6 @@
#include <xcb/render.h>
#include <xcb/xcb.h>
#include "compiler.h"
#include "log.h"
#include "utils.h"
#include "x.h"
struct eglext_info {
bool initialized;
bool has_EGL_MESA_query_driver;

View file

@ -11,15 +11,15 @@
#include <picom/types.h>
#include "backend/backend_common.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "region.h"
#include "utils.h"
#include "utils/misc.h"
#include "backend/backend_common.h"
#include "backend/gl/gl_common.h"
#include "gl_common.h"
void gl_prepare(backend_t *base, const region_t *reg attr_unused) {
auto gd = (struct gl_data *)base;

View file

@ -7,7 +7,7 @@
#include <xcb/xproto.h>
#include "backend/backend.h"
#include "backend/backend_common.h"
#include "log.h"
#include "region.h"

View file

@ -9,13 +9,13 @@
* See LICENSE-mit for more information.
*
*/
#include <X11/Xlib-xcb.h>
#include <limits.h>
#include <pixman.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <X11/Xlib-xcb.h>
#include <pixman.h>
#include <uthash.h>
#include <xcb/composite.h>
#include <xcb/xcb.h>
@ -23,17 +23,17 @@
#include "backend/backend.h"
#include "backend/backend_common.h"
#include "backend/gl/gl_common.h"
#include "backend/gl/glx.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "picom.h"
#include "utils.h"
#include "win.h"
#include "utils/misc.h"
#include "x.h"
#include "gl_common.h"
#include "glx.h"
struct _glx_data {
struct gl_data gl;
xcb_window_t target_win;

View file

@ -1,15 +1,13 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>
#include <X11/Xlib.h>
#include <epoxy/glx.h>
#include <stdbool.h>
#include <xcb/render.h>
#include <xcb/xcb.h>
#include "compiler.h"
#include "log.h"
#include "utils.h"
#include "x.h"
struct glx_fbconfig_info {

View file

@ -0,0 +1 @@
srcs += [ files('blur.c', 'egl.c', 'gl_common.c', 'glx.c', 'shaders.c') ]

View file

@ -2,16 +2,13 @@
srcs += [
files(
'dummy/dummy.c',
'xrender/xrender.c',
'backend.c',
'backend_common.c',
'driver.c',
),
]
subdir('xrender')
# enable opengl
if get_option('opengl')
srcs += [
files('gl/blur.c', 'gl/egl.c', 'gl/gl_common.c', 'gl/glx.c', 'gl/shaders.c'),
]
subdir('gl')
endif

View file

@ -0,0 +1 @@
srcs += [ files('xrender.c') ]

View file

@ -20,12 +20,11 @@
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "kernel.h"
#include "log.h"
#include "picom.h"
#include "region.h"
#include "utils.h"
#include "win.h"
#include "utils/kernel.h"
#include "utils/misc.h"
#include "x.h"
struct xrender_image_data_inner {

View file

@ -1,14 +1,6 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <assert.h>
#include <ctype.h>
@ -34,11 +26,10 @@
#include "compiler.h"
#include "config.h"
#include "log.h"
#include "string_utils.h"
#include "test.h"
#include "uthash_extra.h"
#include "utils.h"
#include "win.h"
#include "utils/str.h"
#include "utils/uthash_extra.h"
#include "wm/win.h"
#include "x.h"
#include "c2.h"

View file

@ -1,13 +1,6 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once

View file

@ -1,15 +1,6 @@
// SPDX-License-Identifier: MIT
/*
* Compton - a compositor for X11
*
* Based on `xcompmgr` - Copyright (c) 2003, Keith Packard
*
* Copyright (c) 2011-2013, Christopher Jeffrey
* Copyright (c) 2018, Yuxuan Shui <yshuiv7@gmail.com>
*
* See LICENSE-mit for more information.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018, Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
@ -28,7 +19,6 @@
// === Includes ===
// For some special functions
#include <assert.h>
#include <stdbool.h>
#include <sys/time.h>
#include <time.h>
@ -36,6 +26,7 @@
#include <X11/Xlib.h>
#include <ev.h>
#include <pixman.h>
#include <uthash.h>
#include <xcb/render.h>
#include <xcb/sync.h>
#include <xcb/xproto.h>
@ -57,8 +48,8 @@
#include "config.h"
#include "region.h"
#include "render.h"
#include "statistics.h"
#include "win_defs.h"
#include "utils/statistics.h"
#include "wm/defs.h"
#include "x.h"
// === Constants ===0

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#ifdef HAS_STDC_PREDEF_H

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <ctype.h>
#include <dlfcn.h>
@ -20,9 +21,9 @@
#include <test.h>
#include "common.h"
#include "kernel.h"
#include "log.h"
#include "string_utils.h"
#include "utils/kernel.h"
#include "utils/str.h"
#include "config.h"

View file

@ -2,6 +2,7 @@
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
/// Common functions and definitions for configuration parsing
@ -19,10 +20,10 @@
#include <picom/types.h>
#include "compiler.h"
#include "kernel.h"
#include "list.h"
#include "log.h"
#include "win_defs.h"
#include "utils/kernel.h"
#include "utils/list.h"
#include "wm/defs.h"
typedef struct session session_t;

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2012-2014 Richard Grenville <pyxlcy@gmail.com>
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <limits.h>
#include <stdio.h>
@ -15,10 +16,10 @@
#include "common.h"
#include "config.h"
#include "log.h"
#include "script.h"
#include "string_utils.h"
#include "utils.h"
#include "win.h"
#include "transition/script.h"
#include "utils/misc.h"
#include "utils/str.h"
#include "wm/win.h"
#pragma GCC diagnostic error "-Wunused-parameter"

View file

@ -1,13 +1,6 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <X11/Xlib.h>
#include <ctype.h>
@ -26,13 +19,13 @@
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "list.h"
#include "log.h"
#include "string_utils.h"
#include "utils.h"
#include "win.h"
#include "win_defs.h"
#include "wm.h"
#include "utils/list.h"
#include "utils/misc.h"
#include "utils/str.h"
#include "wm/defs.h"
#include "wm/win.h"
#include "wm/wm.h"
#include "dbus.h"

View file

@ -1,13 +1,6 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <stdbool.h>

View file

@ -22,10 +22,9 @@
#include "log.h"
#include "picom.h"
#include "region.h"
#include "utils.h"
#include "win.h"
#include "win_defs.h"
#include "wm.h"
#include "utils/misc.h"
#include "wm/defs.h"
#include "wm/wm.h"
#include "x.h"
/// Event handling with X is complicated. Handling events with other events possibly

View file

@ -15,12 +15,11 @@
#include "c2.h"
#include "common.h"
#include "config.h"
#include "err.h"
#include "log.h"
#include "options.h"
#include "utils.h"
#include "win.h"
#include "win_defs.h"
#include "utils/misc.h"
#include "wm/defs.h"
#include "wm/win.h"
#include "x.h"
static struct managed_win *

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <assert.h>
#include <stdarg.h>
#include <stddef.h>
@ -10,13 +13,11 @@
#ifdef CONFIG_OPENGL
#include <epoxy/gl.h>
#include "backend/gl/gl_common.h"
#include "backend/gl/glx.h"
#endif
#include "compiler.h"
#include "log.h"
#include "utils.h"
#include "utils/misc.h"
thread_local struct log *tls_logger;

View file

@ -7,11 +7,10 @@ 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',
'options.c', 'event.c', 'cache.c', 'atom.c', 'file_watch.c', 'statistics.c',
'vblank.c', 'transition.c', 'wm.c', 'renderer/layout.c', 'renderer/command_builder.c',
'renderer/renderer.c', 'renderer/damage.c', 'config_libconfig.c', 'inspect.c', 'script.c', 'api.c') ]
srcs = [ files('picom.c', 'c2.c', 'x.c', 'config.c', 'vsync.c',
'diagnostic.c', 'render.c', 'log.c',
'options.c', 'event.c', 'atom.c',
'vblank.c','config_libconfig.c', 'inspect.c', 'api.c') ]
picom_inc = include_directories(['.', '../include'])
cflags = []
@ -99,6 +98,10 @@ elif (host_system == 'freebsd' or host_system == 'netbsd' or
endif
subdir('backend')
subdir('wm')
subdir('renderer')
subdir('transition')
subdir('utils')
picom = executable('picom', srcs, c_args: cflags,
dependencies: [ base_deps, deps, test_h_dep ],

View file

@ -1,13 +1,5 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
#include <stdio.h>
#include <stdlib.h>
@ -21,14 +13,13 @@
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "kernel.h"
#include "log.h"
#include "region.h"
#include "string_utils.h"
#include "uthash_extra.h"
#include "utils.h"
#include "win.h"
#include "wm.h"
#include "utils/kernel.h"
#include "utils/misc.h"
#include "utils/str.h"
#include "wm/win.h"
#include "wm/wm.h"
#include "opengl.h"
@ -1538,3 +1529,13 @@ bool glx_render(session_t *ps, const glx_texture_t *ptex, int x, int y, int dx,
return true;
}
/**
* Free GLX part of win.
*/
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);
free_glx_bc(ps, &w->glx_blur_cache);
free_texture(ps, &w->glx_texture_bg);
}

View file

@ -1,24 +1,14 @@
// 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.
*
*/
// Copyright (c) 2011-2013, Christopher Jeffrey
#pragma once
#include "common.h"
#include "compiler.h"
#include "log.h"
#include "region.h"
#include "render.h"
#include "win.h"
#include "wm/win.h"
#include <ctype.h>
#include <epoxy/gl.h>
#include <epoxy/glx.h>
#include <locale.h>
@ -234,11 +224,4 @@ static inline void free_paint_glx(session_t *ps, paint_t *ppaint) {
/**
* 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
}
void free_win_res_glx(session_t *ps, struct managed_win *w);

View file

@ -13,13 +13,14 @@
#include <xcb/render.h> // for xcb_render_fixed_t, XXX
#include "backend/backend.h"
#include "c2.h"
#include "common.h"
#include "config.h"
#include "log.h"
#include "options.h"
#include "string_utils.h"
#include "utils.h"
#include "win.h"
#include "transition/script.h"
#include "utils/misc.h"
#include "utils/str.h"
#include "x.h"
#pragma GCC diagnostic error "-Wunused-parameter"

View file

@ -40,38 +40,38 @@
#include <picom/types.h>
#include <test.h>
#include "api_internal.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "inspect.h"
#include "kernel.h"
#include "picom.h"
#include "win_defs.h"
#include "wm.h"
#ifdef CONFIG_OPENGL
#include "opengl.h"
#endif
#include "api_internal.h"
#include "atom.h"
#include "backend/backend.h"
#include "c2.h"
#include "common.h"
#include "compiler.h"
#include "config.h"
#include "dbus.h"
#include "diagnostic.h"
#include "event.h"
#include "file_watch.h"
#include "list.h"
#include "inspect.h"
#include "log.h"
#include "options.h"
#include "picom.h"
#include "region.h"
#include "render.h"
#include "renderer/command_builder.h"
#include "renderer/layout.h"
#include "renderer/renderer.h"
#include "statistics.h"
#include "uthash_extra.h"
#include "utils.h"
#include "utils/file_watch.h"
#include "utils/kernel.h"
#include "utils/list.h"
#include "utils/misc.h"
#include "utils/statistics.h"
#include "utils/uthash_extra.h"
#include "vblank.h"
#include "win.h"
#include "wm/defs.h"
#include "wm/wm.h"
#include "x.h"
/// Get session_t pointer from a pointer to a member of session_t

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MIT
// Copyright (c)
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
// Throw everything in here.
// !!! DON'T !!!
@ -20,7 +21,7 @@
#include "log.h" // XXX clean up
#include "region.h"
#include "render.h"
#include "win.h"
#include "wm/win.h"
#include "x.h"
enum root_flags {
@ -88,14 +89,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.
*/

View file

@ -8,7 +8,7 @@
#include <picom/types.h>
#include "log.h"
#include "utils.h"
#include "utils/misc.h"
typedef struct pixman_region32 pixman_region32_t;
typedef struct pixman_box32 pixman_box32_t;

View file

@ -27,12 +27,12 @@
#include "compiler.h"
#include "config.h"
#include "kernel.h"
#include "log.h"
#include "region.h"
#include "utils.h"
#include "utils/kernel.h"
#include "utils/misc.h"
#include "vsync.h"
#include "win.h"
#include "wm/win.h"
#include "x.h"
#include "backend/backend_common.h"

View file

@ -5,7 +5,7 @@
#include "common.h"
#include "layout.h"
#include "win.h"
#include "wm/win.h"
/// Generate commands for rendering the body of the window in `layer`.
///

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>

View file

@ -1,8 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include "damage.h"
#include "layout.h"
#include "region.h"
#include "win.h"
#include "wm/win.h"
static inline bool attr_unused layer_key_eq(const struct layer_key *a,
const struct layer_key *b) {
if (!a->generation || !b->generation) {

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <picom/types.h>

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <stddef.h>
#include <uthash.h>
@ -7,11 +8,11 @@
#include "command_builder.h"
#include "common.h"
#include "list.h"
#include "region.h"
#include "utils.h"
#include "win.h"
#include "wm.h"
#include "utils/list.h"
#include "utils/misc.h"
#include "wm/win.h"
#include "wm/wm.h"
#include "layout.h"
struct layer_index {

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <pixman.h>
#include <stdint.h>

1
src/renderer/meson.build Normal file
View file

@ -0,0 +1 @@
srcs += [ files('command_builder.c', 'damage.c', 'layout.c', 'renderer.c') ]

View file

@ -6,12 +6,12 @@
#include <inttypes.h>
#include <xcb/xcb_aux.h>
#include "../picom.h"
#include "backend/backend.h"
#include "backend/backend_common.h"
#include "command_builder.h"
#include "damage.h"
#include "layout.h"
#include "picom.h"
struct renderer {
/// Intermediate image to hold what will be presented to the back buffer.

View file

@ -23,7 +23,7 @@
#include "log.h"
#include "rtkit.h"
#include "utils.h"
#include "utils/misc.h"
#define RTKIT_SERVICE_NAME "org.freedesktop.RealtimeKit1"
#define RTKIT_OBJECT_PATH "/org/freedesktop/RealtimeKit1"

View file

@ -1,85 +0,0 @@
//! Rendering statistics
//!
//! Tracks how long it takes to render a frame, for measuring performance, and for pacing
//! the frames.
#include "statistics.h"
#include "log.h"
#include "utils.h"
void render_statistics_init(struct render_statistics *rs, int window_size) {
*rs = (struct render_statistics){0};
rolling_window_init(&rs->render_times, window_size);
rolling_quantile_init_with_tolerance(&rs->render_time_quantile, window_size,
/* q */ 0.98, /* tolerance */ 0.01);
}
void render_statistics_add_vblank_time_sample(struct render_statistics *rs, int time_us) {
auto sample_sd = sqrt(cumulative_mean_and_var_get_var(&rs->vblank_time_us));
auto current_estimate = render_statistics_get_vblank_time(rs);
if (current_estimate != 0 && fabs((double)time_us - current_estimate) > sample_sd * 3) {
// Deviated from the mean by more than 3 sigma (p < 0.003)
log_debug("vblank time outlier: %d %f %f", time_us, rs->vblank_time_us.mean,
cumulative_mean_and_var_get_var(&rs->vblank_time_us));
// An outlier sample, this could mean things like refresh rate changes, so
// we reset the statistics. This could also be benign, but we like to be
// cautious.
cumulative_mean_and_var_init(&rs->vblank_time_us);
}
if (rs->vblank_time_us.mean != 0) {
auto nframes_in_10_seconds =
(unsigned int)(10. * 1000000. / rs->vblank_time_us.mean);
if (rs->vblank_time_us.n > 20 && rs->vblank_time_us.n > nframes_in_10_seconds) {
// We collected 10 seconds worth of samples, we assume the
// estimated refresh rate is stable. We will still reset the
// statistics if we get an outlier sample though, see above.
return;
}
}
cumulative_mean_and_var_update(&rs->vblank_time_us, time_us);
}
void render_statistics_add_render_time_sample(struct render_statistics *rs, int time_us) {
int oldest;
if (rolling_window_push_back(&rs->render_times, time_us, &oldest)) {
rolling_quantile_pop_front(&rs->render_time_quantile, oldest);
}
rolling_quantile_push_back(&rs->render_time_quantile, time_us);
}
/// How much time budget we should give to the backend for rendering, in microseconds.
unsigned int render_statistics_get_budget(struct render_statistics *rs) {
if (rs->render_times.nelem < rs->render_times.window_size) {
// No valid render time estimates yet. Assume maximum budget.
return UINT_MAX;
}
// N-th percentile of render times, see render_statistics_init for N.
auto render_time_percentile =
rolling_quantile_estimate(&rs->render_time_quantile, &rs->render_times);
return (unsigned int)render_time_percentile;
}
unsigned int render_statistics_get_vblank_time(struct render_statistics *rs) {
if (rs->vblank_time_us.n <= 20 || rs->vblank_time_us.mean < 100) {
// Not enough samples yet, or the vblank time is too short to be
// meaningful. Assume maximum budget.
return 0;
}
return (unsigned int)rs->vblank_time_us.mean;
}
void render_statistics_reset(struct render_statistics *rs) {
rolling_window_reset(&rs->render_times);
rolling_quantile_reset(&rs->render_time_quantile);
rs->vblank_time_us = (struct cumulative_mean_and_var){0};
}
void render_statistics_destroy(struct render_statistics *rs) {
render_statistics_reset(rs);
rolling_window_destroy(&rs->render_times);
rolling_quantile_destroy(&rs->render_time_quantile);
}

View file

@ -1,30 +0,0 @@
#pragma once
#include "utils.h"
#define NTIERS (3)
struct render_statistics {
/// Rolling window of rendering times (in us) and the tiers they belong to.
/// We keep track of the tiers because the vblank time estimate can change over
/// time.
struct rolling_window render_times;
/// Estimate the 95-th percentile of rendering times
struct rolling_quantile render_time_quantile;
/// Time between each vblanks
struct cumulative_mean_and_var vblank_time_us;
};
void render_statistics_init(struct render_statistics *rs, int window_size);
void render_statistics_reset(struct render_statistics *rs);
void render_statistics_destroy(struct render_statistics *rs);
void render_statistics_add_vblank_time_sample(struct render_statistics *rs, int time_us);
void render_statistics_add_render_time_sample(struct render_statistics *rs, int time_us);
/// How much time budget we should give to the backend for rendering, in microseconds.
unsigned int render_statistics_get_budget(struct render_statistics *rs);
/// Return the measured vblank interval in microseconds. Returns 0 if not enough
/// samples have been collected yet.
unsigned int render_statistics_get_vblank_time(struct render_statistics *rs);

View file

@ -6,9 +6,10 @@
#include <stddef.h>
#include "compiler.h"
#include "string_utils.h"
#include "transition.h"
#include "utils.h"
#include "utils/misc.h"
#include "utils/str.h"
#include "curve.h"
static double curve_sample_linear(const struct curve *this attr_unused, double progress) {
return progress;

View file

@ -3,7 +3,6 @@
#pragma once
#include <stdbool.h>
#include "compiler.h"
// ========================== Interpolators ==========================

View file

@ -0,0 +1 @@
srcs += [ files('curve.c', 'script.c') ]

View file

@ -1,15 +1,18 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include "script.h"
#include <libconfig.h>
#include <stdbool.h>
#include <stddef.h>
#include <libconfig.h>
#include <uthash.h>
#include "list.h"
#include "string_utils.h"
#include "transition.h"
#include "uthash_extra.h"
#include "utils.h"
#include "utils/list.h"
#include "utils/str.h"
#include "utils/uthash_extra.h"
#include "curve.h"
#include "script.h"
enum op {
OP_ADD = 0,

View file

@ -1,8 +1,12 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <assert.h>
#include <stdalign.h>
#include <stdbool.h>
#include <stddef.h>
#include <uthash.h>
struct script_context_info {

View file

@ -1,6 +1,11 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <assert.h>
#include <uthash.h>
#include "cache.h"
#include "misc.h"
struct cache_handle *cache_get(struct cache *c, const char *key, size_t keylen) {
struct cache_handle *e;

View file

@ -1,7 +1,9 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <uthash.h>
#include "utils.h"
#define cache_entry(ptr, type, member) container_of(ptr, type, member)

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <errno.h>
#include <string.h>
#ifdef HAS_INOTIFY
@ -17,9 +20,8 @@
#include <uthash.h>
#include "file_watch.h"
#include "list.h"
#include "log.h"
#include "utils.h"
#include "misc.h"
struct watched_file {
int wd;

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>

View file

@ -6,8 +6,7 @@
#include "compiler.h"
#include "kernel.h"
#include "log.h"
#include "utils.h"
#include "misc.h"
/// Sum a region convolution kernel. Region is defined by a width x height rectangle whose
/// top left corner is at (x, y)

View file

@ -1,8 +1,8 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include "utils.h"
struct list_node {
struct list_node *next, *prev;

1
src/utils/meson.build Normal file
View file

@ -0,0 +1 @@
srcs += [ files('cache.c', 'file_watch.c', 'kernel.c', 'statistics.c', 'str.c', 'misc.c') ]

View file

@ -34,6 +34,7 @@
/// Return the number of arguments passed in binary, handles at most 31 elements
#define VA_ARGS_LENGTH(...) _ARG33(0, ##__VA_ARGS__, RIOTA32(0))
// clang-format off
#define LIST_APPLY_000000(fn, sep, ...)
#define LIST_APPLY_000001(fn, sep, x, ...) fn(x)
#define LIST_APPLY_000010(fn, sep, x, ...) fn(x) sep() LIST_APPLY_000001(fn, sep, __VA_ARGS__)
@ -67,8 +68,8 @@
#define LIST_APPLY_011110(fn, sep, x, ...) fn(x) sep() LIST_APPLY_011101(fn, sep, __VA_ARGS__)
#define LIST_APPLY_011111(fn, sep, x, ...) fn(x) sep() LIST_APPLY_011110(fn, sep, __VA_ARGS__)
#define LIST_APPLY_(N, fn, sep, ...) CONCAT(LIST_APPLY_, N)(fn, sep, __VA_ARGS__)
#define LIST_APPLY(fn, sep, ...) \
LIST_APPLY_(VA_ARGS_LENGTH(__VA_ARGS__), fn, sep, __VA_ARGS__)
#define LIST_APPLY(fn, sep, ...) LIST_APPLY_(VA_ARGS_LENGTH(__VA_ARGS__), fn, sep, __VA_ARGS__)
// clang-format on
#define SEP_COMMA() ,
#define SEP_COLON() ;

124
src/utils/misc.c Normal file
View file

@ -0,0 +1,124 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include "compiler.h"
#include "misc.h"
#include "rtkit.h"
#include "str.h"
/// Report allocation failure without allocating memory
void report_allocation_failure(const char *func, const char *file, unsigned int line) {
// Since memory allocation failed, we try to print this error message without any
// memory allocation. Since logging framework allocates memory (and might even
// have not been initialized yet), so we can't use it.
char buf[11];
int llen = uitostr(line, buf);
const char msg1[] = " has failed to allocate memory, ";
const char msg2[] = ". Aborting...\n";
const struct iovec v[] = {
{.iov_base = (void *)func, .iov_len = strlen(func)},
{.iov_base = "()", .iov_len = 2},
{.iov_base = (void *)msg1, .iov_len = sizeof(msg1) - 1},
{.iov_base = "at ", .iov_len = 3},
{.iov_base = (void *)file, .iov_len = strlen(file)},
{.iov_base = ":", .iov_len = 1},
{.iov_base = buf, .iov_len = (size_t)llen},
{.iov_base = (void *)msg2, .iov_len = sizeof(msg2) - 1},
};
ssize_t _ attr_unused = writev(STDERR_FILENO, v, ARR_SIZE(v));
abort();
unreachable();
}
///
/// Calculates next closest power of two of 32bit integer n
/// ref: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
///
int next_power_of_two(int n) {
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;
return n;
}
// Find the k-th smallest element in an array.
int quickselect(int *elems, int nelem, int k) {
int l = 0, r = nelem; // [l, r) is the range of candidates
while (l != r) {
int pivot = elems[l];
int i = l, j = r;
while (i < j) {
while (i < j && elems[--j] >= pivot) {
}
elems[i] = elems[j];
while (i < j && elems[++i] <= pivot) {
}
elems[j] = elems[i];
}
elems[i] = pivot;
if (i == k) {
break;
}
if (i < k) {
l = i + 1;
} else {
r = i;
}
}
return elems[k];
}
/// Switch to real-time scheduling policy (SCHED_RR) if possible
///
/// Make picom realtime to reduce latency, and make rendering times more predictable to
/// help pacing.
///
/// This requires the user to set up permissions for the real-time scheduling. e.g. by
/// setting `ulimit -r`, or giving us the CAP_SYS_NICE capability.
void set_rr_scheduling(void) {
static thread_local bool already_tried = false;
if (already_tried) {
return;
}
already_tried = true;
int priority = sched_get_priority_min(SCHED_RR);
if (rtkit_make_realtime(0, priority)) {
log_info("Set realtime priority to %d with rtkit.", priority);
return;
}
// Fallback to use pthread_setschedparam
struct sched_param param;
int old_policy;
int ret = pthread_getschedparam(pthread_self(), &old_policy, &param);
if (ret != 0) {
log_info("Couldn't get old scheduling priority.");
return;
}
param.sched_priority = priority;
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
if (ret != 0) {
log_info("Couldn't set real-time scheduling priority to %d.", priority);
return;
}
log_info("Set real-time scheduling priority to %d.", priority);
}
// vim: set noet sw=8 ts=8 :

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <assert.h>
#include <limits.h>
@ -407,97 +408,9 @@ static inline void free_charpp(char **str) {
///
int next_power_of_two(int n);
struct rolling_window {
int *elem;
int elem_head, nelem;
int window_size;
};
void rolling_window_destroy(struct rolling_window *rw);
void rolling_window_reset(struct rolling_window *rw);
void rolling_window_init(struct rolling_window *rw, int size);
int rolling_window_pop_front(struct rolling_window *rw);
bool rolling_window_push_back(struct rolling_window *rw, int val, int *front);
/// Copy the contents of the rolling window to an array. The array is assumed to
/// have enough space to hold the contents of the rolling window.
static inline void attr_unused rolling_window_copy_to_array(struct rolling_window *rw,
int *arr) {
// The length from head to the end of the array
auto head_len = (size_t)(rw->window_size - rw->elem_head);
if (head_len >= (size_t)rw->nelem) {
memcpy(arr, rw->elem + rw->elem_head, sizeof(int) * (size_t)rw->nelem);
} else {
auto tail_len = (size_t)((size_t)rw->nelem - head_len);
memcpy(arr, rw->elem + rw->elem_head, sizeof(int) * head_len);
memcpy(arr + head_len, rw->elem, sizeof(int) * tail_len);
}
}
struct rolling_max;
struct rolling_max *rolling_max_new(int capacity);
void rolling_max_destroy(struct rolling_max *rm);
void rolling_max_reset(struct rolling_max *rm);
void rolling_max_pop_front(struct rolling_max *rm, int front);
void rolling_max_push_back(struct rolling_max *rm, int val);
int rolling_max_get_max(struct rolling_max *rm);
/// Estimate the mean and variance of random variable X using Welford's online
/// algorithm.
struct cumulative_mean_and_var {
double mean;
double m2;
unsigned int n;
};
static inline attr_unused void
cumulative_mean_and_var_init(struct cumulative_mean_and_var *cmv) {
*cmv = (struct cumulative_mean_and_var){0};
}
static inline attr_unused void
cumulative_mean_and_var_update(struct cumulative_mean_and_var *cmv, double x) {
if (cmv->n == UINT_MAX) {
// We have too many elements, let's keep the mean and variance.
return;
}
cmv->n++;
double delta = x - cmv->mean;
cmv->mean += delta / (double)cmv->n;
cmv->m2 += delta * (x - cmv->mean);
}
static inline attr_unused double
cumulative_mean_and_var_get_var(struct cumulative_mean_and_var *cmv) {
if (cmv->n < 2) {
return 0;
}
return cmv->m2 / (double)(cmv->n - 1);
}
// Find the k-th smallest element in an array.
int quickselect(int *elems, int nelem, int k);
/// A naive quantile estimator.
///
/// Estimates the N-th percentile of a random variable X in a sliding window.
struct rolling_quantile {
int current_rank;
int min_target_rank, max_target_rank;
int estimate;
int capacity;
int *tmp_buffer;
};
void rolling_quantile_init(struct rolling_quantile *rq, int capacity, int mink, int maxk);
void rolling_quantile_init_with_tolerance(struct rolling_quantile *rq, int window_size,
double target, double tolerance);
void rolling_quantile_reset(struct rolling_quantile *rq);
void rolling_quantile_destroy(struct rolling_quantile *rq);
int rolling_quantile_estimate(struct rolling_quantile *rq, struct rolling_window *elements);
void rolling_quantile_push_back(struct rolling_quantile *rq, int x);
void rolling_quantile_pop_front(struct rolling_quantile *rq, int x);
void set_rr_scheduling(void);
// Some versions of the Android libc do not have timespec_get(), use

View file

@ -1,54 +1,16 @@
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <sys/uio.h>
#include "compiler.h"
#include "rtkit.h"
#include "string_utils.h"
#include "test.h"
#include "utils.h"
/// Report allocation failure without allocating memory
void report_allocation_failure(const char *func, const char *file, unsigned int line) {
// Since memory allocation failed, we try to print this error message without any
// memory allocation. Since logging framework allocates memory (and might even
// have not been initialized yet), so we can't use it.
char buf[11];
int llen = uitostr(line, buf);
const char msg1[] = " has failed to allocate memory, ";
const char msg2[] = ". Aborting...\n";
const struct iovec v[] = {
{.iov_base = (void *)func, .iov_len = strlen(func)},
{.iov_base = "()", .iov_len = 2},
{.iov_base = (void *)msg1, .iov_len = sizeof(msg1) - 1},
{.iov_base = "at ", .iov_len = 3},
{.iov_base = (void *)file, .iov_len = strlen(file)},
{.iov_base = ":", .iov_len = 1},
{.iov_base = buf, .iov_len = (size_t)llen},
{.iov_base = (void *)msg2, .iov_len = sizeof(msg2) - 1},
};
ssize_t _ attr_unused = writev(STDERR_FILENO, v, ARR_SIZE(v));
abort();
unreachable();
}
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
/// Rendering statistics
///
/// Calculates next closest power of two of 32bit integer n
/// ref: https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
///
int next_power_of_two(int n) {
n--;
n |= n >> 1;
n |= n >> 2;
n |= n >> 4;
n |= n >> 8;
n |= n >> 16;
n++;
return n;
}
/// Tracks how long it takes to render a frame, for measuring performance, and for pacing
/// the frames.
#include <stdlib.h>
#include "log.h"
#include "misc.h"
#include "statistics.h"
void rolling_window_destroy(struct rolling_window *rw) {
free(rw->elem);
@ -194,35 +156,6 @@ TEST_CASE(rolling_max_test) {
#undef NELEM
}
// Find the k-th smallest element in an array.
int quickselect(int *elems, int nelem, int k) {
int l = 0, r = nelem; // [l, r) is the range of candidates
while (l != r) {
int pivot = elems[l];
int i = l, j = r;
while (i < j) {
while (i < j && elems[--j] >= pivot) {
}
elems[i] = elems[j];
while (i < j && elems[++i] <= pivot) {
}
elems[j] = elems[i];
}
elems[i] = pivot;
if (i == k) {
break;
}
if (i < k) {
l = i + 1;
} else {
r = i;
}
}
return elems[k];
}
void rolling_quantile_init(struct rolling_quantile *rq, int capacity, int mink, int maxk) {
*rq = (struct rolling_quantile){0};
rq->tmp_buffer = malloc(sizeof(int) * (size_t)capacity);
@ -274,45 +207,79 @@ void rolling_quantile_pop_front(struct rolling_quantile *rq, int x) {
}
}
/// Switch to real-time scheduling policy (SCHED_RR) if possible
///
/// Make picom realtime to reduce latency, and make rendering times more predictable to
/// help pacing.
///
/// This requires the user to set up permissions for the real-time scheduling. e.g. by
/// setting `ulimit -r`, or giving us the CAP_SYS_NICE capability.
void set_rr_scheduling(void) {
static thread_local bool already_tried = false;
if (already_tried) {
return;
}
already_tried = true;
void render_statistics_init(struct render_statistics *rs, int window_size) {
*rs = (struct render_statistics){0};
int priority = sched_get_priority_min(SCHED_RR);
if (rtkit_make_realtime(0, priority)) {
log_info("Set realtime priority to %d with rtkit.", priority);
return;
}
// Fallback to use pthread_setschedparam
struct sched_param param;
int old_policy;
int ret = pthread_getschedparam(pthread_self(), &old_policy, &param);
if (ret != 0) {
log_info("Couldn't get old scheduling priority.");
return;
}
param.sched_priority = priority;
ret = pthread_setschedparam(pthread_self(), SCHED_RR, &param);
if (ret != 0) {
log_info("Couldn't set real-time scheduling priority to %d.", priority);
return;
}
log_info("Set real-time scheduling priority to %d.", priority);
rolling_window_init(&rs->render_times, window_size);
rolling_quantile_init_with_tolerance(&rs->render_time_quantile, window_size,
/* q */ 0.98, /* tolerance */ 0.01);
}
// vim: set noet sw=8 ts=8 :
void render_statistics_add_vblank_time_sample(struct render_statistics *rs, int time_us) {
auto sample_sd = sqrt(cumulative_mean_and_var_get_var(&rs->vblank_time_us));
auto current_estimate = render_statistics_get_vblank_time(rs);
if (current_estimate != 0 && fabs((double)time_us - current_estimate) > sample_sd * 3) {
// Deviated from the mean by more than 3 sigma (p < 0.003)
log_debug("vblank time outlier: %d %f %f", time_us, rs->vblank_time_us.mean,
cumulative_mean_and_var_get_var(&rs->vblank_time_us));
// An outlier sample, this could mean things like refresh rate changes, so
// we reset the statistics. This could also be benign, but we like to be
// cautious.
cumulative_mean_and_var_init(&rs->vblank_time_us);
}
if (rs->vblank_time_us.mean != 0) {
auto nframes_in_10_seconds =
(unsigned int)(10. * 1000000. / rs->vblank_time_us.mean);
if (rs->vblank_time_us.n > 20 && rs->vblank_time_us.n > nframes_in_10_seconds) {
// We collected 10 seconds worth of samples, we assume the
// estimated refresh rate is stable. We will still reset the
// statistics if we get an outlier sample though, see above.
return;
}
}
cumulative_mean_and_var_update(&rs->vblank_time_us, time_us);
}
void render_statistics_add_render_time_sample(struct render_statistics *rs, int time_us) {
int oldest;
if (rolling_window_push_back(&rs->render_times, time_us, &oldest)) {
rolling_quantile_pop_front(&rs->render_time_quantile, oldest);
}
rolling_quantile_push_back(&rs->render_time_quantile, time_us);
}
/// How much time budget we should give to the backend for rendering, in microseconds.
unsigned int render_statistics_get_budget(struct render_statistics *rs) {
if (rs->render_times.nelem < rs->render_times.window_size) {
// No valid render time estimates yet. Assume maximum budget.
return UINT_MAX;
}
// N-th percentile of render times, see render_statistics_init for N.
auto render_time_percentile =
rolling_quantile_estimate(&rs->render_time_quantile, &rs->render_times);
return (unsigned int)render_time_percentile;
}
unsigned int render_statistics_get_vblank_time(struct render_statistics *rs) {
if (rs->vblank_time_us.n <= 20 || rs->vblank_time_us.mean < 100) {
// Not enough samples yet, or the vblank time is too short to be
// meaningful. Assume maximum budget.
return 0;
}
return (unsigned int)rs->vblank_time_us.mean;
}
void render_statistics_reset(struct render_statistics *rs) {
rolling_window_reset(&rs->render_times);
rolling_quantile_reset(&rs->render_time_quantile);
rs->vblank_time_us = (struct cumulative_mean_and_var){0};
}
void render_statistics_destroy(struct render_statistics *rs) {
render_statistics_reset(rs);
rolling_window_destroy(&rs->render_times);
rolling_quantile_destroy(&rs->render_time_quantile);
}

126
src/utils/statistics.h Normal file
View file

@ -0,0 +1,126 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <limits.h>
#include <stdbool.h>
#include <string.h>
#include "compiler.h"
#define NTIERS (3)
struct rolling_window {
int *elem;
int elem_head, nelem;
int window_size;
};
void rolling_window_destroy(struct rolling_window *rw);
void rolling_window_reset(struct rolling_window *rw);
void rolling_window_init(struct rolling_window *rw, int size);
int rolling_window_pop_front(struct rolling_window *rw);
bool rolling_window_push_back(struct rolling_window *rw, int val, int *front);
/// Copy the contents of the rolling window to an array. The array is assumed to
/// have enough space to hold the contents of the rolling window.
static inline void attr_unused rolling_window_copy_to_array(struct rolling_window *rw,
int *arr) {
// The length from head to the end of the array
auto head_len = (size_t)(rw->window_size - rw->elem_head);
if (head_len >= (size_t)rw->nelem) {
memcpy(arr, rw->elem + rw->elem_head, sizeof(int) * (size_t)rw->nelem);
} else {
auto tail_len = (size_t)((size_t)rw->nelem - head_len);
memcpy(arr, rw->elem + rw->elem_head, sizeof(int) * head_len);
memcpy(arr + head_len, rw->elem, sizeof(int) * tail_len);
}
}
struct rolling_max;
struct rolling_max *rolling_max_new(int capacity);
void rolling_max_destroy(struct rolling_max *rm);
void rolling_max_reset(struct rolling_max *rm);
void rolling_max_pop_front(struct rolling_max *rm, int front);
void rolling_max_push_back(struct rolling_max *rm, int val);
int rolling_max_get_max(struct rolling_max *rm);
/// Estimate the mean and variance of random variable X using Welford's online
/// algorithm.
struct cumulative_mean_and_var {
double mean;
double m2;
unsigned int n;
};
static inline attr_unused void
cumulative_mean_and_var_init(struct cumulative_mean_and_var *cmv) {
*cmv = (struct cumulative_mean_and_var){0};
}
static inline attr_unused void
cumulative_mean_and_var_update(struct cumulative_mean_and_var *cmv, double x) {
if (cmv->n == UINT_MAX) {
// We have too many elements, let's keep the mean and variance.
return;
}
cmv->n++;
double delta = x - cmv->mean;
cmv->mean += delta / (double)cmv->n;
cmv->m2 += delta * (x - cmv->mean);
}
static inline attr_unused double
cumulative_mean_and_var_get_var(struct cumulative_mean_and_var *cmv) {
if (cmv->n < 2) {
return 0;
}
return cmv->m2 / (double)(cmv->n - 1);
}
/// A naive quantile estimator.
///
/// Estimates the N-th percentile of a random variable X in a sliding window.
struct rolling_quantile {
int current_rank;
int min_target_rank, max_target_rank;
int estimate;
int capacity;
int *tmp_buffer;
};
void rolling_quantile_init(struct rolling_quantile *rq, int capacity, int mink, int maxk);
void rolling_quantile_init_with_tolerance(struct rolling_quantile *rq, int window_size,
double target, double tolerance);
void rolling_quantile_reset(struct rolling_quantile *rq);
void rolling_quantile_destroy(struct rolling_quantile *rq);
int rolling_quantile_estimate(struct rolling_quantile *rq, struct rolling_window *elements);
void rolling_quantile_push_back(struct rolling_quantile *rq, int x);
void rolling_quantile_pop_front(struct rolling_quantile *rq, int x);
struct render_statistics {
/// Rolling window of rendering times (in us) and the tiers they belong to.
/// We keep track of the tiers because the vblank time estimate can change over
/// time.
struct rolling_window render_times;
/// Estimate the 95-th percentile of rendering times
struct rolling_quantile render_time_quantile;
/// Time between each vblanks
struct cumulative_mean_and_var vblank_time_us;
};
void render_statistics_init(struct render_statistics *rs, int window_size);
void render_statistics_reset(struct render_statistics *rs);
void render_statistics_destroy(struct render_statistics *rs);
void render_statistics_add_vblank_time_sample(struct render_statistics *rs, int time_us);
void render_statistics_add_render_time_sample(struct render_statistics *rs, int time_us);
/// How much time budget we should give to the backend for rendering, in microseconds.
unsigned int render_statistics_get_budget(struct render_statistics *rs);
/// Return the measured vblank interval in microseconds. Returns 0 if not enough
/// samples have been collected yet.
unsigned int render_statistics_get_vblank_time(struct render_statistics *rs);

View file

@ -6,9 +6,7 @@
#include <test.h>
#include "compiler.h"
#include "string_utils.h"
#include "utils.h"
#include "str.h"
#pragma GCC diagnostic push

View file

@ -1,13 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <ctype.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "utils.h"
#include "misc.h"
#define mstrncmp(s1, s2) strncmp((s1), (s2), strlen(s1))

View file

@ -1,6 +1,7 @@
#pragma once
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <uthash.h>
#pragma once
#define HASH_ITER2(head, el) \
for (__typeof__(head) el = (head), __tmp = el != NULL ? el->hh.next : NULL; \

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#include <assert.h>
#include <ev.h>
@ -21,7 +24,6 @@
#endif
#include "compiler.h"
#include "list.h" // for container_of
#include "log.h"
#include "vblank.h"
#include "x.h"

View file

@ -1,3 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>

View file

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

View file

@ -1,5 +1,7 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdint.h>
typedef enum {
WINTYPE_UNKNOWN = 0,

1
src/wm/meson.build Normal file
View file

@ -0,0 +1 @@
srcs += [ files('win.c', 'wm.c') ]

View file

@ -1,6 +1,7 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@ -23,20 +24,16 @@
#include "compiler.h"
#include "config.h"
#include "dbus.h"
#include "list.h"
#include "log.h"
#include "picom.h"
#include "region.h"
#include "render.h"
#include "utils.h"
#include "win_defs.h"
#include "wm.h"
#include "utils/list.h"
#include "utils/misc.h"
#include "x.h"
#ifdef CONFIG_OPENGL
// TODO(yshui) Get rid of this include
#include "opengl.h"
#endif
#include "defs.h"
#include "wm.h"
#include "win.h"
@ -1463,6 +1460,13 @@ xcb_window_t win_get_client_window(struct x_connection *c, struct wm *wm,
return cw;
}
#ifdef CONFIG_OPENGL
void free_win_res_glx(session_t *ps, struct managed_win *w);
#else
static inline void free_win_res_glx(session_t * /*ps*/, struct managed_win * /*w*/) {
}
#endif
/**
* Free all resources in a <code>struct _win</code>.
*/

View file

@ -1,6 +1,8 @@
// SPDX-License-Identifier: MIT
// Copyright (c) 2011-2013, Christopher Jeffrey
// Copyright (c) 2013 Richard Grenville <pyxlcy@gmail.com>
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <stdbool.h>
#include <xcb/damage.h>
@ -12,12 +14,12 @@
#include "c2.h"
#include "compiler.h"
#include "list.h"
#include "defs.h"
#include "region.h"
#include "render.h"
#include "script.h"
#include "utils.h"
#include "win_defs.h"
#include "transition/script.h"
#include "utils/list.h"
#include "utils/misc.h"
#include "x.h"
#include "xcb/xproto.h"

View file

@ -4,12 +4,13 @@
#include <uthash.h>
#include <xcb/xproto.h>
#include "list.h"
#include "log.h"
#include "uthash_extra.h"
#include "utils/list.h"
#include "utils/uthash_extra.h"
#include "x.h"
#include "win.h"
#include "wm.h"
#include "x.h"
struct wm {
/// Current window generation, start from 1. 0 is reserved for using as

View file

@ -15,8 +15,9 @@
#include <uthash.h>
#include <xcb/xproto.h>
#include <picom/types.h>
#include "compiler.h"
#include "utils.h"
struct wm;
struct managed_win;

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#include <stdalign.h>
#include <stdbool.h>
#include <stdlib.h>
@ -20,15 +21,12 @@
#include <xcb/xfixes.h>
#include "atom.h"
#ifdef CONFIG_OPENGL
#include "backend/gl/glx.h"
#endif
#include "common.h"
#include "compiler.h"
#include "kernel.h"
#include "log.h"
#include "region.h"
#include "utils.h"
#include "utils/kernel.h"
#include "utils/misc.h"
#include "x.h"
// === Error handling ===

View file

@ -1,5 +1,6 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2018 Yuxuan Shui <yshuiv7@gmail.com>
#pragma once
#include <X11/Xlib.h>
#include <stdbool.h>
@ -13,9 +14,9 @@
#include "atom.h"
#include "compiler.h"
#include "kernel.h"
#include "log.h"
#include "region.h"
#include "utils/kernel.h"
typedef struct session session_t;
struct atom;