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