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 dispatch_assert_queue(dispatch_get_main_queue());
46 presenters_.try_emplace(view_id);
50 dispatch_assert_queue(dispatch_get_main_queue());
51 presenters_.erase(view_id);
55 FlutterBackingStore* backing_store_out) {
56 FlutterView* view = [view_provider_ viewForIdentifier:config->view_id];
61 CGSize size = CGSizeMake(config->size.width, config->size.height);
63 memset(backing_store_out, 0,
sizeof(FlutterBackingStore));
64 backing_store_out->struct_size =
sizeof(FlutterBackingStore);
65 backing_store_out->type = kFlutterBackingStoreTypeMetal;
66 backing_store_out->metal.struct_size =
sizeof(FlutterMetalBackingStore);
72 const FlutterLayer** layers,
73 size_t layers_count) {
74 FlutterView* view = [view_provider_ viewForIdentifier:view_id];
79 NSMutableArray* surfaces = [NSMutableArray array];
80 for (
size_t i = 0; i < layers_count; i++) {
81 const FlutterLayer* layer = layers[i];
82 if (layer->type == kFlutterLayerContentTypeBackingStore) {
84 [
FlutterSurface fromFlutterMetalTexture:&layer->backing_store->metal.texture];
89 info.
offset = CGPointMake(layer->offset.x, layer->offset.y);
91 FlutterBackingStorePresentInfo* present_info = layer->backing_store_present_info;
92 if (present_info !=
nullptr && present_info->paint_region !=
nullptr) {
93 auto paint_region = present_info->paint_region;
96 paint_region->rects, paint_region->rects + paint_region->rects_count);
98 [surfaces addObject:info];
103 CFTimeInterval presentation_time = 0;
105 if (layers_count > 0 && layers[0]->presentation_time != 0) {
106 presentation_time = [time_converter_ engineTimeToCAMediaTime:layers[0]->presentation_time];
111 auto layers_copy = std::make_shared<std::vector<LayerVariant>>(CopyLayers(layers, layers_count));
114 atTime:presentation_time
123 dispatch_assert_queue(dispatch_get_main_queue());
124 auto found_presenter = presenters_.find(view_id);
125 if (found_presenter != presenters_.end()) {
126 found_presenter->second.PresentPlatformViews(
127 view, *layers_copy, platform_view_controller_);
135 return presenters_.size();
138 FlutterCompositor::ViewPresenter::ViewPresenter()
139 : mutator_views_([NSMapTable strongToStrongObjectsMapTable]) {}
141 void FlutterCompositor::ViewPresenter::PresentPlatformViews(
143 const std::vector<LayerVariant>& layers,
145 FML_DCHECK([[NSThread currentThread] isMainThread])
146 <<
"Must be on the main thread to present platform views";
149 NSMutableArray<FlutterMutatorView*>* present_mutators = [NSMutableArray array];
151 for (
size_t i = 0; i < layers.size(); i++) {
152 const auto& layer = layers[i];
153 if (!std::holds_alternative<PlatformViewLayer>(layer)) {
156 const auto& platform_view = std::get<PlatformViewLayer>(layer);
158 PresentPlatformView(default_base_view, platform_view, i, platform_view_controller);
159 [present_mutators addObject:mutator_view];
162 [mutator_view resetHitTestRegion];
163 for (
size_t j = i + 1; j < layers.size(); j++) {
164 const auto& overlay_layer = layers[j];
165 if (!std::holds_alternative<BackingStoreLayer>(overlay_layer)) {
168 const auto& backing_store_layer = std::get<BackingStoreLayer>(overlay_layer);
169 for (
const auto& flutter_rect : backing_store_layer.paint_region) {
170 double scale = default_base_view.layer.contentsScale;
171 CGRect rect = CGRectMake(flutter_rect.left / scale, flutter_rect.top / scale,
172 (flutter_rect.right - flutter_rect.left) / scale,
173 (flutter_rect.bottom - flutter_rect.top) / scale);
174 CGRect intersection = CGRectIntersection(rect, mutator_view.frame);
175 if (!CGRectIsNull(intersection)) {
176 intersection.origin.x -= mutator_view.frame.origin.x;
177 intersection.origin.y -= mutator_view.frame.origin.y;
178 [mutator_view addHitTestIgnoreRegion:intersection];
184 NSMutableArray<FlutterMutatorView*>* obsolete_mutators =
185 [NSMutableArray arrayWithArray:[mutator_views_ objectEnumerator].allObjects];
186 [obsolete_mutators removeObjectsInArray:present_mutators];
189 [mutator_views_ removeObjectForKey:mutator.platformView];
190 [mutator removeFromSuperview];
193 [platform_view_controller disposePlatformViews];
198 const PlatformViewLayer& layer,
201 FML_DCHECK([[NSThread currentThread] isMainThread])
202 <<
"Must be on the main thread to present platform views";
204 int64_t platform_view_id = layer.identifier();
205 NSView* platform_view = [platform_view_controller platformViewWithID:platform_view_id];
207 FML_DCHECK(platform_view) <<
"Platform view not found for id: " << platform_view_id;
209 if (cursor_coordinator_ == nil) {
217 cursorCoordiator:cursor_coordinator_];
218 [mutator_views_ setObject:container forKey:platform_view];
219 [default_base_view addSubview:container];
222 container.layer.zPosition = index;
223 [container applyFlutterLayer:&layer];