This PR applies several minor fixes and improvements to macOS driver settings and the driver settings pane. #### Remove the "exclusive mode" video option on macOS. * There is no real notion of exclusive presentation on macOS beyond what already exists in normal fullscreen. If an application is covering the screen and no other application or window is visible, the system automatically switches to a "direct" presentation mode that optimizes for single-application presentation performance. There is not a good reason to show this option on macOS, even disabled. * By contrast, it is possible (though not implemented by ares) to enter exclusive mode on the audio device with CoreAudio, so leave that option there, just disabled. #### Add a "use native fullscreen" option on macOS. * There are various good reasons to prefer either native platform fullscreen behavior, or a custom borderless windowed fullscreen. Rather than guess what the user wants, offer an option. * If unchecked, make the window title bar enlarge the window rather than fullscreen it, so we don't mix behaviors. #### Implement fullscreen monitor selection behavior for Metal, and correctly enumerate the user's monitor names. * Fullscreen display on the selected monitor in the settings pane was previously not implemented on macOS. This implementation only works if "Use native fullscreen" is disabled, since the macOS fullscreen idiom doesn't feature selecting a specific display. * Additionally, the old function to retrieve the monitor's localized name did not work reliably on newer macOS versions. Use the modern property `localizedName` on NSScreen for macOS versions above 10.15, and fall back to the old implementation otherwise. * Implementing this meant adding a `uintptr` handle to the NSScreen instance in the `Monitor` struct in ruby that uses a bridged cast to interface with Objective-C. I would have preferred not to do this, but I didn't see another good way to handle getting the `NSScreen` instance that didn't involve a serious refactor. #### (all platforms) Disable monitor selection if the video driver's `hasMonitor()` is false. * Just a minor fixup; the existing behavior is that the dropdown list can be navigated and selected, but the selection does not persist. It makes more sense to just disable it if the driver doesn't support it. Co-authored-by: jcm <butt@butts.com>
このコミットが含まれているのは:
コミット
67fc9ea81b
|
@ -27,10 +27,12 @@ auto DriverSettings::construct() -> void {
|
||||||
program.videoFormatUpdate();
|
program.videoFormatUpdate();
|
||||||
videoRefresh();
|
videoRefresh();
|
||||||
});
|
});
|
||||||
|
#if !defined(PLATFORM_MACOS)
|
||||||
videoExclusiveToggle.setText("Exclusive mode").onToggle([&] {
|
videoExclusiveToggle.setText("Exclusive mode").onToggle([&] {
|
||||||
settings.video.exclusive = videoExclusiveToggle.checked();
|
settings.video.exclusive = videoExclusiveToggle.checked();
|
||||||
ruby::video.setExclusive(settings.video.exclusive);
|
ruby::video.setExclusive(settings.video.exclusive);
|
||||||
});
|
});
|
||||||
|
#endif
|
||||||
videoBlockingToggle.setText("Synchronize").onToggle([&] {
|
videoBlockingToggle.setText("Synchronize").onToggle([&] {
|
||||||
settings.video.blocking = videoBlockingToggle.checked();
|
settings.video.blocking = videoBlockingToggle.checked();
|
||||||
ruby::video.setBlocking(settings.video.blocking);
|
ruby::video.setBlocking(settings.video.blocking);
|
||||||
|
@ -48,6 +50,11 @@ auto DriverSettings::construct() -> void {
|
||||||
settings.video.threadedRenderer = videoThreadedRendererToggle.checked();
|
settings.video.threadedRenderer = videoThreadedRendererToggle.checked();
|
||||||
ruby::video.setThreadedRenderer(settings.video.threadedRenderer);
|
ruby::video.setThreadedRenderer(settings.video.threadedRenderer);
|
||||||
});
|
});
|
||||||
|
videoNativeFullScreenToggle.setText("Use native fullscreen").onToggle([&] {
|
||||||
|
settings.video.nativeFullScreen = videoNativeFullScreenToggle.checked();
|
||||||
|
ruby::video.setNativeFullScreen(settings.video.nativeFullScreen);
|
||||||
|
videoRefresh();
|
||||||
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
audioLabel.setText("Audio").setFont(Font().setBold());
|
audioLabel.setText("Audio").setFont(Font().setBold());
|
||||||
|
@ -153,13 +160,16 @@ auto DriverSettings::videoRefresh() -> void {
|
||||||
item.setText(format);
|
item.setText(format);
|
||||||
if(format == ruby::video.format()) item.setSelected();
|
if(format == ruby::video.format()) item.setSelected();
|
||||||
}
|
}
|
||||||
videoMonitorList.setEnabled(videoMonitorList.itemCount() > 1);
|
videoMonitorList.setEnabled(videoMonitorList.itemCount() > 1 && ruby::video.hasMonitor());
|
||||||
videoFormatList.setEnabled(0 && videoFormatList.itemCount() > 1);
|
videoFormatList.setEnabled(0 && videoFormatList.itemCount() > 1);
|
||||||
|
#if !defined(PLATFORM_MACOS)
|
||||||
videoExclusiveToggle.setChecked(ruby::video.exclusive()).setEnabled(ruby::video.hasExclusive());
|
videoExclusiveToggle.setChecked(ruby::video.exclusive()).setEnabled(ruby::video.hasExclusive());
|
||||||
|
#endif
|
||||||
videoBlockingToggle.setChecked(ruby::video.blocking()).setEnabled(ruby::video.hasBlocking());
|
videoBlockingToggle.setChecked(ruby::video.blocking()).setEnabled(ruby::video.hasBlocking());
|
||||||
#if defined(PLATFORM_MACOS)
|
#if defined(PLATFORM_MACOS)
|
||||||
videoColorSpaceToggle.setChecked(ruby::video.forceSRGB()).setEnabled(ruby::video.hasForceSRGB());
|
videoColorSpaceToggle.setChecked(ruby::video.forceSRGB()).setEnabled(ruby::video.hasForceSRGB());
|
||||||
videoThreadedRendererToggle.setChecked(ruby::video.threadedRenderer()).setEnabled(ruby::video.hasThreadedRenderer());
|
videoThreadedRendererToggle.setChecked(ruby::video.threadedRenderer()).setEnabled(ruby::video.hasThreadedRenderer());
|
||||||
|
videoNativeFullScreenToggle.setChecked(ruby::video.nativeFullScreen()).setEnabled(ruby::video.hasNativeFullScreen());
|
||||||
#endif
|
#endif
|
||||||
videoFlushToggle.setChecked(ruby::video.flush()).setEnabled(ruby::video.hasFlush());
|
videoFlushToggle.setChecked(ruby::video.flush()).setEnabled(ruby::video.hasFlush());
|
||||||
VerticalLayout::resize();
|
VerticalLayout::resize();
|
||||||
|
|
|
@ -58,6 +58,7 @@ auto Settings::process(bool load) -> void {
|
||||||
bind(boolean, "Video/Blocking", video.blocking);
|
bind(boolean, "Video/Blocking", video.blocking);
|
||||||
bind(boolean, "Video/PresentSRGB", video.forceSRGB);
|
bind(boolean, "Video/PresentSRGB", video.forceSRGB);
|
||||||
bind(boolean, "Video/ThreadedRenderer", video.threadedRenderer);
|
bind(boolean, "Video/ThreadedRenderer", video.threadedRenderer);
|
||||||
|
bind(boolean, "Video/NativeFullScreen", video.nativeFullScreen);
|
||||||
bind(boolean, "Video/Flush", video.flush);
|
bind(boolean, "Video/Flush", video.flush);
|
||||||
bind(string, "Video/Shader", video.shader);
|
bind(string, "Video/Shader", video.shader);
|
||||||
bind(natural, "Video/Multiplier", video.multiplier);
|
bind(natural, "Video/Multiplier", video.multiplier);
|
||||||
|
|
|
@ -13,6 +13,7 @@ struct Settings : Markup::Node {
|
||||||
bool blocking = false;
|
bool blocking = false;
|
||||||
bool forceSRGB = false;
|
bool forceSRGB = false;
|
||||||
bool threadedRenderer = true;
|
bool threadedRenderer = true;
|
||||||
|
bool nativeFullScreen = false;
|
||||||
bool flush = false;
|
bool flush = false;
|
||||||
string shader = "None";
|
string shader = "None";
|
||||||
u32 multiplier = 2;
|
u32 multiplier = 2;
|
||||||
|
@ -333,12 +334,15 @@ struct DriverSettings : VerticalLayout {
|
||||||
Label videoFormatLabel{&videoPropertyLayout, Size{0, 0}};
|
Label videoFormatLabel{&videoPropertyLayout, Size{0, 0}};
|
||||||
ComboButton videoFormatList{&videoPropertyLayout, Size{0, 0}};
|
ComboButton videoFormatList{&videoPropertyLayout, Size{0, 0}};
|
||||||
HorizontalLayout videoToggleLayout{this, Size{~0, 0}};
|
HorizontalLayout videoToggleLayout{this, Size{~0, 0}};
|
||||||
|
#if !defined(PLATFORM_MACOS)
|
||||||
CheckLabel videoExclusiveToggle{&videoToggleLayout, Size{0, 0}};
|
CheckLabel videoExclusiveToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
|
#endif
|
||||||
CheckLabel videoBlockingToggle{&videoToggleLayout, Size{0, 0}};
|
CheckLabel videoBlockingToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
CheckLabel videoFlushToggle{&videoToggleLayout, Size{0, 0}};
|
CheckLabel videoFlushToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
#if defined(PLATFORM_MACOS)
|
#if defined(PLATFORM_MACOS)
|
||||||
CheckLabel videoColorSpaceToggle{&videoToggleLayout, Size{0, 0}};
|
CheckLabel videoColorSpaceToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
CheckLabel videoThreadedRendererToggle{&videoToggleLayout, Size{0, 0}};
|
CheckLabel videoThreadedRendererToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
|
CheckLabel videoNativeFullScreenToggle{&videoToggleLayout, Size{0, 0}};
|
||||||
#endif
|
#endif
|
||||||
//
|
//
|
||||||
Label audioLabel{this, Size{~0, 0}, 5};
|
Label audioLabel{this, Size{~0, 0}, 5};
|
||||||
|
|
|
@ -31,7 +31,9 @@ struct VideoMetal : VideoDriver, Metal {
|
||||||
auto ready() -> bool override { return _ready; }
|
auto ready() -> bool override { return _ready; }
|
||||||
|
|
||||||
auto hasFullScreen() -> bool override { return true; }
|
auto hasFullScreen() -> bool override { return true; }
|
||||||
|
auto hasMonitor() -> bool override { return !_nativeFullScreen; }
|
||||||
auto hasContext() -> bool override { return true; }
|
auto hasContext() -> bool override { return true; }
|
||||||
|
auto hasFlush() -> bool override { return true; }
|
||||||
auto hasBlocking() -> bool override {
|
auto hasBlocking() -> bool override {
|
||||||
if (@available(macOS 10.15.4, *)) {
|
if (@available(macOS 10.15.4, *)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -41,31 +43,34 @@ struct VideoMetal : VideoDriver, Metal {
|
||||||
}
|
}
|
||||||
auto hasForceSRGB() -> bool override { return true; }
|
auto hasForceSRGB() -> bool override { return true; }
|
||||||
auto hasThreadedRenderer() -> bool override { return true; }
|
auto hasThreadedRenderer() -> bool override { return true; }
|
||||||
auto hasFlush() -> bool override { return true; }
|
auto hasNativeFullScreen() -> bool override { return true; }
|
||||||
auto hasShader() -> bool override { return true; }
|
auto hasShader() -> bool override { return true; }
|
||||||
|
|
||||||
auto setFullScreen(bool fullScreen) -> bool override {
|
auto setFullScreen(bool fullScreen) -> bool override {
|
||||||
/// This function implements non-idiomatic macOS fullscreen behavior that sets the window frame equal to the display's
|
// todo: fix/make consistent mouse cursor hide behavior
|
||||||
/// frame size and hides the cursor. Idiomatic fullscreen is still available via the normal stoplight window controls. This
|
|
||||||
/// version of fullscreen is desirable because it allows us to render around the camera housing on newer Macs
|
if (_nativeFullScreen) {
|
||||||
/// (important for bezel-style shaders), has snappier entrance/exit and tabbing behavior, and functions better with
|
[view.window toggleFullScreen:nil];
|
||||||
/// recording and capture software such as OBS and screen recorders. Hiding the mouse cursor is also essential to
|
|
||||||
/// rendering with appropriate frame pacing in Metal's 'direct' presentation mode.
|
|
||||||
|
|
||||||
// todo: unify with cursor auto-hide in hiro, ideally ares-wide fullscreen mode option
|
|
||||||
|
|
||||||
if (fullScreen) {
|
|
||||||
frameBeforeFullScreen = view.window.frame;
|
|
||||||
[NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
|
|
||||||
[view.window setStyleMask:NSWindowStyleMaskBorderless];
|
|
||||||
[view.window setFrame:view.window.screen.frame display:YES];
|
|
||||||
[NSCursor setHiddenUntilMouseMoves:YES];
|
|
||||||
} else {
|
} else {
|
||||||
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
|
/// This option implements non-idiomatic macOS fullscreen behavior that sets the window frame equal to the selected display's
|
||||||
[view.window setStyleMask:NSWindowStyleMaskTitled];
|
/// frame size and hides the cursor. This version of fullscreen is desirable because it allows us to render around the camera
|
||||||
[view.window setFrame:frameBeforeFullScreen display:YES];
|
/// housing on newer Macs (important for bezel-style shaders), has snappier entrance/exit and tabbing behavior, and functions
|
||||||
|
/// better with recording and capture software such as OBS.
|
||||||
|
if (fullScreen) {
|
||||||
|
auto monitor = Video::monitor(self.monitor);
|
||||||
|
NSScreen *handle = (__bridge NSScreen *)(void *)monitor.nativeHandle; //eew
|
||||||
|
frameBeforeFullScreen = view.window.frame;
|
||||||
|
[NSApp setPresentationOptions:(NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar)];
|
||||||
|
[view.window setStyleMask:NSWindowStyleMaskBorderless];
|
||||||
|
[view.window setFrame:handle.frame display:YES];
|
||||||
|
[NSCursor setHiddenUntilMouseMoves:YES];
|
||||||
|
} else {
|
||||||
|
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
|
||||||
|
[view.window setStyleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable | NSWindowStyleMaskClosable)];
|
||||||
|
[view.window setFrame:frameBeforeFullScreen display:YES];
|
||||||
|
}
|
||||||
|
[view.window makeFirstResponder:view];
|
||||||
}
|
}
|
||||||
[view.window makeFirstResponder:view];
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,6 +97,18 @@ struct VideoMetal : VideoDriver, Metal {
|
||||||
_threaded = threadedRenderer;
|
_threaded = threadedRenderer;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto setNativeFullScreen(bool nativeFullScreen) -> bool override {
|
||||||
|
_nativeFullScreen = nativeFullScreen;
|
||||||
|
if (nativeFullScreen) {
|
||||||
|
//maximize goes fullscreen
|
||||||
|
[view.window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenPrimary];
|
||||||
|
} else {
|
||||||
|
//maximize does not go fullscreen
|
||||||
|
[view.window setCollectionBehavior: NSWindowCollectionBehaviorFullScreenAuxiliary];
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto setFlush(bool flush) -> bool override {
|
auto setFlush(bool flush) -> bool override {
|
||||||
_flush = flush;
|
_flush = flush;
|
||||||
|
@ -562,15 +579,16 @@ private:
|
||||||
bool forceSRGB = self.forceSRGB;
|
bool forceSRGB = self.forceSRGB;
|
||||||
self.setForceSRGB(forceSRGB);
|
self.setForceSRGB(forceSRGB);
|
||||||
view.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable;
|
view.autoresizingMask = NSViewWidthSizable|NSViewHeightSizable;
|
||||||
|
|
||||||
_threaded = self.threadedRenderer;
|
_threaded = self.threadedRenderer;
|
||||||
|
_blocking = self.blocking;
|
||||||
|
setNativeFullScreen(self.nativeFullScreen);
|
||||||
|
|
||||||
_libra = librashader_load_instance();
|
_libra = librashader_load_instance();
|
||||||
if (!_libra.instance_loaded) {
|
if (!_libra.instance_loaded) {
|
||||||
print("Metal: Failed to load librashader: shaders will be disabled\n");
|
print("Metal: Failed to load librashader: shaders will be disabled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
_blocking = self.blocking;
|
|
||||||
|
|
||||||
initialized = true;
|
initialized = true;
|
||||||
return _ready = true;
|
return _ready = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,6 +78,7 @@ struct Metal {
|
||||||
bool _flush = false;
|
bool _flush = false;
|
||||||
bool _vrrIsSupported = false;
|
bool _vrrIsSupported = false;
|
||||||
bool _threaded = true;
|
bool _threaded = true;
|
||||||
|
bool _nativeFullScreen = false;
|
||||||
|
|
||||||
NSRect frameBeforeFullScreen = NSMakeRect(0,0,0,0);
|
NSRect frameBeforeFullScreen = NSMakeRect(0,0,0,0);
|
||||||
|
|
||||||
|
|
|
@ -76,6 +76,14 @@ auto Video::setThreadedRenderer(bool threadedRenderer) -> bool {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto Video::setNativeFullScreen(bool nativeFullScreen) -> bool {
|
||||||
|
lock_guard<recursive_mutex> lock(mutex);
|
||||||
|
if(instance->nativeFullScreen == nativeFullScreen) return true;
|
||||||
|
if(!instance->hasNativeFullScreen()) return false;
|
||||||
|
if(!instance->setNativeFullScreen(instance->nativeFullScreen = nativeFullScreen)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
auto Video::setFlush(bool flush) -> bool {
|
auto Video::setFlush(bool flush) -> bool {
|
||||||
lock_guard<recursive_mutex> lock(mutex);
|
lock_guard<recursive_mutex> lock(mutex);
|
||||||
if(instance->flush == flush) return true;
|
if(instance->flush == flush) return true;
|
||||||
|
@ -300,28 +308,33 @@ auto Video::hasMonitors() -> vector<Monitor> {
|
||||||
monitor.y = rectangle.origin.y;
|
monitor.y = rectangle.origin.y;
|
||||||
monitor.width = rectangle.size.width;
|
monitor.width = rectangle.size.width;
|
||||||
monitor.height = rectangle.size.height;
|
monitor.height = rectangle.size.height;
|
||||||
//getting the name of the monitor on macOS: "Think Different"
|
monitor.nativeHandle = (uintptr)screen;
|
||||||
auto screenDictionary = [screen deviceDescription];
|
if (@available(macOS 10.15, *)) {
|
||||||
auto screenID = [screenDictionary objectForKey:@"NSScreenNumber"];
|
monitor.name = {1 + monitors.size(), ": ", screen.localizedName.UTF8String};
|
||||||
auto displayID = [screenID unsignedIntValue];
|
} else {
|
||||||
CFUUIDRef displayUUID = CGDisplayCreateUUIDFromDisplayID(displayID);
|
//getting the name of the monitor on macOS: "Think Different"
|
||||||
io_service_t displayPort = CGDisplayGetDisplayIDFromUUID(displayUUID);
|
auto screenDictionary = [screen deviceDescription];
|
||||||
auto dictionary = IODisplayCreateInfoDictionary(displayPort, 0);
|
auto screenID = [screenDictionary objectForKey:@"NSScreenNumber"];
|
||||||
CFRetain(dictionary);
|
auto displayID = [screenID unsignedIntValue];
|
||||||
if(auto names = (CFDictionaryRef)CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
|
CFUUIDRef displayUUID = CGDisplayCreateUUIDFromDisplayID(displayID);
|
||||||
auto languageKeys = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
io_service_t displayPort = CGDisplayGetDisplayIDFromUUID(displayUUID);
|
||||||
CFDictionaryApplyFunction(names, MonitorKeyArrayCallback, (void*)languageKeys);
|
auto dictionary = IODisplayCreateInfoDictionary(displayPort, 0);
|
||||||
auto orderLanguageKeys = CFBundleCopyPreferredLocalizationsFromArray(languageKeys);
|
CFRetain(dictionary);
|
||||||
CFRelease(languageKeys);
|
if(auto names = (CFDictionaryRef)CFDictionaryGetValue(dictionary, CFSTR(kDisplayProductName))) {
|
||||||
if(orderLanguageKeys && CFArrayGetCount(orderLanguageKeys)) {
|
auto languageKeys = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
|
||||||
auto languageKey = CFArrayGetValueAtIndex(orderLanguageKeys, 0);
|
CFDictionaryApplyFunction(names, MonitorKeyArrayCallback, (void*)languageKeys);
|
||||||
auto localName = CFDictionaryGetValue(names, languageKey);
|
auto orderLanguageKeys = CFBundleCopyPreferredLocalizationsFromArray(languageKeys);
|
||||||
monitor.name = {1 + monitors.size(), ": ", [(__bridge NSString*)localName UTF8String]};
|
CFRelease(languageKeys);
|
||||||
CFRelease(localName);
|
if(orderLanguageKeys && CFArrayGetCount(orderLanguageKeys)) {
|
||||||
|
auto languageKey = CFArrayGetValueAtIndex(orderLanguageKeys, 0);
|
||||||
|
auto localName = CFDictionaryGetValue(names, languageKey);
|
||||||
|
monitor.name = {1 + monitors.size(), ": ", [(__bridge NSString*)localName UTF8String]};
|
||||||
|
CFRelease(localName);
|
||||||
|
}
|
||||||
|
CFRelease(orderLanguageKeys);
|
||||||
}
|
}
|
||||||
CFRelease(orderLanguageKeys);
|
CFRelease(dictionary);
|
||||||
}
|
}
|
||||||
CFRelease(dictionary);
|
|
||||||
monitors.append(monitor);
|
monitors.append(monitor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ struct VideoDriver {
|
||||||
virtual auto hasBlocking() -> bool { return false; }
|
virtual auto hasBlocking() -> bool { return false; }
|
||||||
virtual auto hasForceSRGB() -> bool { return false; }
|
virtual auto hasForceSRGB() -> bool { return false; }
|
||||||
virtual auto hasThreadedRenderer() -> bool { return false; }
|
virtual auto hasThreadedRenderer() -> bool { return false; }
|
||||||
|
virtual auto hasNativeFullScreen() -> bool { return false; }
|
||||||
virtual auto hasFlush() -> bool { return false; }
|
virtual auto hasFlush() -> bool { return false; }
|
||||||
virtual auto hasFormats() -> vector<string> { return {"ARGB24"}; }
|
virtual auto hasFormats() -> vector<string> { return {"ARGB24"}; }
|
||||||
virtual auto hasShader() -> bool { return false; }
|
virtual auto hasShader() -> bool { return false; }
|
||||||
|
@ -28,6 +29,7 @@ struct VideoDriver {
|
||||||
virtual auto setBlocking(bool blocking) -> bool { return true; }
|
virtual auto setBlocking(bool blocking) -> bool { return true; }
|
||||||
virtual auto setForceSRGB(bool forceSRGB) -> bool { return true; }
|
virtual auto setForceSRGB(bool forceSRGB) -> bool { return true; }
|
||||||
virtual auto setThreadedRenderer(bool threadedRenderer) -> bool { return true; }
|
virtual auto setThreadedRenderer(bool threadedRenderer) -> bool { return true; }
|
||||||
|
virtual auto setNativeFullScreen(bool nativeFullScreen) -> bool { return true; }
|
||||||
virtual auto setFlush(bool flush) -> bool { return true; }
|
virtual auto setFlush(bool flush) -> bool { return true; }
|
||||||
virtual auto setFormat(string format) -> bool { return true; }
|
virtual auto setFormat(string format) -> bool { return true; }
|
||||||
virtual auto setShader(string shader) -> bool { return true; }
|
virtual auto setShader(string shader) -> bool { return true; }
|
||||||
|
@ -52,6 +54,7 @@ protected:
|
||||||
bool blocking = false;
|
bool blocking = false;
|
||||||
bool forceSRGB = false;
|
bool forceSRGB = false;
|
||||||
bool threadedRenderer = true;
|
bool threadedRenderer = true;
|
||||||
|
bool nativeFullScreen = false;
|
||||||
bool flush = false;
|
bool flush = false;
|
||||||
string format = "ARGB24";
|
string format = "ARGB24";
|
||||||
string shader = "None";
|
string shader = "None";
|
||||||
|
@ -70,6 +73,7 @@ struct Video {
|
||||||
s32 y = 0;
|
s32 y = 0;
|
||||||
s32 width = 0;
|
s32 width = 0;
|
||||||
s32 height = 0;
|
s32 height = 0;
|
||||||
|
uintptr_t nativeHandle = 0;
|
||||||
};
|
};
|
||||||
static auto monitor(string name) -> Monitor;
|
static auto monitor(string name) -> Monitor;
|
||||||
static auto hasMonitors() -> vector<Monitor>;
|
static auto hasMonitors() -> vector<Monitor>;
|
||||||
|
@ -94,6 +98,7 @@ struct Video {
|
||||||
auto hasBlocking() -> bool { return instance->hasBlocking(); }
|
auto hasBlocking() -> bool { return instance->hasBlocking(); }
|
||||||
auto hasForceSRGB() -> bool { return instance->hasForceSRGB(); }
|
auto hasForceSRGB() -> bool { return instance->hasForceSRGB(); }
|
||||||
auto hasThreadedRenderer() -> bool { return instance->hasThreadedRenderer(); }
|
auto hasThreadedRenderer() -> bool { return instance->hasThreadedRenderer(); }
|
||||||
|
auto hasNativeFullScreen() -> bool { return instance->hasNativeFullScreen(); }
|
||||||
auto hasFlush() -> bool { return instance->hasFlush(); }
|
auto hasFlush() -> bool { return instance->hasFlush(); }
|
||||||
auto hasFormats() -> vector<string> { return instance->hasFormats(); }
|
auto hasFormats() -> vector<string> { return instance->hasFormats(); }
|
||||||
auto hasShader() -> bool { return instance->hasShader(); }
|
auto hasShader() -> bool { return instance->hasShader(); }
|
||||||
|
@ -107,6 +112,7 @@ struct Video {
|
||||||
auto blocking() -> bool { return instance->blocking; }
|
auto blocking() -> bool { return instance->blocking; }
|
||||||
auto forceSRGB() -> bool { return instance->forceSRGB; }
|
auto forceSRGB() -> bool { return instance->forceSRGB; }
|
||||||
auto threadedRenderer() -> bool { return instance->threadedRenderer; }
|
auto threadedRenderer() -> bool { return instance->threadedRenderer; }
|
||||||
|
auto nativeFullScreen() -> bool { return instance->nativeFullScreen; }
|
||||||
auto flush() -> bool { return instance->flush; }
|
auto flush() -> bool { return instance->flush; }
|
||||||
auto format() -> string { return instance->format; }
|
auto format() -> string { return instance->format; }
|
||||||
auto shader() -> string { return instance->shader; }
|
auto shader() -> string { return instance->shader; }
|
||||||
|
@ -118,6 +124,7 @@ struct Video {
|
||||||
auto setBlocking(bool blocking) -> bool;
|
auto setBlocking(bool blocking) -> bool;
|
||||||
auto setForceSRGB(bool forceSRGB) -> bool;
|
auto setForceSRGB(bool forceSRGB) -> bool;
|
||||||
auto setThreadedRenderer(bool threadedRenderer) -> bool;
|
auto setThreadedRenderer(bool threadedRenderer) -> bool;
|
||||||
|
auto setNativeFullScreen(bool nativeFullScreen) -> bool;
|
||||||
auto setFlush(bool flush) -> bool;
|
auto setFlush(bool flush) -> bool;
|
||||||
auto setFormat(string format) -> bool;
|
auto setFormat(string format) -> bool;
|
||||||
auto setShader(string shader) -> bool;
|
auto setShader(string shader) -> bool;
|
||||||
|
|
読み込み中…
新しいイシューから参照