• 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/window/GLWindowContext.h"
11#include "tools/window/mac/WindowContextFactory_mac.h"
12#include "include/gpu/ganesh/gl/mac/GrGLMakeMacInterface.h"
13
14#include <OpenGL/gl.h>
15#include <Cocoa/Cocoa.h>
16
17using skwindow::DisplayParams;
18using skwindow::MacWindowInfo;
19using skwindow::internal::GLWindowContext;
20
21namespace {
22
23class GLWindowContext_mac : public GLWindowContext {
24public:
25    GLWindowContext_mac(const MacWindowInfo&, const DisplayParams&);
26
27    ~GLWindowContext_mac() override;
28
29    sk_sp<const GrGLInterface> onInitializeContext() override;
30    void onDestroyContext() override;
31
32    void resize(int w, int h) override;
33
34private:
35    void teardownContext();
36    void onSwapBuffers() override;
37
38    NSView*              fMainView;
39    NSOpenGLContext*     fGLContext;
40    NSOpenGLPixelFormat* fPixelFormat;
41};
42
43GLWindowContext_mac::GLWindowContext_mac(const MacWindowInfo& info, const DisplayParams& params)
44        : GLWindowContext(params)
45        , fMainView(info.fMainView)
46        , fGLContext(nil) {
47
48    // any config code here (particularly for msaa)?
49
50    this->initializeContext();
51}
52
53GLWindowContext_mac::~GLWindowContext_mac() {
54    teardownContext();
55}
56
57void GLWindowContext_mac::teardownContext() {
58    [NSOpenGLContext clearCurrentContext];
59    [fPixelFormat release];
60    fPixelFormat = nil;
61    [fGLContext release];
62    fGLContext = nil;
63}
64
65sk_sp<const GrGLInterface> GLWindowContext_mac::onInitializeContext() {
66    SkASSERT(nil != fMainView);
67
68    if (!fGLContext) {
69        fPixelFormat = skwindow::GetGLPixelFormat(fDisplayParams.fMSAASampleCount);
70        if (nil == fPixelFormat) {
71            return nullptr;
72        }
73
74        // create context
75        fGLContext = [[NSOpenGLContext alloc] initWithFormat:fPixelFormat shareContext:nil];
76        if (nil == fGLContext) {
77            [fPixelFormat release];
78            fPixelFormat = nil;
79            return nullptr;
80        }
81
82        [fMainView setWantsBestResolutionOpenGLSurface:YES];
83        [fGLContext setView:fMainView];
84    }
85
86    GLint swapInterval = fDisplayParams.fDisableVsync ? 0 : 1;
87    [fGLContext setValues:&swapInterval forParameter:NSOpenGLCPSwapInterval];
88
89    // make context current
90    [fGLContext makeCurrentContext];
91
92    glClearStencil(0);
93    glClearColor(0, 0, 0, 255);
94    glStencilMask(0xffffffff);
95    glClear(GL_STENCIL_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
96
97    GLint stencilBits;
98    [fPixelFormat getValues:&stencilBits forAttribute:NSOpenGLPFAStencilSize forVirtualScreen:0];
99    fStencilBits = stencilBits;
100    GLint sampleCount;
101    [fPixelFormat getValues:&sampleCount forAttribute:NSOpenGLPFASamples forVirtualScreen:0];
102    fSampleCount = sampleCount;
103    fSampleCount = std::max(fSampleCount, 1);
104
105    CGFloat backingScaleFactor = skwindow::GetBackingScaleFactor(fMainView);
106    fWidth = fMainView.bounds.size.width * backingScaleFactor;
107    fHeight = fMainView.bounds.size.height * backingScaleFactor;
108    glViewport(0, 0, fWidth, fHeight);
109
110    return GrGLInterfaces::MakeMac();
111}
112
113void GLWindowContext_mac::onDestroyContext() {
114    // We only need to tear down the GLContext if we've changed the sample count.
115    if (fGLContext && fSampleCount != fDisplayParams.fMSAASampleCount) {
116        teardownContext();
117    }
118}
119
120void GLWindowContext_mac::onSwapBuffers() {
121    [fGLContext flushBuffer];
122}
123
124void GLWindowContext_mac::resize(int w, int h) {
125    [fGLContext update];
126
127    // The super class always recreates the context.
128    GLWindowContext::resize(0, 0);
129}
130
131
132}  // anonymous namespace
133
134namespace skwindow {
135
136std::unique_ptr<WindowContext> MakeGLForMac(const MacWindowInfo& info,
137                                            const DisplayParams& params) {
138    std::unique_ptr<WindowContext> ctx(new GLWindowContext_mac(info, params));
139    if (!ctx->isValid()) {
140        return nullptr;
141    }
142    return ctx;
143}
144
145}  // namespace skwindow
146