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

Commit 1b318f0

Browse files
authored
Revert "[macOS] Refactor rendering infrastructure (#37789)"
This reverts commit 6cd8561.
1 parent 8915b81 commit 1b318f0

26 files changed

+879
-864
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5050,6 +5050,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngin
50505050
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h
50515051
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.h
50525052
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTexture.mm
5053+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h
5054+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.mm
50535055
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyPrimaryResponder.h
50545056
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.h
50555057
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterKeyboardManager.mm
@@ -5070,8 +5072,10 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatf
50705072
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h
50715073
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm
50725074
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm
5073-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.h
5074-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurface.mm
5075+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.h
5076+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizableBackingStoreProvider.mm
5077+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.h
5078+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterResizeSynchronizer.mm
50755079
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h
50765080
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm
50775081
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManagerTest.mm
@@ -5083,8 +5087,6 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextI
50835087
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm
50845088
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.h
50855089
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.mm
5086-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h
5087-
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm
50885090
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h
50895091
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm
50905092
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm

shell/platform/darwin/macos/BUILD.gn

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ 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",
7476
"framework/Source/FlutterKeyPrimaryResponder.h",
7577
"framework/Source/FlutterKeyboardManager.h",
7678
"framework/Source/FlutterKeyboardManager.mm",
@@ -86,8 +88,10 @@ source_set("flutter_framework_source") {
8688
"framework/Source/FlutterPlatformViewController.mm",
8789
"framework/Source/FlutterRenderer.h",
8890
"framework/Source/FlutterRenderer.mm",
89-
"framework/Source/FlutterSurface.h",
90-
"framework/Source/FlutterSurface.mm",
91+
"framework/Source/FlutterResizableBackingStoreProvider.h",
92+
"framework/Source/FlutterResizableBackingStoreProvider.mm",
93+
"framework/Source/FlutterResizeSynchronizer.h",
94+
"framework/Source/FlutterResizeSynchronizer.mm",
9195
"framework/Source/FlutterSurfaceManager.h",
9296
"framework/Source/FlutterSurfaceManager.mm",
9397
"framework/Source/FlutterTextInputPlugin.h",
@@ -96,8 +100,6 @@ source_set("flutter_framework_source") {
96100
"framework/Source/FlutterTextInputSemanticsObject.mm",
97101
"framework/Source/FlutterTextureRegistrar.h",
98102
"framework/Source/FlutterTextureRegistrar.mm",
99-
"framework/Source/FlutterThreadSynchronizer.h",
100-
"framework/Source/FlutterThreadSynchronizer.mm",
101103
"framework/Source/FlutterView.h",
102104
"framework/Source/FlutterView.mm",
103105
"framework/Source/FlutterViewController.mm",

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

Lines changed: 62 additions & 3 deletions
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-
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
14-
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
13+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
14+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
1515
#include "flutter/shell/platform/embedder/embedder.h"
1616

1717
namespace flutter {
@@ -28,7 +28,8 @@ 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);
31+
FlutterPlatformViewController* platform_views_controller,
32+
id<MTLDevice> mtl_device);
3233

3334
~FlutterCompositor() = default;
3435

@@ -47,12 +48,57 @@ class FlutterCompositor {
4748
bool CreateBackingStore(const FlutterBackingStoreConfig* config,
4849
FlutterBackingStore* backing_store_out);
4950

51+
// Releases the memory for any resources that were allocated for the
52+
// specified backing store.
53+
bool CollectBackingStore(const FlutterBackingStore* backing_store);
54+
5055
// Presents the FlutterLayers by updating the FlutterView specified by
5156
// `view_id` using the layer content. Sets frame_started_ to false.
5257
bool Present(uint64_t view_id,
5358
const FlutterLayer** layers,
5459
size_t layers_count);
5560

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

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

67116
// The controller used to manage creation and deletion of platform views.
68117
const FlutterPlatformViewController* platform_view_controller_;
69118

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+
70129
FML_DISALLOW_COPY_AND_ASSIGN(FlutterCompositor);
71130
};
72131

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

Lines changed: 127 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@
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"
89

910
namespace flutter {
1011

1112
FlutterCompositor::FlutterCompositor(id<FlutterViewProvider> view_provider,
12-
FlutterPlatformViewController* platform_view_controller)
13-
: view_provider_(view_provider), platform_view_controller_(platform_view_controller) {
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) {
1418
FML_CHECK(view_provider != nullptr) << "view_provider cannot be nullptr";
1519
}
1620

@@ -19,67 +23,103 @@
1923
// TODO(dkwingsmt): This class only supports single-view for now. As more
2024
// classes are gradually converted to multi-view, it should get the view ID
2125
// from somewhere.
22-
FlutterView* view = [view_provider_ getView:kFlutterDefaultViewId];
26+
FlutterView* view = GetView(kFlutterDefaultViewId);
2327
if (!view) {
2428
return false;
2529
}
2630

2731
CGSize size = CGSizeMake(config->size.width, config->size.height);
28-
FlutterSurface* surface = [view.surfaceManager surfaceForSize:size];
29-
memset(backing_store_out, 0, sizeof(FlutterBackingStore));
30-
backing_store_out->struct_size = sizeof(FlutterBackingStore);
31-
backing_store_out->type = kFlutterBackingStoreTypeMetal;
32+
3233
backing_store_out->metal.struct_size = sizeof(FlutterMetalBackingStore);
33-
backing_store_out->metal.texture = surface.asFlutterMetalTexture;
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+
62+
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+
}
3479
return true;
3580
}
3681

3782
bool FlutterCompositor::Present(uint64_t view_id,
3883
const FlutterLayer** layers,
3984
size_t layers_count) {
40-
FlutterView* view = [view_provider_ getView:view_id];
85+
FlutterView* view = GetView(view_id);
4186
if (!view) {
4287
return false;
4388
}
4489

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];
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;
58107
}
59-
}
108+
case kFlutterLayerContentTypePlatformView: {
109+
PresentPlatformView(view, layer, i);
110+
break;
111+
}
112+
};
60113
}
61114

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;
115+
return EndFrame(has_flutter_content);
78116
}
79117

80118
void FlutterCompositor::PresentPlatformView(FlutterView* default_base_view,
81119
const FlutterLayer* layer,
82120
size_t layer_position) {
121+
// TODO (https://github.com/flutter/flutter/issues/96668)
122+
// once the issue is fixed, this check will pass.
83123
FML_DCHECK([[NSThread currentThread] isMainThread])
84124
<< "Must be on the main thread to present platform views";
85125

@@ -88,7 +128,7 @@
88128

89129
FML_DCHECK(platform_view) << "Platform view not found for id: " << platform_view_id;
90130

91-
CGFloat scale = platform_view.layer.contentsScale;
131+
CGFloat scale = [[NSScreen mainScreen] backingScaleFactor];
92132
platform_view.frame = CGRectMake(layer->offset.x / scale, layer->offset.y / scale,
93133
layer->size.width / scale, layer->size.height / scale);
94134
if (platform_view.superview == nil) {
@@ -97,4 +137,51 @@
97137
platform_view.layer.zPosition = layer_position;
98138
}
99139

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

0 commit comments

Comments
 (0)