Treat first frame after redirection differently
Because first frame no window has their pixmap bound, which doesn't happen in frames after the first. If a window is unmapped in that frame, the compositor will try to render a window with no pixmap bound if fading is enabled. Now we keep track if we are in the first frame, and if that's the case we skip fading in unmap/destroy. Fixes #239, bug number 2 Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
parent
f493447b33
commit
a69ed89114
|
@ -210,6 +210,8 @@ typedef struct session {
|
||||||
#endif
|
#endif
|
||||||
/// Sync fence to sync draw operations
|
/// Sync fence to sync draw operations
|
||||||
xcb_sync_fence_t sync_fence;
|
xcb_sync_fence_t sync_fence;
|
||||||
|
/// Whether we are rendering the first frame after screen is redirected
|
||||||
|
bool first_frame;
|
||||||
|
|
||||||
// === Operation related ===
|
// === Operation related ===
|
||||||
/// Flags related to the root window
|
/// Flags related to the root window
|
||||||
|
|
|
@ -1212,6 +1212,7 @@ static bool redirect_start(session_t *ps) {
|
||||||
x_sync(ps->c);
|
x_sync(ps->c);
|
||||||
|
|
||||||
ps->redirected = true;
|
ps->redirected = true;
|
||||||
|
ps->first_frame = true;
|
||||||
|
|
||||||
// Re-detect driver since we now have a backend
|
// Re-detect driver since we now have a backend
|
||||||
ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root);
|
ps->drivers = detect_driver(ps->c, ps->backend_data, ps->root);
|
||||||
|
@ -1378,6 +1379,20 @@ static void handle_pending_updates(EV_P_ struct session *ps) {
|
||||||
static void _draw_callback(EV_P_ session_t *ps, int revents attr_unused) {
|
static void _draw_callback(EV_P_ session_t *ps, int revents attr_unused) {
|
||||||
handle_pending_updates(EV_A_ ps);
|
handle_pending_updates(EV_A_ ps);
|
||||||
|
|
||||||
|
if (ps->first_frame) {
|
||||||
|
// If we are still rendering the first frame, if some of the windows are
|
||||||
|
// unmapped/destroyed during the above handle_pending_updates() call, they
|
||||||
|
// won't have pixmap before we rendered it, causing us to crash.
|
||||||
|
// But we will only render them if they are in fading. So we just skip
|
||||||
|
// fading for all windows here.
|
||||||
|
//
|
||||||
|
// Using foreach_safe here since skipping fading can cause window to be
|
||||||
|
// freed if it's destroyed.
|
||||||
|
win_stack_foreach_managed_safe(w, &ps->window_stack) {
|
||||||
|
auto _ attr_unused = win_skip_fading(ps, w);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (ps->o.benchmark) {
|
if (ps->o.benchmark) {
|
||||||
if (ps->o.benchmark_wid) {
|
if (ps->o.benchmark_wid) {
|
||||||
auto w = find_managed_win(ps, ps->o.benchmark_wid);
|
auto w = find_managed_win(ps, ps->o.benchmark_wid);
|
||||||
|
@ -1428,6 +1443,7 @@ static void _draw_callback(EV_P_ session_t *ps, int revents attr_unused) {
|
||||||
paint_all(ps, bottom, false);
|
paint_all(ps, bottom, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ps->first_frame = false;
|
||||||
paint++;
|
paint++;
|
||||||
if (ps->o.benchmark && paint >= ps->o.benchmark)
|
if (ps->o.benchmark && paint >= ps->o.benchmark)
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
Loading…
Reference in New Issue