Skip to content

Commit

Permalink
core: simplify the pacing logic a little bit
Browse files Browse the repository at this point in the history
Make it simpler to stop requesting PresentCompleteNotify when there is
nothing to render.

Related: #1079

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
  • Loading branch information
yshui committed Jun 24, 2023
1 parent c5c41f8 commit 5702daa
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 114 deletions.
12 changes: 8 additions & 4 deletions src/backend/backend.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,17 @@ void handle_device_reset(session_t *ps) {
}

/// paint all windows
void paint_all_new(session_t *ps, struct managed_win *t) {
///
/// Returns if any render command is issued. IOW if nothing on the screen has changed,
/// this1 function will return false.
bool paint_all_new(session_t *ps, struct managed_win *const t) {
struct timespec now = get_time_timespec();
auto paint_all_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) {
return handle_device_reset(ps);
handle_device_reset(ps);
return false;
}
if (ps->o.xrender_sync_fence) {
if (ps->xsync_exists && !x_fence_sync(ps->c, ps->sync_fence)) {
Expand All @@ -114,7 +118,7 @@ void paint_all_new(session_t *ps, struct managed_win *t) {

if (!pixman_region32_not_empty(&reg_damage)) {
pixman_region32_fini(&reg_damage);
return;
return false;
}

#ifdef DEBUG_REPAINT
Expand Down Expand Up @@ -199,7 +203,6 @@ void paint_all_new(session_t *ps, struct managed_win *t) {
ps->last_schedule_delay = after_damage_us - ps->next_render;
}
}
ps->did_render = true;

if (ps->backend_data->ops->prepare) {
ps->backend_data->ops->prepare(ps->backend_data, &reg_paint);
Expand Down Expand Up @@ -541,6 +544,7 @@ void paint_all_new(session_t *ps, struct managed_win *t) {
for (win *w = t; w; w = w->prev_trans)
log_trace(" %#010lx", w->id);
#endif
return true;
}

// vim: set noet sw=8 ts=8 :
6 changes: 5 additions & 1 deletion src/backend/backend.h
Original file line number Diff line number Diff line change
Expand Up @@ -371,4 +371,8 @@ struct backend_operations {

extern struct backend_operations *backend_list[];

void paint_all_new(session_t *ps, struct managed_win *const t) attr_nonnull(1);
/// paint all windows
///
/// Returns if any render command is issued. IOW if nothing on the screen has changed,
/// this1 function will return false.
bool paint_all_new(session_t *ps, struct managed_win *t) attr_nonnull(1);
25 changes: 18 additions & 7 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,17 @@ struct shader_info {
UT_hash_handle hh;
};

enum render_progress {
/// Render is finished and presented to the screen.
RENDER_IDLE = 0,
/// Rendering is queued, but not started yet.
RENDER_QUEUED,
/// Backend has been called, render commands have been issued.
RENDER_STARTED,
/// Backend reported render commands have been finished. (not actually used).
RENDER_FINISHED,
};

/// Structure containing all necessary data for a session.
typedef struct session {
// === Event handlers ===
Expand Down Expand Up @@ -249,17 +260,11 @@ typedef struct session {
uint64_t last_msc_instant;
/// The last MSC number
uint64_t last_msc;
/// When the currently rendered frame will be displayed.
/// 0 means there is no pending frame.
uint64_t target_msc;
/// The delay between when the last frame was scheduled to be rendered, and when
/// the render actually started.
uint64_t last_schedule_delay;
/// When do we want our next frame to start rendering.
uint64_t next_render;
/// Did we actually render the last frame. Sometimes redraw will be scheduled only
/// to find out nothing has changed. In which case this will be set to false.
bool did_render;
/// Whether we can perform frame pacing.
bool frame_pacing;

Expand All @@ -273,7 +278,13 @@ typedef struct session {
options_t o;
/// Whether we have hit unredirection timeout.
bool tmout_unredir_hit;
/// Whether we need to redraw the screen
/// Rendering is currently in progress. This means we are in any stage of
/// rendering a frame. The render could be queued but not yet started, or it could
/// have finished but not yet presented.
enum render_progress render_in_progress;
/// Whether there are changes pending for the next render. A render is currently
/// in progress, otherwise we would have started a new render instead of setting
/// this flag.
bool redraw_needed;

/// Cache a xfixes region so we don't need to allocate it every time.
Expand Down
Loading

0 comments on commit 5702daa

Please sign in to comment.