diff options
author | wm4 <wm4@nowhere> | 2014-10-03 21:53:32 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-10-03 23:07:08 +0200 |
commit | a74a324b98a2484995cdf9206f0e586a7249f1af (patch) | |
tree | 04e1363cd00f0722807fe62c1f77a9e1441efe12 | |
parent | 9d5d031b6d23402a465618892a40b7af6d4e3c28 (diff) | |
download | mpv-a74a324b98a2484995cdf9206f0e586a7249f1af.tar.bz2 mpv-a74a324b98a2484995cdf9206f0e586a7249f1af.tar.xz |
video: return responsibility of video redraw back to playloop
When the VO was moved it its own thread, responsibility for redrawing
was given to the VO thread itself. So if there was a condition that
indicated that redrawing was required, like expose events or certain
VOCTRLs, the VO thread was redrawing itself.
This worked fine, but there are some corner cases where this works
rather badly. E.g. if I fullscreen the player and hit panscan controls
with mpv's default autorepeat rate, playback stops. This happens because
the VO redraws itself after every panscan change command. Running each
(repeated) command takes so long due to redrawing and (involuntary)
waiting on vsync, that it never leaves the input processing loop while
the key is held down. I suspect that in my case, redrawing in fullscreen
mode just gets slow enough that it takes 2 vsyncs instead of 1 on
average, and the processing time gets larger than the autorepeat delay.
Fix this by taking redraw control from the VO, and instead let the
playloop issue a "real" redraw command to the VO if needed. This
basically reverts redraw handling to what it was before moving the VO to
a thread.
CC: @mpv-player/stable
-rw-r--r-- | player/playloop.c | 3 | ||||
-rw-r--r-- | video/out/vo.c | 22 | ||||
-rw-r--r-- | video/out/vo.h | 1 |
3 files changed, 22 insertions, 4 deletions
diff --git a/player/playloop.c b/player/playloop.c index 5cefcb8ac5..c5077b43dd 100644 --- a/player/playloop.c +++ b/player/playloop.c @@ -533,7 +533,8 @@ static void handle_osd_redraw(struct MPContext *mpctx) // Don't redraw immediately during a seek (makes it significantly slower). if (mpctx->d_video && mp_time_sec() - mpctx->start_timestamp < 0.1) return; - bool want_redraw = osd_query_and_reset_want_redraw(mpctx->osd); + bool want_redraw = osd_query_and_reset_want_redraw(mpctx->osd) || + vo_want_redraw(mpctx->video_out); if (!want_redraw) return; vo_redraw(mpctx->video_out); diff --git a/video/out/vo.c b/video/out/vo.c index 9d005647e2..fcc15e4008 100644 --- a/video/out/vo.c +++ b/video/out/vo.c @@ -125,7 +125,8 @@ struct vo_internal { bool hasframe; bool hasframe_rendered; - bool request_redraw; + bool request_redraw; // redraw request from player to VO + bool want_redraw; // redraw request from VO to player bool paused; int64_t flip_queue_offset; // queue flip events at most this much in advance @@ -615,6 +616,7 @@ static bool render_frame(struct vo *vo) vo->want_redraw = false; + in->want_redraw = false; in->request_redraw = false; in->rendering = false; @@ -634,6 +636,7 @@ static void do_redraw(struct vo *vo) pthread_mutex_lock(&in->lock); in->request_redraw = false; + in->want_redraw = false; bool skip = !in->paused && in->dropped_frame; struct mp_image *img = in->dropped_image; if (!skip) { @@ -685,9 +688,13 @@ static void *vo_thread(void *ptr) mp_input_wakeup(vo->input_ctx); } } - vo->want_redraw |= in->request_redraw; + if (vo->want_redraw && !in->want_redraw) { + in->want_redraw = true; + mp_input_wakeup(vo->input_ctx); + } + bool redraw = in->request_redraw; pthread_mutex_unlock(&in->lock); - if (wait_until > now && vo->want_redraw) { + if (wait_until > now && redraw) { do_redraw(vo); // now is a good time continue; } @@ -731,6 +738,15 @@ void vo_redraw(struct vo *vo) pthread_mutex_unlock(&in->lock); } +bool vo_want_redraw(struct vo *vo) +{ + struct vo_internal *in = vo->in; + pthread_mutex_lock(&in->lock); + bool r = in->want_redraw; + pthread_mutex_unlock(&in->lock); + return r; +} + void vo_seek_reset(struct vo *vo) { pthread_mutex_lock(&vo->in->lock); diff --git a/video/out/vo.h b/video/out/vo.h index 0b6c0a5144..feb2907c67 100644 --- a/video/out/vo.h +++ b/video/out/vo.h @@ -292,6 +292,7 @@ void vo_wait_frame(struct vo *vo); bool vo_still_displaying(struct vo *vo); bool vo_has_frame(struct vo *vo); void vo_redraw(struct vo *vo); +bool vo_want_redraw(struct vo *vo); void vo_seek_reset(struct vo *vo); void vo_destroy(struct vo *vo); void vo_set_paused(struct vo *vo, bool paused); |