summaryrefslogtreecommitdiffstats
path: root/video/out
diff options
context:
space:
mode:
Diffstat (limited to 'video/out')
-rw-r--r--video/out/cocoa/events_view.m19
-rw-r--r--video/out/cocoa/window.h5
-rw-r--r--video/out/cocoa/window.m87
-rw-r--r--video/out/cocoa_common.m194
-rw-r--r--video/out/drm_common.c2
-rw-r--r--video/out/opengl/angle_dynamic.h7
-rw-r--r--video/out/opengl/context.c2
-rw-r--r--video/out/opengl/context.h5
-rw-r--r--video/out/opengl/context_angle.c897
-rw-r--r--video/out/opengl/context_drm_egl.c2
-rw-r--r--video/out/opengl/context_dxinterop.c23
-rw-r--r--video/out/opengl/context_w32.c14
-rw-r--r--video/out/opengl/context_wayland.c3
-rw-r--r--video/out/opengl/context_x11.c23
-rw-r--r--video/out/opengl/context_x11egl.c34
-rw-r--r--video/out/opengl/egl_helpers.c70
-rw-r--r--video/out/opengl/egl_helpers.h16
-rw-r--r--video/out/opengl/hwdec.c63
-rw-r--r--video/out/opengl/hwdec.h8
-rw-r--r--video/out/opengl/hwdec_cuda.c158
-rw-r--r--video/out/opengl/hwdec_vaegl.c177
-rw-r--r--video/out/opengl/hwdec_vaglx.c2
-rw-r--r--video/out/opengl/hwdec_vdpau.c3
-rw-r--r--video/out/opengl/video.c11
-rw-r--r--video/out/vo.c9
-rw-r--r--video/out/vo_drm.c4
-rw-r--r--video/out/vo_opengl.c22
-rw-r--r--video/out/vo_opengl_cb.c36
-rw-r--r--video/out/vo_vaapi.c10
-rw-r--r--video/out/w32_common.c171
-rw-r--r--video/out/win_state.c21
-rw-r--r--video/out/win_state.h2
-rw-r--r--video/out/x11_common.c31
-rw-r--r--video/out/x11_common.h3
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