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

Commit d5dfc8c

Browse files
committed
Refactor MacOS to use FlutterMacOSCompositor for creating backing stores using
FlutterSurfaceManager.
1 parent 59b01e0 commit d5dfc8c

10 files changed

+354
-57
lines changed

shell/platform/darwin/macos/BUILD.gn

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ source_set("flutter_framework_source") {
5252
"framework/Source/FlutterEngine_Internal.h",
5353
"framework/Source/FlutterExternalTextureGL.h",
5454
"framework/Source/FlutterExternalTextureGL.mm",
55+
"framework/Source/FlutterMacOSGLCompositor.h",
56+
"framework/Source/FlutterMacOSGLCompositor.mm",
5557
"framework/Source/FlutterMouseCursorPlugin.h",
5658
"framework/Source/FlutterMouseCursorPlugin.mm",
5759
"framework/Source/FlutterResizeSynchronizer.h",
@@ -74,10 +76,12 @@ source_set("flutter_framework_source") {
7476

7577
deps = [
7678
"//flutter/flow:flow",
79+
"//flutter/fml",
7780
"//flutter/fml:fml",
7881
"//flutter/shell/platform/common/cpp:common_cpp_switches",
7982
"//flutter/shell/platform/darwin/common:framework_shared",
8083
"//flutter/shell/platform/embedder:embedder_as_internal_library",
84+
"//third_party/skia",
8185
]
8286

8387
public_configs = [ "//flutter:config" ]
@@ -117,7 +121,9 @@ executable("flutter_desktop_darwin_unittests") {
117121

118122
sources = [
119123
"framework/Source/FlutterEngineTest.mm",
124+
"framework/Source/FlutterMacOSGLCompositorUnittests.mm",
120125
"framework/Source/FlutterViewControllerTest.mm",
126+
"framework/Source/MockFlutterViewController.h",
121127
]
122128

123129
cflags_objcc = [ "-fobjc-arc" ]

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

Lines changed: 45 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/FlutterMacOSGLCompositor.h"
1414
#import "flutter/shell/platform/embedder/embedder.h"
1515

1616
/**
@@ -193,6 +193,9 @@ @implementation FlutterEngine {
193193

194194
// Pointer to the Dart AOT snapshot and instruction data.
195195
_FlutterEngineAOTData* _aotData;
196+
197+
// FlutterMacOSGLCompositor is created by the engine.
198+
std::unique_ptr<flutter::FlutterMacOSGLCompositor> _macOSCompositor;
196199
}
197200

198201
- (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project {
@@ -302,6 +305,13 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint {
302305
flutterArguments.aot_data = _aotData;
303306
}
304307

308+
// Only create a Compositor if we have a ViewController.
309+
if (_viewController) {
310+
FlutterCompositor compositor = {};
311+
[self setupCompositor:&compositor];
312+
flutterArguments.compositor = &compositor;
313+
}
314+
305315
FlutterEngineResult result = _embedderAPI.Initialize(
306316
FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine);
307317
if (result != kSuccess) {
@@ -360,6 +370,40 @@ - (void)setViewController:(FlutterViewController*)controller {
360370
}
361371
}
362372

373+
- (void)setupCompositor:(FlutterCompositor*)compositor {
374+
[_mainOpenGLContext makeCurrentContext];
375+
376+
_macOSCompositor = std::make_unique<flutter::FlutterMacOSGLCompositor>(_viewController);
377+
378+
compositor->struct_size = sizeof(FlutterCompositor);
379+
compositor->user_data = _macOSCompositor.get();
380+
381+
compositor->create_backing_store_callback = [](const FlutterBackingStoreConfig* config, //
382+
FlutterBackingStore* backing_store_out, //
383+
void* user_data //
384+
) {
385+
return reinterpret_cast<flutter::FlutterMacOSGLCompositor*>(user_data)->CreateBackingStore(
386+
config, backing_store_out);
387+
};
388+
389+
compositor->collect_backing_store_callback = [](const FlutterBackingStore* backing_store, //
390+
void* user_data //
391+
) {
392+
return reinterpret_cast<flutter::FlutterMacOSGLCompositor*>(user_data)->CollectBackingStore(
393+
backing_store);
394+
};
395+
396+
compositor->present_layers_callback = [](const FlutterLayer** layers, //
397+
size_t layers_count, //
398+
void* user_data //
399+
) {
400+
return reinterpret_cast<flutter::FlutterMacOSGLCompositor*>(user_data)->Present(layers,
401+
layers_count);
402+
};
403+
404+
_macOSCompositor->SetPresentCallback([self]() { return [self engineCallbackOnPresent]; });
405+
}
406+
363407
- (id<FlutterBinaryMessenger>)binaryMessenger {
364408
// TODO(stuartmorgan): Switch to FlutterBinaryMessengerRelay to avoid plugins
365409
// keeping the engine alive.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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 <vector>
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+
class FlutterMacOSGLCompositor {
16+
public:
17+
FlutterMacOSGLCompositor(FlutterViewController* view_controller);
18+
19+
virtual ~FlutterMacOSGLCompositor();
20+
21+
bool CreateBackingStore(const FlutterBackingStoreConfig* config,
22+
FlutterBackingStore* backing_store_out);
23+
24+
bool CollectBackingStore(const FlutterBackingStore* backing_store);
25+
26+
bool Present(const FlutterLayer** layers, size_t layers_count);
27+
28+
using PresentCallback = std::function<bool()>;
29+
30+
void SetPresentCallback(const PresentCallback& present_callback);
31+
32+
protected:
33+
sk_sp<GrDirectContext> context_;
34+
FlutterViewController* view_controller_;
35+
PresentCallback present_callback_;
36+
NSOpenGLContext* openGLContext_;
37+
38+
bool CreateSoftwareRenderSurface(const FlutterBackingStoreConfig* config,
39+
FlutterBackingStore* renderer_out);
40+
41+
bool CreateGLRenderSurface(const FlutterBackingStoreConfig* config,
42+
FlutterBackingStore* backing_store_out);
43+
44+
bool CreateBackingStoreUsingSurfaceManager(
45+
const FlutterBackingStoreConfig* config,
46+
FlutterBackingStore* backing_store_out);
47+
48+
void TextureBackedByIOSurface(const FlutterBackingStoreConfig* config,
49+
FlutterBackingStore* backing_store_out,
50+
GLuint texture,
51+
GLuint fbo,
52+
IOSurfaceRef* io_surface);
53+
54+
FML_DISALLOW_COPY_AND_ASSIGN(FlutterMacOSGLCompositor);
55+
};
56+
57+
} // namespace flutter
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
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/FlutterMacOSGLCompositor.h"
6+
7+
#import <OpenGL/gl.h>
8+
#import "flutter/fml/logging.h"
9+
#import "flutter/fml/platform/darwin/cf_utils.h"
10+
#import "flutter/shell/platform/darwin/macos/framework/Source/MacOSSwitchableGLContext.h"
11+
#import "third_party/skia/include/core/SkCanvas.h"
12+
#import "third_party/skia/include/core/SkSurface.h"
13+
#import "third_party/skia/include/gpu/gl/GrGLAssembleInterface.h"
14+
#import "third_party/skia/include/utils/mac/SkCGUtils.h"
15+
16+
#include <unistd.h>
17+
18+
namespace flutter {
19+
20+
FlutterMacOSGLCompositor::FlutterMacOSGLCompositor(FlutterViewController* view_controller)
21+
: view_controller_(view_controller) {
22+
auto interface = GrGLMakeNativeInterface();
23+
GrContextOptions options;
24+
context_ = GrDirectContext::MakeGL(GrGLMakeNativeInterface(), options);
25+
26+
openGLContext_ =
27+
[[NSOpenGLContext alloc] initWithFormat:view_controller_.flutterView.openGLContext.pixelFormat
28+
shareContext:view_controller_.flutterView.openGLContext];
29+
}
30+
31+
FlutterMacOSGLCompositor::~FlutterMacOSGLCompositor() = default;
32+
33+
bool FlutterMacOSGLCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config,
34+
FlutterBackingStore* backing_store_out) {
35+
return CreateBackingStoreUsingSurfaceManager(config, backing_store_out);
36+
}
37+
38+
bool FlutterMacOSGLCompositor::CollectBackingStore(const FlutterBackingStore* backing_store) {
39+
// We have already set the destruction callback for the various backing
40+
// stores. Our user_data is just the canvas from that backing store and does
41+
// not need to be explicitly collected. Embedders might have some other state
42+
// they want to collect though.
43+
return true;
44+
}
45+
46+
bool FlutterMacOSGLCompositor::Present(const FlutterLayer** layers, size_t layers_count) {
47+
for (size_t i = 0; i < layers_count; ++i) {
48+
const auto* layer = layers[i];
49+
FlutterBackingStore* backing_store = const_cast<FlutterBackingStore*>(layer->backing_store);
50+
switch (layer->type) {
51+
case kFlutterLayerContentTypeBackingStore: {
52+
FlutterSurfaceManager* surfaceManager =
53+
(__bridge FlutterSurfaceManager*)backing_store->user_data;
54+
55+
CGSize size = CGSizeMake(layer->size.width, layer->size.height);
56+
[view_controller_.flutterView getFrameBufferIdForSize:size];
57+
[surfaceManager setLayerContentWithIOSurface:[surfaceManager getIOSurface]];
58+
break;
59+
}
60+
case kFlutterLayerContentTypePlatformView:
61+
// Add functionality in follow up PR.
62+
break;
63+
};
64+
}
65+
return present_callback_();
66+
}
67+
68+
bool FlutterMacOSGLCompositor::CreateBackingStoreUsingSurfaceManager(
69+
const FlutterBackingStoreConfig* config,
70+
FlutterBackingStore* backing_store_out) {
71+
FlutterSurfaceManager* surfaceManager =
72+
[[FlutterSurfaceManager alloc] initWithLayer:view_controller_.flutterView.layer
73+
openGLContext:openGLContext_];
74+
75+
GLuint fbo = [surfaceManager getFramebuffer];
76+
GLuint texture = [surfaceManager getTexture];
77+
IOSurfaceRef* io_surface_ref = [surfaceManager getIOSurface];
78+
79+
CGSize size = CGSizeMake(config->size.width, config->size.height);
80+
81+
[surfaceManager BackTextureWithIOSurface:size
82+
withBackingTexture:texture
83+
withFbo:fbo
84+
withIOSurface:io_surface_ref];
85+
86+
backing_store_out->type = kFlutterBackingStoreTypeOpenGL;
87+
backing_store_out->user_data = (__bridge_retained void*)surfaceManager;
88+
backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer;
89+
backing_store_out->open_gl.framebuffer.target = GL_RGBA8;
90+
backing_store_out->open_gl.framebuffer.name = fbo;
91+
backing_store_out->open_gl.framebuffer.user_data = nullptr;
92+
// surfaceManager is managed by ARC. Nothing to be done in destruction callback.
93+
backing_store_out->open_gl.framebuffer.destruction_callback = [](void* user_data) {};
94+
95+
return true;
96+
}
97+
98+
void FlutterMacOSGLCompositor::SetPresentCallback(
99+
const FlutterMacOSGLCompositor::PresentCallback& present_callback) {
100+
present_callback_ = present_callback;
101+
}
102+
103+
} // namespace flutter
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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 <Foundation/Foundation.h>
6+
7+
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h"
8+
#import "flutter/shell/platform/darwin/macos/framework/Source/MockFlutterViewController.h"
9+
#import "flutter/testing/testing.h"
10+
11+
namespace flutter::testing {
12+
13+
TEST(FlutterMacOSGLCompositorTest, TestPresent) {
14+
id mockViewController = CreateMockViewController(nil);
15+
16+
std::unique_ptr<flutter::FlutterMacOSGLCompositor> macos_compositor =
17+
std::make_unique<FlutterMacOSGLCompositor>(mockViewController);
18+
19+
bool flag = false;
20+
macos_compositor->SetPresentCallback([f = &flag]() {
21+
*f = true;
22+
return true;
23+
});
24+
25+
ASSERT_TRUE(macos_compositor->Present(nil, 0));
26+
ASSERT_TRUE(flag);
27+
}
28+
29+
} // flutter::testing

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,19 @@
1010

1111
- (uint32_t)glFrameBufferId;
1212

13+
- (void)setLayerContent;
14+
- (void)setLayerContentWithIOSurface:(IOSurfaceRef*)ioSurface;
15+
16+
- (void)BackTextureWithIOSurface:(CGSize)size
17+
withBackingTexture:(GLuint)texture
18+
withFbo:(GLuint)fbo
19+
withIOSurface:(IOSurfaceRef*)ioSurface;
20+
21+
// Methods used by FlutterMacOSCompositor to render Flutter content
22+
// using a single Framebuffer/Texture/IOSurface.
23+
- (uint32_t)getFramebuffer;
24+
- (uint32_t)getTexture;
25+
- (IOSurfaceRef*)getIOSurface;
26+
- (CALayer*)getCALayer;
27+
1328
@end

0 commit comments

Comments
 (0)