forked from flutter/engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathFlutterMetalRenderer.mm
More file actions
141 lines (120 loc) · 5.74 KB
/
FlutterMetalRenderer.mm
File metadata and controls
141 lines (120 loc) · 5.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMetalRenderer.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureMetal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"
#include "flutter/shell/platform/embedder/embedder.h"
#pragma mark - Static callbacks that require the engine.
static FlutterMetalTexture OnGetNextDrawableForDefaultView(FlutterEngine* engine,
const FlutterFrameInfo* frameInfo) {
// TODO(dkwingsmt): This callback only supports single-view, therefore it only
// operates on the default view. To support multi-view, we need a new callback
// that also receives a view ID, or pass the ID via FlutterFrameInfo.
uint64_t viewId = 0;
CGSize size = CGSizeMake(frameInfo->size.width, frameInfo->size.height);
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(engine.renderer);
return [metalRenderer createTextureForView:viewId size:size];
}
static bool OnPresentDrawableOfDefaultView(FlutterEngine* engine,
const FlutterMetalTexture* texture) {
// TODO(dkwingsmt): This callback only supports single-view, therefore it only
// operates on the default view. To support multi-view, we need a new callback
// that also receives a view ID.
uint64_t viewId = 0;
return [engine.renderer present:viewId];
}
static bool OnAcquireExternalTexture(FlutterEngine* engine,
int64_t textureIdentifier,
size_t width,
size_t height,
FlutterMetalExternalTexture* metalTexture) {
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(engine.renderer);
return [metalRenderer populateTextureWithIdentifier:textureIdentifier metalTexture:metalTexture];
}
#pragma mark - FlutterMetalRenderer implementation
@implementation FlutterMetalRenderer {
FlutterViewEngineProvider* _viewProvider;
FlutterDarwinContextMetalSkia* _darwinMetalContext;
}
- (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine {
self = [super initWithDelegate:self engine:flutterEngine];
if (self) {
_viewProvider = [[FlutterViewEngineProvider alloc] initWithEngine:flutterEngine];
_device = MTLCreateSystemDefaultDevice();
if (!_device) {
NSLog(@"Could not acquire Metal device.");
return nil;
}
_commandQueue = [_device newCommandQueue];
if (!_commandQueue) {
NSLog(@"Could not create Metal command queue.");
return nil;
}
_darwinMetalContext = [[FlutterDarwinContextMetalSkia alloc] initWithMTLDevice:_device
commandQueue:_commandQueue];
}
return self;
}
- (FlutterRendererConfig)createRendererConfig {
FlutterRendererConfig config = {
.type = FlutterRendererType::kMetal,
.metal.struct_size = sizeof(FlutterMetalRendererConfig),
.metal.device = (__bridge FlutterMetalDeviceHandle)_device,
.metal.present_command_queue = (__bridge FlutterMetalCommandQueueHandle)_commandQueue,
.metal.get_next_drawable_callback =
reinterpret_cast<FlutterMetalTextureCallback>(OnGetNextDrawableForDefaultView),
.metal.present_drawable_callback =
reinterpret_cast<FlutterMetalPresentCallback>(OnPresentDrawableOfDefaultView),
.metal.external_texture_frame_callback =
reinterpret_cast<FlutterMetalTextureFrameCallback>(OnAcquireExternalTexture),
};
return config;
}
#pragma mark - Embedder callback implementations.
- (FlutterMetalTexture)createTextureForView:(uint64_t)viewId size:(CGSize)size {
FlutterView* view = [_viewProvider getView:viewId];
if (view == nil) {
FML_LOG(WARNING) << "Can't create texture on a non-existent view.";
// FlutterMetalTexture has texture `null`, therefore is discarded.
return FlutterMetalTexture{};
}
FlutterMetalRenderBackingStore* backingStore =
(FlutterMetalRenderBackingStore*)[view backingStoreForSize:size];
id<MTLTexture> texture = backingStore.texture;
FlutterMetalTexture embedderTexture;
embedderTexture.struct_size = sizeof(FlutterMetalTexture);
embedderTexture.texture = (__bridge void*)texture;
embedderTexture.texture_id = reinterpret_cast<int64_t>(texture);
return embedderTexture;
}
- (BOOL)present:(uint64_t)viewId {
FlutterView* view = [_viewProvider getView:viewId];
if (view == nil) {
return NO;
}
[view present];
return YES;
}
- (void)presentWithoutContent:(uint64_t)viewId {
FlutterView* view = [_viewProvider getView:viewId];
if (view == nil) {
return;
}
[view presentWithoutContent];
}
#pragma mark - FlutterTextureRegistrar methods.
- (BOOL)populateTextureWithIdentifier:(int64_t)textureID
metalTexture:(FlutterMetalExternalTexture*)textureOut {
id<FlutterMacOSExternalTexture> texture = [self getTextureWithID:textureID];
FlutterExternalTextureMetal* metalTexture =
reinterpret_cast<FlutterExternalTextureMetal*>(texture);
return [metalTexture populateTexture:textureOut];
}
- (id<FlutterMacOSExternalTexture>)onRegisterTexture:(id<FlutterTexture>)texture {
return [[FlutterExternalTextureMetal alloc] initWithFlutterTexture:texture
darwinMetalContext:_darwinMetalContext];
}
@end