scene: add buffer release point to 'sample' event

This commit is contained in:
Félix Poisot 2025-01-31 18:36:07 +00:00
parent 0af9b9d003
commit 1f3d351abb
2 changed files with 28 additions and 2 deletions

View file

@ -153,6 +153,8 @@ struct wlr_scene_outputs_update_event {
struct wlr_scene_output_sample_event { struct wlr_scene_output_sample_event {
struct wlr_scene_output *output; struct wlr_scene_output *output;
bool direct_scanout; bool direct_scanout;
struct wlr_drm_syncobj_timeline *release_timeline;
uint64_t release_point;
}; };
struct wlr_scene_frame_done_event { struct wlr_scene_frame_done_event {
@ -264,6 +266,8 @@ struct wlr_scene_output {
struct wlr_drm_syncobj_timeline *in_timeline; struct wlr_drm_syncobj_timeline *in_timeline;
uint64_t in_point; uint64_t in_point;
struct wlr_drm_syncobj_timeline *out_timeline;
uint64_t out_point;
} WLR_PRIVATE; } WLR_PRIVATE;
}; };

View file

@ -1524,6 +1524,8 @@ static void scene_entry_render(struct render_list_entry *entry, const struct ren
struct wlr_scene_output_sample_event sample_event = { struct wlr_scene_output_sample_event sample_event = {
.output = data->output, .output = data->output,
.direct_scanout = false, .direct_scanout = false,
.release_timeline = data->output->in_timeline,
.release_point = data->output->in_point,
}; };
wl_signal_emit_mutable(&scene_buffer->events.output_sample, &sample_event); wl_signal_emit_mutable(&scene_buffer->events.output_sample, &sample_event);
@ -1756,7 +1758,10 @@ struct wlr_scene_output *wlr_scene_output_create(struct wlr_scene *scene,
if (drm_fd >= 0 && output->backend->features.timeline && if (drm_fd >= 0 && output->backend->features.timeline &&
output->renderer != NULL && output->renderer->features.timeline) { output->renderer != NULL && output->renderer->features.timeline) {
scene_output->in_timeline = wlr_drm_syncobj_timeline_create(drm_fd); scene_output->in_timeline = wlr_drm_syncobj_timeline_create(drm_fd);
if (scene_output->in_timeline == NULL) { scene_output->out_timeline = wlr_drm_syncobj_timeline_create(drm_fd);
if (scene_output->in_timeline == NULL || scene_output->out_timeline == NULL) {
wlr_drm_syncobj_timeline_unref(scene_output->in_timeline);
wlr_drm_syncobj_timeline_unref(scene_output->out_timeline);
return NULL; return NULL;
} }
} }
@ -1811,7 +1816,14 @@ void wlr_scene_output_destroy(struct wlr_scene_output *scene_output) {
wl_list_remove(&scene_output->output_commit.link); wl_list_remove(&scene_output->output_commit.link);
wl_list_remove(&scene_output->output_damage.link); wl_list_remove(&scene_output->output_damage.link);
wl_list_remove(&scene_output->output_needs_frame.link); wl_list_remove(&scene_output->output_needs_frame.link);
wlr_drm_syncobj_timeline_unref(scene_output->in_timeline); if (scene_output->in_timeline != NULL) {
wlr_drm_syncobj_timeline_signal(scene_output->in_timeline, UINT64_MAX);
wlr_drm_syncobj_timeline_unref(scene_output->in_timeline);
}
if (scene_output->out_timeline != NULL) {
wlr_drm_syncobj_timeline_signal(scene_output->out_timeline, UINT64_MAX);
wlr_drm_syncobj_timeline_unref(scene_output->out_timeline);
}
wlr_color_transform_unref(scene_output->gamma_lut_color_transform); wlr_color_transform_unref(scene_output->gamma_lut_color_transform);
wlr_color_transform_unref(scene_output->prev_gamma_lut_color_transform); wlr_color_transform_unref(scene_output->prev_gamma_lut_color_transform);
wlr_color_transform_unref(scene_output->prev_supplied_color_transform); wlr_color_transform_unref(scene_output->prev_supplied_color_transform);
@ -2099,6 +2111,11 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout(
wlr_output_state_set_wait_timeline(&pending, buffer->wait_timeline, buffer->wait_point); wlr_output_state_set_wait_timeline(&pending, buffer->wait_timeline, buffer->wait_point);
} }
if (scene_output->out_timeline) {
scene_output->out_point++;
wlr_output_state_set_signal_timeline(&pending, scene_output->out_timeline, scene_output->out_point);
}
if (buffer->color_encoding == WLR_COLOR_ENCODING_IDENTITY && if (buffer->color_encoding == WLR_COLOR_ENCODING_IDENTITY &&
buffer->color_range == WLR_COLOR_RANGE_FULL) { buffer->color_range == WLR_COLOR_RANGE_FULL) {
// IDENTITY+FULL (used for RGB formats) is equivalent to no color // IDENTITY+FULL (used for RGB formats) is equivalent to no color
@ -2121,6 +2138,8 @@ static enum scene_direct_scanout_result scene_entry_try_direct_scanout(
struct wlr_scene_output_sample_event sample_event = { struct wlr_scene_output_sample_event sample_event = {
.output = scene_output, .output = scene_output,
.direct_scanout = true, .direct_scanout = true,
.release_timeline = data->output->out_timeline,
.release_point = data->output->out_point,
}; };
wl_signal_emit_mutable(&buffer->events.output_sample, &sample_event); wl_signal_emit_mutable(&buffer->events.output_sample, &sample_event);
return SCANOUT_SUCCESS; return SCANOUT_SUCCESS;
@ -2580,6 +2599,9 @@ bool wlr_scene_output_build_state(struct wlr_scene_output *scene_output,
if (scene_output->in_timeline != NULL) { if (scene_output->in_timeline != NULL) {
wlr_output_state_set_wait_timeline(state, scene_output->in_timeline, wlr_output_state_set_wait_timeline(state, scene_output->in_timeline,
scene_output->in_point); scene_output->in_point);
scene_output->out_point++;
wlr_output_state_set_signal_timeline(state, scene_output->out_timeline,
scene_output->out_point);
} }
if (!render_gamma_lut) { if (!render_gamma_lut) {