1/* 2 * Copyright 2024 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/GraphiteNativeMetalWindowContext.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::GraphiteMetalWindowContext; 17 18@interface GraphiteMetalView : MainView 19@end 20 21@implementation GraphiteMetalView 22+ (Class) layerClass { 23 return [CAMetalLayer class]; 24} 25@end 26 27namespace { 28 29class GraphiteMetalWindowContext_ios : public GraphiteMetalWindowContext { 30public: 31 GraphiteMetalWindowContext_ios(const IOSWindowInfo&, std::unique_ptr<const DisplayParams>); 32 33 ~GraphiteMetalWindowContext_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 GraphiteMetalView* fMetalView; 44}; 45 46GraphiteMetalWindowContext_ios::GraphiteMetalWindowContext_ios( 47 const IOSWindowInfo& info, std::unique_ptr<const DisplayParams> params) 48 : GraphiteMetalWindowContext(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 56GraphiteMetalWindowContext_ios::~GraphiteMetalWindowContext_ios() { 57 this->destroyContext(); 58 [fMetalView removeFromSuperview]; 59 [fMetalView release]; 60} 61 62bool GraphiteMetalWindowContext_ios::onInitializeContext() { 63 SkASSERT(fWindow != nil); 64 SkASSERT(fViewController != nil); 65 66 CGRect frameRect = [fViewController.view frame]; 67 fMetalView = [[[GraphiteMetalView 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 fMetalLayer.framebufferOnly = false; 76 77 fMetalLayer.contentsGravity = kCAGravityTopLeft; 78 79 fWidth = frameRect.size.width; 80 fHeight = frameRect.size.height; 81 82 return true; 83} 84 85void GraphiteMetalWindowContext_ios::onDestroyContext() {} 86 87void GraphiteMetalWindowContext_ios::resize(int w, int h) { 88 fMetalLayer.drawableSize = fMetalView.frame.size; 89 fMetalLayer.frame = fMetalView.frame; 90 fWidth = w; 91 fHeight = h; 92} 93 94} // anonymous namespace 95 96namespace skwindow { 97 98std::unique_ptr<WindowContext> MakeGraphiteMetalForIOS( 99 const IOSWindowInfo& info, std::unique_ptr<const DisplayParams> params) { 100 std::unique_ptr<WindowContext> ctx(new GraphiteMetalWindowContext_ios(info, std::move(params))); 101 if (!ctx->isValid()) { 102 return nullptr; 103 } 104 return ctx; 105} 106 107} // namespace skwindow 108