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