Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 50a9413

Browse files
committed
[macos] Refactor rendering process
1 parent 0930a76 commit 50a9413

28 files changed

+958
-888
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2638,8 +2638,6 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngin
26382638
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
26392639
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.h
26402640
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm
2641-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h
2642-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.mm
26432641
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyPrimaryResponder.h
26442642
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.h
26452643
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.mm
@@ -2660,13 +2658,13 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatf
26602658
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h
26612659
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm
26622660
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm
2663-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.h
2664-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm
2665-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h
2666-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm
2661+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.h
2662+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.mm
26672663
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h
26682664
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm
26692665
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm
2666+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager_Internal.h
2667+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface_Internal.h
26702668
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.h
26712669
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPlugin.mm
26722670
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputPluginTest.mm
@@ -2675,6 +2673,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextI
26752673
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm
26762674
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.h
26772675
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.mm
2676+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h
2677+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm
26782678
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h
26792679
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm
26802680
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm

shell/platform/darwin/macos/BUILD.gn

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ source_set("flutter_framework_source") {
7171
"framework/Source/FlutterEngine_Internal.h",
7272
"framework/Source/FlutterExternalTexture.h",
7373
"framework/Source/FlutterExternalTexture.mm",
74-
"framework/Source/FlutterIOSurfaceHolder.h",
75-
"framework/Source/FlutterIOSurfaceHolder.mm",
7674
"framework/Source/FlutterKeyPrimaryResponder.h",
7775
"framework/Source/FlutterKeyboardManager.h",
7876
"framework/Source/FlutterKeyboardManager.mm",
@@ -88,18 +86,20 @@ source_set("flutter_framework_source") {
8886
"framework/Source/FlutterPlatformViewController.mm",
8987
"framework/Source/FlutterRenderer.h",
9088
"framework/Source/FlutterRenderer.mm",
91-
"framework/Source/FlutterResizableBackingStoreProvider.h",
92-
"framework/Source/FlutterResizableBackingStoreProvider.mm",
93-
"framework/Source/FlutterResizeSynchronizer.h",
94-
"framework/Source/FlutterResizeSynchronizer.mm",
89+
"framework/Source/FlutterSurface.h",
90+
"framework/Source/FlutterSurface.mm",
9591
"framework/Source/FlutterSurfaceManager.h",
9692
"framework/Source/FlutterSurfaceManager.mm",
93+
"framework/Source/FlutterSurfaceManager_Internal.h",
94+
"framework/Source/FlutterSurface_Internal.h",
9795
"framework/Source/FlutterTextInputPlugin.h",
9896
"framework/Source/FlutterTextInputPlugin.mm",
9997
"framework/Source/FlutterTextInputSemanticsObject.h",
10098
"framework/Source/FlutterTextInputSemanticsObject.mm",
10199
"framework/Source/FlutterTextureRegistrar.h",
102100
"framework/Source/FlutterTextureRegistrar.mm",
101+
"framework/Source/FlutterThreadSynchronizer.h",
102+
"framework/Source/FlutterThreadSynchronizer.mm",
103103
"framework/Source/FlutterView.h",
104104
"framework/Source/FlutterView.mm",
105105
"framework/Source/FlutterViewController.mm",

shell/platform/darwin/macos/framework/Source/FlutterCompositor.h

Lines changed: 5 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
#include <list>
1010

1111
#include "flutter/fml/macros.h"
12-
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
13-
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
14-
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
1512
#include "flutter/shell/platform/embedder/embedder.h"
1613

14+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
15+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
16+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
17+
1718
namespace flutter {
1819

1920
// FlutterCompositor creates and manages the backing stores used for
@@ -28,8 +29,7 @@ class FlutterCompositor {
2829
// It must not be null, and is typically FlutterViewEngineProvider.
2930
explicit FlutterCompositor(
3031
id<FlutterViewProvider> view_provider,
31-
FlutterPlatformViewController* platform_views_controller,
32-
id<MTLDevice> mtl_device);
32+
FlutterPlatformViewController* platform_views_controller);
3333

3434
~FlutterCompositor() = default;
3535

@@ -48,57 +48,12 @@ class FlutterCompositor {
4848
bool CreateBackingStore(const FlutterBackingStoreConfig* config,
4949
FlutterBackingStore* backing_store_out);
5050

51-
// Releases the memory for any resources that were allocated for the
52-
// specified backing store.
53-
bool CollectBackingStore(const FlutterBackingStore* backing_store);
54-
5551
// Presents the FlutterLayers by updating the FlutterView specified by
5652
// `view_id` using the layer content. Sets frame_started_ to false.
5753
bool Present(uint64_t view_id,
5854
const FlutterLayer** layers,
5955
size_t layers_count);
6056

61-
// Callback triggered at the end of the Present function. has_flutter_content
62-
// is true when Flutter content was rendered, otherwise false.
63-
using PresentCallback = std::function<bool(bool has_flutter_content)>;
64-
65-
// Registers a callback to be triggered at the end of the Present function.
66-
// If a callback was previously registered, it will be replaced.
67-
void SetPresentCallback(const PresentCallback& present_callback);
68-
69-
// The status of the frame being composited.
70-
// Started: A new frame has begun and we have cleared the old layer tree and
71-
// are now creating backingstore(s) for the embedder to use.
72-
// Presenting: the embedder has finished rendering into the provided
73-
// backingstore(s) and we are creating the layer tree for the system
74-
// compositor to present with.
75-
// Ended: The frame has been presented and we are no longer processing it.
76-
typedef enum { kStarted, kPresenting, kEnded } FrameStatus;
77-
78-
protected:
79-
// Returns the view associated with the view ID.
80-
//
81-
// Returns nil if the ID is invalid.
82-
FlutterView* GetView(uint64_t view_id);
83-
84-
// Gets and sets the FrameStatus for the current frame.
85-
void SetFrameStatus(FrameStatus frame_status);
86-
FrameStatus GetFrameStatus();
87-
88-
// Clears the previous CALayers and updates the frame status to frame started.
89-
void StartFrame();
90-
91-
// Calls the present callback and ensures the frame status is updated
92-
// to frame ended, returning whether the present was successful or not.
93-
bool EndFrame(bool has_flutter_content);
94-
95-
// Creates a CALayer object which is backed by the supplied IOSurface, and
96-
// adds it to the root CALayer for the given view.
97-
void InsertCALayerForIOSurface(
98-
FlutterView* view,
99-
const IOSurfaceRef& io_surface,
100-
CATransform3D transform = CATransform3DIdentity);
101-
10257
private:
10358
// Presents the platform view layer represented by `layer`. `layer_index` is
10459
// used to position the layer in the z-axis. If the layer does not have a
@@ -107,25 +62,12 @@ class FlutterCompositor {
10762
const FlutterLayer* layer,
10863
size_t layer_position);
10964

110-
// A list of the active CALayer objects for the frame that need to be removed.
111-
std::list<CALayer*> active_ca_layers_;
112-
11365
// Where the compositor can query FlutterViews. Must not be null.
11466
id<FlutterViewProvider> const view_provider_;
11567

11668
// The controller used to manage creation and deletion of platform views.
11769
const FlutterPlatformViewController* platform_view_controller_;
11870

119-
// The Metal device used to draw graphics.
120-
const id<MTLDevice> mtl_device_;
121-
122-
// Callback set by the embedder to be called when the layer tree has been
123-
// correctly set up for this frame.
124-
PresentCallback present_callback_;
125-
126-
// Current frame status.
127-
FrameStatus frame_status_ = kEnded;
128-
12971
FML_DISALLOW_COPY_AND_ASSIGN(FlutterCompositor);
13072
};
13173

shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm

Lines changed: 36 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,12 @@
55
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h"
66

77
#include "flutter/fml/logging.h"
8-
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
98

109
namespace flutter {
1110

1211
FlutterCompositor::FlutterCompositor(id<FlutterViewProvider> view_provider,
13-
FlutterPlatformViewController* platform_view_controller,
14-
id<MTLDevice> mtl_device)
15-
: view_provider_(view_provider),
16-
platform_view_controller_(platform_view_controller),
17-
mtl_device_(mtl_device) {
12+
FlutterPlatformViewController* platform_view_controller)
13+
: view_provider_(view_provider), platform_view_controller_(platform_view_controller) {
1814
FML_CHECK(view_provider != nullptr) << "view_provider cannot be nullptr";
1915
}
2016

@@ -23,103 +19,62 @@
2319
// TODO(dkwingsmt): This class only supports single-view for now. As more
2420
// classes are gradually converted to multi-view, it should get the view ID
2521
// from somewhere.
26-
FlutterView* view = GetView(kFlutterDefaultViewId);
22+
FlutterView* view = [view_provider_ getView:kFlutterDefaultViewId];
2723
if (!view) {
2824
return false;
2925
}
3026

3127
CGSize size = CGSizeMake(config->size.width, config->size.height);
32-
33-
backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
34-
backing_store_out->metal.texture.struct_size = sizeof(FlutterMetalTexture);
35-
36-
if (GetFrameStatus() != FrameStatus::kStarted) {
37-
StartFrame();
38-
// If the backing store is for the first layer, return the MTLTexture for the
39-
// FlutterView.
40-
FlutterRenderBackingStore* backingStore = [view backingStoreForSize:size];
41-
backing_store_out->metal.texture.texture =
42-
(__bridge FlutterMetalTextureHandle)backingStore.texture;
43-
} else {
44-
FlutterIOSurfaceHolder* io_surface_holder = [[FlutterIOSurfaceHolder alloc] init];
45-
[io_surface_holder recreateIOSurfaceWithSize:size];
46-
auto texture_descriptor =
47-
[MTLTextureDescriptor texture2DDescriptorWithPixelFormat:MTLPixelFormatBGRA8Unorm
48-
width:size.width
49-
height:size.height
50-
mipmapped:NO];
51-
texture_descriptor.usage =
52-
MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget | MTLTextureUsageShaderWrite;
53-
54-
backing_store_out->metal.texture.texture = (__bridge_retained FlutterMetalTextureHandle)
55-
[mtl_device_ newTextureWithDescriptor:texture_descriptor
56-
iosurface:[io_surface_holder ioSurface]
57-
plane:0];
58-
59-
backing_store_out->metal.texture.user_data = (__bridge_retained void*)io_surface_holder;
60-
}
61-
28+
FlutterSurface* surface = [view.surfaceManager surfaceForSize:size];
29+
memset(backing_store_out, 0, sizeof(FlutterBackingStore));
30+
backing_store_out->struct_size = sizeof(FlutterBackingStore);
6231
backing_store_out->type = kFlutterBackingStoreTypeMetal;
63-
backing_store_out->metal.texture.destruction_callback = [](void* user_data) {
64-
if (user_data != nullptr) {
65-
CFRelease(user_data);
66-
}
67-
};
68-
69-
return true;
70-
}
71-
72-
bool FlutterCompositor::CollectBackingStore(const FlutterBackingStore* backing_store) {
73-
// If we allocated this MTLTexture ourselves, user_data is not null, and we will need
74-
// to release it manually.
75-
if (backing_store->metal.texture.user_data != nullptr &&
76-
backing_store->metal.texture.texture != nullptr) {
77-
CFRelease(backing_store->metal.texture.texture);
78-
}
32+
backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
33+
backing_store_out->metal.texture = surface.asFlutterMetalTexture;
7934
return true;
8035
}
8136

8237
bool FlutterCompositor::Present(uint64_t view_id,
8338
const FlutterLayer** layers,
8439
size_t layers_count) {
85-
FlutterView* view = GetView(view_id);
40+
FlutterView* view = [view_provider_ getView:view_id];
8641
if (!view) {
8742
return false;
8843
}
8944

90-
SetFrameStatus(FrameStatus::kPresenting);
91-
92-
bool has_flutter_content = false;
93-
for (size_t i = 0; i < layers_count; ++i) {
94-
const auto* layer = layers[i];
95-
FlutterBackingStore* backing_store = const_cast<FlutterBackingStore*>(layer->backing_store);
96-
97-
switch (layer->type) {
98-
case kFlutterLayerContentTypeBackingStore: {
99-
if (backing_store->metal.texture.user_data) {
100-
FlutterIOSurfaceHolder* io_surface_holder =
101-
(__bridge FlutterIOSurfaceHolder*)backing_store->metal.texture.user_data;
102-
IOSurfaceRef io_surface = [io_surface_holder ioSurface];
103-
InsertCALayerForIOSurface(view, io_surface);
104-
}
105-
has_flutter_content = true;
106-
break;
107-
}
108-
case kFlutterLayerContentTypePlatformView: {
109-
PresentPlatformView(view, layer, i);
110-
break;
45+
NSMutableArray* surfaces = [NSMutableArray array];
46+
for (size_t i = 0; i < layers_count; i++) {
47+
FlutterLayer* layer = (FlutterLayer*)layers[i];
48+
if (layer->type == kFlutterLayerContentTypeBackingStore) {
49+
FlutterSurface* surface =
50+
[view.surfaceManager lookupSurface:&layer->backing_store->metal.texture];
51+
if (surface) {
52+
FlutterSurfacePresentInfo* info = [[FlutterSurfacePresentInfo alloc] init];
53+
info.surface = surface;
54+
info.offset = CGPointMake(layer->offset.x, layer->offset.y);
55+
info.zIndex = i;
56+
[surfaces addObject:info];
11157
}
112-
};
58+
}
11359
}
11460

115-
return EndFrame(has_flutter_content);
61+
[view.surfaceManager present:surfaces
62+
notify:^{
63+
for (size_t i = 0; i < layers_count; i++) {
64+
FlutterLayer* layer = (FlutterLayer*)layers[i];
65+
if (layer->type == kFlutterLayerContentTypePlatformView) {
66+
PresentPlatformView(view, layer, i);
67+
}
68+
}
69+
[platform_view_controller_ disposePlatformViews];
70+
}];
71+
72+
return true;
11673
}
11774

11875
void FlutterCompositor::PresentPlatformView(FlutterView* default_base_view,
11976
const FlutterLayer* layer,
12077
size_t layer_position) {
121-
// TODO (https://github.com/flutter/flutter/issues/96668)
122-
// once the issue is fixed, this check will pass.
12378
FML_DCHECK([[NSThread currentThread] isMainThread])
12479
<< "Must be on the main thread to present platform views";
12580

@@ -128,60 +83,14 @@
12883

12984
FML_DCHECK(platform_view) << "Platform view not found for id: " << platform_view_id;
13085

131-
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];
86+
CGFloat scale = platform_view.layer.contentsScale;
13287
platform_view.frame = CGRectMake(layer->offset.x / scale, layer->offset.y / scale,
13388
layer->size.width / scale, layer->size.height / scale);
13489
if (platform_view.superview == nil) {
13590
[default_base_view addSubview:platform_view];
91+
[default_base_view.layer addSublayer:platform_view.layer];
13692
}
13793
platform_view.layer.zPosition = layer_position;
13894
}
13995

140-
void FlutterCompositor::SetPresentCallback(
141-
const FlutterCompositor::PresentCallback& present_callback) {
142-
present_callback_ = present_callback;
143-
}
144-
145-
void FlutterCompositor::StartFrame() {
146-
// First remove all CALayers from the superlayer.
147-
for (auto layer : active_ca_layers_) {
148-
[layer removeFromSuperlayer];
149-
}
150-
151-
// Reset active layers.
152-
active_ca_layers_.clear();
153-
SetFrameStatus(FrameStatus::kStarted);
154-
}
155-
156-
bool FlutterCompositor::EndFrame(bool has_flutter_content) {
157-
bool status = present_callback_(has_flutter_content);
158-
SetFrameStatus(FrameStatus::kEnded);
159-
return status;
160-
}
161-
162-
FlutterView* FlutterCompositor::GetView(uint64_t view_id) {
163-
return [view_provider_ getView:view_id];
164-
}
165-
166-
void FlutterCompositor::SetFrameStatus(FlutterCompositor::FrameStatus frame_status) {
167-
frame_status_ = frame_status;
168-
}
169-
170-
FlutterCompositor::FrameStatus FlutterCompositor::GetFrameStatus() {
171-
return frame_status_;
172-
}
173-
174-
void FlutterCompositor::InsertCALayerForIOSurface(FlutterView* view,
175-
const IOSurfaceRef& io_surface,
176-
CATransform3D transform) {
177-
// FlutterCompositor manages the lifecycle of CALayers.
178-
CALayer* content_layer = [[CALayer alloc] init];
179-
content_layer.transform = transform;
180-
content_layer.frame = view.layer.bounds;
181-
[content_layer setContents:(__bridge id)io_surface];
182-
[view.layer addSublayer:content_layer];
183-
184-
active_ca_layers_.push_back(content_layer);
185-
}
186-
18796
} // namespace flutter

0 commit comments

Comments
 (0)