change SDL 1.2 to SDL 2.0
[platform/upstream/SDL.git] / src / video / uikit / SDL_uikitopengles.m
1 /*
2   Simple DirectMedia Layer
3   Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org>
4
5   This software is provided 'as-is', without any express or implied
6   warranty.  In no event will the authors be held liable for any damages
7   arising from the use of this software.
8
9   Permission is granted to anyone to use this software for any purpose,
10   including commercial applications, and to alter it and redistribute it
11   freely, subject to the following restrictions:
12
13   1. The origin of this software must not be misrepresented; you must not
14      claim that you wrote the original software. If you use this software
15      in a product, an acknowledgment in the product documentation would be
16      appreciated but is not required.
17   2. Altered source versions must be plainly marked as such, and must not be
18      misrepresented as being the original software.
19   3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22
23 #if SDL_VIDEO_DRIVER_UIKIT
24
25 #include "SDL_uikitopengles.h"
26 #import "SDL_uikitopenglview.h"
27 #include "SDL_uikitmodes.h"
28 #include "SDL_uikitwindow.h"
29 #include "SDL_uikitevents.h"
30 #include "../SDL_sysvideo.h"
31 #include "../../events/SDL_keyboard_c.h"
32 #include "../../events/SDL_mouse_c.h"
33 #include "../../power/uikit/SDL_syspower.h"
34 #include "SDL_loadso.h"
35 #include <dlfcn.h>
36
37 @interface SDLEAGLContext : EAGLContext
38
39 /* The OpenGL ES context owns a view / drawable. */
40 @property (nonatomic, strong) SDL_uikitopenglview *sdlView;
41
42 @end
43
44 @implementation SDLEAGLContext
45
46 - (void)dealloc
47 {
48     /* When the context is deallocated, its view should be removed from any
49      * SDL window that it's attached to. */
50     [self.sdlView setSDLWindow:NULL];
51 }
52
53 @end
54
55 void *
56 UIKit_GL_GetProcAddress(_THIS, const char *proc)
57 {
58     /* Look through all SO's for the proc symbol.  Here's why:
59      * -Looking for the path to the OpenGL Library seems not to work in the iOS Simulator.
60      * -We don't know that the path won't change in the future. */
61     return dlsym(RTLD_DEFAULT, proc);
62 }
63
64 /*
65   note that SDL_GL_DeleteContext makes it current without passing the window
66 */
67 int
68 UIKit_GL_MakeCurrent(_THIS, SDL_Window * window, SDL_GLContext context)
69 {
70     @autoreleasepool {
71         SDLEAGLContext *eaglcontext = (__bridge SDLEAGLContext *) context;
72
73         if (![EAGLContext setCurrentContext:eaglcontext]) {
74             return SDL_SetError("Could not make EAGL context current");
75         }
76
77         if (eaglcontext) {
78             [eaglcontext.sdlView setSDLWindow:window];
79         }
80     }
81
82     return 0;
83 }
84
85 void
86 UIKit_GL_GetDrawableSize(_THIS, SDL_Window * window, int * w, int * h)
87 {
88     @autoreleasepool {
89         SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
90         UIView *view = data.viewcontroller.view;
91         if ([view isKindOfClass:[SDL_uikitopenglview class]]) {
92             SDL_uikitopenglview *glview = (SDL_uikitopenglview *) view;
93             if (w) {
94                 *w = glview.backingWidth;
95             }
96             if (h) {
97                 *h = glview.backingHeight;
98             }
99         }
100     }
101 }
102
103 int
104 UIKit_GL_LoadLibrary(_THIS, const char *path)
105 {
106     /* We shouldn't pass a path to this function, since we've already loaded the
107      * library. */
108     if (path != NULL) {
109         return SDL_SetError("iOS GL Load Library just here for compatibility");
110     }
111     return 0;
112 }
113
114 void UIKit_GL_SwapWindow(_THIS, SDL_Window * window)
115 {
116     @autoreleasepool {
117         SDLEAGLContext *context = (__bridge SDLEAGLContext *) SDL_GL_GetCurrentContext();
118
119 #if SDL_POWER_UIKIT
120         /* Check once a frame to see if we should turn off the battery monitor. */
121         SDL_UIKit_UpdateBatteryMonitoring();
122 #endif
123
124         [context.sdlView swapBuffers];
125
126         /* You need to pump events in order for the OS to make changes visible.
127          * We don't pump events here because we don't want iOS application events
128          * (low memory, terminate, etc.) to happen inside low level rendering. */
129     }
130 }
131
132 SDL_GLContext
133 UIKit_GL_CreateContext(_THIS, SDL_Window * window)
134 {
135     @autoreleasepool {
136         SDLEAGLContext *context = nil;
137         SDL_uikitopenglview *view;
138         SDL_WindowData *data = (__bridge SDL_WindowData *) window->driverdata;
139         CGRect frame = UIKit_ComputeViewFrame(window, data.uiwindow.screen);
140         EAGLSharegroup *sharegroup = nil;
141         CGFloat scale = 1.0;
142         int samples = 0;
143
144         /* The EAGLRenderingAPI enum values currently map 1:1 to major GLES
145          * versions. */
146         EAGLRenderingAPI api = _this->gl_config.major_version;
147
148         if (_this->gl_config.multisamplebuffers > 0) {
149             samples = _this->gl_config.multisamplesamples;
150         }
151
152         if (_this->gl_config.share_with_current_context) {
153             EAGLContext *context = (__bridge EAGLContext *) SDL_GL_GetCurrentContext();
154             sharegroup = context.sharegroup;
155         }
156
157         if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
158             /* Set the scale to the natural scale factor of the screen - the
159              * backing dimensions of the OpenGL view will match the pixel
160              * dimensions of the screen rather than the dimensions in points. */
161 #ifdef __IPHONE_8_0
162             if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
163                 scale = data.uiwindow.screen.nativeScale;
164             } else
165 #endif
166             {
167                 scale = data.uiwindow.screen.scale;
168             }
169         }
170
171         context = [[SDLEAGLContext alloc] initWithAPI:api sharegroup:sharegroup];
172         if (!context) {
173             SDL_SetError("OpenGL ES %d context could not be created", _this->gl_config.major_version);
174             return NULL;
175         }
176
177         /* construct our view, passing in SDL's OpenGL configuration data */
178         view = [[SDL_uikitopenglview alloc] initWithFrame:frame
179                                                     scale:scale
180                                             retainBacking:_this->gl_config.retained_backing
181                                                     rBits:_this->gl_config.red_size
182                                                     gBits:_this->gl_config.green_size
183                                                     bBits:_this->gl_config.blue_size
184                                                     aBits:_this->gl_config.alpha_size
185                                                 depthBits:_this->gl_config.depth_size
186                                               stencilBits:_this->gl_config.stencil_size
187                                                      sRGB:_this->gl_config.framebuffer_srgb_capable
188                                              multisamples:samples
189                                                   context:context];
190
191         if (!view) {
192             return NULL;
193         }
194
195         /* The context owns the view / drawable. */
196         context.sdlView = view;
197
198         if (UIKit_GL_MakeCurrent(_this, window, (__bridge SDL_GLContext) context) < 0) {
199             UIKit_GL_DeleteContext(_this, (SDL_GLContext) CFBridgingRetain(context));
200             return NULL;
201         }
202
203         /* We return a +1'd context. The window's driverdata owns the view (via
204          * MakeCurrent.) */
205         return (SDL_GLContext) CFBridgingRetain(context);
206     }
207 }
208
209 void
210 UIKit_GL_DeleteContext(_THIS, SDL_GLContext context)
211 {
212     @autoreleasepool {
213         /* The context was retained in SDL_GL_CreateContext, so we release it
214          * here. The context's view will be detached from its window when the
215          * context is deallocated. */
216         CFRelease(context);
217     }
218 }
219
220 #endif /* SDL_VIDEO_DRIVER_UIKIT */
221
222 /* vi: set ts=4 sw=4 expandtab: */