xref: /aosp_15_r20/external/skia/tools/window/mac/GaneshMetalWindowContext_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#include "tools/window/mac/GaneshMetalWindowContext_mac.h"
8
9#include "tools/window/mac/MacWindowInfo.h"
10#include "tools/window/mac/MacWindowGLUtils.h"
11#include "tools/window/MetalWindowContext.h"
12#include "tools/window/mac/MacWindowInfo.h"
13
14#import <Cocoa/Cocoa.h>
15#import <QuartzCore/CAConstraintLayoutManager.h>
16
17using skwindow::DisplayParams;
18using skwindow::MacWindowInfo;
19using skwindow::internal::MetalWindowContext;
20
21namespace {
22
23class MetalWindowContext_mac : public MetalWindowContext {
24public:
25    MetalWindowContext_mac(const MacWindowInfo&, std::unique_ptr<const DisplayParams>);
26
27    ~MetalWindowContext_mac() override;
28
29    bool onInitializeContext() override;
30    void onDestroyContext() override;
31
32    void resize(int w, int h) override;
33
34private:
35    NSView* fMainView;
36};
37
38MetalWindowContext_mac::MetalWindowContext_mac(const MacWindowInfo& info,
39                                               std::unique_ptr<const DisplayParams> params)
40        : MetalWindowContext(std::move(params)), fMainView(info.fMainView) {
41    // any config code here (particularly for msaa)?
42
43    this->initializeContext();
44}
45
46MetalWindowContext_mac::~MetalWindowContext_mac() { this->destroyContext(); }
47
48bool MetalWindowContext_mac::onInitializeContext() {
49    SkASSERT(nil != fMainView);
50
51    fMetalLayer = [CAMetalLayer layer];
52    fMetalLayer.device = fDevice.get();
53    fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
54
55    // resize ignores the passed values and uses the fMainView directly.
56    this->resize(0, 0);
57
58    BOOL useVsync = fDisplayParams->disableVsync() ? NO : YES;
59    fMetalLayer.displaySyncEnabled = useVsync;  // TODO: need solution for 10.12 or lower
60    fMetalLayer.layoutManager = [CAConstraintLayoutManager layoutManager];
61    fMetalLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
62    fMetalLayer.contentsGravity = kCAGravityTopLeft;
63    fMetalLayer.magnificationFilter = kCAFilterNearest;
64    NSColorSpace* cs = fMainView.window.colorSpace;
65    fMetalLayer.colorspace = cs.CGColorSpace;
66
67    fMainView.layer = fMetalLayer;
68    fMainView.wantsLayer = YES;
69
70    return true;
71}
72
73void MetalWindowContext_mac::onDestroyContext() {}
74
75void MetalWindowContext_mac::resize(int w, int h) {
76    CGFloat backingScaleFactor = skwindow::GetBackingScaleFactor(fMainView);
77    CGSize backingSize = fMainView.bounds.size;
78    backingSize.width *= backingScaleFactor;
79    backingSize.height *= backingScaleFactor;
80
81    fMetalLayer.drawableSize = backingSize;
82    fMetalLayer.contentsScale = backingScaleFactor;
83
84    fWidth = backingSize.width;
85    fHeight = backingSize.height;
86}
87
88}  // anonymous namespace
89
90namespace skwindow {
91
92std::unique_ptr<WindowContext> MakeGaneshMetalForMac(const MacWindowInfo& info,
93                                                     std::unique_ptr<const DisplayParams> params) {
94    std::unique_ptr<WindowContext> ctx(new MetalWindowContext_mac(info, std::move(params)));
95    if (!ctx->isValid()) {
96        return nullptr;
97    }
98    return ctx;
99}
100
101}  // namespace skwindow
102