SDL  2.0
SDL_uikitmetalview.m
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2017 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 
22 /*
23  * @author Mark Callow, www.edgewise-consulting.com.
24  *
25  * Thanks to Alex Szpakowski, @slime73 on GitHub, for his gist showing
26  * how to add a CAMetalLayer backed view.
27  */
28 
29 #include "../../SDL_internal.h"
30 
31 #if SDL_VIDEO_VULKAN && SDL_VIDEO_DRIVER_UIKIT
32 
33 #import "../SDL_sysvideo.h"
34 #import "SDL_uikitwindow.h"
35 #import "SDL_uikitmetalview.h"
36 
37 #include "SDL_assert.h"
38 
39 @implementation SDL_uikitmetalview
40 
41 /* Returns a Metal-compatible layer. */
42 + (Class)layerClass
43 {
44  return [CAMetalLayer class];
45 }
46 
47 - (instancetype)initWithFrame:(CGRect)frame
48  scale:(CGFloat)scale
49  tag:(int)tag
50 {
51  if ((self = [super initWithFrame:frame])) {
52  /* Resize properly when rotated. */
53  self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
54 
55  /* Set the appropriate scale (for retina display support) */
56  self.contentScaleFactor = scale;
57  self.tag = tag;
58 
59  [self updateDrawableSize];
60  }
61 
62  return self;
63 }
64 
65 /* Set the size of the metal drawables when the view is resized. */
66 - (void)layoutSubviews
67 {
68  [super layoutSubviews];
69  [self updateDrawableSize];
70 }
71 
72 - (void)updateDrawableSize
73 {
74  CGSize size = self.bounds.size;
75  size.width *= self.contentScaleFactor;
76  size.height *= self.contentScaleFactor;
77 
78  ((CAMetalLayer *) self.layer).drawableSize = size;
79 }
80 
81 @end
82 
85 {
86  SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
87  SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
88  CGFloat scale = 1.0;
89 
90  if (window->flags & SDL_WINDOW_ALLOW_HIGHDPI) {
91  /* Set the scale to the natural scale factor of the screen - the
92  * backing dimensions of the Metal view will match the pixel
93  * dimensions of the screen rather than the dimensions in points.
94  */
95 #ifdef __IPHONE_8_0
96  if ([data.uiwindow.screen respondsToSelector:@selector(nativeScale)]) {
97  scale = data.uiwindow.screen.nativeScale;
98  } else
99 #endif
100  {
101  scale = data.uiwindow.screen.scale;
102  }
103  }
104  SDL_uikitmetalview *metalview
105  = [[SDL_uikitmetalview alloc] initWithFrame:view.frame
106  scale:scale
107  tag:METALVIEW_TAG];
108 #if 1
109  [view addSubview:metalview];
110 #else
111  /* Sets this view as the controller's view, and adds the view to
112  * the window hierarchy.
113  *
114  * Left here for information. Not used because I suspect that for correct
115  * operation it will be necesary to copy everything from the window's
116  * current SDL_uikitview instance to the SDL_uikitview portion of the
117  * SDL_metalview. The latter would be derived from SDL_uikitview rather
118  * than UIView. */
119  [metalview setSDLWindow:window];
120 #endif
121 
122  return metalview;
123 }
124 
125 void
126 UIKit_Mtl_GetDrawableSize(SDL_Window * window, int * w, int * h)
127 {
128  @autoreleasepool {
129  SDL_WindowData *data = (__bridge SDL_WindowData *)window->driverdata;
130  SDL_uikitview *view = (SDL_uikitview*)data.uiwindow.rootViewController.view;
131  SDL_uikitmetalview* metalview = [view viewWithTag:METALVIEW_TAG];
132  if (metalview) {
133  CAMetalLayer *layer = (CAMetalLayer*)metalview.layer;
134  assert(layer != NULL);
135  if (w) {
136  *w = layer.drawableSize.width;
137  }
138  if (h) {
139  *h = layer.drawableSize.height;
140  }
141  } else {
142  SDL_GetWindowSize(window, w, h);
143  }
144  }
145 }
146 
147 #endif
GLenum GLenum GLenum GLenum GLenum scale
GLfloat GLfloat GLfloat GLfloat h
void UIKit_Mtl_GetDrawableSize(SDL_Window *window, int *w, int *h)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLenum GLuint GLint GLint layer
#define assert(x)
Definition: SDL_malloc.c:1219
#define SDL_GetWindowSize
int frame
Definition: teststreaming.c:60
GLubyte GLubyte GLubyte GLubyte w
UIWindow * uiwindow
GLsizeiptr size
#define NULL
Definition: begin_code.h:164
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char int SDL_PRINTF_FORMAT_STRING const char const char SDL_SCANF_FORMAT_STRING const char return SDL_ThreadFunction const char void return Uint32 return Uint32 void
The type used to identify a window.
Definition: SDL_sysvideo.h:73
void * driverdata
Definition: SDL_sysvideo.h:111
SDL_uikitmetalview * UIKit_Mtl_AddMetalView(SDL_Window *window)
Uint32 flags
Definition: SDL_sysvideo.h:83