perf(wave2): dynamic config arrays, flat dwindle tree, dual client arrays
Wave 2 changes: - Dynamic Config arrays with geometric growth (cap=16, 2x growth) → saves ~2.5 MB heap for typical configs vs fixed 128-entry arrays - Proper deep-copy protocol in on_config_reload/do_reload (free old, move new, zero source) - Flat DwindleTree array with int children[2]/parent indices → eliminates pointer chasing, contiguous allocation, iterative two-pass recalc - Lazy per-tag allocation (DwindleTree.nodes starts NULL, allocates on first use) - Dual client_arr + fstack_arr arrays alongside wl_list/fstack for cache-friendly iteration → arrange() and focustop() use array scan instead of linked-list pointer chase - All arrays maintain size-tracking (nclients, nfstack) for bounds checking - Zero-warning build with clang -Werror -Wpedantic
This commit is contained in:
@@ -30,6 +30,11 @@ typedef union {
|
||||
#define MAX(A, B) ((A) > (B) ? (A) : (B))
|
||||
#define MIN(A, B) ((A) < (B) ? (A) : (B))
|
||||
|
||||
extern struct Client **client_arr;
|
||||
extern int nclients;
|
||||
extern struct Client **fstack_arr;
|
||||
extern int nfstack;
|
||||
|
||||
/* Convenience wrapper for the function below */
|
||||
#define VISIBLEON(C, M) visibleon((C), (M))
|
||||
|
||||
|
||||
+26
-14
@@ -5,10 +5,8 @@
|
||||
#include <wlr/types/wlr_session_lock_v1.h>
|
||||
#include "wlr_ext_workspace_v1.h"
|
||||
|
||||
/* forward declarations */
|
||||
struct Client;
|
||||
struct LayerSurface;
|
||||
typedef struct DwindleNode DwindleNode;
|
||||
|
||||
#ifndef TAGCOUNT
|
||||
#define TAGCOUNT 9
|
||||
@@ -21,15 +19,30 @@ typedef struct {
|
||||
void (*arrange)(Monitor *);
|
||||
} Layout;
|
||||
|
||||
/* Cold state — accessed only on layout changes, not every frame.
|
||||
* Allocated lazily on first dwindle/master layout use. */
|
||||
struct DwindleNode {
|
||||
int children[2];
|
||||
int parent;
|
||||
struct Client *client;
|
||||
struct wlr_box box;
|
||||
float split_ratio;
|
||||
int split_top;
|
||||
int is_node;
|
||||
};
|
||||
typedef struct DwindleNode DwindleNode;
|
||||
|
||||
typedef struct {
|
||||
struct DwindleNode *nodes;
|
||||
int node_count;
|
||||
int node_cap;
|
||||
} DwindleTree;
|
||||
|
||||
typedef struct MonitorCold {
|
||||
const Layout *lt[TAGCOUNT][2];
|
||||
unsigned int sellt[TAGCOUNT];
|
||||
float mfact;
|
||||
int nmaster;
|
||||
char ltsymbol[TAGCOUNT][16];
|
||||
DwindleNode *dwindle_root[TAGCOUNT];
|
||||
DwindleTree dwindle_tree[TAGCOUNT];
|
||||
struct Client *dwindle_focus[TAGCOUNT];
|
||||
struct Client *master_master[TAGCOUNT];
|
||||
int master_side[TAGCOUNT];
|
||||
@@ -39,23 +52,22 @@ struct Monitor {
|
||||
struct wl_list link;
|
||||
struct wlr_output *wlr_output;
|
||||
struct wlr_scene_output *scene_output;
|
||||
struct wlr_scene_rect *fullscreen_bg; /* See createmon() for info */
|
||||
struct wlr_scene_rect *fullscreen_bg;
|
||||
struct wl_listener frame;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener request_state;
|
||||
struct wl_listener destroy_lock_surface;
|
||||
struct wlr_session_lock_surface_v1 *lock_surface;
|
||||
struct wlr_box m; /* monitor area, layout-relative */
|
||||
struct wlr_box w; /* window area, layout-relative */
|
||||
struct wl_list layers[4]; /* LayerSurface.link */
|
||||
struct MonitorCold *cold; /* lazy-allocated layout state */
|
||||
struct wlr_box m;
|
||||
struct wlr_box w;
|
||||
struct wl_list layers[4];
|
||||
struct MonitorCold *cold;
|
||||
int gaps;
|
||||
unsigned int seltags;
|
||||
struct wlr_ext_workspace_group_handle_v1 *ext_group;
|
||||
uint32_t tagset[2];
|
||||
int asleep;
|
||||
int scratchpad_visible; /* whether scratchpad is shown */
|
||||
struct Client *scratchpad_prev_focus; /* client focused before scratchpad opened */
|
||||
struct Client *scratchpad_current; /* currently visible scratchpad client */
|
||||
int scratchpad_visible;
|
||||
struct Client *scratchpad_prev_focus;
|
||||
struct Client *scratchpad_current;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user