Skip to content

Commit 1859e1b

Browse files
dkwingsmtschwa423
authored andcommitted
[macOS, multiwindow] Compositor gets FlutterView lazily (flutter#36392)
1 parent 50acc94 commit 1859e1b

16 files changed

+317
-49
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2662,6 +2662,10 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewC
26622662
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h
26632663
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm
26642664
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h
2665+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h
2666+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.mm
2667+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderUnittests.mm
2668+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h
26652669
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/KeyCodeMap.g.mm
26662670
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/KeyCodeMap_Internal.h
26672671
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h

shell/platform/darwin/macos/BUILD.gn

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ source_set("flutter_framework_source") {
121121
"framework/Source/FlutterView.mm",
122122
"framework/Source/FlutterViewController.mm",
123123
"framework/Source/FlutterViewController_Internal.h",
124+
"framework/Source/FlutterViewEngineProvider.h",
125+
"framework/Source/FlutterViewEngineProvider.mm",
126+
"framework/Source/FlutterViewProvider.h",
124127
"framework/Source/KeyCodeMap.g.mm",
125128
"framework/Source/MacOSGLContextSwitch.h",
126129
"framework/Source/MacOSGLContextSwitch.mm",
@@ -202,6 +205,7 @@ executable("flutter_desktop_darwin_unittests") {
202205
"framework/Source/FlutterViewControllerTest.mm",
203206
"framework/Source/FlutterViewControllerTestUtils.h",
204207
"framework/Source/FlutterViewControllerTestUtils.mm",
208+
"framework/Source/FlutterViewEngineProviderUnitTests.mm",
205209
"framework/Source/TestFlutterPlatformView.h",
206210
"framework/Source/TestFlutterPlatformView.mm",
207211
]

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
#include <list>
1010

1111
#include "flutter/fml/macros.h"
12-
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
12+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
13+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
1314
#include "flutter/shell/platform/embedder/embedder.h"
1415

1516
namespace flutter {
@@ -19,7 +20,12 @@ namespace flutter {
1920
// Platform views are not yet supported.
2021
class FlutterCompositor {
2122
public:
22-
explicit FlutterCompositor(FlutterViewController* view_controller);
23+
// Create a FlutterCompositor with a view provider.
24+
//
25+
// The view_provider is used to query FlutterViews from view IDs,
26+
// which are used for presenting and creating backing stores.
27+
// It must not be null, and is typically FlutterViewEngineProvider.
28+
explicit FlutterCompositor(id<FlutterViewProvider> view_provider);
2329

2430
virtual ~FlutterCompositor() = default;
2531

@@ -62,7 +68,10 @@ class FlutterCompositor {
6268
typedef enum { kStarted, kPresenting, kEnded } FrameStatus;
6369

6470
protected:
65-
__weak const FlutterViewController* view_controller_;
71+
// Get the view associated with the view ID.
72+
//
73+
// Returns nil if the ID is invalid.
74+
FlutterView* GetView(uint64_t view_id);
6675

6776
// Gets and sets the FrameStatus for the current frame.
6877
void SetFrameStatus(FrameStatus frame_status);
@@ -76,15 +85,19 @@ class FlutterCompositor {
7685
bool EndFrame(bool has_flutter_content);
7786

7887
// Creates a CALayer object which is backed by the supplied IOSurface, and
79-
// adds it to the root CALayer for this FlutterViewController's view.
88+
// adds it to the root CALayer for the given view.
8089
void InsertCALayerForIOSurface(
90+
FlutterView* view,
8191
const IOSurfaceRef& io_surface,
8292
CATransform3D transform = CATransform3DIdentity);
8393

8494
private:
8595
// A list of the active CALayer objects for the frame that need to be removed.
8696
std::list<CALayer*> active_ca_layers_;
8797

98+
// Where the compositor can query FlutterViews. Must not be null.
99+
id<FlutterViewProvider> const view_provider_;
100+
88101
// Callback set by the embedder to be called when the layer tree has been
89102
// correctly set up for this frame.
90103
PresentCallback present_callback_;

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

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
namespace flutter {
99

10-
FlutterCompositor::FlutterCompositor(FlutterViewController* view_controller) {
11-
FML_CHECK(view_controller != nullptr) << "FlutterViewController* cannot be nullptr";
12-
13-
view_controller_ = view_controller;
10+
FlutterCompositor::FlutterCompositor(id<FlutterViewProvider> view_provider)
11+
: view_provider_(view_provider) {
12+
FML_CHECK(view_provider != nullptr) << "FlutterViewProvider* cannot be nullptr";
1413
}
1514

1615
void FlutterCompositor::SetPresentCallback(
@@ -35,6 +34,10 @@
3534
return status;
3635
}
3736

37+
FlutterView* FlutterCompositor::GetView(uint64_t view_id) {
38+
return [view_provider_ getView:view_id];
39+
}
40+
3841
void FlutterCompositor::SetFrameStatus(FlutterCompositor::FrameStatus frame_status) {
3942
frame_status_ = frame_status;
4043
}
@@ -43,14 +46,15 @@
4346
return frame_status_;
4447
}
4548

46-
void FlutterCompositor::InsertCALayerForIOSurface(const IOSurfaceRef& io_surface,
49+
void FlutterCompositor::InsertCALayerForIOSurface(FlutterView* view,
50+
const IOSurfaceRef& io_surface,
4751
CATransform3D transform) {
4852
// FlutterCompositor manages the lifecycle of CALayers.
4953
CALayer* content_layer = [[CALayer alloc] init];
5054
content_layer.transform = transform;
51-
content_layer.frame = view_controller_.flutterView.layer.bounds;
55+
content_layer.frame = view.layer.bounds;
5256
[content_layer setContents:(__bridge id)io_surface];
53-
[view_controller_.flutterView.layer addSublayer:content_layer];
57+
[view.layer addSublayer:content_layer];
5458

5559
active_ca_layers_.push_back(content_layer);
5660
}

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

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
2222
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderingBackend.h"
2323
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
24+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"
2425
#include "flutter/shell/platform/embedder/embedder.h"
2526

2627
/**
@@ -211,6 +212,8 @@ @implementation FlutterEngine {
211212
// This is either a FlutterGLCompositor or a FlutterMetalCompositor instance.
212213
std::unique_ptr<flutter::FlutterCompositor> _macOSCompositor;
213214

215+
FlutterViewEngineProvider* _viewProvider;
216+
214217
// FlutterCompositor is copied and used in embedder.cc.
215218
FlutterCompositor _compositor;
216219

@@ -244,6 +247,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
244247
_currentMessengerConnection = 1;
245248
_allowHeadlessExecution = allowHeadlessExecution;
246249
_semanticsEnabled = NO;
250+
_viewProvider = [[FlutterViewEngineProvider alloc] initWithEngine:self];
247251

248252
_embedderAPI.struct_size = sizeof(FlutterEngineProcTable);
249253
FlutterEngineGetProcAddresses(&_embedderAPI);
@@ -437,12 +441,12 @@ - (FlutterCompositor*)createFlutterCompositor {
437441
if ([FlutterRenderingBackend renderUsingMetal]) {
438442
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(_renderer);
439443
_macOSCompositor = std::make_unique<flutter::FlutterMetalCompositor>(
440-
_viewController, _platformViewController, metalRenderer.device);
444+
_viewProvider, _platformViewController, metalRenderer.device);
441445
} else {
442446
FlutterOpenGLRenderer* openGLRenderer = reinterpret_cast<FlutterOpenGLRenderer*>(_renderer);
443447
[openGLRenderer.openGLContext makeCurrentContext];
444-
_macOSCompositor = std::make_unique<flutter::FlutterGLCompositor>(_viewController,
445-
openGLRenderer.openGLContext);
448+
_macOSCompositor =
449+
std::make_unique<flutter::FlutterGLCompositor>(_viewProvider, openGLRenderer.openGLContext);
446450
}
447451
_macOSCompositor->SetPresentCallback([weakSelf](bool has_flutter_content) {
448452
if (has_flutter_content) {

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace flutter {
1919
// FlutterGLCompositor is created and destroyed by FlutterEngine.
2020
class FlutterGLCompositor : public FlutterCompositor {
2121
public:
22-
FlutterGLCompositor(FlutterViewController* view_controller,
22+
FlutterGLCompositor(id<FlutterViewProvider> view_provider,
2323
NSOpenGLContext* opengl_context);
2424

2525
virtual ~FlutterGLCompositor() = default;

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

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,17 @@
1919

2020
namespace flutter {
2121

22-
FlutterGLCompositor::FlutterGLCompositor(FlutterViewController* view_controller,
22+
FlutterGLCompositor::FlutterGLCompositor(id<FlutterViewProvider> view_provider,
2323
NSOpenGLContext* opengl_context)
24-
: FlutterCompositor(view_controller), open_gl_context_(opengl_context) {}
24+
: FlutterCompositor(view_provider), open_gl_context_(opengl_context) {}
2525

2626
bool FlutterGLCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config,
2727
FlutterBackingStore* backing_store_out) {
28-
if (!view_controller_) {
28+
// TODO(dkwingsmt): This class only supports single-view for now. As more
29+
// classes are gradually converted to multi-view, it should get the view ID
30+
// from somewhere.
31+
FlutterView* view = GetView(kFlutterDefaultViewId);
32+
if (!view) {
2933
return false;
3034
}
3135

@@ -36,8 +40,7 @@
3640
// If the backing store is for the first layer, return the fbo for the
3741
// FlutterView.
3842
FlutterOpenGLRenderBackingStore* backingStore =
39-
reinterpret_cast<FlutterOpenGLRenderBackingStore*>(
40-
[view_controller_.flutterView backingStoreForSize:size]);
43+
reinterpret_cast<FlutterOpenGLRenderBackingStore*>([view backingStoreForSize:size]);
4144
backing_store_out->open_gl.framebuffer.name = backingStore.frameBufferID;
4245
} else {
4346
FlutterFrameBufferProvider* fb_provider =
@@ -75,6 +78,14 @@
7578
}
7679

7780
bool FlutterGLCompositor::Present(const FlutterLayer** layers, size_t layers_count) {
81+
// TODO(dkwingsmt): This class only supports single-view for now. As more
82+
// classes are gradually converted to multi-view, it should get the view ID
83+
// from somewhere.
84+
FlutterView* view = GetView(kFlutterDefaultViewId);
85+
if (!view) {
86+
return false;
87+
}
88+
7889
SetFrameStatus(FrameStatus::kPresenting);
7990

8091
bool has_flutter_content = false;
@@ -93,7 +104,7 @@
93104

94105
// The surface is an OpenGL texture, which means it has origin in bottom left corner
95106
// and needs to be flipped vertically
96-
InsertCALayerForIOSurface(io_surface, CATransform3DMakeScale(1, -1, 1));
107+
InsertCALayerForIOSurface(view, io_surface, CATransform3DMakeScale(1, -1, 1));
97108
}
98109
has_flutter_content = true;
99110
break;

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

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,52 @@
33
// found in the LICENSE file.
44

55
#import <Foundation/Foundation.h>
6+
#import <OCMock/OCMock.h>
67

78
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositor.h"
89
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h"
910
#import "flutter/testing/testing.h"
1011

12+
@interface FlutterViewMockProviderGL : NSObject <FlutterViewProvider> {
13+
FlutterView* _defaultView;
14+
}
15+
/**
16+
* Create a FlutterViewMockProviderGL with the provided view as the default view.
17+
*/
18+
- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view;
19+
@end
20+
21+
@implementation FlutterViewMockProviderGL
22+
23+
- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view {
24+
self = [super init];
25+
if (self != nil) {
26+
_defaultView = view;
27+
}
28+
return self;
29+
}
30+
31+
- (nullable FlutterView*)getView:(uint64_t)viewId {
32+
if (viewId == kFlutterDefaultViewId) {
33+
return _defaultView;
34+
}
35+
return nil;
36+
}
37+
38+
@end
39+
1140
namespace flutter::testing {
41+
namespace {
1242

13-
TEST(FlutterGLCompositorTest, TestPresent) {
14-
id mockViewController = CreateMockViewController();
43+
id<FlutterViewProvider> MockViewProvider() {
44+
id viewMock = OCMClassMock([FlutterView class]);
45+
return [[FlutterViewMockProviderGL alloc] initWithDefaultView:viewMock];
46+
}
47+
} // namespace
1548

49+
TEST(FlutterGLCompositorTest, TestPresent) {
1650
std::unique_ptr<flutter::FlutterGLCompositor> macos_compositor =
17-
std::make_unique<FlutterGLCompositor>(mockViewController, nullptr);
51+
std::make_unique<FlutterGLCompositor>(MockViewProvider(), nullptr);
1852

1953
bool flag = false;
2054
macos_compositor->SetPresentCallback([f = &flag](bool has_flutter_content) {

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ namespace flutter {
1414
class FlutterMetalCompositor : public FlutterCompositor {
1515
public:
1616
explicit FlutterMetalCompositor(
17-
FlutterViewController* view_controller,
17+
id<FlutterViewProvider> view_provider,
1818
FlutterPlatformViewController* platform_views_controller,
1919
id<MTLDevice> mtl_device);
2020

@@ -46,8 +46,11 @@ class FlutterMetalCompositor : public FlutterCompositor {
4646

4747
private:
4848
// Presents the platform view layer represented by `layer`. `layer_index` is
49-
// used to position the layer in the z-axis.
50-
void PresentPlatformView(const FlutterLayer* layer, size_t layer_index);
49+
// used to position the layer in the z-axis. If the layer does not have a
50+
// superview, it will become subview of `default_base_view`.
51+
void PresentPlatformView(FlutterView* default_base_view,
52+
const FlutterLayer* layer,
53+
size_t layer_position);
5154

5255
const id<MTLDevice> mtl_device_;
5356
const FlutterPlatformViewController* platform_views_controller_;

0 commit comments

Comments
 (0)