Flutter Engine
The Flutter Engine
main.mm
Go to the documentation of this file.
1// Copyright 2019 Google LLC.
2// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
3
4// This is an example of a minimal iOS application that uses Skia to draw to
5// a Metal drawable.
6
7// Much of this code is copied from the default application created by XCode.
8
10
21#include "src/base/SkTime.h"
22
23#import <Metal/Metal.h>
24#import <MetalKit/MetalKit.h>
25#import <UIKit/UIKit.h>
26
27////////////////////////////////////////////////////////////////////////////////
28
29static void config_paint(SkPaint* paint) {
30 if (!paint->getShader()) {
32 const SkPoint points[2] = {{0, -1024}, {0, 1024}};
33 paint->setShader(SkGradientShader::MakeLinear(points, colors, nullptr, nullptr, 2,
34 SkTileMode::kClamp, 0, nullptr));
35 }
36}
37
38static void draw_example(SkSurface* surface, const SkPaint& paint, double rotation) {
39 SkCanvas* canvas = surface->getCanvas();
40 canvas->translate(surface->width() * 0.5f, surface->height() * 0.5f);
41 canvas->rotate(rotation);
42 canvas->drawPaint(paint);
43}
44
45////////////////////////////////////////////////////////////////////////////////
46
47@interface AppViewDelegate : NSObject <MTKViewDelegate>
48@property (assign, nonatomic) GrDirectContext* grContext; // non-owning pointer.
49@property (assign, nonatomic) id<MTLCommandQueue> metalQueue;
50@end
51
52@implementation AppViewDelegate {
53 SkPaint fPaint;
54}
55
56- (void)drawInMTKView:(nonnull MTKView *)view {
57 if (![self grContext] || !view) {
58 return;
59 }
60 // Do as much as possible before creating surface.
61 config_paint(&fPaint);
62 float rotation = (float)(180 * 1e-9 * SkTime::GetNSecs());
63
64 // Create surface:
66 if (!surface) {
67 NSLog(@"error: no sksurface");
68 return;
69 }
70
71 draw_example(surface.get(), fPaint, rotation);
72
73 // Must flush *and* present for this to work!
75 surface = nullptr;
76
77 id<MTLCommandBuffer> commandBuffer = [[self metalQueue] commandBuffer];
78 [commandBuffer presentDrawable:[view currentDrawable]];
79 [commandBuffer commit];
80}
81
82- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size {
83 // change anything on size change?
84}
85@end
86
87////////////////////////////////////////////////////////////////////////////////
88
89@interface AppViewController : UIViewController
90@property (strong, nonatomic) id<MTLDevice> metalDevice;
91@property (strong, nonatomic) id<MTLCommandQueue> metalQueue;
92@end
93
94@implementation AppViewController {
95 GrContextHolder fGrContext;
96}
97
98- (void)loadView {
99 [self setView:[[MTKView alloc] initWithFrame:[[UIScreen mainScreen] bounds] device:nil]];
100}
101
102- (void)viewDidLoad {
103 [super viewDidLoad];
104 if (!fGrContext) {
105 [self setMetalDevice:MTLCreateSystemDefaultDevice()];
106 [self setMetalQueue:[[self metalDevice] newCommandQueue]];
107 fGrContext = SkMetalDeviceToGrContext([self metalDevice], [self metalQueue]);
108 }
109 if (![self view] || ![self metalDevice]) {
110 NSLog(@"Metal is not supported on this device");
111 self.view = [[UIView alloc] initWithFrame:self.view.frame];
112 return;
113 }
114 MTKView* mtkView = (MTKView*)[self view];
115 [mtkView setDevice:[self metalDevice]];
116 [mtkView setBackgroundColor:[UIColor blackColor]];
117 SkMtkViewConfigForSkia(mtkView);
118 AppViewDelegate* viewDelegate = [[AppViewDelegate alloc] init];
119 [viewDelegate setGrContext:fGrContext.get()];
120 [viewDelegate setMetalQueue:[self metalQueue]];
121 [viewDelegate mtkView:mtkView drawableSizeWillChange:[mtkView bounds].size];
122 [mtkView setDelegate:viewDelegate];
123}
124@end
125
126////////////////////////////////////////////////////////////////////////////////
127
128@interface AppDelegate : UIResponder <UIApplicationDelegate>
129@property (strong, nonatomic) UIWindow *window;
130@end
131
132@implementation AppDelegate
133- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary*)opts {
134 // Override point for customization after application launch.
135 [self setWindow:[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]];
136 [[self window] setFrame:[[UIScreen mainScreen] bounds]];
137 [[self window] setRootViewController:[[AppViewController alloc] init]];
138 [[self window] makeKeyAndVisible];
139 return YES;
140}
141@end
142
143////////////////////////////////////////////////////////////////////////////////
144
145int main(int argc, char* argv[]) {
146 @autoreleasepool {
147 return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
148 }
149}
std::unique_ptr< GrDirectContext, GrContextRelease > GrContextHolder
static const int points[]
void SkMtkViewConfigForSkia(MTKView *)
sk_sp< SkSurface > SkMtkViewToSurface(MTKView *, GrRecordingContext *)
GrContextHolder SkMetalDeviceToGrContext(id< MTLDevice >, id< MTLCommandQueue >)
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawPaint(const SkPaint &paint)
Definition: SkCanvas.cpp:1668
void rotate(SkScalar degrees)
Definition: SkCanvas.cpp:1300
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
const Paint & paint
Definition: color_source.cc:38
VkSurfaceKHR surface
Definition: main.cc:49
UIWindow * window
Definition: AppDelegate.h:12
id< MTLDevice > metalDevice
Definition: main.mm:90
void loadView()
Definition: main.mm:98
id< MTLCommandQueue > metalQueue
Definition: main.mm:91
GrDirectContext * grContext
Definition: main.mm:48
id< MTLCommandQueue > metalQueue
Definition: main.mm:49
void mtkView:drawableSizeWillChange:(nonnull MTKView *view, [drawableSizeWillChange] CGSize size)
Definition: main.mm:82
char ** argv
Definition: library.h:9
constexpr SkColor4f kWhite
Definition: SkColor.h:439
constexpr SkColor4f kBlack
Definition: SkColor.h:435
PODArray< SkColor > colors
Definition: SkRecords.h:276
double GetNSecs()
Definition: SkTime.cpp:17
SK_API GrSemaphoresSubmitted Flush(sk_sp< SkSurface >)
int main(int argc, char *argv[])
Definition: main.mm:8
static void config_paint(SkPaint *paint)
Definition: main.mm:29
static void draw_example(SkSurface *surface, const SkPaint &paint, double rotation)
Definition: main.mm:38
int BOOL
Definition: windows_types.h:37