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