Skip to content

Commit 7d32cea

Browse files
authored
(MacOS) Add FlutterGLCompositor with support for rendering multiple layers (flutter#22782)
* Create FlutterGLCompositor. * Add additional state to manage frame status and CALayers to FlutterGLCompositor FlutterGLCompositor supports rendering multiple layers. The first layer is rendered using the FlutterView. Additional CALayers are created if there is more than one layer. Platform view support will be added in following PR.
1 parent 78b567f commit 7d32cea

15 files changed

+441
-28
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterPlug
10531053
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Headers/FlutterViewController.h
10541054
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Info.plist
10551055
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterAppDelegate.mm
1056+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterBackingStoreData.h
1057+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterBackingStoreData.mm
10561058
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject.mm
10571059
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h
10581060
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
@@ -1062,6 +1064,9 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExter
10621064
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.mm
10631065
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h
10641066
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.mm
1067+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositor.h
1068+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositor.mm
1069+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositorUnittests.mm
10651070
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h
10661071
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.mm
10671072
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.h
@@ -1078,6 +1083,8 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.
10781083
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm
10791084
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm
10801085
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm
1086+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h
1087+
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm
10811088
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h
10821089
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h
10831090
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.mm

shell/platform/darwin/macos/BUILD.gn

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ source_set("flutter_framework_source") {
4646

4747
sources = [
4848
"framework/Source/FlutterAppDelegate.mm",
49+
"framework/Source/FlutterBackingStoreData.h",
50+
"framework/Source/FlutterBackingStoreData.mm",
4951
"framework/Source/FlutterDartProject.mm",
5052
"framework/Source/FlutterDartProject_Internal.h",
5153
"framework/Source/FlutterEngine.mm",
@@ -54,6 +56,8 @@ source_set("flutter_framework_source") {
5456
"framework/Source/FlutterExternalTextureGL.mm",
5557
"framework/Source/FlutterFrameBufferProvider.h",
5658
"framework/Source/FlutterFrameBufferProvider.mm",
59+
"framework/Source/FlutterGLCompositor.h",
60+
"framework/Source/FlutterGLCompositor.mm",
5761
"framework/Source/FlutterIOSurfaceHolder.h",
5862
"framework/Source/FlutterIOSurfaceHolder.mm",
5963
"framework/Source/FlutterMouseCursorPlugin.h",
@@ -77,9 +81,12 @@ source_set("flutter_framework_source") {
7781
sources += _flutter_framework_headers
7882

7983
deps = [
84+
"//flutter/flow:flow",
85+
"//flutter/fml",
8086
"//flutter/shell/platform/common/cpp:common_cpp_switches",
8187
"//flutter/shell/platform/darwin/common:framework_shared",
8288
"//flutter/shell/platform/embedder:embedder_as_internal_library",
89+
"//third_party/skia",
8390
]
8491

8592
public_configs = [ "//flutter:config" ]
@@ -119,7 +126,10 @@ executable("flutter_desktop_darwin_unittests") {
119126

120127
sources = [
121128
"framework/Source/FlutterEngineTest.mm",
129+
"framework/Source/FlutterGLCompositorUnittests.mm",
122130
"framework/Source/FlutterViewControllerTest.mm",
131+
"framework/Source/FlutterViewControllerTestUtils.h",
132+
"framework/Source/FlutterViewControllerTestUtils.mm",
123133
]
124134

125135
cflags_objcc = [ "-fobjc-arc" ]
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
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+
5+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h"
6+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
7+
8+
#import <Cocoa/Cocoa.h>
9+
#import <Foundation/Foundation.h>
10+
11+
/**
12+
* FlutterBackingStoreData holds data to be stored in the
13+
* BackingStore's user_data.
14+
*/
15+
@interface FlutterBackingStoreData : NSObject
16+
17+
- (nullable instancetype)initWithLayerId:(size_t)layerId
18+
fbProvider:(nonnull FlutterFrameBufferProvider*)fbProvider
19+
ioSurfaceHolder:(nonnull FlutterIOSurfaceHolder*)ioSurfaceHolder;
20+
21+
/**
22+
* The layer's key value in FlutterGLCompositor's ca_layer_map_.
23+
*/
24+
@property(nonatomic, readonly) size_t layerId;
25+
26+
/**
27+
* Provides the fbo for rendering the layer.
28+
*/
29+
@property(nonnull, nonatomic, readonly) FlutterFrameBufferProvider* frameBufferProvider;
30+
31+
/**
32+
* Contains the IOSurfaceRef with the layer contents.
33+
*/
34+
@property(nonnull, nonatomic, readonly) FlutterIOSurfaceHolder* ioSurfaceHolder;
35+
36+
@end
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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+
5+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterBackingStoreData.h"
6+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterFrameBufferProvider.h"
7+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterIOSurfaceHolder.h"
8+
9+
#include <OpenGL/gl.h>
10+
11+
@implementation FlutterBackingStoreData
12+
13+
- (nullable instancetype)initWithLayerId:(size_t)layerId
14+
fbProvider:(nonnull FlutterFrameBufferProvider*)fbProvider
15+
ioSurfaceHolder:(nonnull FlutterIOSurfaceHolder*)ioSurfaceHolder {
16+
if (self = [super init]) {
17+
_layerId = layerId;
18+
_frameBufferProvider = fbProvider;
19+
_ioSurfaceHolder = ioSurfaceHolder;
20+
}
21+
return self;
22+
}
23+
24+
@end

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

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h"
1212
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterExternalTextureGL.h"
13-
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
13+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterGLCompositor.h"
1414
#import "flutter/shell/platform/embedder/embedder.h"
1515

1616
/**
@@ -197,6 +197,13 @@ @implementation FlutterEngine {
197197

198198
// Pointer to the Dart AOT snapshot and instruction data.
199199
_FlutterEngineAOTData* _aotData;
200+
201+
// _macOSGLCompositor is created when the engine is created and
202+
// it's destruction is handled by ARC when the engine is destroyed.
203+
std::unique_ptr<flutter::FlutterGLCompositor> _macOSGLCompositor;
204+
205+
// FlutterCompositor is copied and used in embedder.cc.
206+
FlutterCompositor _compositor;
200207
}
201208

202209
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project {
@@ -306,6 +313,8 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
306313
flutterArguments.aot_data = _aotData;
307314
}
308315

316+
flutterArguments.compositor = [self createFlutterCompositor];
317+
309318
FlutterEngineResult result = _embedderAPI.Initialize(
310319
FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine);
311320
if (result != kSuccess) {
@@ -360,6 +369,54 @@ - (void)setViewController:(FlutterViewController*)controller {
360369
}
361370
}
362371

372+
- (FlutterCompositor*)createFlutterCompositor {
373+
// TODO(richardjcai): Add support for creating a FlutterGLCompositor
374+
// with a nil _viewController for headless engines.
375+
// https://github.com/flutter/flutter/issues/71606
376+
if (_viewController == nullptr) {
377+
return nullptr;
378+
}
379+
380+
[_mainOpenGLContext makeCurrentContext];
381+
382+
_macOSGLCompositor = std::make_unique<flutter::FlutterGLCompositor>(_viewController);
383+
384+
_compositor = {};
385+
_compositor.struct_size = sizeof(FlutterCompositor);
386+
_compositor.user_data = _macOSGLCompositor.get();
387+
388+
_compositor.create_backing_store_callback = [](const FlutterBackingStoreConfig* config, //
389+
FlutterBackingStore* backing_store_out, //
390+
void* user_data //
391+
) {
392+
return reinterpret_cast<flutter::FlutterGLCompositor*>(user_data)->CreateBackingStore(
393+
config, backing_store_out);
394+
};
395+
396+
_compositor.collect_backing_store_callback = [](const FlutterBackingStore* backing_store, //
397+
void* user_data //
398+
) {
399+
return reinterpret_cast<flutter::FlutterGLCompositor*>(user_data)->CollectBackingStore(
400+
backing_store);
401+
};
402+
403+
_compositor.present_layers_callback = [](const FlutterLayer** layers, //
404+
size_t layers_count, //
405+
void* user_data //
406+
) {
407+
return reinterpret_cast<flutter::FlutterGLCompositor*>(user_data)->Present(layers,
408+
layers_count);
409+
};
410+
411+
__weak FlutterEngine* weak_self = self;
412+
_macOSGLCompositor->SetPresentCallback(
413+
[weak_self]() { return [weak_self engineCallbackOnPresent]; });
414+
415+
_compositor.avoid_backing_store_cache = true;
416+
417+
return &_compositor;
418+
}
419+
363420
- (id<FlutterBinaryMessenger>)binaryMessenger {
364421
// TODO(stuartmorgan): Switch to FlutterBinaryMessengerRelay to avoid plugins
365422
// keeping the engine alive.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*/
1010
@interface FlutterFrameBufferProvider : NSObject
1111

12-
- (nullable instancetype)initWithOpenGLContext:(nonnull NSOpenGLContext*)opengLContext;
12+
- (nullable instancetype)initWithOpenGLContext:(nonnull const NSOpenGLContext*)opengLContext;
1313

1414
/**
1515
* Returns the id of the framebuffer.

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ @interface FlutterFrameBufferProvider () {
1515
@end
1616

1717
@implementation FlutterFrameBufferProvider
18-
- (instancetype)initWithOpenGLContext:(NSOpenGLContext*)openGLContext {
18+
- (instancetype)initWithOpenGLContext:(const NSOpenGLContext*)openGLContext {
1919
if (self = [super init]) {
2020
MacOSGLContextSwitch context_switch(openGLContext);
2121

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
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+
5+
#include <map>
6+
7+
#include "flutter/fml/macros.h"
8+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h"
9+
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
10+
#include "flutter/shell/platform/embedder/embedder.h"
11+
#include "third_party/skia/include/gpu/GrDirectContext.h"
12+
13+
namespace flutter {
14+
15+
// FlutterGLCompositor creates and manages the backing stores used for
16+
// rendering Flutter content and presents Flutter content and Platform views.
17+
// Platform views are not yet supported.
18+
// FlutterGLCompositor is created and destroyed by FlutterEngine.
19+
class FlutterGLCompositor {
20+
public:
21+
FlutterGLCompositor(FlutterViewController* view_controller);
22+
23+
// Creates a BackingStore and saves updates the backing_store_out
24+
// data with the new BackingStore data.
25+
// If the backing store is being requested for the first time
26+
// for a given frame, we do not create a new backing store but
27+
// rather return the backing store associated with the
28+
// FlutterView's FlutterSurfaceManager.
29+
//
30+
// Any additional state allocated for the backing store and
31+
// saved as user_data in the backing store must be collected
32+
// in the backing_store's desctruction_callback field which will
33+
// be called when the embedder collects the backing store.
34+
bool CreateBackingStore(const FlutterBackingStoreConfig* config,
35+
FlutterBackingStore* backing_store_out);
36+
37+
// Releases the memory for any state used by the backing store.
38+
bool CollectBackingStore(const FlutterBackingStore* backing_store);
39+
40+
// Presents the FlutterLayers by updating FlutterView(s) using the
41+
// layer content.
42+
// Present sets frame_started_ to false.
43+
bool Present(const FlutterLayer** layers, size_t layers_count);
44+
45+
using PresentCallback = std::function<bool()>;
46+
47+
// PresentCallback is called at the end of the Present function.
48+
void SetPresentCallback(const PresentCallback& present_callback);
49+
50+
private:
51+
const FlutterViewController* view_controller_;
52+
const NSOpenGLContext* open_gl_context_;
53+
PresentCallback present_callback_;
54+
55+
// Count for how many CALayers have been created for a frame.
56+
// Resets when a frame is finished.
57+
// ca_layer_count_ is also used as a layerId.
58+
size_t ca_layer_count_ = 0;
59+
60+
// Maps a layer_id (size_t) to a CALayer.
61+
// The layer_id starts at 0 for a given frame
62+
// and increments by 1 for each new CALayer.
63+
std::map<size_t, CALayer*> ca_layer_map_;
64+
65+
// frame_started_ keeps track of if a layer has been
66+
// created for the frame.
67+
bool frame_started_ = false;
68+
69+
// Set frame_started_ to true and reset all layer state.
70+
void StartFrame();
71+
72+
// Creates a CALayer and adds it to ca_layer_map_ and increments
73+
// ca_layer_count_; Returns the key value (size_t) for the layer in
74+
// ca_layer_map_.
75+
size_t CreateCALayer();
76+
77+
FML_DISALLOW_COPY_AND_ASSIGN(FlutterGLCompositor);
78+
};
79+
80+
} // namespace flutter

0 commit comments

Comments
 (0)