#include "../../SDL_internal.h"
#if SDL_VIDEO_DRIVER_UIKIT && (SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2)
#include "SDL_uikitopengles.h"
#import "SDL_uikitopenglview.h"
#include "SDL_uikitmodes.h"
#include "SDL_uikitwindow.h"
#include "SDL_uikitevents.h"
#include "../SDL_sysvideo.h"
#include "../../events/SDL_keyboard_c.h"
#include "../../events/SDL_mouse_c.h"
#include "../../power/uikit/SDL_syspower.h"
#include "SDL_loadso.h"
#include <dlfcn.h>
@interface SDLEAGLContext : EAGLContext
@property (nonatomic, strong) SDL_uikitopenglview *sdlView;
@end
@implementation SDLEAGLContext
- (void)dealloc
{
[self.sdlView setSDLWindow:NULL];
}
@end
void *
UIKit_GL_GetProcAddress(_THIS, const char *proc)
{
return dlsym(RTLD_DEFAULT, proc);
}
int
UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
{
@autoreleasepool {
SDLEAGLContext *eaglcontext = (__bridge SDLEAGLContext *) context;
if (![EAGLContext setCurrentContext:eaglcontext]) {
return SDL_SetError("Could not make EAGL context current");
}
if (eaglcontext) {
[eaglcontext.sdlView setSDLWindow:window];
}
}
return 0;
}
void
UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
{
@autoreleasepool {
SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
UIView *view = data.viewcontroller.view;
if ([view isKindOfClass:[SDL_uikitopenglview class]]) {
SDL_uikitopenglview *glview = (SDL_uikitopenglview *) view;
if (w) {
*w = glview.backingWidth;
}
if (h) {
*h = glview.backingHeight;
}
} else {
SDL_GetWindowSize(window, w, h);
}
}
}
int
UIKit_GL_LoadLibrary(_THIS, const char *path)
{
if (path != NULL) {
return SDL_SetError("iOS GL Load Library just here for compatibility");
}
return 0;
}
int UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
{
@autoreleasepool {
SDLEAGLContext *context = (__bridge SDLEAGLContext *) SDL_GL_GetCurrentContext();
#if SDL_POWER_UIKIT
SDL_UIKit_UpdateBatteryMonitoring();
#endif
[context.sdlView swapBuffers];
}
return 0;
}
SDL_GLContext
UIKit_GL_CreateContext(_THIS, SDL_Window * window)
{
@autoreleasepool {
SDLEAGLContext *context = nil;
SDL_uikitopenglview *view;
SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
EAGLSharegroup *sharegroup = nil;
CGFloat scale = 1.0;
int samples = 0;
int major = _this->gl_config.major_version;
int minor = _this->gl_config.minor_version;
EAGLRenderingAPI api = major;
if (major > 3 || (major == 3 && minor > 0)) {
SDL_SetError("OpenGL ES %d.%d context could not be created", major, minor);
return NULL;
}
if (_this->gl_config.multisamplebuffers > 0) {
samples = _this->gl_config.multisamplesamples;
}
if (_this->gl_config.share_with_current_context) {
EAGLContext *currContext = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
sharegroup = currContext.sharegroup;
}
if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
scale = data.uiwindow.screen.nativeScale;
}
context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup];
if (!context) {
SDL_SetError("OpenGL ES %d context could not be created", _this->gl_config.major_version);
return NULL;
}
view = [[SDL_uikitopenglview alloc] initWithFrame:frame
scale:scale
retainBacking:_this->gl_config.retained_backing
rBits:_this->gl_config.red_size
gBits:_this->gl_config.green_size
bBits:_this->gl_config.blue_size
aBits:_this->gl_config.alpha_size
depthBits:_this->gl_config.depth_size
stencilBits:_this->gl_config.stencil_size
sRGB:_this->gl_config.framebuffer_srgb_capable
multisamples:samples
context:context];
if (!view) {
return NULL;
}
context.sdlView = view;
if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
return NULL;
}
return (SDL_GLContext) CFBridgingRetain(context);
}
}
void
UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
{
@autoreleasepool {
CFRelease(context);
}
}
void
UIKit_GL_RestoreCurrentContext(void)
{
@autoreleasepool {
EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
if (context != NULL && [EAGLContext currentContext] != context) {
[EAGLContext setCurrentContext:context];
}
}
}
#endif