mirror of https://github.com/mpv-player/mpv
w32_common: don't wait for GUI thread when polling for events
VOCTRL_CHECK_EVENTS is called on every frame. This is by design, and is supposed to check the event queue of the windowing API. With the decoupled GUI thread in w32_common.c this doesn't make too much sense, and the purpose of VOCTRL_CHECK_EVENTS is really reduced to checking event flags. Even worse, waiting on the GUI thread can interfere with playback, since win32 sometimes blocks the event loop (e.g. clicking the window title bar). Change the code such that we really only query the event flags. Use atomics to avoid having to add a new mutex. (We assume we always have real atomics available. The build system doesn't check this properly, and it could fall back to dummy atomics, which are not atomic.) Should help with #3393. Doesn't help if the core happens to send a synchronous request, most commonly via VOCTRL_SET_CURSOR_VISIBILITY or VOCTRL_UPDATE_PLAYBACK_STATE.
This commit is contained in:
parent
9f70117233
commit
088a0075c5
|
@ -95,7 +95,7 @@ struct vo_w32_state {
|
||||||
|
|
||||||
bool disable_screensaver;
|
bool disable_screensaver;
|
||||||
bool cursor_visible;
|
bool cursor_visible;
|
||||||
int event_flags;
|
atomic_uint event_flags;
|
||||||
|
|
||||||
BOOL tracking;
|
BOOL tracking;
|
||||||
TRACKMOUSEEVENT trackEvent;
|
TRACKMOUSEEVENT trackEvent;
|
||||||
|
@ -569,7 +569,7 @@ static bool handle_char(struct vo_w32_state *w32, wchar_t wc)
|
||||||
|
|
||||||
static void signal_events(struct vo_w32_state *w32, int events)
|
static void signal_events(struct vo_w32_state *w32, int events)
|
||||||
{
|
{
|
||||||
w32->event_flags |= events;
|
atomic_fetch_or(&w32->event_flags, events);
|
||||||
vo_wakeup(w32->vo);
|
vo_wakeup(w32->vo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,8 +1498,7 @@ static void do_control(void *ptr)
|
||||||
void *arg = p[3];
|
void *arg = p[3];
|
||||||
int *ret = p[4];
|
int *ret = p[4];
|
||||||
*ret = gui_thread_control(w32, request, arg);
|
*ret = gui_thread_control(w32, request, arg);
|
||||||
*events |= w32->event_flags;
|
*events |= atomic_fetch_and(&w32->event_flags, 0);
|
||||||
w32->event_flags = 0;
|
|
||||||
// Safe access, since caller (owner of vo) is blocked.
|
// Safe access, since caller (owner of vo) is blocked.
|
||||||
if (*events & VO_EVENT_RESIZE) {
|
if (*events & VO_EVENT_RESIZE) {
|
||||||
w32->vo->dwidth = w32->dw;
|
w32->vo->dwidth = w32->dw;
|
||||||
|
@ -1510,10 +1509,15 @@ static void do_control(void *ptr)
|
||||||
int vo_w32_control(struct vo *vo, int *events, int request, void *arg)
|
int vo_w32_control(struct vo *vo, int *events, int request, void *arg)
|
||||||
{
|
{
|
||||||
struct vo_w32_state *w32 = vo->w32;
|
struct vo_w32_state *w32 = vo->w32;
|
||||||
int r;
|
if (request == VOCTRL_CHECK_EVENTS) {
|
||||||
void *p[] = {w32, events, &request, arg, &r};
|
*events |= atomic_fetch_and(&w32->event_flags, 0);
|
||||||
mp_dispatch_run(w32->dispatch, do_control, p);
|
return VO_TRUE;
|
||||||
return r;
|
} else {
|
||||||
|
int r;
|
||||||
|
void *p[] = {w32, events, &request, arg, &r};
|
||||||
|
mp_dispatch_run(w32->dispatch, do_control, p);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void do_terminate(void *ptr)
|
static void do_terminate(void *ptr)
|
||||||
|
|
Loading…
Reference in New Issue