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