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/ios/WindowContextFactory_ios.h" 10 11#import <Metal/Metal.h> 12#import <UIKit/UIKit.h> 13 14using skwindow::DisplayParams; 15using skwindow::IOSWindowInfo; 16using skwindow::internal::MetalWindowContext; 17 18@interface MetalView : MainView 19@end 20 21@implementation MetalView 22+ (Class) layerClass { 23 return [CAMetalLayer class]; 24} 25@end 26 27namespace { 28 29class MetalWindowContext_ios : public MetalWindowContext { 30public: 31 MetalWindowContext_ios(const IOSWindowInfo&, std::unique_ptr<const DisplayParams>); 32 33 ~MetalWindowContext_ios() override; 34 35 bool onInitializeContext() override; 36 void onDestroyContext() override; 37 38 void resize(int w, int h) override; 39 40private: 41 sk_app::Window_ios* fWindow; 42 UIViewController* fViewController; 43 MetalView* fMetalView; 44}; 45 46MetalWindowContext_ios::MetalWindowContext_ios(const IOSWindowInfo& info, 47 std::unique_ptr<const DisplayParams> params) 48 : MetalWindowContext(std::move(params)) 49 , fWindow(info.fWindow) 50 , fViewController(info.fViewController) { 51 // iOS test apps currently ignore MSAA settings. 52 53 this->initializeContext(); 54} 55 56MetalWindowContext_ios::~MetalWindowContext_ios() { 57 this->destroyContext(); 58 [fMetalView removeFromSuperview]; 59 [fMetalView release]; 60} 61 62bool MetalWindowContext_ios::onInitializeContext() { 63 SkASSERT(fWindow != nil); 64 SkASSERT(fViewController != nil); 65 66 CGRect frameRect = [fViewController.view frame]; 67 fMetalView = [[[MetalView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; 68 [fViewController.view addSubview:fMetalView]; 69 70 fMetalLayer = (CAMetalLayer*)fMetalView.layer; 71 fMetalLayer.device = fDevice.get(); 72 fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; 73 fMetalLayer.drawableSize = frameRect.size; 74 fMetalLayer.frame = frameRect; 75 76 fMetalLayer.contentsGravity = kCAGravityTopLeft; 77 78 fWidth = frameRect.size.width; 79 fHeight = frameRect.size.height; 80 81 return true; 82} 83 84void MetalWindowContext_ios::onDestroyContext() {} 85 86void MetalWindowContext_ios::resize(int w, int h) { 87 fMetalLayer.drawableSize = fMetalView.frame.size; 88 fMetalLayer.frame = fMetalView.frame; 89 fWidth = w; 90 fHeight = h; 91} 92 93} // anonymous namespace 94 95namespace skwindow { 96 97std::unique_ptr<WindowContext> MakeMetalForIOS(const IOSWindowInfo& info, 98 std::unique_ptr<const DisplayParams> params) { 99 std::unique_ptr<WindowContext> ctx(new MetalWindowContext_ios(info, std::move(params))); 100 if (!ctx->isValid()) { 101 return nullptr; 102 } 103 return ctx; 104} 105 106} // namespace skwindow 107