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