Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / tools / skottie_ios_app / SkiaMetalContext.mm
1 // Copyright 2020 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 #include "tools/skottie_ios_app/SkiaContext.h"
5
6 #include "include/core/SkSurface.h"
7 #include "include/gpu/GrDirectContext.h"
8 #include "tools/skottie_ios_app/SkMetalViewBridge.h"
9
10 #import <Metal/Metal.h>
11 #import <MetalKit/MetalKit.h>
12 #import <UIKit/UIKit.h>
13
14 // A UIView that uses a Metal-backed SkSurface to draw.
15 @interface SkiaMtkView : MTKView
16     @property (strong) SkiaViewController* controller;
17
18     // Override of the MTKView interface.  Uses Skia+Metal to draw.
19     - (void)drawRect:(CGRect)rect;
20
21     // Required initializer.
22     - (instancetype)initWithFrame:(CGRect)frameRect
23                     device:(id<MTLDevice>)device
24                     queue:(id<MTLCommandQueue>)queue
25                     grDevice:(GrDirectContext*)dContext;
26 @end
27
28 @implementation SkiaMtkView {
29     id<MTLCommandQueue> fQueue;
30     GrDirectContext*    fDContext;
31 }
32
33 - (instancetype)initWithFrame:(CGRect)frameRect
34                 device:(id<MTLDevice>)mtlDevice
35                 queue:(id<MTLCommandQueue>)queue
36                 grDevice:(GrDirectContext*)dContext {
37     self = [super initWithFrame:frameRect device:mtlDevice];
38     fQueue = queue;
39     fDContext = dContext;
40     SkMtkViewConfigForSkia(self);
41     return self;
42 }
43
44 - (void)drawRect:(CGRect)rect {
45     [super drawRect:rect];
46     // TODO(halcanary): Use the rect and the InvalidationController to speed up rendering.
47     SkiaViewController* viewController = [self controller];
48     if (!viewController || ![[self currentDrawable] texture] || !fDContext) {
49         return;
50     }
51     CGSize size = [self drawableSize];
52     sk_sp<SkSurface> surface = SkMtkViewToSurface(self, fDContext);
53     if (!surface) {
54         NSLog(@"error: no sksurface");
55         return;
56     }
57     [viewController draw:rect toCanvas:surface->getCanvas() atSize:size];
58     surface->flushAndSubmit();
59     surface = nullptr;
60
61     id<MTLCommandBuffer> commandBuffer = [fQueue commandBuffer];
62     [commandBuffer presentDrawable:[self currentDrawable]];
63     [commandBuffer commit];
64
65     bool paused = [viewController isPaused];
66     [self setEnableSetNeedsDisplay:paused];
67     [self setPaused:paused];
68 }
69 @end
70
71 @interface SkiaMetalContext : SkiaContext
72     @property (strong) id<MTLDevice> metalDevice;
73     @property (strong) id<MTLCommandQueue> metalQueue;
74     - (instancetype) init;
75     - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame;
76     - (SkiaViewController*) getViewController:(UIView*)view;
77 @end
78
79 @implementation SkiaMetalContext {
80     sk_sp<GrDirectContext> fDContext;
81 }
82
83 - (instancetype) init {
84     self = [super init];
85     [self setMetalDevice:MTLCreateSystemDefaultDevice()];
86     if(![self metalDevice]) {
87         NSLog(@"Metal is not supported on this device");
88         return nil;
89     }
90     [self setMetalQueue:[[self metalDevice] newCommandQueue]];
91     fDContext = GrDirectContext::MakeMetal((__bridge void*)[self metalDevice],
92                                            (__bridge void*)[self metalQueue],
93                                            GrContextOptions());
94
95     if (!fDContext) {
96         NSLog(@"GrDirectContext::MakeMetal failed");
97         return nil;
98     }
99     return self;
100 }
101
102 - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame {
103     SkiaMtkView* skiaView = [[SkiaMtkView alloc] initWithFrame:frame
104                                                  device:[self metalDevice]
105                                                  queue:[self metalQueue]
106                                                  grDevice:fDContext.get()];
107     [skiaView setPreferredFramesPerSecond:30];
108     [skiaView setController:vc];
109     return skiaView;
110 }
111
112 - (SkiaViewController*) getViewController:(UIView*)view {
113     return [view isKindOfClass:[SkiaMtkView class]] ? [(SkiaMtkView*)view controller] : nil;
114 }
115 @end
116
117 SkiaContext* MakeSkiaMetalContext() { return [[SkiaMetalContext alloc] init]; }