7 #include "flutter/common/constants.h"
8 #include "flutter/fml/logging.h"
13 std::vector<LayerVariant> CopyLayers(
const FlutterLayer** layers,
size_t layer_count) {
14 std::vector<LayerVariant> layers_copy;
15 for (
size_t i = 0; i < layer_count; i++) {
16 const auto& layer = layers[i];
17 if (layer->type == kFlutterLayerContentTypePlatformView) {
18 layers_copy.push_back(PlatformViewLayer(layer));
19 }
else if (layer->type == kFlutterLayerContentTypeBackingStore) {
20 std::vector<FlutterRect> rects;
21 auto present_info = layer->backing_store_present_info;
22 if (present_info !=
nullptr && present_info->paint_region !=
nullptr) {
23 rects.reserve(present_info->paint_region->rects_count);
24 std::copy(present_info->paint_region->rects,
25 present_info->paint_region->rects + present_info->paint_region->rects_count,
26 std::back_inserter(rects));
28 layers_copy.push_back(BackingStoreLayer{rects});
38 : view_provider_(view_provider),
39 time_converter_(time_converter),
40 platform_view_controller_(platform_view_controller) {
41 FML_CHECK(view_provider !=
nullptr) <<
"view_provider cannot be nullptr";
45 FlutterBackingStore* backing_store_out) {
49 FlutterView* view = [view_provider_ viewForIdentifier:kFlutterImplicitViewId];
54 CGSize size = CGSizeMake(config->size.width, config->size.height);
56 memset(backing_store_out, 0,
sizeof(FlutterBackingStore));
57 backing_store_out->struct_size =
sizeof(FlutterBackingStore);
58 backing_store_out->type = kFlutterBackingStoreTypeMetal;
59 backing_store_out->metal.struct_size =
sizeof(FlutterMetalBackingStore);
65 const FlutterLayer** layers,
66 size_t layers_count) {
67 FlutterView* view = [view_provider_ viewForIdentifier:view_id];
72 NSMutableArray* surfaces = [NSMutableArray array];
73 for (
size_t i = 0; i < layers_count; i++) {
74 const FlutterLayer* layer = layers[i];
75 if (layer->type == kFlutterLayerContentTypeBackingStore) {
77 [
FlutterSurface fromFlutterMetalTexture:&layer->backing_store->metal.texture];
82 info.
offset = CGPointMake(layer->offset.x, layer->offset.y);
84 FlutterBackingStorePresentInfo* present_info = layer->backing_store_present_info;
85 if (present_info !=
nullptr && present_info->paint_region !=
nullptr) {
86 auto paint_region = present_info->paint_region;
89 paint_region->rects, paint_region->rects + paint_region->rects_count);
91 [surfaces addObject:info];
96 CFTimeInterval presentation_time = 0;
98 if (layers_count > 0 && layers[0]->presentation_time != 0) {
99 presentation_time = [time_converter_ engineTimeToCAMediaTime:layers[0]->presentation_time];
104 auto layers_copy = std::make_shared<std::vector<LayerVariant>>(CopyLayers(layers, layers_count));
107 presentSurfaces:surfaces
108 atTime:presentation_time
111 ViewPresenter& presenter = presenters_[view_id];
112 presenter.PresentPlatformViews(view, *layers_copy, platform_view_controller_);
118 FlutterCompositor::ViewPresenter::ViewPresenter()
119 : mutator_views_([NSMapTable strongToStrongObjectsMapTable]) {}
121 void FlutterCompositor::ViewPresenter::PresentPlatformViews(
123 const std::vector<LayerVariant>& layers,
125 FML_DCHECK([[NSThread currentThread] isMainThread])
126 <<
"Must be on the main thread to present platform views";
129 NSMutableArray<FlutterMutatorView*>* present_mutators = [NSMutableArray array];
131 for (
size_t i = 0; i < layers.size(); i++) {
132 const auto& layer = layers[i];
133 if (!std::holds_alternative<PlatformViewLayer>(layer)) {
136 const auto& platform_view = std::get<PlatformViewLayer>(layer);
138 PresentPlatformView(default_base_view, platform_view, i, platform_view_controller);
139 [present_mutators addObject:mutator_view];
142 [mutator_view resetHitTestRegion];
143 for (
size_t j = i + 1; j < layers.size(); j++) {
144 const auto& overlay_layer = layers[j];
145 if (!std::holds_alternative<BackingStoreLayer>(overlay_layer)) {
148 const auto& backing_store_layer = std::get<BackingStoreLayer>(overlay_layer);
149 for (
const auto& flutter_rect : backing_store_layer.paint_region) {
150 double scale = default_base_view.layer.contentsScale;
151 CGRect rect = CGRectMake(flutter_rect.left / scale, flutter_rect.top / scale,
152 (flutter_rect.right - flutter_rect.left) / scale,
153 (flutter_rect.bottom - flutter_rect.top) / scale);
154 CGRect intersection = CGRectIntersection(rect, mutator_view.frame);
155 if (!CGRectIsNull(intersection)) {
156 intersection.origin.x -= mutator_view.frame.origin.x;
157 intersection.origin.y -= mutator_view.frame.origin.y;
158 [mutator_view addHitTestIgnoreRegion:intersection];
164 NSMutableArray<FlutterMutatorView*>* obsolete_mutators =
165 [NSMutableArray arrayWithArray:[mutator_views_ objectEnumerator].allObjects];
166 [obsolete_mutators removeObjectsInArray:present_mutators];
169 [mutator_views_ removeObjectForKey:mutator.platformView];
170 [mutator removeFromSuperview];
173 [platform_view_controller disposePlatformViews];
178 const PlatformViewLayer& layer,
181 FML_DCHECK([[NSThread currentThread] isMainThread])
182 <<
"Must be on the main thread to present platform views";
184 int64_t platform_view_id = layer.identifier();
185 NSView* platform_view = [platform_view_controller platformViewWithID:platform_view_id];
187 FML_DCHECK(platform_view) <<
"Platform view not found for id: " << platform_view_id;
189 if (cursor_coordinator_ == nil) {
197 cursorCoordiator:cursor_coordinator_];
198 [mutator_views_ setObject:container forKey:platform_view];
199 [default_base_view addSubview:container];
202 container.layer.zPosition = index;
203 [container applyFlutterLayer:&layer];