Flutter Engine
 
Loading...
Searching...
No Matches
overlay_layer_pool.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
6
9
10namespace flutter {
11
12OverlayLayer::OverlayLayer(UIView* overlay_view,
13 UIView* overlay_view_wrapper,
14 std::unique_ptr<IOSSurface> ios_surface,
15 std::unique_ptr<Surface> surface)
16 : overlay_view(overlay_view),
17 overlay_view_wrapper(overlay_view_wrapper),
18 ios_surface(std::move(ios_surface)),
19 surface(std::move(surface)) {};
20
21void OverlayLayer::UpdateViewState(UIView* flutter_view,
22 DlRect rect,
23 int64_t view_id,
24 int64_t overlay_id) {
25 auto screenScale = [UIScreen mainScreen].scale;
26 // Set the size of the overlay view wrapper.
27 // This wrapper view masks the overlay view.
29 CGRectMake(rect.GetX() / screenScale, rect.GetY() / screenScale,
30 rect.GetWidth() / screenScale, rect.GetHeight() / screenScale);
31 // Set a unique view identifier, so the overlay_view_wrapper can be identified in XCUITests.
32 overlay_view_wrapper.accessibilityIdentifier =
33 [NSString stringWithFormat:@"platform_view[%lld].overlay[%lld]", view_id, overlay_id];
34
35 // Set the size of the overlay view.
36 // This size is equal to the device screen size.
37 overlay_view.frame = [flutter_view convertRect:flutter_view.bounds toView:overlay_view_wrapper];
38 // Set a unique view identifier, so the overlay_view can be identified in XCUITests.
39 overlay_view.accessibilityIdentifier =
40 [NSString stringWithFormat:@"platform_view[%lld].overlay_view[%lld]", view_id, overlay_id];
41}
42
43// OverlayLayerPool
44////////////////////////////////////////////////////////
45
46std::shared_ptr<OverlayLayer> OverlayLayerPool::GetNextLayer() {
47 std::shared_ptr<OverlayLayer> result;
48 if (available_layer_index_ < layers_.size()) {
49 result = layers_[available_layer_index_];
50 available_layer_index_++;
51 }
52
53 return result;
54}
55
56void OverlayLayerPool::CreateLayer(const std::shared_ptr<IOSContext>& ios_context,
57 MTLPixelFormat pixel_format) {
58 FML_DCHECK([[NSThread currentThread] isMainThread]);
59 std::shared_ptr<OverlayLayer> layer;
60 UIView* overlay_view;
61 UIView* overlay_view_wrapper;
62
63 CGFloat screenScale = [UIScreen mainScreen].scale;
64 overlay_view = [[FlutterOverlayView alloc] initWithContentsScale:screenScale
65 pixelFormat:pixel_format];
66 overlay_view_wrapper = [[FlutterOverlayView alloc] initWithContentsScale:screenScale
67 pixelFormat:pixel_format];
68
69 CALayer* ca_layer = overlay_view.layer;
70 std::unique_ptr<IOSSurface> ios_surface = IOSSurface::Create(ios_context, ca_layer);
71 std::unique_ptr<Surface> surface = ios_surface->CreateGPUSurface();
72
73 layer = std::make_shared<OverlayLayer>(overlay_view, overlay_view_wrapper, std::move(ios_surface),
74 std::move(surface));
75
76 // The overlay view wrapper masks the overlay view.
77 // This is required to keep the backing surface size unchanged between frames.
78 //
79 // Otherwise, changing the size of the overlay would require a new surface,
80 // which can be very expensive.
81 //
82 // This is the case of an animation in which the overlay size is changing in every frame.
83 //
84 // +------------------------+
85 // | overlay_view |
86 // | +--------------+ | +--------------+
87 // | | wrapper | | == mask => | overlay_view |
88 // | +--------------+ | +--------------+
89 // +------------------------+
90 layer->overlay_view_wrapper.clipsToBounds = YES;
91 [layer->overlay_view_wrapper addSubview:layer->overlay_view];
92
93 layers_.push_back(layer);
94}
95
97 available_layer_index_ = 0;
98}
99
100std::vector<std::shared_ptr<OverlayLayer>> OverlayLayerPool::RemoveUnusedLayers() {
101 std::vector<std::shared_ptr<OverlayLayer>> results;
102 for (size_t i = available_layer_index_; i < layers_.size(); i++) {
103 results.push_back(layers_[i]);
104 }
105 // Leave at least one overlay layer, to work around cases where scrolling
106 // platform views under an app bar continually adds and removes an
107 // overlay layer. This logic could be removed if https://github.com/flutter/flutter/issues/150646
108 // is fixed.
109 static constexpr size_t kLeakLayerCount = 1;
110 size_t erase_offset = std::max(available_layer_index_, kLeakLayerCount);
111 if (erase_offset < layers_.size()) {
112 layers_.erase(layers_.begin() + erase_offset, layers_.end());
113 }
114 return results;
115}
116
118 return layers_.size();
119}
120
121} // namespace flutter
static std::unique_ptr< IOSSurface > Create(std::shared_ptr< IOSContext > context, CALayer *layer)
void RecycleLayers()
Marks the layers in the pool as available for reuse.
std::vector< std::shared_ptr< OverlayLayer > > RemoveUnusedLayers()
Removes unused layers from the pool. Returns the unused layers.
size_t size() const
The count of layers currently in the pool.
std::shared_ptr< OverlayLayer > GetNextLayer()
Gets a layer from the pool if available.
void CreateLayer(const std::shared_ptr< IOSContext > &ios_context, MTLPixelFormat pixel_format)
Create a new overlay layer.
VkSurfaceKHR surface
Definition main.cc:65
G_BEGIN_DECLS FlutterViewId view_id
#define FML_DCHECK(condition)
Definition logging.h:122
Definition ref_ptr.h:261
OverlayLayer(int id, std::unique_ptr< AndroidSurface > android_surface, std::unique_ptr< Surface > surface)
void UpdateViewState(UIView *flutter_view, DlRect rect, int64_t view_id, int64_t overlay_id)
constexpr Type GetY() const
Returns the Y coordinate of the upper left corner, equivalent to |GetOrigin().y|.
Definition rect.h:337
constexpr Type GetHeight() const
Returns the height of the rectangle, equivalent to |GetSize().height|.
Definition rect.h:347
constexpr Type GetX() const
Returns the X coordinate of the upper left corner, equivalent to |GetOrigin().x|.
Definition rect.h:333
constexpr Type GetWidth() const
Returns the width of the rectangle, equivalent to |GetSize().width|.
Definition rect.h:341