Skip to content

Commit

Permalink
Merge branch 'yshui:next' into next
Browse files Browse the repository at this point in the history
  • Loading branch information
pijulius committed May 29, 2024
2 parents 66fd22f + c3883b8 commit 9aff31b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 43 deletions.
25 changes: 0 additions & 25 deletions src/backend/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,31 +80,6 @@ bool backend_can_present(struct backend_info *info) {
return info->can_present;
}

void handle_device_reset(session_t *ps) {
log_error("Device reset detected");
// Wait for reset to complete
// Although ideally the backend should return DEVICE_STATUS_NORMAL after a reset
// is completed, it's not always possible.
//
// According to ARB_robustness (emphasis mine):
//
// "If a reset status other than NO_ERROR is returned and subsequent
// calls return NO_ERROR, the context reset was encountered and
// completed. If a reset status is repeatedly returned, the context **may**
// be in the process of resetting."
//
// Which means it may also not be in the process of resetting. For example on
// AMDGPU devices, Mesa OpenGL always return CONTEXT_RESET after a reset has
// started, completed or not.
//
// So here we blindly wait 5 seconds and hope ourselves best of the luck.
sleep(5);

// Reset picom
log_info("Resetting picom after device reset");
ev_break(ps->loop, EVBREAK_ALL);
}

/// Execute a list of backend commands on the backend
/// @param target the image to render into
/// @param root_image the image containing the desktop background
Expand Down
61 changes: 45 additions & 16 deletions src/picom.c
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,22 @@ static void handle_pending_updates(EV_P_ struct session *ps, double delta_t) {
}
}

/**
* Turn on the program reset flag.
*
* This will result in the compositor resetting itself after next paint.
*/
static void reset_enable(EV_P_ ev_signal *w attr_unused, int revents attr_unused) {
log_info("picom is resetting...");
ev_break(EV_A_ EVBREAK_ALL);
}

static void exit_enable(EV_P attr_unused, ev_signal *w, int revents attr_unused) {
session_t *ps = session_ptr(w, int_signal);
log_info("picom is quitting...");
quit(ps);
}

static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
assert(!ps->backend_busy);
assert(ps->render_queued);
Expand Down Expand Up @@ -1789,6 +1805,35 @@ static void draw_callback_impl(EV_P_ session_t *ps, int revents attr_unused) {
now = get_time_timespec();
auto render_start_us =
(uint64_t)now.tv_sec * 1000000UL + (uint64_t)now.tv_nsec / 1000;
if (ps->backend_data->ops.device_status &&
ps->backend_data->ops.device_status(ps->backend_data) !=
DEVICE_STATUS_NORMAL) {
log_error("Device reset detected");
// Wait for reset to complete
// Although ideally the backend should return
// DEVICE_STATUS_NORMAL after a reset is completed, it's
// not always possible.
//
// According to ARB_robustness (emphasis mine):
//
// "If a reset status other than NO_ERROR is returned
// and subsequent calls return NO_ERROR, the context
// reset was encountered and completed. If a reset
// status is repeatedly returned, the context **may**
// be in the process of resetting."
//
// Which means it may also not be in the process of
// resetting. For example on AMDGPU devices, Mesa OpenGL
// always return CONTEXT_RESET after a reset has started,
// completed or not.
//
// So here we blindly wait 5 seconds and hope ourselves
// best of the luck.
sleep(5);
log_info("Resetting picom after device reset");
reset_enable(ps->loop, NULL, 0);
return;
}
layout_manager_append_layout(
ps->layout_manager, ps->wm, ps->root_image_generation,
(ivec2){.width = ps->root_width, .height = ps->root_height});
Expand Down Expand Up @@ -1889,22 +1934,6 @@ static void x_event_callback(EV_P attr_unused, ev_io *w, int revents attr_unused
}
}

/**
* Turn on the program reset flag.
*
* This will result in the compositor resetting itself after next paint.
*/
static void reset_enable(EV_P_ ev_signal *w attr_unused, int revents attr_unused) {
log_info("picom is resetting...");
ev_break(EV_A_ EVBREAK_ALL);
}

static void exit_enable(EV_P attr_unused, ev_signal *w, int revents attr_unused) {
session_t *ps = session_ptr(w, int_signal);
log_info("picom is quitting...");
quit(ps);
}

static void config_file_change_cb(void *_ps) {
auto ps = (struct session *)_ps;
reset_enable(ps->loop, NULL, 0);
Expand Down
9 changes: 7 additions & 2 deletions src/x.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,19 +56,24 @@ typedef struct pending_reply {
} pending_reply_t;

struct x_connection {
// Public fields
// These are part of the public ABI, changing these
// requires bumping PICOM_API_MAJOR.
/// XCB connection.
xcb_connection_t *c;
/// Display in use.
Display *dpy;
/// Default screen
int screen;

// Private fields
/// Head pointer of the error ignore linked list.
pending_reply_t *pending_reply_head;
/// Pointer to the <code>next</code> member of tail element of the error
/// ignore linked list.
pending_reply_t **pending_reply_tail;
/// Previous handler of X errors
XErrorHandler previous_xerror_handler;
/// Default screen
int screen;
/// Information about the default screen
xcb_screen_t *screen_info;
};
Expand Down

0 comments on commit 9aff31b

Please sign in to comment.