mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 15:32:59 +00:00
370 lines
10 KiB
C
370 lines
10 KiB
C
|
|
static uint32_t cocoagl_gfx_ctx_get_flags(void *data)
|
|
{
|
|
uint32_t flags = 0;
|
|
cocoa_ctx_data_t *cocoa_ctx = (cocoa_ctx_data_t*)data;
|
|
|
|
BIT32_SET(flags, GFX_CTX_FLAGS_NONE);
|
|
|
|
if (cocoa_ctx->core_hw_context_enable)
|
|
BIT32_SET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT);
|
|
|
|
return flags;
|
|
}
|
|
|
|
static void cocoagl_gfx_ctx_set_flags(void *data, uint32_t flags)
|
|
{
|
|
(void)flags;
|
|
cocoa_ctx_data_t *cocoa_ctx = (cocoa_ctx_data_t*)data;
|
|
|
|
if (BIT32_GET(flags, GFX_CTX_FLAGS_GL_CORE_CONTEXT))
|
|
cocoa_ctx->core_hw_context_enable = true;
|
|
}
|
|
|
|
void *glkitview_init(void)
|
|
{
|
|
#if defined(HAVE_COCOATOUCH)
|
|
#if TARGET_OS_IOS
|
|
/* iOS Pause menu and lifecycle. */
|
|
UINib *xib = (UINib*)[UINib nibWithNibName:BOXSTRING("PauseIndicatorView") bundle:nil];
|
|
g_pause_indicator_view = [[xib instantiateWithOwner:[RetroArch_iOS get] options:nil] lastObject];
|
|
#endif
|
|
|
|
g_view = [GLKView new];
|
|
#if TARGET_OS_IOS
|
|
g_view.multipleTouchEnabled = YES;
|
|
[g_view addSubview:g_pause_indicator_view];
|
|
#endif
|
|
g_view.enableSetNeedsDisplay = NO;
|
|
|
|
return (BRIDGE void *)((GLKView*)g_view);
|
|
#else
|
|
return nsview_get_ptr();
|
|
#endif
|
|
}
|
|
|
|
#if defined(HAVE_COCOATOUCH)
|
|
void cocoagl_bind_game_view_fbo(void)
|
|
{
|
|
if (g_context)
|
|
[g_view bindDrawable];
|
|
}
|
|
#endif
|
|
|
|
static float get_from_selector(Class obj_class, id obj_id, SEL selector, CGFloat *ret)
|
|
{
|
|
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
|
|
[obj_class instanceMethodSignatureForSelector:selector]];
|
|
[invocation setSelector:selector];
|
|
[invocation setTarget:obj_id];
|
|
[invocation invoke];
|
|
[invocation getReturnValue:ret];
|
|
RELEASE(invocation);
|
|
return *ret;
|
|
}
|
|
|
|
void *get_chosen_screen(void)
|
|
{
|
|
settings_t *settings = config_get_ptr();
|
|
NSArray *screens = [RAScreen screens];
|
|
if (!screens || !settings)
|
|
return NULL;
|
|
|
|
if (settings->uints.video_monitor_index >= screens.count)
|
|
{
|
|
RARCH_WARN("video_monitor_index is greater than the number of connected monitors; using main screen instead.");
|
|
return (BRIDGE void*)screens;
|
|
}
|
|
|
|
return ((BRIDGE void*)[screens objectAtIndex:settings->uints.video_monitor_index]);
|
|
}
|
|
|
|
float get_backing_scale_factor(void)
|
|
{
|
|
static float
|
|
backing_scale_def = 0.0f;
|
|
RAScreen *screen = NULL;
|
|
|
|
(void)screen;
|
|
|
|
if (backing_scale_def != 0.0f)
|
|
return backing_scale_def;
|
|
|
|
backing_scale_def = 1.0f;
|
|
#ifdef HAVE_COCOA_METAL
|
|
screen = (BRIDGE RAScreen*)get_chosen_screen();
|
|
|
|
if (screen)
|
|
{
|
|
SEL selector = NSSelectorFromString(BOXSTRING("backingScaleFactor"));
|
|
if ([screen respondsToSelector:selector])
|
|
{
|
|
CGFloat ret;
|
|
NSView *g_view = apple_platform.renderView;
|
|
//CocoaView *g_view = (CocoaView*)nsview_get_ptr();
|
|
backing_scale_def = (float)get_from_selector
|
|
([[g_view window] class], [g_view window], selector, &ret);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
return backing_scale_def;
|
|
}
|
|
|
|
void cocoagl_gfx_ctx_update(void)
|
|
{
|
|
switch (cocoagl_api)
|
|
{
|
|
case GFX_CTX_OPENGL_API:
|
|
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
|
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
|
|
#if MAC_OS_X_VERSION_10_7
|
|
CGLUpdateContext(g_hw_ctx.CGLContextObj);
|
|
CGLUpdateContext(g_context.CGLContextObj);
|
|
#else
|
|
[g_hw_ctx update];
|
|
[g_context update];
|
|
#endif
|
|
#endif
|
|
#endif
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void cocoagl_gfx_ctx_destroy(void *data)
|
|
{
|
|
cocoa_ctx_data_t *cocoa_ctx = (cocoa_ctx_data_t*)data;
|
|
|
|
if (!cocoa_ctx)
|
|
return;
|
|
|
|
switch (cocoagl_api)
|
|
{
|
|
case GFX_CTX_OPENGL_API:
|
|
case GFX_CTX_OPENGL_ES_API:
|
|
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES)
|
|
[GLContextClass clearCurrentContext];
|
|
|
|
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
|
|
[g_context clearDrawable];
|
|
RELEASE(g_context);
|
|
RELEASE(g_format);
|
|
if (g_hw_ctx)
|
|
{
|
|
[g_hw_ctx clearDrawable];
|
|
}
|
|
RELEASE(g_hw_ctx);
|
|
#endif
|
|
[GLContextClass clearCurrentContext];
|
|
g_context = nil;
|
|
#endif
|
|
break;
|
|
case GFX_CTX_VULKAN_API:
|
|
#ifdef HAVE_VULKAN
|
|
vulkan_context_destroy(&cocoa_ctx->vk, cocoa_ctx->vk.vk_surface != VK_NULL_HANDLE);
|
|
if (cocoa_ctx->vk.context.queue_lock) {
|
|
slock_free(cocoa_ctx->vk.context.queue_lock);
|
|
}
|
|
memset(&cocoa_ctx->vk, 0, sizeof(cocoa_ctx->vk));
|
|
|
|
#endif
|
|
break;
|
|
case GFX_CTX_NONE:
|
|
default:
|
|
break;
|
|
}
|
|
|
|
free(cocoa_ctx);
|
|
}
|
|
|
|
static enum gfx_ctx_api cocoagl_gfx_ctx_get_api(void *data)
|
|
{
|
|
return cocoagl_api;
|
|
}
|
|
|
|
static void cocoagl_gfx_ctx_show_mouse(void *data, bool state)
|
|
{
|
|
(void)data;
|
|
|
|
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
|
|
if (state)
|
|
[NSCursor unhide];
|
|
else
|
|
[NSCursor hide];
|
|
#endif
|
|
}
|
|
|
|
float cocoagl_gfx_ctx_get_native_scale(void)
|
|
{
|
|
static CGFloat ret = 0.0f;
|
|
SEL selector = NSSelectorFromString(BOXSTRING("nativeScale"));
|
|
RAScreen *screen = (BRIDGE RAScreen*)get_chosen_screen();
|
|
|
|
if (ret != 0.0f)
|
|
return ret;
|
|
if (!screen)
|
|
return 0.0f;
|
|
|
|
if ([screen respondsToSelector:selector])
|
|
return (float)get_from_selector([screen class], screen, selector, &ret);
|
|
|
|
ret = 1.0f;
|
|
selector = NSSelectorFromString(BOXSTRING("scale"));
|
|
if ([screen respondsToSelector:selector])
|
|
ret = screen.scale;
|
|
return ret;
|
|
}
|
|
|
|
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
|
|
static void cocoagl_gfx_ctx_update_title(void *data, void *data2)
|
|
{
|
|
ui_window_cocoa_t view;
|
|
const ui_window_t *window = ui_companion_driver_get_window_ptr();
|
|
|
|
#if defined(HAVE_COCOA)
|
|
view.data = (CocoaView*)nsview_get_ptr();
|
|
#elif defined(HAVE_COCOA_METAL)
|
|
view.data = (BRIDGE void *)apple_platform.renderView;
|
|
#endif
|
|
|
|
if (window)
|
|
{
|
|
char title[128];
|
|
|
|
title[0] = '\0';
|
|
|
|
video_driver_get_window_title(title, sizeof(title));
|
|
|
|
if (title[0])
|
|
window->set_title(&view, title);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static bool cocoagl_gfx_ctx_get_metrics(void *data, enum display_metric_types type,
|
|
float *value)
|
|
{
|
|
RAScreen *screen = (BRIDGE RAScreen*)get_chosen_screen();
|
|
#if defined(HAVE_COCOA) || defined(HAVE_COCOA_METAL)
|
|
NSDictionary *description = [screen deviceDescription];
|
|
NSSize display_pixel_size = [[description objectForKey:NSDeviceSize] sizeValue];
|
|
CGSize display_physical_size = CGDisplayScreenSize(
|
|
[[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
|
|
|
|
float display_width = display_pixel_size.width;
|
|
float display_height = display_pixel_size.height;
|
|
float physical_width = display_physical_size.width;
|
|
float physical_height = display_physical_size.height;
|
|
float scale = get_backing_scale_factor();
|
|
float dpi = (display_width/ physical_width) * 25.4f * scale;
|
|
#elif defined(HAVE_COCOATOUCH)
|
|
float scale = cocoagl_gfx_ctx_get_native_scale();
|
|
CGRect screen_rect = [screen bounds];
|
|
float display_height = screen_rect.size.height;
|
|
float physical_width = screen_rect.size.width * scale;
|
|
float physical_height = screen_rect.size.height * scale;
|
|
float dpi = 160 * scale;
|
|
unsigned idiom_type = UI_USER_INTERFACE_IDIOM();
|
|
|
|
switch (idiom_type)
|
|
{
|
|
case -1: /* UIUserInterfaceIdiomUnspecified */
|
|
/* TODO */
|
|
break;
|
|
case UIUserInterfaceIdiomPad:
|
|
dpi = 132 * scale;
|
|
break;
|
|
case UIUserInterfaceIdiomPhone:
|
|
dpi = 163 * scale;
|
|
break;
|
|
case UIUserInterfaceIdiomTV:
|
|
case UIUserInterfaceIdiomCarPlay:
|
|
/* TODO */
|
|
break;
|
|
}
|
|
#endif
|
|
|
|
(void)display_height;
|
|
|
|
switch (type)
|
|
{
|
|
case DISPLAY_METRIC_MM_WIDTH:
|
|
*value = physical_width;
|
|
break;
|
|
case DISPLAY_METRIC_MM_HEIGHT:
|
|
*value = physical_height;
|
|
break;
|
|
case DISPLAY_METRIC_DPI:
|
|
*value = dpi;
|
|
break;
|
|
case DISPLAY_METRIC_NONE:
|
|
default:
|
|
*value = 0;
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool cocoagl_gfx_ctx_has_focus(void *data)
|
|
{
|
|
(void)data;
|
|
#if defined(HAVE_COCOATOUCH)
|
|
return ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive);
|
|
#else
|
|
return [NSApp isActive];
|
|
#endif
|
|
}
|
|
|
|
static bool cocoagl_gfx_ctx_suppress_screensaver(void *data, bool enable)
|
|
{
|
|
(void)data;
|
|
(void)enable;
|
|
|
|
return false;
|
|
}
|
|
|
|
#if !defined(HAVE_COCOATOUCH)
|
|
static bool cocoagl_gfx_ctx_has_windowed(void *data)
|
|
{
|
|
return true;
|
|
}
|
|
#endif
|
|
|
|
static void cocoagl_gfx_ctx_input_driver(void *data,
|
|
const char *name,
|
|
const input_driver_t **input, void **input_data)
|
|
{
|
|
*input = NULL;
|
|
*input_data = NULL;
|
|
}
|
|
|
|
static void cocoagl_gfx_ctx_get_video_size(void *data, unsigned* width, unsigned* height)
|
|
{
|
|
float screenscale = cocoagl_gfx_ctx_get_native_scale();
|
|
#if defined(HAVE_COCOA_METAL)
|
|
CGRect size;
|
|
GLsizei backingPixelWidth, backingPixelHeight;
|
|
#if defined(HAVE_COCOA_METAL)
|
|
NSView *g_view = apple_platform.renderView;
|
|
#elif defined(HAVE_COCOA)
|
|
CocoaView *g_view = (CocoaView*)nsview_get_ptr();
|
|
#endif
|
|
CGRect cgrect = NSRectToCGRect([g_view frame]);
|
|
#if MAC_OS_X_VERSION_10_7
|
|
SEL selector = NSSelectorFromString(BOXSTRING("convertRectToBacking:"));
|
|
if ([g_view respondsToSelector:selector])
|
|
cgrect = NSRectToCGRect([g_view convertRectToBacking:[g_view bounds]]);
|
|
#endif
|
|
backingPixelWidth = CGRectGetWidth(cgrect);
|
|
backingPixelHeight = CGRectGetHeight(cgrect);
|
|
size = CGRectMake(0, 0, backingPixelWidth, backingPixelHeight);
|
|
#else
|
|
CGRect size = g_view.bounds;
|
|
#endif
|
|
*width = CGRectGetWidth(size) * screenscale;
|
|
*height = CGRectGetHeight(size) * screenscale;
|
|
}
|