Skip to content

Commit 468d34c

Browse files
committed
vo: allow VOs to request waiting before advancing frames
This is essentially for vo_dmabuf_wayland, but there is a race condition during initialization where we should wait on an event from the compositor to set the appropriate description for the image (namely for color management) before flipping the page. Previously, there was an off-by-one frame difference which resulted in the initial frame not being appropriately color managed. Fix this by telling the core render loop that it is not ready for the next frame. This keeps the frame queue from advancing and allows the backend to process events appropriately until it signals that it is ready.
1 parent 1af136b commit 468d34c

File tree

5 files changed

+27
-4
lines changed

5 files changed

+27
-4
lines changed

video/out/vo.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ struct vo_internal {
138138
bool send_reset; // send VOCTRL_RESET
139139
bool paused;
140140
bool visible;
141+
bool wait_on_vo;
141142
bool wakeup_on_done;
142143
int queued_events; // event mask for the user
143144
int internal_events; // event mask for us
@@ -836,7 +837,7 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts)
836837
{
837838
struct vo_internal *in = vo->in;
838839
mp_mutex_lock(&in->lock);
839-
bool r = vo->config_ok && !in->frame_queued &&
840+
bool r = vo->config_ok && !in->wait_on_vo && !in->frame_queued &&
840841
(!in->current_frame || in->current_frame->num_vsyncs < 1);
841842
if (r && next_pts >= 0) {
842843
// Don't show the frame too early - it would basically freeze the
@@ -898,6 +899,14 @@ void vo_wait_frame(struct vo *vo)
898899
mp_mutex_unlock(&in->lock);
899900
}
900901

902+
void vo_wait_on_vo(struct vo *vo, bool wait)
903+
{
904+
struct vo_internal *in = vo->in;
905+
mp_mutex_lock(&in->lock);
906+
in->wait_on_vo = wait;
907+
mp_mutex_unlock(&in->lock);
908+
}
909+
901910
// Wait until realtime is >= ts
902911
// called without lock
903912
static void wait_until(struct vo *vo, int64_t target)

video/out/vo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -533,6 +533,7 @@ bool vo_is_ready_for_frame(struct vo *vo, int64_t next_pts);
533533
bool vo_is_visible(struct vo *vo);
534534
void vo_queue_frame(struct vo *vo, struct vo_frame *frame);
535535
void vo_wait_frame(struct vo *vo);
536+
void vo_wait_on_vo(struct vo *vo, bool wait);
536537
bool vo_still_displaying(struct vo *vo);
537538
void vo_request_wakeup_on_done(struct vo *vo);
538539
bool vo_has_frame(struct vo *vo);

video/out/vo_dmabuf_wayland.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ struct priv {
103103

104104
bool destroy_buffers;
105105
bool force_window;
106+
bool vo_is_waiting;
106107
enum hwdec_type hwdec_type;
107108

108109
struct mp_image_params target_params;
@@ -626,6 +627,11 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
626627
wl_surface_damage_buffer(wl->video_surface, 0, 0, 1, 1);
627628
}
628629

630+
if (wl->color_surface && (!wl->image_description_processed || p->vo_is_waiting)) {
631+
vo_wait_on_vo(vo, !wl->image_description_processed);
632+
p->vo_is_waiting = !wl->image_description_processed;
633+
}
634+
629635
pts = frame->current ? frame->current->pts : 0;
630636
if (frame->current) {
631637
buf = buffer_get(vo, frame);
@@ -660,10 +666,13 @@ static bool draw_frame(struct vo *vo, struct vo_frame *frame)
660666
static void flip_page(struct vo *vo)
661667
{
662668
struct vo_wayland_state *wl = vo->wl;
669+
struct priv *p = vo->priv;
663670

664-
wl_surface_commit(wl->osd_surface);
665-
wl_surface_commit(wl->video_surface);
666-
wl_surface_commit(wl->surface);
671+
if (!p->vo_is_waiting) {
672+
wl_surface_commit(wl->osd_surface);
673+
wl_surface_commit(wl->video_surface);
674+
wl_surface_commit(wl->surface);
675+
}
667676

668677
if (wl->opts->wl_internal_vsync)
669678
vo_wayland_wait_frame(wl);

video/out/wayland_common.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,6 +2108,7 @@ static void image_description_failed(void *data, struct wp_image_description_v1
21082108
MP_VERBOSE(wl, "Image description failed: %d, %s\n", cause, msg);
21092109
wp_color_management_surface_v1_unset_image_description(wl->color_surface);
21102110
wp_image_description_v1_destroy(image_description);
2111+
wl->image_description_processed = true;
21112112
}
21122113

21132114
static void image_description_ready2(void *data, struct wp_image_description_v1 *image_description,
@@ -2118,6 +2119,7 @@ static void image_description_ready2(void *data, struct wp_image_description_v1
21182119
WP_COLOR_MANAGER_V1_RENDER_INTENT_PERCEPTUAL);
21192120
MP_TRACE(wl, "Image description set on color surface.\n");
21202121
wp_image_description_v1_destroy(image_description);
2122+
wl->image_description_processed = true;
21212123
}
21222124

21232125
static void image_description_ready(void *data, struct wp_image_description_v1 *image_description,
@@ -3538,6 +3540,7 @@ static void set_color_management(struct vo_wayland_state *wl)
35383540
wp_image_description_creator_params_v1_set_max_fall(image_creator_params, lrintf(hdr.max_fall));
35393541
}
35403542
struct wp_image_description_v1 *image_description = wp_image_description_creator_params_v1_create(image_creator_params);
3543+
wl->image_description_processed = false;
35413544
wp_image_description_v1_add_listener(image_description, &image_description_listener, wl);
35423545
#endif
35433546
}

video/out/wayland_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ struct vo_wayland_state {
9595
struct wp_color_management_surface_feedback_v1 *color_surface_feedback;
9696
struct wp_image_description_creator_icc_v1 *icc_creator;
9797
struct mp_image_params target_params;
98+
bool image_description_processed;
9899
bool supports_parametric;
99100
bool supports_display_primaries;
100101
int primaries_map[PL_COLOR_PRIM_COUNT];

0 commit comments

Comments
 (0)