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