Flutter Engine
The Flutter Engine
GLWindowContext_ios.mm
Go to the documentation of this file.
2/*
3 * Copyright 2019 Google Inc.
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
13
14#import <OpenGLES/ES3/gl.h>
15#import <UIKit/UIKit.h>
16
20
21@interface GLView : MainView
22@end
23
24@implementation GLView
25+ (Class) layerClass {
26 return [CAEAGLLayer class];
27}
28@end
29
30namespace {
31
32class GLWindowContext_ios : public GLWindowContext {
33public:
34 GLWindowContext_ios(const IOSWindowInfo&, const DisplayParams&);
35
36 ~GLWindowContext_ios() override;
37
38 sk_sp<const GrGLInterface> onInitializeContext() override;
39 void onDestroyContext() override;
40
41 void resize(int w, int h) override;
42
43private:
44 void onSwapBuffers() override;
45
46 sk_app::Window_ios* fWindow;
47 UIViewController* fViewController;
48 GLView* fGLView;
49 EAGLContext* fGLContext;
50 GLuint fFramebuffer;
51 GLuint fRenderbuffer;
52};
53
54GLWindowContext_ios::GLWindowContext_ios(const IOSWindowInfo& info, const DisplayParams& params)
56 , fWindow(info.fWindow)
57 , fViewController(info.fViewController)
58 , fGLContext(nil) {
59
60 // iOS test apps currently ignore MSAA settings.
61
62 this->initializeContext();
63}
64
65GLWindowContext_ios::~GLWindowContext_ios() {
66 this->destroyContext();
67 [fGLView removeFromSuperview];
68 [fGLView release];
69}
70
71sk_sp<const GrGLInterface> GLWindowContext_ios::onInitializeContext() {
72 SkASSERT(nil != fViewController);
73 SkASSERT(!fGLContext);
74
75 CGRect frameRect = [fViewController.view frame];
76 fGLView = [[[GLView alloc] initWithFrame:frameRect] initWithWindow:fWindow];
77 [fViewController.view addSubview:fGLView];
78
79 fGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
80
81 if (!fGLContext)
82 {
83 SkDebugf("Could Not Create OpenGL ES Context\n");
84 return nullptr;
85 }
86
87 if (![EAGLContext setCurrentContext:fGLContext]) {
88 SkDebugf("Could Not Set OpenGL ES Context As Current\n");
89 this->onDestroyContext();
90 return nullptr;
91 }
92
93 // Set up EAGLLayer
94 CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fGLView.layer;
95 eaglLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO,
96 kEAGLDrawablePropertyColorFormat : kEAGLColorFormatRGBA8 };
97 eaglLayer.opaque = YES;
98 eaglLayer.frame = frameRect;
99 eaglLayer.contentsGravity = kCAGravityTopLeft;
100
101 // Set up framebuffer
102 glGenFramebuffers(1, &fFramebuffer);
103 glBindFramebuffer(GL_FRAMEBUFFER, fFramebuffer);
104
105 glGenRenderbuffers(1, &fRenderbuffer);
106 glBindRenderbuffer(GL_RENDERBUFFER, fRenderbuffer);
107 glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fRenderbuffer);
108
109 [fGLContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer];
110
111 GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
112 if (status != GL_FRAMEBUFFER_COMPLETE) {
113 SkDebugf("Invalid Framebuffer\n");
114 this->onDestroyContext();
115 return nullptr;
116 }
117
118 glClearStencil(0);
119 glClearColor(0, 0, 0, 255);
120 glStencilMask(0xffffffff);
121 glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
122
123 fStencilBits = 8;
124 fSampleCount = 1; // TODO: handle multisampling
125
126 fWidth = fViewController.view.frame.size.width;
127 fHeight = fViewController.view.frame.size.height;
128
129 glViewport(0, 0, fWidth, fHeight);
130
132}
133
134void GLWindowContext_ios::onDestroyContext() {
135 glDeleteFramebuffers(1, &fFramebuffer);
136 glDeleteRenderbuffers(1, &fRenderbuffer);
137 [EAGLContext setCurrentContext:nil];
138 [fGLContext release];
139 fGLContext = nil;
140}
141
142void GLWindowContext_ios::onSwapBuffers() {
143 glBindRenderbuffer(GL_RENDERBUFFER, fRenderbuffer);
144 [fGLContext presentRenderbuffer:GL_RENDERBUFFER];
145}
146
147void GLWindowContext_ios::resize(int w, int h) {
148 GLWindowContext::resize(w, h);
149}
150
151} // anonymous namespace
152
153namespace skwindow {
154
155std::unique_ptr<WindowContext> MakeGLForIOS(const IOSWindowInfo& info,
156 const DisplayParams& params) {
157 std::unique_ptr<WindowContext> ctx(new GLWindowContext_ios(info, params));
158 if (!ctx->isValid()) {
159 return nullptr;
160 }
161 return ctx;
162}
163
164} // namespace skwindow
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SkASSERT(cond)
Definition: SkAssert.h:116
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
const EmbeddedViewParams * params
Class layerClass()
SK_API sk_sp< const GrGLInterface > MakeIOS()
std::unique_ptr< WindowContext > MakeGLForIOS(const IOSWindowInfo &info, const DisplayParams &params)
SkScalar w
SkScalar h