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/mac/WindowContextFactory_mac.h" 12cb93a386Sopenharmony_ci 13cb93a386Sopenharmony_ci#include <OpenGL/gl.h> 14cb93a386Sopenharmony_ci#include <Cocoa/Cocoa.h> 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ciusing sk_app::DisplayParams; 17cb93a386Sopenharmony_ciusing sk_app::window_context_factory::MacWindowInfo; 18cb93a386Sopenharmony_ciusing sk_app::GLWindowContext; 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_cinamespace { 21cb93a386Sopenharmony_ci 22cb93a386Sopenharmony_ciclass GLWindowContext_mac : public GLWindowContext { 23cb93a386Sopenharmony_cipublic: 24cb93a386Sopenharmony_ci GLWindowContext_mac(const MacWindowInfo&, const DisplayParams&); 25cb93a386Sopenharmony_ci 26cb93a386Sopenharmony_ci ~GLWindowContext_mac() override; 27cb93a386Sopenharmony_ci 28cb93a386Sopenharmony_ci void onSwapBuffers() override; 29cb93a386Sopenharmony_ci 30cb93a386Sopenharmony_ci sk_sp<const GrGLInterface> onInitializeContext() override; 31cb93a386Sopenharmony_ci void onDestroyContext() override; 32cb93a386Sopenharmony_ci 33cb93a386Sopenharmony_ci void resize(int w, int h) override; 34cb93a386Sopenharmony_ci 35cb93a386Sopenharmony_ciprivate: 36cb93a386Sopenharmony_ci void teardownContext(); 37cb93a386Sopenharmony_ci 38cb93a386Sopenharmony_ci NSView* fMainView; 39cb93a386Sopenharmony_ci NSOpenGLContext* fGLContext; 40cb93a386Sopenharmony_ci NSOpenGLPixelFormat* fPixelFormat; 41cb93a386Sopenharmony_ci 42cb93a386Sopenharmony_ci using INHERITED = GLWindowContext; 43cb93a386Sopenharmony_ci}; 44cb93a386Sopenharmony_ci 45cb93a386Sopenharmony_ciGLWindowContext_mac::GLWindowContext_mac(const MacWindowInfo& info, const DisplayParams& params) 46cb93a386Sopenharmony_ci : INHERITED(params) 47cb93a386Sopenharmony_ci , fMainView(info.fMainView) 48cb93a386Sopenharmony_ci , fGLContext(nil) { 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci // any config code here (particularly for msaa)? 51cb93a386Sopenharmony_ci 52cb93a386Sopenharmony_ci this->initializeContext(); 53cb93a386Sopenharmony_ci} 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ciGLWindowContext_mac::~GLWindowContext_mac() { 56cb93a386Sopenharmony_ci teardownContext(); 57cb93a386Sopenharmony_ci} 58cb93a386Sopenharmony_ci 59cb93a386Sopenharmony_civoid GLWindowContext_mac::teardownContext() { 60cb93a386Sopenharmony_ci [NSOpenGLContext clearCurrentContext]; 61cb93a386Sopenharmony_ci [fPixelFormat release]; 62cb93a386Sopenharmony_ci fPixelFormat = nil; 63cb93a386Sopenharmony_ci [fGLContext release]; 64cb93a386Sopenharmony_ci fGLContext = nil; 65cb93a386Sopenharmony_ci} 66cb93a386Sopenharmony_ci 67cb93a386Sopenharmony_cisk_sp<const GrGLInterface> GLWindowContext_mac::onInitializeContext() { 68cb93a386Sopenharmony_ci SkASSERT(nil != fMainView); 69cb93a386Sopenharmony_ci 70cb93a386Sopenharmony_ci if (!fGLContext) { 71cb93a386Sopenharmony_ci // set up pixel format 72cb93a386Sopenharmony_ci constexpr int kMaxAttributes = 19; 73cb93a386Sopenharmony_ci NSOpenGLPixelFormatAttribute attributes[kMaxAttributes]; 74cb93a386Sopenharmony_ci int numAttributes = 0; 75cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAAccelerated; 76cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAClosestPolicy; 77cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFADoubleBuffer; 78cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAOpenGLProfile; 79cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLProfileVersion3_2Core; 80cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAColorSize; 81cb93a386Sopenharmony_ci attributes[numAttributes++] = 24; 82cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAAlphaSize; 83cb93a386Sopenharmony_ci attributes[numAttributes++] = 8; 84cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFADepthSize; 85cb93a386Sopenharmony_ci attributes[numAttributes++] = 0; 86cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAStencilSize; 87cb93a386Sopenharmony_ci attributes[numAttributes++] = 8; 88cb93a386Sopenharmony_ci if (fDisplayParams.fMSAASampleCount > 1) { 89cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFAMultisample; 90cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFASampleBuffers; 91cb93a386Sopenharmony_ci attributes[numAttributes++] = 1; 92cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFASamples; 93cb93a386Sopenharmony_ci attributes[numAttributes++] = fDisplayParams.fMSAASampleCount; 94cb93a386Sopenharmony_ci } else { 95cb93a386Sopenharmony_ci attributes[numAttributes++] = NSOpenGLPFASampleBuffers; 96cb93a386Sopenharmony_ci attributes[numAttributes++] = 0; 97cb93a386Sopenharmony_ci } 98cb93a386Sopenharmony_ci attributes[numAttributes++] = 0; 99cb93a386Sopenharmony_ci SkASSERT(numAttributes <= kMaxAttributes); 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci fPixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; 102cb93a386Sopenharmony_ci if (nil == fPixelFormat) { 103cb93a386Sopenharmony_ci return nullptr; 104cb93a386Sopenharmony_ci } 105cb93a386Sopenharmony_ci 106cb93a386Sopenharmony_ci // create context 107cb93a386Sopenharmony_ci fGLContext = [[NSOpenGLContext alloc] initWithFormat:fPixelFormat shareContext:nil]; 108cb93a386Sopenharmony_ci if (nil == fGLContext) { 109cb93a386Sopenharmony_ci [fPixelFormat release]; 110cb93a386Sopenharmony_ci fPixelFormat = nil; 111cb93a386Sopenharmony_ci return nullptr; 112cb93a386Sopenharmony_ci } 113cb93a386Sopenharmony_ci 114cb93a386Sopenharmony_ci [fMainView setWantsBestResolutionOpenGLSurface:YES]; 115cb93a386Sopenharmony_ci [fGLContext setView:fMainView]; 116cb93a386Sopenharmony_ci } 117cb93a386Sopenharmony_ci 118cb93a386Sopenharmony_ci GLint swapInterval = fDisplayParams.fDisableVsync ? 0 : 1; 119cb93a386Sopenharmony_ci [fGLContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval]; 120cb93a386Sopenharmony_ci 121cb93a386Sopenharmony_ci // make context current 122cb93a386Sopenharmony_ci [fGLContext makeCurrentContext]; 123cb93a386Sopenharmony_ci 124cb93a386Sopenharmony_ci glClearStencil(0); 125cb93a386Sopenharmony_ci glClearColor(0, 0, 0, 255); 126cb93a386Sopenharmony_ci glStencilMask(0xffffffff); 127cb93a386Sopenharmony_ci glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT); 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci GLint stencilBits; 130cb93a386Sopenharmony_ci [fPixelFormat getValues:&stencilBits forAttribute:NSOpenGLPFAStencilSize forVirtualScreen:0]; 131cb93a386Sopenharmony_ci fStencilBits = stencilBits; 132cb93a386Sopenharmony_ci GLint sampleCount; 133cb93a386Sopenharmony_ci [fPixelFormat getValues:&sampleCount forAttribute:NSOpenGLPFASamples forVirtualScreen:0]; 134cb93a386Sopenharmony_ci fSampleCount = sampleCount; 135cb93a386Sopenharmony_ci fSampleCount = std::max(fSampleCount, 1); 136cb93a386Sopenharmony_ci 137cb93a386Sopenharmony_ci CGFloat backingScaleFactor = sk_app::GetBackingScaleFactor(fMainView); 138cb93a386Sopenharmony_ci fWidth = fMainView.bounds.size.width * backingScaleFactor; 139cb93a386Sopenharmony_ci fHeight = fMainView.bounds.size.height * backingScaleFactor; 140cb93a386Sopenharmony_ci glViewport(0, 0, fWidth, fHeight); 141cb93a386Sopenharmony_ci 142cb93a386Sopenharmony_ci return GrGLMakeNativeInterface(); 143cb93a386Sopenharmony_ci} 144cb93a386Sopenharmony_ci 145cb93a386Sopenharmony_civoid GLWindowContext_mac::onDestroyContext() { 146cb93a386Sopenharmony_ci // We only need to tear down the GLContext if we've changed the sample count. 147cb93a386Sopenharmony_ci if (fGLContext && fSampleCount != fDisplayParams.fMSAASampleCount) { 148cb93a386Sopenharmony_ci teardownContext(); 149cb93a386Sopenharmony_ci } 150cb93a386Sopenharmony_ci} 151cb93a386Sopenharmony_ci 152cb93a386Sopenharmony_civoid GLWindowContext_mac::onSwapBuffers() { 153cb93a386Sopenharmony_ci [fGLContext flushBuffer]; 154cb93a386Sopenharmony_ci} 155cb93a386Sopenharmony_ci 156cb93a386Sopenharmony_civoid GLWindowContext_mac::resize(int w, int h) { 157cb93a386Sopenharmony_ci [fGLContext update]; 158cb93a386Sopenharmony_ci 159cb93a386Sopenharmony_ci // The super class always recreates the context. 160cb93a386Sopenharmony_ci INHERITED::resize(0, 0); 161cb93a386Sopenharmony_ci} 162cb93a386Sopenharmony_ci 163cb93a386Sopenharmony_ci 164cb93a386Sopenharmony_ci} // anonymous namespace 165cb93a386Sopenharmony_ci 166cb93a386Sopenharmony_cinamespace sk_app { 167cb93a386Sopenharmony_cinamespace window_context_factory { 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_cistd::unique_ptr<WindowContext> MakeGLForMac(const MacWindowInfo& info, 170cb93a386Sopenharmony_ci const DisplayParams& params) { 171cb93a386Sopenharmony_ci std::unique_ptr<WindowContext> ctx(new GLWindowContext_mac(info, params)); 172cb93a386Sopenharmony_ci if (!ctx->isValid()) { 173cb93a386Sopenharmony_ci return nullptr; 174cb93a386Sopenharmony_ci } 175cb93a386Sopenharmony_ci return ctx; 176cb93a386Sopenharmony_ci} 177cb93a386Sopenharmony_ci 178cb93a386Sopenharmony_ci} // namespace window_context_factory 179cb93a386Sopenharmony_ci} // namespace sk_app 180