| Flutter macOS Embedder |

FlutterCompositor.mm
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h"
6 #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMutatorView.h"
7
8 #include "flutter/fml/logging.h"
9
10 namespace flutter {
11
12 namespace {
13 std::vector<PlatformViewLayerWithIndex> CopyPlatformViewLayers(const FlutterLayer** layers,
14 size_t layer_count) {
15 std::vector<PlatformViewLayerWithIndex> platform_views;
16 for (size_t i = 0; i < layer_count; i++) {
17 if (layers[i]->type == kFlutterLayerContentTypePlatformView) {
18 platform_views.push_back(std::make_pair(PlatformViewLayer(layers[i]), i));
19 }
20 }
21 return platform_views;
22 }
23 } // namespace
24
25 FlutterCompositor::FlutterCompositor(id<FlutterViewProvider> view_provider,
26 FlutterTimeConverter* time_converter,
27 FlutterPlatformViewController* platform_view_controller)
28 : view_provider_(view_provider),
29 time_converter_(time_converter),
30 platform_view_controller_(platform_view_controller),
31 mutator_views_([NSMapTable strongToStrongObjectsMapTable]) {
32 FML_CHECK(view_provider != nullptr) << "view_provider cannot be nullptr";
33 }
34
35 bool FlutterCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config,
36 FlutterBackingStore* backing_store_out) {
37 // TODO(dkwingsmt): This class only supports single-view for now. As more
38 // classes are gradually converted to multi-view, it should get the view ID
39 // from somewhere.
40 FlutterView* view = [view_provider_ viewForId:kFlutterImplicitViewId];
41 if (!view) {
42 return false;
43 }
44
45 CGSize size = CGSizeMake(config->size.width, config->size.height);
46 FlutterSurface* surface = [view.surfaceManager surfaceForSize:size];
47 memset(backing_store_out, 0, sizeof(FlutterBackingStore));
48 backing_store_out->struct_size = sizeof(FlutterBackingStore);
49 backing_store_out->type = kFlutterBackingStoreTypeMetal;
50 backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
51 backing_store_out->metal.texture = surface.asFlutterMetalTexture;
52 return true;
53 }
54
55 bool FlutterCompositor::Present(FlutterViewId view_id,
56 const FlutterLayer** layers,
57 size_t layers_count) {
58 FlutterView* view = [view_provider_ viewForId:view_id];
59 if (!view) {
60 return false;
61 }
62
63 NSMutableArray* surfaces = [NSMutableArray array];
64 for (size_t i = 0; i < layers_count; i++) {
65 const FlutterLayer* layer = layers[i];
66 if (layer->type == kFlutterLayerContentTypeBackingStore) {
67 FlutterSurface* surface =
68 [FlutterSurface fromFlutterMetalTexture:&layer->backing_store->metal.texture];
69
70 if (surface) {
71 FlutterSurfacePresentInfo* info = [[FlutterSurfacePresentInfo alloc] init];
72 info.surface = surface;
73 info.offset = CGPointMake(layer->offset.x, layer->offset.y);
74 info.zIndex = i;
75 FlutterBackingStorePresentInfo* present_info = layer->backing_store_present_info;
76 if (present_info != nullptr && present_info->paint_region != nullptr) {
77 auto paint_region = present_info->paint_region;
78 // Safe because the size of FlutterRect is not expected to change.
79 info.paintRegion = std::vector<FlutterRect>(
80 paint_region->rects, paint_region->rects + paint_region->rects_count);
81 }
82 [surfaces addObject:info];
83 }
84 }
85 }
86
87 CFTimeInterval presentation_time = 0;
88
89 if (layers_count > 0 && layers[0]->presentation_time != 0) {
90 presentation_time = [time_converter_ engineTimeToCAMediaTime:layers[0]->presentation_time];
91 }
92
93 // Notify block below may be called asynchronously, hence the need to copy
94 // the layer information instead of passing the original pointers from embedder.
95 auto platform_views_layers = std::make_shared<std::vector<PlatformViewLayerWithIndex>>(
96 CopyPlatformViewLayers(layers, layers_count));
97
98 [view.surfaceManager presentSurfaces:surfaces
99 atTime:presentation_time
100 notify:^{
101 PresentPlatformViews(view, *platform_views_layers);
102 }];
103
104 return true;
105 }
106
107 void FlutterCompositor::PresentPlatformViews(
108 FlutterView* default_base_view,
109 const std::vector<PlatformViewLayerWithIndex>& platform_views) {
110 FML_DCHECK([[NSThread currentThread] isMainThread])
111 << "Must be on the main thread to present platform views";
112
113 // Active mutator views for this frame.
114 NSMutableArray<FlutterMutatorView*>* present_mutators = [NSMutableArray array];
115
116 for (const auto& platform_view : platform_views) {
117 [present_mutators addObject:PresentPlatformView(default_base_view, platform_view.first,
118 platform_view.second)];
119 }
120
121 NSMutableArray<FlutterMutatorView*>* obsolete_mutators =
122 [NSMutableArray arrayWithArray:[mutator_views_ objectEnumerator].allObjects];
123 [obsolete_mutators removeObjectsInArray:present_mutators];
124
125 for (FlutterMutatorView* mutator in obsolete_mutators) {
126 [mutator_views_ removeObjectForKey:mutator.platformView];
127 [mutator removeFromSuperview];
128 }
129
130 [platform_view_controller_ disposePlatformViews];
131 }
132
133 FlutterMutatorView* FlutterCompositor::PresentPlatformView(FlutterView* default_base_view,
134 const PlatformViewLayer& layer,
135 size_t index) {
136 FML_DCHECK([[NSThread currentThread] isMainThread])
137 << "Must be on the main thread to present platform views";
138
139 int64_t platform_view_id = layer.identifier();
140 NSView* platform_view = [platform_view_controller_ platformViewWithID:platform_view_id];
141
142 FML_DCHECK(platform_view) << "Platform view not found for id: " << platform_view_id;
143
144 FlutterMutatorView* container = [mutator_views_ objectForKey:platform_view];
145
146 if (!container) {
147 container = [[FlutterMutatorView alloc] initWithPlatformView:platform_view];
148 [mutator_views_ setObject:container forKey:platform_view];
149 [default_base_view addSubview:container];
150 }
151
152 container.layer.zPosition = index;
153 [container applyFlutterLayer:&layer];
154
155 return container;
156 }
157
158 } // namespace flutter
FlutterMutatorView.h
FlutterView::surfaceManager
FlutterSurfaceManager * surfaceManager
Definition: FlutterView.h:69
FlutterMutatorView
Definition: FlutterMutatorView.h:42
-[FlutterSurface asFlutterMetalTexture]
FlutterMetalTexture asFlutterMetalTexture()
Definition: FlutterSurface.mm:45
FlutterPlatformViewController
Definition: FlutterPlatformViewController.h:17
kFlutterImplicitViewId
constexpr FlutterViewId kFlutterImplicitViewId
Definition: FlutterView.h:26
flutter::FlutterCompositor::Present
bool Present(FlutterViewId view_id, const FlutterLayer **layers, size_t layers_count)
Definition: FlutterCompositor.mm:55
FlutterSurface
Definition: FlutterSurface.h:16
flutter::FlutterCompositor::FlutterCompositor
FlutterCompositor(id< FlutterViewProvider > view_provider, FlutterTimeConverter *time_converter, FlutterPlatformViewController *platform_views_controller)
Definition: FlutterCompositor.mm:25
flutter::FlutterCompositor::CreateBackingStore
bool CreateBackingStore(const FlutterBackingStoreConfig *config, FlutterBackingStore *backing_store_out)
Definition: FlutterCompositor.mm:35
FlutterSurfacePresentInfo::surface
FlutterSurface * surface
Definition: FlutterSurfaceManager.h:20
flutter
Definition: AccessibilityBridgeMac.h:16
FlutterSurfacePresentInfo::offset
CGPoint offset
Definition: FlutterSurfaceManager.h:21
FlutterTimeConverter
Converts between the time representation used by Flutter Engine and CAMediaTime.
Definition: FlutterTimeConverter.h:13
FlutterSurfacePresentInfo
Definition: FlutterSurfaceManager.h:18
FlutterSurfacePresentInfo::zIndex
size_t zIndex
Definition: FlutterSurfaceManager.h:22
FlutterView
Definition: FlutterView.h:48
FlutterSurfacePresentInfo::paintRegion
std::vector< FlutterRect > paintRegion
Definition: FlutterSurfaceManager.h:23
FlutterCompositor.h
FlutterViewId
int64_t FlutterViewId
Definition: FlutterView.h:15