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