ext_image_copy_capture_v1: replace schedule_frame with request_frame

schedule_frame is only called when the client has submitted damage
and a new frame should be rendered immediately. schedule_frame is
not called when the capture client is waiting for the next frame
but hasn't submitted damage.

Sources implementing a rendering loop based on the capture rate
need to know when a capture client is ready to accept a new frame.
Such sources want to trigger a redraw if and only if (1) they are
dirty (their contents have changed) and (2) the capture client is
ready to accept a new frame.

Replace schedule_frame with request_frame, triggered each time a
client sends a capture request. A flag indicates whether the capture
client has submitted damage.
This commit is contained in:
Simon Ser 2026-01-04 17:33:28 +01:00 committed by Simon Zeni
parent 6ae54dca23
commit f93865ed1f
4 changed files with 23 additions and 14 deletions

View file

@ -21,7 +21,7 @@ struct wlr_ext_image_capture_source_v1_interface {
// TODO: drop with_cursors flag
void (*start)(struct wlr_ext_image_capture_source_v1 *source, bool with_cursors);
void (*stop)(struct wlr_ext_image_capture_source_v1 *source);
void (*schedule_frame)(struct wlr_ext_image_capture_source_v1 *source);
void (*request_frame)(struct wlr_ext_image_capture_source_v1 *source, bool schedule_frame);
void (*copy_frame)(struct wlr_ext_image_capture_source_v1 *source,
struct wlr_ext_image_copy_capture_frame_v1 *dst_frame,
struct wlr_ext_image_capture_source_v1_frame_event *frame_event);

View file

@ -70,9 +70,12 @@ static void output_source_stop(struct wlr_ext_image_capture_source_v1 *base) {
}
}
static void output_source_schedule_frame(struct wlr_ext_image_capture_source_v1 *base) {
static void output_source_request_frame(struct wlr_ext_image_capture_source_v1 *base,
bool schedule_frame) {
struct wlr_ext_output_image_capture_source_v1 *source = wl_container_of(base, source, base);
wlr_output_update_needs_frame(source->output);
if (schedule_frame) {
wlr_output_update_needs_frame(source->output);
}
}
static void output_source_copy_frame(struct wlr_ext_image_capture_source_v1 *base,
@ -99,7 +102,7 @@ static struct wlr_ext_image_capture_source_v1_cursor *output_source_get_pointer_
static const struct wlr_ext_image_capture_source_v1_interface output_source_impl = {
.start = output_source_start,
.stop = output_source_stop,
.schedule_frame = output_source_schedule_frame,
.request_frame = output_source_request_frame,
.copy_frame = output_source_copy_frame,
.get_pointer_cursor = output_source_get_pointer_cursor,
};
@ -258,10 +261,13 @@ struct wlr_ext_output_image_capture_source_manager_v1 *wlr_ext_output_image_capt
return manager;
}
static void output_cursor_source_schedule_frame(struct wlr_ext_image_capture_source_v1 *base) {
static void output_cursor_source_request_frame(struct wlr_ext_image_capture_source_v1 *base,
bool schedule_frame) {
struct output_cursor_source *cursor_source = wl_container_of(base, cursor_source, base);
wlr_output_update_needs_frame(cursor_source->output);
cursor_source->needs_frame = true;
if (schedule_frame) {
wlr_output_update_needs_frame(cursor_source->output);
cursor_source->needs_frame = true;
}
}
static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_v1 *base,
@ -288,7 +294,7 @@ static void output_cursor_source_copy_frame(struct wlr_ext_image_capture_source_
}
static const struct wlr_ext_image_capture_source_v1_interface output_cursor_source_impl = {
.schedule_frame = output_cursor_source_schedule_frame,
.request_frame = output_cursor_source_request_frame,
.copy_frame = output_cursor_source_copy_frame,
};

View file

@ -128,9 +128,12 @@ static void source_stop(struct wlr_ext_image_capture_source_v1 *base) {
wlr_output_state_finish(&state);
}
static void source_schedule_frame(struct wlr_ext_image_capture_source_v1 *base) {
static void source_request_frame(struct wlr_ext_image_capture_source_v1 *base,
bool schedule_frame) {
struct scene_node_source *source = wl_container_of(base, source, base);
wlr_output_update_needs_frame(&source->output);
if (schedule_frame) {
wlr_output_update_needs_frame(&source->output);
}
}
static void source_copy_frame(struct wlr_ext_image_capture_source_v1 *base,
@ -149,7 +152,7 @@ static void source_copy_frame(struct wlr_ext_image_capture_source_v1 *base,
static const struct wlr_ext_image_capture_source_v1_interface source_impl = {
.start = source_start,
.stop = source_stop,
.schedule_frame = source_schedule_frame,
.request_frame = source_request_frame,
.copy_frame = source_copy_frame,
};

View file

@ -281,10 +281,10 @@ static void frame_handle_capture(struct wl_client *client,
frame->capturing = true;
bool need_frame = !pixman_region32_empty(&frame->session->damage);
bool schedule_frame = !pixman_region32_empty(&frame->session->damage);
struct wlr_ext_image_capture_source_v1 *source = frame->session->source;
if (need_frame && source->impl->schedule_frame) {
source->impl->schedule_frame(source);
if (source->impl->request_frame) {
source->impl->request_frame(source, schedule_frame);
}
}