Flutter Engine
The Flutter Engine
SkiaGLContext.mm
Go to the documentation of this file.
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
5
15#include "src/base/SkTime.h"
16
17#import <GLKit/GLKit.h>
18#import <UIKit/UIKit.h>
19#import <OpenGLES/ES3/gl.h>
20
21#include <CoreFoundation/CoreFoundation.h>
22
23static void configure_glkview_for_skia(GLKView* view) {
24 [view setDrawableColorFormat:GLKViewDrawableColorFormatRGBA8888];
25 [view setDrawableDepthFormat:GLKViewDrawableDepthFormat24];
26 [view setDrawableStencilFormat:GLKViewDrawableStencilFormat8];
27}
28
30 static constexpr int kStencilBits = 8;
31 static constexpr int kSampleCount = 1;
32 static const SkSurfaceProps surfaceProps;
33 if (!dContext || width <= 0 || height <= 0) {
34 return nullptr;
35 }
36 GLint fboid = 0;
37 glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &fboid);
39 dContext,
41 height,
43 kStencilBits,
44 GrGLFramebufferInfo{(GrGLuint)fboid, GL_RGBA8}),
47 nullptr,
48 &surfaceProps);
49}
50
51// A UIView that uses a GL-backed SkSurface to draw.
52@interface SkiaGLView : GLKView
53 @property (strong) SkiaViewController* controller;
54
55 // Override of the UIView interface.
56 - (void)drawRect:(CGRect)rect;
57
58 // Required initializer.
59 - (instancetype)initWithFrame:(CGRect)frame
60 withEAGLContext:(EAGLContext*)eaglContext
61 withDirectContext:(GrDirectContext*)dContext;
62@end
63
64@implementation SkiaGLView {
66}
67
68- (instancetype)initWithFrame:(CGRect)frame
69 withEAGLContext:(EAGLContext*)eaglContext
70 withDirectContext:(GrDirectContext*)dContext {
71 self = [super initWithFrame:frame context:eaglContext];
72 fDContext = dContext;
74 return self;
75}
76
77- (void)drawRect:(CGRect)rect {
79 static constexpr double kFrameRate = 1.0 / 30.0;
80 double next = [viewController isPaused] ? 0 : kFrameRate + SkTime::GetNSecs() * 1e-9;
81
82 [super drawRect:rect];
83
84 int width = (int)[self drawableWidth],
85 height = (int)[self drawableHeight];
86 if (!(fDContext)) {
87 NSLog(@"Error: GrDirectContext missing.\n");
88 return;
89 }
91 [viewController draw:rect
92 toCanvas:(surface->getCanvas())
93 atSize:CGSize{(CGFloat)width, (CGFloat)height}];
95 }
96 if (next) {
97 [NSTimer scheduledTimerWithTimeInterval:std::max(0.0, next - SkTime::GetNSecs() * 1e-9)
98 target:self
99 selector:@selector(setNeedsDisplay)
100 userInfo:nil
101 repeats:NO];
102 }
103}
104@end
105
107 @property (strong) EAGLContext* eaglContext;
108 - (instancetype) init;
109 - (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame;
110 - (SkiaViewController*) getViewController:(UIView*)view;
111@end
112
113@implementation SkiaGLContext {
115}
116- (instancetype) init {
117 self = [super init];
118 [self setEaglContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]];
119 if (![self eaglContext]) {
120 NSLog(@"Falling back to GLES2.\n");
121 [self setEaglContext:[[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]];
122 }
123 if (![self eaglContext]) {
124 NSLog(@"[[EAGLContext alloc] initWithAPI:...] failed");
125 return nil;
126 }
127 EAGLContext* oldContext = [EAGLContext currentContext];
128 [EAGLContext setCurrentContext:[self eaglContext]];
130 [EAGLContext setCurrentContext:oldContext];
131 if (!fDContext) {
132 NSLog(@"GrDirectContexts::MakeGL failed");
133 return nil;
134 }
135 return self;
136}
137
138- (UIView*) makeViewWithController:(SkiaViewController*)vc withFrame:(CGRect)frame {
139 SkiaGLView* skiaView = [[SkiaGLView alloc] initWithFrame:frame
140 withEAGLContext:[self eaglContext]
141 withDirectContext:fDContext.get()];
142 [skiaView setController:vc];
143 return skiaView;
144}
145- (SkiaViewController*) getViewController:(UIView*)view {
146 return [view isKindOfClass:[SkiaGLView class]] ? [(SkiaGLView*)view controller] : nil;
147}
148@end
149
150SkiaContext* MakeSkiaGLContext() { return [[SkiaGLContext alloc] init]; }
static constexpr int kSampleCount
unsigned int GrGLuint
Definition: GrGLTypes.h:113
@ kBottomLeft_GrSurfaceOrigin
Definition: GrTypes.h:149
static float next(float f)
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
static void configure_glkview_for_skia(GLKView *view)
static sk_sp< SkSurface > make_gl_surface(GrDirectContext *dContext, int width, int height)
SkiaContext * MakeSkiaGLContext()
GrDirectContext * fDContext
void flushAndSubmit(GrSyncCpu sync=GrSyncCpu::kNo)
VkSurfaceKHR surface
Definition: main.cc:49
double frame
Definition: examples.cpp:31
EAGLContext * eaglContext
SkiaViewController * controller
void draw:toCanvas:atSize:(CGRect rect,[toCanvas] SkCanvas *canvas,[atSize] CGSize size)
FlutterViewController * viewController
instancetype initWithFrame
SK_API GrBackendRenderTarget MakeGL(int width, int height, int sampleCnt, int stencilBits, const GrGLFramebufferInfo &glInfo)
SK_API sk_sp< GrDirectContext > MakeGL(sk_sp< const GrGLInterface >, const GrContextOptions &)
static bool init()
sk_sp< SkBlender > blender SkRect rect
Definition: SkRecords.h:350
SK_API sk_sp< SkSurface > WrapBackendRenderTarget(GrRecordingContext *context, const GrBackendRenderTarget &backendRenderTarget, GrSurfaceOrigin origin, SkColorType colorType, sk_sp< SkColorSpace > colorSpace, const SkSurfaceProps *surfaceProps, RenderTargetReleaseProc releaseProc=nullptr, ReleaseContext releaseContext=nullptr)
double GetNSecs()
Definition: SkTime.cpp:17
int32_t height
int32_t width