mirror of
https://github.com/DreamMaoMao/maomaowm.git
synced 2026-02-23 01:40:16 -05:00
opt: optimize frame skip logic
This commit is contained in:
parent
6b2d694b23
commit
f8fa7a856c
3 changed files with 31 additions and 48 deletions
|
|
@ -990,6 +990,10 @@ void resize(Client *c, struct wlr_box geo, int32_t interact) {
|
|||
c->configure_serial = client_set_size(c, c->geom.width - 2 * c->bw,
|
||||
c->geom.height - 2 * c->bw);
|
||||
|
||||
if (c->configure_serial != 0) {
|
||||
c->mon->resizing_count_pending++;
|
||||
}
|
||||
|
||||
if (c == grabc) {
|
||||
c->animation.running = false;
|
||||
c->need_output_flush = false;
|
||||
|
|
|
|||
|
|
@ -243,34 +243,6 @@ static inline int32_t client_is_rendered_on_mon(Client *c, Monitor *m) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline int32_t client_is_stopped(Client *c) {
|
||||
int32_t pid;
|
||||
siginfo_t in = {0};
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
wl_client_get_credentials(c->surface.xdg->client->client, &pid, NULL, NULL);
|
||||
if (waitid(P_PID, pid, &in, WNOHANG | WCONTINUED | WSTOPPED | WNOWAIT) <
|
||||
0) {
|
||||
/* This process is not our child process. We cannot determine its
|
||||
* stopped state; assume it is not stopped to avoid blocking frame skip.
|
||||
*/
|
||||
if (errno == ECHILD)
|
||||
return 0; // if not our child, assume not stopped
|
||||
/* Other errors, also assume not stopped. */
|
||||
return 0;
|
||||
} else if (in.si_pid) {
|
||||
if (in.si_code == CLD_STOPPED || in.si_code == CLD_TRAPPED)
|
||||
return 1;
|
||||
if (in.si_code == CLD_CONTINUED)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int32_t client_is_unmanaged(Client *c) {
|
||||
#ifdef XWAYLAND
|
||||
if (client_is_x11(c))
|
||||
|
|
|
|||
47
src/mango.c
47
src/mango.c
|
|
@ -503,13 +503,15 @@ struct Monitor {
|
|||
struct wl_listener request_state;
|
||||
struct wl_listener destroy_lock_surface;
|
||||
struct wlr_session_lock_surface_v1 *lock_surface;
|
||||
struct wl_event_source *skip_timeout;
|
||||
struct wl_event_source *skip_frame_timeout;
|
||||
struct wlr_box m; /* monitor area, layout-relative */
|
||||
struct wlr_box w; /* window area, layout-relative */
|
||||
struct wl_list layers[4]; /* LayerSurface::link */
|
||||
uint32_t seltags;
|
||||
uint32_t tagset[2];
|
||||
bool skiping_frame;
|
||||
uint32_t resizing_count_pending;
|
||||
uint32_t resizing_count_current;
|
||||
|
||||
struct wl_list dwl_ipc_outputs;
|
||||
int32_t gappih; /* horizontal gap between windows */
|
||||
|
|
@ -786,7 +788,7 @@ static Client *get_scroll_stack_head(Client *c);
|
|||
static bool client_only_in_one_tag(Client *c);
|
||||
static Client *get_focused_stack_client(Client *sc);
|
||||
static bool client_is_in_same_stack(Client *sc, Client *tc, Client *fc);
|
||||
static void monitor_stop_skip_timer(Monitor *m);
|
||||
static void monitor_stop_skip_frame_timer(Monitor *m);
|
||||
static int monitor_skip_frame_timeout_callback(void *data);
|
||||
|
||||
#include "data/static_keymap.h"
|
||||
|
|
@ -2234,10 +2236,10 @@ void cleanupmon(struct wl_listener *listener, void *data) {
|
|||
wlr_scene_node_destroy(&m->blur->node);
|
||||
m->blur = NULL;
|
||||
}
|
||||
if (m->skip_timeout) {
|
||||
monitor_stop_skip_timer(m);
|
||||
wl_event_source_remove(m->skip_timeout);
|
||||
m->skip_timeout = NULL;
|
||||
if (m->skip_frame_timeout) {
|
||||
monitor_stop_skip_frame_timer(m);
|
||||
wl_event_source_remove(m->skip_frame_timeout);
|
||||
m->skip_frame_timeout = NULL;
|
||||
}
|
||||
m->wlr_output->data = NULL;
|
||||
free(m->pertag);
|
||||
|
|
@ -2790,9 +2792,11 @@ void createmon(struct wl_listener *listener, void *data) {
|
|||
struct wl_event_loop *loop = wl_display_get_event_loop(dpy);
|
||||
m = wlr_output->data = ecalloc(1, sizeof(*m));
|
||||
|
||||
m->skip_timeout =
|
||||
m->skip_frame_timeout =
|
||||
wl_event_loop_add_timer(loop, monitor_skip_frame_timeout_callback, m);
|
||||
m->skiping_frame = false;
|
||||
m->resizing_count_pending = 0;
|
||||
m->resizing_count_current = 0;
|
||||
|
||||
m->wlr_output = wlr_output;
|
||||
m->wlr_output->data = m;
|
||||
|
|
@ -4443,10 +4447,12 @@ void client_set_opacity(Client *c, double opacity) {
|
|||
scene_buffer_apply_opacity, &opacity);
|
||||
}
|
||||
|
||||
void monitor_stop_skip_timer(Monitor *m) {
|
||||
if (m->skip_timeout)
|
||||
wl_event_source_timer_update(m->skip_timeout, 0);
|
||||
void monitor_stop_skip_frame_timer(Monitor *m) {
|
||||
if (m->skip_frame_timeout)
|
||||
wl_event_source_timer_update(m->skip_frame_timeout, 0);
|
||||
m->skiping_frame = false;
|
||||
m->resizing_count_pending = 0;
|
||||
m->resizing_count_current = 0;
|
||||
}
|
||||
|
||||
static int monitor_skip_frame_timeout_callback(void *data) {
|
||||
|
|
@ -4455,20 +4461,22 @@ static int monitor_skip_frame_timeout_callback(void *data) {
|
|||
|
||||
wl_list_for_each_safe(c, tmp, &clients, link) { c->configure_serial = 0; }
|
||||
|
||||
monitor_stop_skip_timer(m);
|
||||
monitor_stop_skip_frame_timer(m);
|
||||
wlr_output_schedule_frame(m->wlr_output);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void monitor_check_skip_frame_timeout(Monitor *m) {
|
||||
if (m->skiping_frame) {
|
||||
if (m->skiping_frame &&
|
||||
m->resizing_count_pending == m->resizing_count_current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (m->skip_timeout) {
|
||||
wl_event_source_timer_update(m->skip_timeout, 100); // 100ms
|
||||
if (m->skip_frame_timeout) {
|
||||
m->resizing_count_current = m->resizing_count_pending;
|
||||
m->skiping_frame = true;
|
||||
wl_event_source_timer_update(m->skip_frame_timeout, 100); // 100ms
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4511,16 +4519,15 @@ void rendermon(struct wl_listener *listener, void *data) {
|
|||
// 绘制客户端
|
||||
wl_list_for_each(c, &clients, link) {
|
||||
need_more_frames = client_draw_frame(c) || need_more_frames;
|
||||
if (!animations && !(allow_tearing && frame_allow_tearing) &&
|
||||
c->configure_serial && client_is_rendered_on_mon(c, m) &&
|
||||
!client_is_stopped(c) && !grabc) {
|
||||
if (!animations && !grabc && c->configure_serial &&
|
||||
client_is_rendered_on_mon(c, m)) {
|
||||
monitor_check_skip_frame_timeout(m);
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
|
||||
if (m->skiping_frame) {
|
||||
monitor_stop_skip_timer(m);
|
||||
monitor_stop_skip_frame_timer(m);
|
||||
}
|
||||
|
||||
// 只有在需要帧时才构建和提交状态
|
||||
|
|
@ -5960,9 +5967,9 @@ void updatemons(struct wl_listener *listener, void *data) {
|
|||
c->mon = selmon;
|
||||
reset_foreign_tolevel(c);
|
||||
}
|
||||
if(c->tags ==0 && !c->is_in_scratchpad) {
|
||||
if (c->tags == 0 && !c->is_in_scratchpad) {
|
||||
c->tags = selmon->tagset[selmon->seltags];
|
||||
set_size_per(selmon,c);
|
||||
set_size_per(selmon, c);
|
||||
}
|
||||
}
|
||||
focusclient(focustop(selmon), 1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue