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

Commit 6cd8561

Browse files
knoppcbracken
andauthored
[macOS] Refactor rendering infrastructure (#37789)
* [macos] Refactor rendering process * Put includes and imports together * Update shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm Co-authored-by: Chris Bracken <[email protected]> * Remove cast * Do not manually add platform view layer to FlutterView * Remove unnecesary _Internal header files * Make surfaceManager a readonly property * Add comment * Style nit: Rewrite as a noun phrase. * Naming nit for consistency with removeSurfaceForSize: * Write as ternary conditional. * Fix plural in comment. * Offset and index are already set to 0. * Remove FlutterSurfaceManager lookupSurface And the associate bookkeeping of borrowed (lent) surfaces. * Update shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h Co-authored-by: Chris Bracken <[email protected]> * Update shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h Co-authored-by: Chris Bracken <[email protected]> * Fix build error * Address nits * Replace EVent with fml::AutoResetWaitableEvent * Remove unecessary CATransaction * Add GetRequiredFrameSize Co-authored-by: Chris Bracken <[email protected]>
1 parent 479bb73 commit 6cd8561

26 files changed

+864
-879
lines changed

ci/licenses_golden/licenses_flutter

+4-6
Original file line numberDiff line numberDiff line change
@@ -2717,8 +2717,6 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngin
27172717
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
27182718
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.h
27192719
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm
2720-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h
2721-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.mm
27222720
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyPrimaryResponder.h
27232721
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.h
27242722
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.mm
@@ -2739,10 +2737,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatf
27392737
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h
27402738
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm
27412739
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm
2742-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.h
2743-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm
2744-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h
2745-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm
2740+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.h
2741+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.mm
27462742
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h
27472743
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm
27482744
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm
@@ -2754,6 +2750,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextI
27542750
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm
27552751
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.h
27562752
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.mm
2753+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h
2754+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm
27572755
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h
27582756
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm
27592757
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm

shell/platform/darwin/macos/BUILD.gn

+4-6
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,10 +86,8 @@ 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",
9793
"framework/Source/FlutterTextInputPlugin.h",
@@ -100,6 +96,8 @@ source_set("flutter_framework_source") {
10096
"framework/Source/FlutterTextInputSemanticsObject.mm",
10197
"framework/Source/FlutterTextureRegistrar.h",
10298
"framework/Source/FlutterTextureRegistrar.mm",
99+
"framework/Source/FlutterThreadSynchronizer.h",
100+
"framework/Source/FlutterThreadSynchronizer.mm",
103101
"framework/Source/FlutterView.h",
104102
"framework/Source/FlutterView.mm",
105103
"framework/Source/FlutterViewController.mm",

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

+3-62
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010

1111
#include "flutter/fml/macros.h"
1212
#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"
13+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
14+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
1515
#include "flutter/shell/platform/embedder/embedder.h"
1616

1717
namespace flutter {
@@ -28,8 +28,7 @@ class FlutterCompositor {
2828
// It must not be null, and is typically FlutterViewEngineProvider.
2929
explicit FlutterCompositor(
3030
id<FlutterViewProvider> view_provider,
31-
FlutterPlatformViewController* platform_views_controller,
32-
id<MTLDevice> mtl_device);
31+
FlutterPlatformViewController* platform_views_controller);
3332

3433
~FlutterCompositor() = default;
3534

@@ -48,57 +47,12 @@ class FlutterCompositor {
4847
bool CreateBackingStore(const FlutterBackingStoreConfig* config,
4948
FlutterBackingStore* backing_store_out);
5049

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

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-
10256
private:
10357
// Presents the platform view layer represented by `layer`. `layer_index` is
10458
// used to position the layer in the z-axis. If the layer does not have a
@@ -107,25 +61,12 @@ class FlutterCompositor {
10761
const FlutterLayer* layer,
10862
size_t layer_position);
10963

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

11667
// The controller used to manage creation and deletion of platform views.
11768
const FlutterPlatformViewController* platform_view_controller_;
11869

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-
12970
FML_DISALLOW_COPY_AND_ASSIGN(FlutterCompositor);
13071
};
13172

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

+40-127
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,67 @@
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+
const FlutterLayer* layer = layers[i];
48+
if (layer->type == kFlutterLayerContentTypeBackingStore) {
49+
FlutterSurface* surface =
50+
[FlutterSurface fromFlutterMetalTexture:&layer->backing_store->metal.texture];
51+
52+
if (surface) {
53+
FlutterSurfacePresentInfo* info = [[FlutterSurfacePresentInfo alloc] init];
54+
info.surface = surface;
55+
info.offset = CGPointMake(layer->offset.x, layer->offset.y);
56+
info.zIndex = i;
57+
[surfaces addObject:info];
11158
}
112-
};
59+
}
11360
}
11461

115-
return EndFrame(has_flutter_content);
62+
[view.surfaceManager present:surfaces
63+
notify:^{
64+
for (size_t i = 0; i < layers_count; i++) {
65+
const FlutterLayer* layer = layers[i];
66+
switch (layer->type) {
67+
case kFlutterLayerContentTypeBackingStore:
68+
break;
69+
case kFlutterLayerContentTypePlatformView:
70+
PresentPlatformView(view, layer, i);
71+
break;
72+
}
73+
}
74+
[platform_view_controller_ disposePlatformViews];
75+
}];
76+
77+
return true;
11678
}
11779

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

@@ -128,7 +88,7 @@
12888

12989
FML_DCHECK(platform_view) << "Platform view not found for id: " << platform_view_id;
13090

131-
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];
91+
CGFloat scale = platform_view.layer.contentsScale;
13292
platform_view.frame = CGRectMake(layer->offset.x / scale, layer->offset.y / scale,
13393
layer->size.width / scale, layer->size.height / scale);
13494
if (platform_view.superview == nil) {
@@ -137,51 +97,4 @@
13797
platform_view.layer.zPosition = layer_position;
13898
}
13999

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-
187100
} // namespace flutter

0 commit comments

Comments
 (0)