• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/MetalWindowContext.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::MetalWindowContext;
17
18namespace {
19
20class MetalWindowContext_mac : public MetalWindowContext {
21public:
22    MetalWindowContext_mac(const MacWindowInfo&, const DisplayParams&);
23
24    ~MetalWindowContext_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
35MetalWindowContext_mac::MetalWindowContext_mac(const MacWindowInfo& info,
36                                               const DisplayParams& params)
37    : MetalWindowContext(params)
38    , fMainView(info.fMainView) {
39
40    // any config code here (particularly for msaa)?
41
42    this->initializeContext();
43}
44
45MetalWindowContext_mac::~MetalWindowContext_mac() {
46    this->destroyContext();
47}
48
49bool MetalWindowContext_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;  // TODO: need solution for 10.12 or lower
61    fMetalLayer.layoutManager = [CAConstraintLayoutManager layoutManager];
62    fMetalLayer.autoresizingMask = kCALayerHeightSizable | kCALayerWidthSizable;
63    fMetalLayer.contentsGravity = kCAGravityTopLeft;
64    fMetalLayer.magnificationFilter = kCAFilterNearest;
65    NSColorSpace* cs = fMainView.window.colorSpace;
66    fMetalLayer.colorspace = cs.CGColorSpace;
67
68    fMainView.layer = fMetalLayer;
69    fMainView.wantsLayer = YES;
70
71    return true;
72}
73
74void MetalWindowContext_mac::onDestroyContext() {}
75
76void MetalWindowContext_mac::resize(int w, int h) {
77    CGFloat backingScaleFactor = skwindow::GetBackingScaleFactor(fMainView);
78    CGSize backingSize = fMainView.bounds.size;
79    backingSize.width *= backingScaleFactor;
80    backingSize.height *= backingScaleFactor;
81
82    fMetalLayer.drawableSize = backingSize;
83    fMetalLayer.contentsScale = backingScaleFactor;
84
85    fWidth = backingSize.width;
86    fHeight = backingSize.height;
87}
88
89}  // anonymous namespace
90
91namespace skwindow {
92
93std::unique_ptr<WindowContext> MakeMetalForMac(const MacWindowInfo& info,
94                                               const DisplayParams& params) {
95    std::unique_ptr<WindowContext> ctx(new MetalWindowContext_mac(info, params));
96    if (!ctx->isValid()) {
97        return nullptr;
98    }
99    return ctx;
100}
101
102}  // namespace skwindow
103