mirror of https://github.com/mpv-player/mpv
cocoa: reintroduce async resize
After removing synchronous libdispatch calls, this looks like it doesn't deadlock anymore. I also experimented with pthread_mutex_trylock liek wm4 suggested, but it leads to some annoying black flickering. I will fallback to that only if some new deadlocks are discovered.
This commit is contained in:
parent
421bce0077
commit
fa904150bf
|
@ -19,8 +19,6 @@
|
||||||
#include "video/out/vo.h"
|
#include "video/out/vo.h"
|
||||||
|
|
||||||
@interface MpvCocoaAdapter : NSObject
|
@interface MpvCocoaAdapter : NSObject
|
||||||
- (void)lock;
|
|
||||||
- (void)unlock;
|
|
||||||
- (void)setNeedsResize;
|
- (void)setNeedsResize;
|
||||||
- (void)signalMouseMovement:(NSPoint)point;
|
- (void)signalMouseMovement:(NSPoint)point;
|
||||||
- (void)putKeyEvent:(NSEvent*)event;
|
- (void)putKeyEvent:(NSEvent*)event;
|
||||||
|
@ -29,6 +27,7 @@
|
||||||
- (void)putCommand:(char*)cmd;
|
- (void)putCommand:(char*)cmd;
|
||||||
- (void)handleFilesArray:(NSArray *)files;
|
- (void)handleFilesArray:(NSArray *)files;
|
||||||
- (void)didChangeWindowedScreenProfile:(NSScreen *)screen;
|
- (void)didChangeWindowedScreenProfile:(NSScreen *)screen;
|
||||||
|
- (void)performAsyncResize:(NSSize)size;
|
||||||
|
|
||||||
- (BOOL)isInFullScreenMode;
|
- (BOOL)isInFullScreenMode;
|
||||||
- (BOOL)keyboardEnabled;
|
- (BOOL)keyboardEnabled;
|
||||||
|
|
|
@ -40,4 +40,10 @@
|
||||||
{
|
{
|
||||||
return [self convertRectToBacking:[self frame]];
|
return [self convertRectToBacking:[self frame]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)drawRect:(NSRect)rect
|
||||||
|
{
|
||||||
|
[self.adapter performAsyncResize:[self frameInPixels].size];
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct vo_cocoa_state {
|
||||||
int pending_events;
|
int pending_events;
|
||||||
|
|
||||||
bool waiting_frame;
|
bool waiting_frame;
|
||||||
|
bool skip_swap_buffer;
|
||||||
bool embedded; // wether we are embedding in another GUI
|
bool embedded; // wether we are embedding in another GUI
|
||||||
|
|
||||||
IOPMAssertionID power_mgmt_assertion;
|
IOPMAssertionID power_mgmt_assertion;
|
||||||
|
@ -83,6 +84,8 @@ struct vo_cocoa_state {
|
||||||
char *icc_wnd_profile_path;
|
char *icc_wnd_profile_path;
|
||||||
char *icc_fs_profile_path;
|
char *icc_fs_profile_path;
|
||||||
id fs_icc_changed_ns_observer;
|
id fs_icc_changed_ns_observer;
|
||||||
|
|
||||||
|
void (*resize_redraw)(struct vo *vo, int w, int h);
|
||||||
};
|
};
|
||||||
|
|
||||||
static void with_cocoa_lock(struct vo *vo, void(^block)(void))
|
static void with_cocoa_lock(struct vo *vo, void(^block)(void))
|
||||||
|
@ -175,6 +178,13 @@ static int vo_cocoa_set_cursor_visibility(struct vo *vo, bool *visible)
|
||||||
return VO_TRUE;
|
return VO_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void vo_cocoa_register_resize_callback(struct vo *vo,
|
||||||
|
void (*cb)(struct vo *vo, int w, int h))
|
||||||
|
{
|
||||||
|
struct vo_cocoa_state *s = vo->cocoa;
|
||||||
|
s->resize_redraw = cb;
|
||||||
|
}
|
||||||
|
|
||||||
void vo_cocoa_uninit(struct vo *vo)
|
void vo_cocoa_uninit(struct vo *vo)
|
||||||
{
|
{
|
||||||
with_cocoa_lock(vo, ^{
|
with_cocoa_lock(vo, ^{
|
||||||
|
@ -456,6 +466,26 @@ void vo_cocoa_set_current_context(struct vo *vo, bool current)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void vo_cocoa_resize_redraw(struct vo *vo, int width, int height)
|
||||||
|
{
|
||||||
|
struct vo_cocoa_state *s = vo->cocoa;
|
||||||
|
|
||||||
|
if (!s->gl_ctx)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (!s->resize_redraw)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vo_cocoa_set_current_context(vo, true);
|
||||||
|
|
||||||
|
[s->gl_ctx update];
|
||||||
|
s->resize_redraw(vo, width, height);
|
||||||
|
s->skip_swap_buffer = true;
|
||||||
|
|
||||||
|
[s->gl_ctx flushBuffer];
|
||||||
|
vo_cocoa_set_current_context(vo, false);
|
||||||
|
}
|
||||||
|
|
||||||
static void draw_changes_after_next_frame(struct vo *vo)
|
static void draw_changes_after_next_frame(struct vo *vo)
|
||||||
{
|
{
|
||||||
struct vo_cocoa_state *s = vo->cocoa;
|
struct vo_cocoa_state *s = vo->cocoa;
|
||||||
|
@ -468,7 +498,13 @@ static void draw_changes_after_next_frame(struct vo *vo)
|
||||||
void vo_cocoa_swap_buffers(struct vo *vo)
|
void vo_cocoa_swap_buffers(struct vo *vo)
|
||||||
{
|
{
|
||||||
struct vo_cocoa_state *s = vo->cocoa;
|
struct vo_cocoa_state *s = vo->cocoa;
|
||||||
[s->gl_ctx flushBuffer];
|
if (s->skip_swap_buffer) {
|
||||||
|
s->skip_swap_buffer = false;
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
[s->gl_ctx flushBuffer];
|
||||||
|
}
|
||||||
|
|
||||||
if (s->waiting_frame) {
|
if (s->waiting_frame) {
|
||||||
s->waiting_frame = false;
|
s->waiting_frame = false;
|
||||||
NSEnableScreenUpdates();
|
NSEnableScreenUpdates();
|
||||||
|
@ -687,12 +723,8 @@ void *vo_cocoa_cgl_pixel_format(struct vo *vo)
|
||||||
@implementation MpvCocoaAdapter
|
@implementation MpvCocoaAdapter
|
||||||
@synthesize vout = _video_output;
|
@synthesize vout = _video_output;
|
||||||
|
|
||||||
- (void)lock {
|
- (void)performAsyncResize:(NSSize)size {
|
||||||
vo_cocoa_set_current_context(self.vout, true);
|
vo_cocoa_resize_redraw(self.vout, size.width, size.height);
|
||||||
}
|
|
||||||
|
|
||||||
- (void)unlock {
|
|
||||||
vo_cocoa_set_current_context(self.vout, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)keyboardEnabled {
|
- (BOOL)keyboardEnabled {
|
||||||
|
|
|
@ -149,6 +149,7 @@ void mpgl_set_backend_cocoa(MPGLContext *ctx)
|
||||||
ctx->releaseGlContext = releaseGlContext_cocoa;
|
ctx->releaseGlContext = releaseGlContext_cocoa;
|
||||||
ctx->swapGlBuffers = swapGlBuffers_cocoa;
|
ctx->swapGlBuffers = swapGlBuffers_cocoa;
|
||||||
ctx->vo_init = vo_cocoa_init;
|
ctx->vo_init = vo_cocoa_init;
|
||||||
|
ctx->register_resize_callback = vo_cocoa_register_resize_callback;
|
||||||
ctx->vo_uninit = vo_cocoa_uninit;
|
ctx->vo_uninit = vo_cocoa_uninit;
|
||||||
ctx->vo_control = vo_cocoa_control;
|
ctx->vo_control = vo_cocoa_control;
|
||||||
ctx->set_current = set_current_cocoa;
|
ctx->set_current = set_current_cocoa;
|
||||||
|
|
|
@ -2388,6 +2388,18 @@ static int validate_scaler_opt(struct mp_log *log, const m_option_t *opt,
|
||||||
return handle_scaler_opt(s) ? 1 : M_OPT_INVALID;
|
return handle_scaler_opt(s) ? 1 : M_OPT_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resize and redraw the contents of the window without further configuration.
|
||||||
|
// Intended to be used in situations where the frontend can't really be
|
||||||
|
// involved with reconfiguring the VO properly.
|
||||||
|
// gl_video_resize() should be called when user interaction is done.
|
||||||
|
void gl_video_resize_redraw(struct gl_video *p, int w, int h)
|
||||||
|
{
|
||||||
|
p->gl->Viewport(p->vp_x, p->vp_y, w, h);
|
||||||
|
p->vp_w = w;
|
||||||
|
p->vp_h = h;
|
||||||
|
gl_video_render_frame(p);
|
||||||
|
}
|
||||||
|
|
||||||
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec)
|
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec)
|
||||||
{
|
{
|
||||||
p->hwdec = hwdec;
|
p->hwdec = hwdec;
|
||||||
|
|
|
@ -74,6 +74,7 @@ bool gl_video_set_equalizer(struct gl_video *p, const char *name, int val);
|
||||||
bool gl_video_get_equalizer(struct gl_video *p, const char *name, int *val);
|
bool gl_video_get_equalizer(struct gl_video *p, const char *name, int *val);
|
||||||
|
|
||||||
void gl_video_set_debug(struct gl_video *p, bool enable);
|
void gl_video_set_debug(struct gl_video *p, bool enable);
|
||||||
|
void gl_video_resize_redraw(struct gl_video *p, int w, int h);
|
||||||
|
|
||||||
struct gl_hwdec;
|
struct gl_hwdec;
|
||||||
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec);
|
void gl_video_set_hwdec(struct gl_video *p, struct gl_hwdec *hwdec);
|
||||||
|
|
|
@ -203,6 +203,13 @@ static bool config_window(struct gl_priv *p, int flags)
|
||||||
return mpgl_config_window(p->glctx, mpgl_caps, flags);
|
return mpgl_config_window(p->glctx, mpgl_caps, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void video_resize_redraw_callback(struct vo *vo, int w, int h)
|
||||||
|
{
|
||||||
|
struct gl_priv *p = vo->priv;
|
||||||
|
gl_video_resize_redraw(p->renderer, w, h);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
|
static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
|
||||||
{
|
{
|
||||||
struct gl_priv *p = vo->priv;
|
struct gl_priv *p = vo->priv;
|
||||||
|
@ -214,6 +221,10 @@ static int reconfig(struct vo *vo, struct mp_image_params *params, int flags)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (p->glctx->register_resize_callback) {
|
||||||
|
p->glctx->register_resize_callback(vo, video_resize_redraw_callback);
|
||||||
|
}
|
||||||
|
|
||||||
gl_video_config(p->renderer, params);
|
gl_video_config(p->renderer, params);
|
||||||
|
|
||||||
p->vo_flipped = !!(flags & VOFLAG_FLIPPING);
|
p->vo_flipped = !!(flags & VOFLAG_FLIPPING);
|
||||||
|
|
Loading…
Reference in New Issue