diff options
Diffstat (limited to 'video/out')
34 files changed, 1541 insertions, 593 deletions
diff --git a/video/out/cocoa/events_view.m b/video/out/cocoa/events_view.m index d377597006..f76ca0d617 100644 --- a/video/out/cocoa/events_view.m +++ b/video/out/cocoa/events_view.m @@ -313,23 +313,14 @@ - (BOOL)performDragOperation:(id <NSDraggingInfo>)sender { NSPasteboard *pboard = [sender draggingPasteboard]; - if ([[pboard types] containsObject:NSURLPboardType]) { - NSArray *pbitems = [pboard readObjectsForClasses:@[[NSURL class]] - options:@{}]; - NSMutableArray* ar = [[[NSMutableArray alloc] init] autorelease]; - for (NSURL* url in pbitems) { - if (url.fileURL) { - [ar addObject:[url path]]; - } else { - [ar addObject:[url absoluteString]]; - } - } - [self.adapter handleFilesArray:ar]; - return YES; - } else if ([[pboard types] containsObject:NSFilenamesPboardType]) { + if ([[pboard types] containsObject:NSFilenamesPboardType]) { NSArray *pbitems = [pboard propertyListForType:NSFilenamesPboardType]; [self.adapter handleFilesArray:pbitems]; return YES; + } else if ([[pboard types] containsObject:NSURLPboardType]) { + NSURL *url = [NSURL URLFromPasteboard:pboard]; + [self.adapter handleFilesArray:@[[url absoluteString]]]; + return YES; } return NO; } diff --git a/video/out/cocoa/window.h b/video/out/cocoa/window.h index 485831a932..af04b2b1c6 100644 --- a/video/out/cocoa/window.h +++ b/video/out/cocoa/window.h @@ -18,11 +18,12 @@ #import <Cocoa/Cocoa.h> #import "video/out/cocoa/mpvadapter.h" -@protocol MpvSizing +@protocol MpvWindowUpdate - (void)queueNewVideoSize:(NSSize)newSize; +- (void)updateBorder:(int)border; @end -@interface MpvVideoWindow : NSWindow <NSWindowDelegate, MpvSizing> +@interface MpvVideoWindow : NSWindow <NSWindowDelegate, MpvWindowUpdate> @property(nonatomic, retain) MpvCocoaAdapter *adapter; - (BOOL)canBecomeKeyWindow; - (BOOL)canBecomeMainWindow; diff --git a/video/out/cocoa/window.m b/video/out/cocoa/window.m index 68e5222a03..1ff57acde9 100644 --- a/video/out/cocoa/window.m +++ b/video/out/cocoa/window.m @@ -49,20 +49,22 @@ styleMask:(NSUInteger)style_mask backing:(NSBackingStoreType)buffering_type defer:(BOOL)flag + screen:(NSScreen *)screen { if (self = [super initWithContentRect:content_rect styleMask:style_mask backing:buffering_type - defer:flag]) { + defer:flag + screen:screen]) { [self setBackgroundColor:[NSColor blackColor]]; [self setMinSize:NSMakeSize(50,50)]; [self setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary]; - self.targetScreen = [self screen]; - self.currentScreen = [self screen]; + self.targetScreen = screen; + self.currentScreen = screen; _is_animating = 0; _unfs_content_frame = [self convertRectToScreen:[[self contentView] frame]]; - _unfs_screen_frame = [[self screen] frame]; + _unfs_screen_frame = [screen frame]; } return self; } @@ -97,18 +99,28 @@ [super toggleFullScreen:sender]; if (![self.adapter isInFullScreenMode]) { - [self setStyleMask:([self styleMask] | NSWindowStyleMaskFullScreen)]; - NSRect frame = [[self targetScreen] frame]; - [self setFrame:frame display:YES]; + [self setToFullScreen]; } else { - [self setStyleMask:([self styleMask] & ~NSWindowStyleMaskFullScreen)]; - NSRect frame = [self calculateWindowPositionForScreen:[self targetScreen]]; - [self setFrame:frame display:YES]; - [self setContentAspectRatio:_unfs_content_frame.size]; - [self setCenteredContentSize:_unfs_content_frame.size]; + [self setToWindow]; } } +- (void)setToFullScreen +{ + [self setStyleMask:([self styleMask] | NSWindowStyleMaskFullScreen)]; + NSRect frame = [[self targetScreen] frame]; + [self setFrame:frame display:YES]; +} + +- (void)setToWindow +{ + [self setStyleMask:([self styleMask] & ~NSWindowStyleMaskFullScreen)]; + NSRect frame = [self calculateWindowPositionForScreen:[self targetScreen]]; + [self setFrame:frame display:YES]; + [self setContentAspectRatio:_unfs_content_frame.size]; + [self setCenteredContentSize:_unfs_content_frame.size]; +} + - (NSArray *)customWindowsToEnterFullScreenForWindow:(NSWindow *)window { return [NSArray arrayWithObject:window]; @@ -139,11 +151,13 @@ - (void)windowDidFailToEnterFullScreen:(NSWindow *)window { _is_animating = 0; + [self setToWindow]; } - (void)windowDidFailToExitFullScreen:(NSWindow *)window { _is_animating = 0; + [self setToFullScreen]; } - (void)windowDidChangeBackingProperties:(NSNotification *)notification @@ -159,8 +173,10 @@ if (!_is_animating && ![[self currentScreen] isEqual:[self screen]]) { self.previousScreen = [self screen]; } + if (![[self currentScreen] isEqual:[self screen]]) { + [self.adapter windowDidChangeScreen:notification]; + } self.currentScreen = [self screen]; - [self.adapter windowDidChangeScreen:notification]; } - (void)windowDidChangeScreenProfile:(NSNotification *)notification @@ -212,6 +228,34 @@ [self.adapter putCommand:cmd]; } +- (void)updateBorder:(int)border +{ + int borderStyle = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable| + NSWindowStyleMaskMiniaturizable; + if (border) { + int window_mask = [self styleMask] & ~NSWindowStyleMaskBorderless; + window_mask |= borderStyle; + [self setStyleMask:window_mask]; + } else { + int window_mask = [self styleMask] & ~borderStyle; + window_mask |= NSWindowStyleMaskBorderless; + [self setStyleMask:window_mask]; + } + + if (![self.adapter isInFullScreenMode]) { + // XXX: workaround to force redrawing of window decoration + if (border) { + NSRect frame = [self frame]; + frame.size.width += 1; + [self setFrame:frame display:YES]; + frame.size.width -= 1; + [self setFrame:frame display:YES]; + } + + [self setContentAspectRatio:_unfs_content_frame.size]; + } +} + - (NSRect)frameRect:(NSRect)f forCenteredContentSize:(NSSize)ns { NSRect cr = [self contentRectForFrameRect:f]; @@ -259,11 +303,12 @@ - (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen { - if (_is_animating) - screen = [self targetScreen]; + if (_is_animating && ![self.adapter isInFullScreenMode]) + return nf; + screen = screen ?: self.screen ?: [NSScreen mainScreen]; NSRect of = [self frame]; - NSRect vf = [screen ?: self.screen ?: [NSScreen mainScreen] visibleFrame]; + NSRect vf = [_is_animating ? [self targetScreen] : screen visibleFrame]; NSRect ncf = [self contentRectForFrameRect:nf]; // Prevent the window's titlebar from exiting the screen on the top edge. @@ -304,11 +349,6 @@ display:NO]; } -- (void)updateWindowFrame:(NSSize)newSize -{ - _unfs_content_frame = [self frameRect:_unfs_content_frame forCenteredContentSize:newSize]; -} - - (void)tryDequeueSize { if (_queued_video_size.width <= 0.0 || _queued_video_size.height <= 0.0) @@ -321,9 +361,8 @@ - (void)queueNewVideoSize:(NSSize)newSize { - if ([self.adapter isInFullScreenMode]) { - [self updateWindowFrame:newSize]; - } else { + _unfs_content_frame = [self frameRect:_unfs_content_frame forCenteredContentSize:newSize]; + if (![self.adapter isInFullScreenMode]) { if (NSEqualSizes(_queued_video_size, newSize)) return; _queued_video_size = newSize; diff --git a/video/out/cocoa_common.m b/video/out/cocoa_common.m index 164663c332..0420b0dda2 100644 --- a/video/out/cocoa_common.m +++ b/video/out/cocoa_common.m @@ -69,7 +69,6 @@ struct vo_cocoa_state { NSOpenGLContext *nsgl_ctx; NSScreen *current_screen; - double screen_fps; NSInteger window_level; int fullscreen; @@ -87,6 +86,11 @@ struct vo_cocoa_state { uint32_t old_dwidth; uint32_t old_dheight; + CVDisplayLinkRef link; + pthread_mutex_t sync_lock; + pthread_cond_t sync_wakeup; + uint64_t sync_counter; + pthread_mutex_t lock; pthread_cond_t wakeup; @@ -113,14 +117,36 @@ static void run_on_main_thread(struct vo *vo, void(^block)(void)) dispatch_sync(dispatch_get_main_queue(), block); } +static NSRect calculate_window_geometry(struct vo *vo, NSRect rect) +{ + struct vo_cocoa_state *s = vo->cocoa; + struct mp_vo_opts *opts = vo->opts; + + NSRect screenFrame = [s->current_screen frame]; + rect.origin.y = screenFrame.size.height - (rect.origin.y + rect.size.height); + + if(!opts->hidpi_window_scale) { + NSRect oldRect = rect; + rect = [s->current_screen convertRectFromBacking:rect]; + + CGFloat x_per = screenFrame.size.width - oldRect.size.width; + CGFloat y_per = screenFrame.size.height - oldRect.size.height; + if (x_per > 0) x_per = oldRect.origin.x/x_per; + if (y_per > 0) y_per = oldRect.origin.y/y_per; + + rect.origin.x = (screenFrame.size.width - rect.size.width)*x_per; + rect.origin.y = (screenFrame.size.height - rect.size.height)*y_per; + } + + return rect; +} + static void queue_new_video_size(struct vo *vo, int w, int h) { struct vo_cocoa_state *s = vo->cocoa; struct mp_vo_opts *opts = vo->opts; - id<MpvSizing> win = (id<MpvSizing>) s->window; - NSRect r = NSMakeRect(0, 0, w, h); - if(!opts->hidpi_window_scale) - r = [s->current_screen convertRectFromBacking:r]; + id<MpvWindowUpdate> win = (id<MpvWindowUpdate>) s->window; + NSRect r = calculate_window_geometry(vo, NSMakeRect(0, 0, w, h)); [win queueNewVideoSize:NSMakeSize(r.size.width, r.size.height)]; } @@ -283,6 +309,26 @@ static void vo_cocoa_update_screen_info(struct vo *vo) } } +static void vo_cocoa_init_displaylink(struct vo *vo) +{ + struct vo_cocoa_state *s = vo->cocoa; + + NSDictionary* sinfo = [s->current_screen deviceDescription]; + NSNumber* sid = [sinfo objectForKey:@"NSScreenNumber"]; + CGDirectDisplayID did = [sid longValue]; + + CVDisplayLinkCreateWithCGDisplay(did, &s->link); + CVDisplayLinkSetOutputCallback(s->link, &displayLinkCallback, vo); + CVDisplayLinkStart(s->link); +} + +static void vo_cocoa_uninit_displaylink(struct vo_cocoa_state *s) +{ + if (CVDisplayLinkIsRunning(s->link)) + CVDisplayLinkStop(s->link); + CVDisplayLinkRelease(s->link); +} + void vo_cocoa_init(struct vo *vo) { struct vo_cocoa_state *s = talloc_zero(NULL, struct vo_cocoa_state); @@ -299,8 +345,11 @@ void vo_cocoa_init(struct vo *vo) } pthread_mutex_init(&s->lock, NULL); pthread_cond_init(&s->wakeup, NULL); + pthread_mutex_init(&s->sync_lock, NULL); + pthread_cond_init(&s->sync_wakeup, NULL); vo->cocoa = s; vo_cocoa_update_screen_info(vo); + vo_cocoa_init_displaylink(vo); cocoa_init_light_sensor(vo); cocoa_add_screen_reconfiguration_observer(vo); if (!s->embedded) { @@ -338,8 +387,22 @@ void vo_cocoa_uninit(struct vo *vo) pthread_cond_signal(&s->wakeup); pthread_mutex_unlock(&s->lock); + // close window beforehand to prevent undefined behavior when in fullscreen + // that resets the desktop to space 1 + run_on_main_thread(vo, ^{ + // if using --wid + libmpv there's no window to release + if (s->window) { + [s->window setDelegate:nil]; + [s->window close]; + } + }); + run_on_main_thread(vo, ^{ enable_power_management(s); + vo_cocoa_uninit_displaylink(s); + pthread_mutex_lock(&s->sync_lock); + pthread_cond_signal(&s->sync_wakeup); + pthread_mutex_unlock(&s->sync_lock); cocoa_uninit_light_sensor(s); cocoa_rm_screen_reconfiguration_observer(vo); @@ -353,60 +416,61 @@ void vo_cocoa_uninit(struct vo *vo) [s->view removeFromSuperview]; [s->view release]; - // if using --wid + libmpv there's no window to release - if (s->window) { - [s->window setDelegate:nil]; - [s->window close]; - } - if (!s->embedded) [s->blankCursor release]; + pthread_cond_destroy(&s->sync_wakeup); + pthread_mutex_destroy(&s->sync_lock); pthread_cond_destroy(&s->wakeup); pthread_mutex_destroy(&s->lock); talloc_free(s); }); } -static void vo_cocoa_update_screen_fps(struct vo *vo) +static void vo_cocoa_update_displaylink(struct vo *vo) { struct vo_cocoa_state *s = vo->cocoa; - NSDictionary* sinfo = [s->current_screen deviceDescription]; - NSNumber* sid = [sinfo objectForKey:@"NSScreenNumber"]; - CGDirectDisplayID did = [sid longValue]; + vo_cocoa_uninit_displaylink(s); + vo_cocoa_init_displaylink(vo); +} - CVDisplayLinkRef link; - CVDisplayLinkCreateWithCGDisplay(did, &link); - CVDisplayLinkSetOutputCallback(link, &displayLinkCallback, NULL); - CVDisplayLinkStart(link); - CVDisplayLinkSetCurrentCGDisplay(link, did); +static double vo_cocoa_update_screen_fps(struct vo *vo) +{ + struct vo_cocoa_state *s = vo->cocoa; + double actual_fps = CVDisplayLinkGetActualOutputVideoRefreshPeriod(s->link); + const CVTime t = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(s->link); - double display_period = CVDisplayLinkGetActualOutputVideoRefreshPeriod(link); + if (!(t.flags & kCVTimeIsIndefinite)) { + double nominal_fps = (t.timeScale / (double) t.timeValue); - if (display_period > 0) { - s->screen_fps = 1/display_period; - } else { - // Fallback to using Nominal refresh rate from DisplayLink, - // CVDisplayLinkGet *Actual* OutputVideoRefreshPeriod seems to - // return 0 on some Apple devices. Use the nominal refresh period - // instead. - const CVTime t = CVDisplayLinkGetNominalOutputVideoRefreshPeriod(link); - if (!(t.flags & kCVTimeIsIndefinite)) { - s->screen_fps = (t.timeScale / (double) t.timeValue); - MP_VERBOSE(vo, "Falling back to %f for display sync.\n", s->screen_fps); + if (actual_fps > 0) + actual_fps = 1/actual_fps; + + if (fabs(actual_fps - nominal_fps) > 0.1) { + MP_VERBOSE(vo, "Falling back to nominal display " + "refresh rate: %fHz\n", nominal_fps); + return nominal_fps; + } else { + return actual_fps; } } - CVDisplayLinkRelease(link); - - flag_events(vo, VO_EVENT_WIN_STATE); + MP_WARN(vo, "Falling back to standard display refresh rate: 60Hz\n"); + return 60.0; } static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp* now, const CVTimeStamp* outputTime, CVOptionFlags flagsIn, CVOptionFlags* flagsOut, void* displayLinkContext) { + struct vo *vo = displayLinkContext; + struct vo_cocoa_state *s = vo->cocoa; + + pthread_mutex_lock(&s->sync_lock); + s->sync_counter += 1; + pthread_cond_signal(&s->sync_wakeup); + pthread_mutex_unlock(&s->sync_lock); return kCVReturnSuccess; } @@ -422,8 +486,10 @@ static void vo_set_level(struct vo *vo, int ontop) s->window_level = NSNormalWindowLevel; } - [[s->view window] setLevel:s->window_level]; - [s->window setLevel:s->window_level]; + [s->window setLevel:s->window_level]; + NSWindowCollectionBehavior behavior = [s->window collectionBehavior] & + ~NSWindowCollectionBehaviorTransient; + [s->window setCollectionBehavior:behavior|NSWindowCollectionBehaviorManaged]; } static int vo_cocoa_ontop(struct vo *vo) @@ -472,10 +538,8 @@ static void create_ui(struct vo *vo, struct mp_rect *win, int geo_flags) if (s->embedded) { parent = (NSView *) (intptr_t) opts->WinID; } else { - NSRect wr = - NSMakeRect(win->x0, win->y0, win->x1 - win->x0, win->y1 - win->y0); - if(!opts->hidpi_window_scale) - wr = [s->current_screen convertRectFromBacking:wr]; + NSRect wr = calculate_window_geometry(vo, + NSMakeRect(win->x0, win->y0, win->x1 - win->x0, win->y1 - win->y0)); s->window = create_window(wr, s->current_screen, opts->border, adapter); parent = [s->window contentView]; } @@ -532,13 +596,36 @@ static int cocoa_set_window_title(struct vo *vo) return VO_TRUE; } +static int vo_cocoa_window_border(struct vo *vo) +{ + struct vo_cocoa_state *s = vo->cocoa; + if (s->embedded) + return VO_NOTIMPL; + + struct mp_vo_opts *opts = vo->opts; + id<MpvWindowUpdate> win = (id<MpvWindowUpdate>) s->window; + [win updateBorder:opts->border]; + if (opts->border) + cocoa_set_window_title(vo); + + return VO_TRUE; +} + static void cocoa_screen_reconfiguration_observer( CGDirectDisplayID display, CGDisplayChangeSummaryFlags flags, void *ctx) { if (flags & kCGDisplaySetModeFlag) { struct vo *vo = ctx; - MP_WARN(vo, "detected display mode change, updating screen info\n"); - vo_cocoa_update_screen_fps(vo); + struct vo_cocoa_state *s = vo->cocoa; + + NSDictionary* sinfo = [s->current_screen deviceDescription]; + NSNumber* sid = [sinfo objectForKey:@"NSScreenNumber"]; + CGDirectDisplayID did = [sid longValue]; + + if (did == display) { + MP_VERBOSE(vo, "detected display mode change, updating screen refresh rate\n"); + flag_events(vo, VO_EVENT_WIN_STATE); + } } } @@ -569,8 +656,6 @@ int vo_cocoa_config_window(struct vo *vo) struct mp_vo_opts *opts = vo->opts; run_on_main_thread(vo, ^{ - vo_cocoa_update_screen_fps(vo); - NSRect r = [s->current_screen frame]; struct mp_rect screenrc = {0, 0, r.size.width, r.size.height}; struct vo_win_geometry geo; @@ -666,6 +751,13 @@ void vo_cocoa_swap_buffers(struct vo *vo) if (skip) return; + pthread_mutex_lock(&s->sync_lock); + uint64_t old_counter = s->sync_counter; + while(old_counter == s->sync_counter) { + pthread_cond_wait(&s->sync_wakeup, &s->sync_lock); + } + pthread_mutex_unlock(&s->sync_lock); + pthread_mutex_lock(&s->lock); s->frame_w = vo->dwidth; s->frame_h = vo->dheight; @@ -727,6 +819,8 @@ static int vo_cocoa_control_on_main_thread(struct vo *vo, int request, void *arg return VO_TRUE; case VOCTRL_ONTOP: return vo_cocoa_ontop(vo); + case VOCTRL_BORDER: + return vo_cocoa_window_border(vo); case VOCTRL_GET_UNFS_WINDOW_SIZE: { int *sz = arg; NSSize size = [s->view frame].size; @@ -764,10 +858,8 @@ static int vo_cocoa_control_on_main_thread(struct vo *vo, int request, void *arg vo_cocoa_control_get_icc_profile(vo, arg); return VO_TRUE; case VOCTRL_GET_DISPLAY_FPS: - if (s->screen_fps > 0.0) { - *(double *)arg = s->screen_fps; - return VO_TRUE; - } + *(double *)arg = vo_cocoa_update_screen_fps(vo); + return VO_TRUE; break; case VOCTRL_GET_AMBIENT_LUX: if (s->light_sensor != IO_OBJECT_NULL) { @@ -885,7 +977,8 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg) - (void)windowDidChangeScreen:(NSNotification *)notification { vo_cocoa_update_screen_info(self.vout); - vo_cocoa_update_screen_fps(self.vout); + vo_cocoa_update_displaylink(self.vout); + flag_events(self.vout, VO_EVENT_WIN_STATE); } - (void)windowDidEnterFullScreen:(NSNotification *)notification @@ -915,6 +1008,7 @@ int vo_cocoa_control(struct vo *vo, int *events, int request, void *arg) - (void)didChangeWindowedScreenProfile:(NSNotification *)notification { + vo_cocoa_update_screen_info(self.vout); flag_events(self.vout, VO_EVENT_ICC_PROFILE_CHANGED); } diff --git a/video/out/drm_common.c b/video/out/drm_common.c index 44e017e4b2..c7b4edf91f 100644 --- a/video/out/drm_common.c +++ b/video/out/drm_common.c @@ -19,7 +19,7 @@ #include <string.h> #include <signal.h> #include <sys/ioctl.h> -#include <sys/poll.h> +#include <poll.h> #include <sys/stat.h> #include <sys/vt.h> #include <unistd.h> diff --git a/video/out/opengl/angle_dynamic.h b/video/out/opengl/angle_dynamic.h index 87ad85c268..12a0c692eb 100644 --- a/video/out/opengl/angle_dynamic.h +++ b/video/out/opengl/angle_dynamic.h @@ -45,9 +45,12 @@ (EGLDisplay, EGLint)) \ FN(eglSwapBuffers, EGLBoolean (*EGLAPIENTRY PFN_eglSwapBuffers) \ (EGLDisplay, EGLSurface)) \ + FN(eglSwapInterval, EGLBoolean (*EGLAPIENTRY PFN_eglSwapInterval) \ + (EGLDisplay, EGLint)) \ FN(eglReleaseTexImage, EGLBoolean (*EGLAPIENTRY PFN_eglReleaseTexImage) \ (EGLDisplay, EGLSurface, EGLint)) \ - FN(eglTerminate, EGLBoolean (*EGLAPIENTRY PFN_eglTerminate)(EGLDisplay)) + FN(eglTerminate, EGLBoolean (*EGLAPIENTRY PFN_eglTerminate)(EGLDisplay)) \ + FN(eglWaitClient, EGLBoolean (*EGLAPIENTRY PFN_eglWaitClient)(void)) #define ANGLE_EXT_DECL(NAME, VAR) \ extern VAR; @@ -76,7 +79,9 @@ bool angle_load(void); #define eglQueryString PFN_eglQueryString #define eglReleaseTexImage PFN_eglReleaseTexImage #define eglSwapBuffers PFN_eglSwapBuffers +#define eglSwapInterval PFN_eglSwapInterval #define eglTerminate PFN_eglTerminate +#define eglWaitClient PFN_eglWaitClient #endif #endif diff --git a/video/out/opengl/context.c b/video/out/opengl/context.c index fb3471cd3b..f7fce4fae5 100644 --- a/video/out/opengl/context.c +++ b/video/out/opengl/context.c @@ -57,7 +57,6 @@ static const struct mpgl_driver *const backends[] = { #endif #if HAVE_EGL_ANGLE &mpgl_driver_angle, - &mpgl_driver_angle_es2, #endif #if HAVE_GL_WIN32 &mpgl_driver_w32, @@ -159,6 +158,7 @@ static MPGLContext *init_backend(struct vo *vo, const struct mpgl_driver *driver *ctx = (MPGLContext) { .gl = talloc_zero(ctx, GL), .vo = vo, + .global = vo->global, .driver = driver, }; if (probing) diff --git a/video/out/opengl/context.h b/video/out/opengl/context.h index d0588ddbd9..0a02bd2867 100644 --- a/video/out/opengl/context.h +++ b/video/out/opengl/context.h @@ -32,7 +32,6 @@ enum { VOFLAG_GL_DEBUG = 1 << 2, // Hint to request debug OpenGL context VOFLAG_ALPHA = 1 << 3, // Hint to request alpha framebuffer VOFLAG_SW = 1 << 4, // Hint to accept a software GL renderer - VOFLAG_ANGLE_DCOMP = 1 << 5, // Whether DirectComposition is allowed VOFLAG_PROBING = 1 << 6, // The backend is being auto-probed. }; @@ -78,14 +77,12 @@ typedef struct MPGLContext { GL *gl; struct vo *vo; const struct mpgl_driver *driver; + struct mpv_global *global; // For hwdec_vaegl.c. const char *native_display_type; void *native_display; - // Windows-specific hack. See vo_opengl dwmflush suboption. - int dwm_flush_opt; - // Flip the rendered image vertically. This is useful for dxinterop. bool flip_v; diff --git a/video/out/opengl/context_angle.c b/video/out/opengl/context_angle.c index 44aed340e3..7a011a80a4 100644 --- a/video/out/opengl/context_angle.c +++ b/video/out/opengl/context_angle.c @@ -19,14 +19,21 @@ #include <EGL/egl.h> #include <EGL/eglext.h> #include <d3d11.h> -#include <dxgi.h> +#include <dxgi1_2.h> +#include <dwmapi.h> #include "angle_dynamic.h" +#include "egl_helpers.h" #include "common/common.h" +#include "options/m_config.h" #include "video/out/w32_common.h" +#include "osdep/windows_utils.h" #include "context.h" +#ifndef EGL_D3D_TEXTURE_ANGLE +#define EGL_D3D_TEXTURE_ANGLE 0x33A3 +#endif #ifndef EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE #define EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE 0x33A7 #define EGL_SURFACE_ORIENTATION_ANGLE 0x33A8 @@ -36,79 +43,190 @@ // Windows 8 enum value, not present in mingw-w64 headers #define DXGI_ADAPTER_FLAG_SOFTWARE (2) +enum { + RENDERER_AUTO, + RENDERER_D3D9, + RENDERER_D3D11, +}; + +struct angle_opts { + int renderer; + int d3d11_warp; + int d3d11_feature_level; + int egl_windowing; + int swapchain_length; // Currently only works with DXGI 1.2+ + int max_frame_latency; +}; + +#define OPT_BASE_STRUCT struct angle_opts +const struct m_sub_options angle_conf = { + .opts = (const struct m_option[]) { + OPT_CHOICE("angle-renderer", renderer, 0, + ({"auto", RENDERER_AUTO}, + {"d3d9", RENDERER_D3D9}, + {"d3d11", RENDERER_D3D11})), + OPT_CHOICE("angle-d3d11-warp", d3d11_warp, 0, + ({"auto", -1}, + {"no", 0}, + {"yes", 1})), + OPT_CHOICE("angle-d3d11-feature-level", d3d11_feature_level, 0, + ({"11_0", D3D_FEATURE_LEVEL_11_0}, + {"10_1", D3D_FEATURE_LEVEL_10_1}, + {"10_0", D3D_FEATURE_LEVEL_10_0}, + {"9_3", D3D_FEATURE_LEVEL_9_3})), + OPT_CHOICE("angle-egl-windowing", egl_windowing, 0, + ({"auto", -1}, + {"no", 0}, + {"yes", 1})), + OPT_INTRANGE("angle-swapchain-length", swapchain_length, 0, 2, 16), + OPT_INTRANGE("angle-max-frame-latency", max_frame_latency, 0, 1, 16), + {0} + }, + .defaults = &(const struct angle_opts) { + .renderer = RENDERER_AUTO, + .d3d11_warp = -1, + .d3d11_feature_level = D3D_FEATURE_LEVEL_11_0, + .egl_windowing = -1, + .sw |