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/GraphiteMetalWindowContext.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&, 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(const IOSWindowInfo& info, 47 const DisplayParams& params) 48 : GraphiteMetalWindowContext(params) 49 , fWindow(info.fWindow) 50 , fViewController(info.fViewController) { 51 52 // iOS test apps currently ignore MSAA settings. 53 54 this->initializeContext(); 55} 56 57GraphiteMetalWindowContext_ios::~GraphiteMetalWindowContext_ios() { 58 this->destroyContext(); 59 [fMetalView removeFromSuperview]; 60 [fMetalView release]; 61} 62 63bool GraphiteMetalWindowContext_ios::onInitializeContext() { 64 SkASSERT(fWindow != nil); 65 SkASSERT(fViewController != nil); 66 67 CGRect frameRect = [fViewController.view frame]; 68 fMetalView = [[[GraphiteMetalView alloc] initWithFrame:frameRect] initWithWindow:fWindow]; 69 [fViewController.view addSubview:fMetalView]; 70 71 fMetalLayer = (CAMetalLayer*)fMetalView.layer; 72 fMetalLayer.device = fDevice.get(); 73 fMetalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm; 74 fMetalLayer.drawableSize = frameRect.size; 75 fMetalLayer.frame = frameRect; 76 fMetalLayer.framebufferOnly = false; 77 78 fMetalLayer.contentsGravity = kCAGravityTopLeft; 79 80 fWidth = frameRect.size.width; 81 fHeight = frameRect.size.height; 82 83 return true; 84} 85 86void GraphiteMetalWindowContext_ios::onDestroyContext() {} 87 88void GraphiteMetalWindowContext_ios::resize(int w, int h) { 89 fMetalLayer.drawableSize = fMetalView.frame.size; 90 fMetalLayer.frame = fMetalView.frame; 91 fWidth = w; 92 fHeight = h; 93} 94 95} // anonymous namespace 96 97namespace skwindow { 98 99std::unique_ptr<WindowContext> MakeGraphiteMetalForIOS(const IOSWindowInfo& info, 100 const DisplayParams& params) { 101 std::unique_ptr<WindowContext> ctx(new GraphiteMetalWindowContext_ios(info, params)); 102 if (!ctx->isValid()) { 103 return nullptr; 104 } 105 return ctx; 106} 107 108} // namespace skwindow 109