1cb93a386Sopenharmony_ci// Copyright 2020 Google LLC. 2cb93a386Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. 3cb93a386Sopenharmony_ci 4cb93a386Sopenharmony_ci#include "tools/skottie_ios_app/SkiaContext.h" 5cb93a386Sopenharmony_ci 6cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 7cb93a386Sopenharmony_ci#include "include/core/SkTime.h" 8cb93a386Sopenharmony_ci#include "include/utils/mac/SkCGUtils.h" 9cb93a386Sopenharmony_ci 10cb93a386Sopenharmony_ci#import <UIKit/UIKit.h> 11cb93a386Sopenharmony_ci 12cb93a386Sopenharmony_ci// A UIView that uses a CPU-backed SkSurface to draw. 13cb93a386Sopenharmony_ci@interface SkiaUIView : UIView 14cb93a386Sopenharmony_ci @property (strong) SkiaViewController* controller; 15cb93a386Sopenharmony_ci 16cb93a386Sopenharmony_ci // Override of the UIView interface. 17cb93a386Sopenharmony_ci - (void)drawRect:(CGRect)rect; 18cb93a386Sopenharmony_ci@end 19cb93a386Sopenharmony_ci 20cb93a386Sopenharmony_ci@implementation SkiaUIView { 21cb93a386Sopenharmony_ci SkBitmap fBackBuffer; 22cb93a386Sopenharmony_ci} 23cb93a386Sopenharmony_ci 24cb93a386Sopenharmony_ci- (void)drawRect:(CGRect)rect { 25cb93a386Sopenharmony_ci SkiaViewController* viewController = [self controller]; 26cb93a386Sopenharmony_ci static constexpr double kFrameRate = 1.0 / 30.0; 27cb93a386Sopenharmony_ci double next = [viewController isPaused] ? 0 : kFrameRate + SkTime::GetNSecs() * 1e-9; 28cb93a386Sopenharmony_ci [super drawRect:rect]; 29cb93a386Sopenharmony_ci CGSize size = [self bounds].size; 30cb93a386Sopenharmony_ci SkISize iSize = {(int)size.width, (int)size.height}; 31cb93a386Sopenharmony_ci if (fBackBuffer.drawsNothing() || iSize != fBackBuffer.dimensions()) { 32cb93a386Sopenharmony_ci fBackBuffer.allocN32Pixels(iSize.fWidth, iSize.fHeight); 33cb93a386Sopenharmony_ci } 34cb93a386Sopenharmony_ci fBackBuffer.eraseColor(SK_ColorTRANSPARENT); 35cb93a386Sopenharmony_ci { 36cb93a386Sopenharmony_ci SkCanvas canvas(fBackBuffer); 37cb93a386Sopenharmony_ci [viewController draw:rect toCanvas:&canvas atSize:size]; 38cb93a386Sopenharmony_ci } 39cb93a386Sopenharmony_ci SkCGDrawBitmap(UIGraphicsGetCurrentContext(), fBackBuffer, 0, 0); 40cb93a386Sopenharmony_ci if (next) { 41cb93a386Sopenharmony_ci [NSTimer scheduledTimerWithTimeInterval:std::max(0.0, next - SkTime::GetNSecs() * 1e-9) 42cb93a386Sopenharmony_ci target:self 43cb93a386Sopenharmony_ci selector:@selector(setNeedsDisplay) 44cb93a386Sopenharmony_ci userInfo:nil 45cb93a386Sopenharmony_ci repeats:NO]; 46cb93a386Sopenharmony_ci } 47cb93a386Sopenharmony_ci} 48cb93a386Sopenharmony_ci@end 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci@interface SkiaUIContext : SkiaContext 51cb93a386Sopenharmony_ci - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame; 52cb93a386Sopenharmony_ci - (SkiaViewController*) getViewController:(UIView*)view; 53cb93a386Sopenharmony_ci@end 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci@implementation SkiaUIContext 56cb93a386Sopenharmony_ci- (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame { 57cb93a386Sopenharmony_ci SkiaUIView* skiaView = [[SkiaUIView alloc] initWithFrame:frame]; 58cb93a386Sopenharmony_ci [skiaView setController:vc]; 59cb93a386Sopenharmony_ci return skiaView; 60cb93a386Sopenharmony_ci} 61cb93a386Sopenharmony_ci- (SkiaViewController*) getViewController:(UIView*)view { 62cb93a386Sopenharmony_ci return [view isKindOfClass:[SkiaUIView class]] ? [(SkiaUIView*)view controller] : nil; 63cb93a386Sopenharmony_ci} 64cb93a386Sopenharmony_ci@end 65cb93a386Sopenharmony_ci 66cb93a386Sopenharmony_ciSkiaContext* MakeSkiaUIContext() { return [[SkiaUIContext alloc] init]; } 67