Update rive-cpp to 2.0 version
[platform/core/uifw/rive-tizen.git] / submodule / skia / tools / skottie_ios_app / SkiaGLContext.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/SkColorSpace.h"
7 #include "include/core/SkSurface.h"
8 #include "include/core/SkTime.h"
9 #include "include/gpu/GrBackendSurface.h"
10 #include "include/gpu/GrDirectContext.h"
11 #include "include/gpu/gl/GrGLInterface.h"
12 #include "include/gpu/gl/GrGLTypes.h"
13
14 #import <GLKit/GLKit.h>
15 #import <UIKit/UIKit.h>
16 #import <OpenGLES/ES3/gl.h>
17
18 #include <CoreFoundation/CoreFoundation.h>
19
20 static void configure_glkview_for_skia(GLKView* view) {
21     [view setDrawableColorFormat:GLKViewDrawableColorFormatRGBA8888];
22     [view setDrawableDepthFormat:GLKViewDrawableDepthFormat24];
23     [view setDrawableStencilFormat:GLKViewDrawableStencilFormat8];
24 }
25
26 static sk_sp<SkSurface> make_gl_surface(GrDirectContext* dContext, int width, int height) {
27     static constexpr int kStencilBits = 8;
28     static constexpr int kSampleCount = 1;
29     static const SkSurfaceProps surfaceProps;
30     if (!dContext || width <= 0 || height <= 0) {
31         return nullptr;
32     }
33     GLint fboid = 0;
34     glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboid);
35     return SkSurface::MakeFromBackendRenderTarget(
36             dContext,
37             GrBackendRenderTarget(width,
38                                   height,
39                                   kSampleCount,
40                                   kStencilBits,
41                                   GrGLFramebufferInfo{(GrGLuint)fboid, GL_RGBA8}),
42             kBottomLeft_GrSurfaceOrigin,
43             kRGBA_8888_SkColorType,
44             nullptr,
45             &surfaceProps);
46 }
47
48 // A UIView that uses a GL-backed SkSurface to draw.
49 @interface SkiaGLView : GLKView
50     @property (strong) SkiaViewController* controller;
51
52     // Override of the UIView interface.
53     - (void)drawRect:(CGRect)rect;
54
55     // Required initializer.
56     - (instancetype)initWithFrame:(CGRect)frame
57                     withEAGLContext:(EAGLContext*)eaglContext
58                     withDirectContext:(GrDirectContext*)dContext;
59 @end
60
61 @implementation SkiaGLView {
62     GrDirectContext* fDContext;
63 }
64
65 - (instancetype)initWithFrame:(CGRect)frame
66                 withEAGLContext:(EAGLContext*)eaglContext
67                 withDirectContext:(GrDirectContext*)dContext {
68     self = [super initWithFrame:frame context:eaglContext];
69     fDContext = dContext;
70     configure_glkview_for_skia(self);
71     return self;
72 }
73
74 - (void)drawRect:(CGRect)rect {
75     SkiaViewController* viewController = [self controller];
76     static constexpr double kFrameRate = 1.0 / 30.0;
77     double next = [viewController isPaused] ? 0 : kFrameRate + SkTime::GetNSecs() * 1e-9;
78
79     [super drawRect:rect];
80
81     int width  = (int)[self drawableWidth],
82         height = (int)[self drawableHeight];
83     if (!(fDContext)) {
84         NSLog(@"Error: GrDirectContext missing.\n");
85         return;
86     }
87     if (sk_sp<SkSurface> surface = make_gl_surface(fDContext, width, height)) {
88         [viewController draw:rect
89                         toCanvas:(surface->getCanvas())
90                         atSize:CGSize{(CGFloat)width, (CGFloat)height}];
91         surface->flushAndSubmit();
92     }
93     if (next) {
94         [NSTimer scheduledTimerWithTimeInterval:std::max(0.0, next - SkTime::GetNSecs() * 1e-9)
95                  target:self
96                  selector:@selector(setNeedsDisplay)
97                  userInfo:nil
98                  repeats:NO];
99     }
100 }
101 @end
102
103 @interface SkiaGLContext : SkiaContext
104     @property (strong) EAGLContext* eaglContext;
105     - (instancetype) init;
106     - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame;
107     - (SkiaViewController*) getViewController:(UIView*)view;
108 @end
109
110 @implementation SkiaGLContext {
111     sk_sp<GrDirectContext> fDContext;
112 }
113 - (instancetype) init {
114     self = [super init];
115     [self setEaglContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]];
116     if (![self eaglContext]) {
117         NSLog(@"Falling back to GLES2.\n");
118         [self setEaglContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
119     }
120     if (![self eaglContext]) {
121         NSLog(@"[[EAGLContext alloc] initWithAPI:...] failed");
122         return nil;
123     }
124     EAGLContext* oldContext = [EAGLContext currentContext];
125     [EAGLContext setCurrentContext:[self eaglContext]];
126     fDContext = GrDirectContext::MakeGL(nullptr, GrContextOptions());
127     [EAGLContext setCurrentContext:oldContext];
128     if (!fDContext) {
129         NSLog(@"GrDirectContext::MakeGL failed");
130         return nil;
131     }
132     return self;
133 }
134
135 - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame {
136     SkiaGLView* skiaView = [[SkiaGLView alloc] initWithFrame:frame
137                                                withEAGLContext:[self eaglContext]
138                                                withDirectContext:fDContext.get()];
139     [skiaView setController:vc];
140     return skiaView;
141 }
142 - (SkiaViewController*) getViewController:(UIView*)view {
143     return [view isKindOfClass:[SkiaGLView class]] ? [(SkiaGLView*)view controller] : nil;
144 }
145 @end
146
147 SkiaContext* MakeSkiaGLContext() { return [[SkiaGLContext alloc] init]; }