• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1
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
9#include "include/gpu/gl/GrGLInterface.h"
10#include "tools/sk_app/GLWindowContext.h"
11#include "tools/sk_app/ios/WindowContextFactory_ios.h"
12
13#import <OpenGLES/ES3/gl.h>
14#import <UIKit/UIKit.h>
15
16using sk_app::DisplayParams;
17using sk_app::window_context_factory::IOSWindowInfo;
18using sk_app::GLWindowContext;
19
20@interface GLView : MainView
21@end
22
23@implementation GLView
24+ (Class) layerClass {
25    return [CAEAGLLayer class];
26}
27@end
28
29namespace {
30
31class GLWindowContext_ios : public GLWindowContext {
32public:
33    GLWindowContext_ios(const IOSWindowInfo&, const DisplayParams&);
34
35    ~GLWindowContext_ios() override;
36
37    void onSwapBuffers() override;
38
39    sk_sp<const GrGLInterface> onInitializeContext() override;
40    void onDestroyContext() override;
41
42    void resize(int w, int h) override;
43
44private:
45    sk_app::Window_ios*  fWindow;
46    UIViewController*    fViewController;
47    GLView*              fGLView;
48    EAGLContext*         fGLContext;
49    GLuint               fFramebuffer;
50    GLuint               fRenderbuffer;
51
52    using INHERITED = GLWindowContext;
53};
54
55GLWindowContext_ios::GLWindowContext_ios(const IOSWindowInfo& info, const DisplayParams& params)
56    : INHERITED(params)
57    , fWindow(info.fWindow)
58    , fViewController(info.fViewController)
59    , fGLContext(nil) {
60
61    // any config code here (particularly for msaa)?
62
63    this->initializeContext();
64}
65
66GLWindowContext_ios::~GLWindowContext_ios() {
67    this->destroyContext();
68    [fGLView removeFromSuperview];
69    [fGLView release];
70}
71
72sk_sp<const GrGLInterface> GLWindowContext_ios::onInitializeContext() {
73    SkASSERT(nil != fViewController);
74    SkASSERT(!fGLContext);
75
76    CGRect frameRect = [fViewController.view frame];
77    fGLView = [[[GLView alloc] initWithFrame:frameRect] initWithWindow:fWindow];
78    [fViewController.view addSubview:fGLView];
79
80    fGLContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
81
82    if (!fGLContext)
83    {
84        SkDebugf("Could Not Create OpenGL ES Context\n");
85        return nullptr;
86    }
87
88    if (![EAGLContext setCurrentContext:fGLContext]) {
89        SkDebugf("Could Not Set OpenGL ES Context As Current\n");
90        this->onDestroyContext();
91        return nullptr;
92    }
93
94    // Set up EAGLLayer
95    CAEAGLLayer* eaglLayer = (CAEAGLLayer*)fGLView.layer;
96    eaglLayer.drawableProperties = @{kEAGLDrawablePropertyRetainedBacking : @NO,
97                                     kEAGLDrawablePropertyColorFormat     : kEAGLColorFormatRGBA8 };
98    eaglLayer.opaque = YES;
99    eaglLayer.frame = frameRect;
100    eaglLayer.contentsGravity = kCAGravityTopLeft;
101
102    // Set up framebuffer
103    glGenFramebuffers(1, &fFramebuffer);
104    glBindFramebuffer(GL_FRAMEBUFFER, fFramebuffer);
105
106    glGenRenderbuffers(1, &fRenderbuffer);
107    glBindRenderbuffer(GL_RENDERBUFFER, fRenderbuffer);
108    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, fRenderbuffer);
109
110    [fGLContext renderbufferStorage:GL_RENDERBUFFER fromDrawable:eaglLayer];
111
112    GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
113    if (status != GL_FRAMEBUFFER_COMPLETE) {
114        SkDebugf("Invalid Framebuffer\n");
115        this->onDestroyContext();
116        return nullptr;
117    }
118
119    glClearStencil(0);
120    glClearColor(0, 0, 0, 255);
121    glStencilMask(0xffffffff);
122    glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
123
124    fStencilBits = 8;
125    fSampleCount = 1; // TODO: handle multisampling
126
127    fWidth = fViewController.view.frame.size.width;
128    fHeight = fViewController.view.frame.size.height;
129
130    glViewport(0, 0, fWidth, fHeight);
131
132    return GrGLMakeNativeInterface();
133}
134
135void GLWindowContext_ios::onDestroyContext() {
136    glDeleteFramebuffers(1, &fFramebuffer);
137    glDeleteRenderbuffers(1, &fRenderbuffer);
138    [EAGLContext setCurrentContext:nil];
139    [fGLContext release];
140    fGLContext = nil;
141}
142
143void GLWindowContext_ios::onSwapBuffers() {
144    glBindRenderbuffer(GL_RENDERBUFFER, fRenderbuffer);
145    [fGLContext presentRenderbuffer:GL_RENDERBUFFER];
146}
147
148void GLWindowContext_ios::resize(int w, int h) {
149    // TODO: handle rotation
150    // [fGLContext update];
151     INHERITED::resize(w, h);
152}
153
154}  // anonymous namespace
155
156namespace sk_app {
157namespace window_context_factory {
158
159std::unique_ptr<WindowContext> MakeGLForIOS(const IOSWindowInfo& info,
160                                            const DisplayParams& params) {
161    std::unique_ptr<WindowContext> ctx(new GLWindowContext_ios(info, params));
162    if (!ctx->isValid()) {
163        return nullptr;
164    }
165    return ctx;
166}
167
168}  // namespace window_context_factory
169}  // namespace sk_app
170