diff --git a/shell/platform/darwin/macos/BUILD.gn b/shell/platform/darwin/macos/BUILD.gn index aef31afad26a0..3ad09aa02bd78 100644 --- a/shell/platform/darwin/macos/BUILD.gn +++ b/shell/platform/darwin/macos/BUILD.gn @@ -77,7 +77,6 @@ source_set("flutter_framework_source") { deps = [ "//flutter/flow:flow", "//flutter/fml", - "//flutter/fml:fml", "//flutter/shell/platform/common/cpp:common_cpp_switches", "//flutter/shell/platform/darwin/common:framework_shared", "//flutter/shell/platform/embedder:embedder_as_internal_library", @@ -123,8 +122,8 @@ executable("flutter_desktop_darwin_unittests") { "framework/Source/FlutterEngineTest.mm", "framework/Source/FlutterMacOSGLCompositorUnittests.mm", "framework/Source/FlutterViewControllerTest.mm", - "framework/Source/FlutterViewControllerTestsUtils.h", - "framework/Source/FlutterViewControllerTestsUtils.mm", + "framework/Source/FlutterViewControllerTestUtils.h", + "framework/Source/FlutterViewControllerTestUtils.mm", ] cflags_objcc = [ "-fobjc-arc" ] diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 2cb72d1745a46..03e942fbbe1a9 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -151,6 +151,7 @@ static bool OnPresent(FlutterEngine* engine) { } static uint32_t OnFBO(FlutterEngine* engine, const FlutterFrameInfo* info) { + NSLog(@"OnFBO"); return [engine engineCallbackOnFBO:info]; } @@ -201,7 +202,11 @@ @implementation FlutterEngine { // FlutterMacOSGLCompositor is created by the engine. // This is only created when the engine has a FlutterViewController // and used to support platform views. + // Creation / Destruction. std::unique_ptr _macOSCompositor; + + // FlutterCompositor is copied and used in embedder.cc. + FlutterCompositor _compositor; } - (instancetype)initWithName:(NSString*)labelPrefix project:(FlutterDartProject*)project { @@ -311,14 +316,8 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { flutterArguments.aot_data = _aotData; } - // Only create a Compositor if we have a ViewController. - if (_viewController) { - // Engine does not need to manage the life cycle of compositor - // since compositor is captured and copied in embedder.cc. - FlutterCompositor compositor = {}; - [self setupCompositor:&compositor]; - flutterArguments.compositor = &compositor; - } + [self setupCompositor]; + flutterArguments.compositor = &_compositor; FlutterEngineResult result = _embedderAPI.Initialize( FLUTTER_ENGINE_VERSION, &rendererConfig, &flutterArguments, (__bridge void*)(self), &_engine); @@ -374,16 +373,16 @@ - (void)setViewController:(FlutterViewController*)controller { } } -- (void)setupCompositor:(FlutterCompositor*)compositor { +- (void)setupCompositor { [_mainOpenGLContext makeCurrentContext]; - _macOSCompositor = - std::make_unique(_viewController, _resourceContext); + _macOSCompositor = std::make_unique(_viewController); - compositor->struct_size = sizeof(FlutterCompositor); - compositor->user_data = _macOSCompositor.get(); + _compositor = {}; + _compositor.struct_size = sizeof(FlutterCompositor); + _compositor.user_data = _macOSCompositor.get(); - compositor->create_backing_store_callback = [](const FlutterBackingStoreConfig* config, // + _compositor.create_backing_store_callback = [](const FlutterBackingStoreConfig* config, // FlutterBackingStore* backing_store_out, // void* user_data // ) { @@ -391,14 +390,14 @@ - (void)setupCompositor:(FlutterCompositor*)compositor { config, backing_store_out); }; - compositor->collect_backing_store_callback = [](const FlutterBackingStore* backing_store, // + _compositor.collect_backing_store_callback = [](const FlutterBackingStore* backing_store, // void* user_data // ) { return reinterpret_cast(user_data)->CollectBackingStore( backing_store); }; - compositor->present_layers_callback = [](const FlutterLayer** layers, // + _compositor.present_layers_callback = [](const FlutterLayer** layers, // size_t layers_count, // void* user_data // ) { @@ -406,7 +405,9 @@ - (void)setupCompositor:(FlutterCompositor*)compositor { layers_count); }; - _macOSCompositor->SetPresentCallback([self]() { return [self engineCallbackOnPresent]; }); + __weak FlutterEngine* weak_self = self; + _macOSCompositor->SetPresentCallback( + [weak_self]() { return [weak_self engineCallbackOnPresent]; }); } - (id)binaryMessenger { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h index d7da3be7599d3..0439b4acf35fa 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h @@ -12,19 +12,15 @@ namespace flutter { -/** - * FlutterMacOSGLCompositor creates and manages backing stores used for - * rendering Flutter content and presents Flutter content and Platform views. - */ +// FlutterMacOSGLCompositor creates and manages the backing stores used for +// rendering Flutter content and presents Flutter content and Platform views. +// Platform views are not yet supported. class FlutterMacOSGLCompositor { public: - FlutterMacOSGLCompositor(FlutterViewController* view_controller, - NSOpenGLContext* open_gl_context); + FlutterMacOSGLCompositor(FlutterViewController* view_controller); - virtual ~FlutterMacOSGLCompositor(); - - // Creates a backing store according to FlutterBackingStoreConfig - // by modifying backing_store_out. + // Creates a FlutterSurfaceManager and uses the FlutterSurfaceManager's + // underlying FBO and texture in the backing store. bool CreateBackingStore(const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out); @@ -40,17 +36,11 @@ class FlutterMacOSGLCompositor { // PresentCallback is called at the end of the Present function. void SetPresentCallback(const PresentCallback& present_callback); - protected: + private: FlutterViewController* view_controller_; PresentCallback present_callback_; NSOpenGLContext* open_gl_context_; - // Creates a FlutterSurfaceManager and uses the FlutterSurfaceManager's - // underlying FBO and texture in the backing store. - bool CreateBackingStoreUsingSurfaceManager( - const FlutterBackingStoreConfig* config, - FlutterBackingStore* backing_store_out); - FML_DISALLOW_COPY_AND_ASSIGN(FlutterMacOSGLCompositor); }; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.mm b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.mm index 975532b791c94..a8c795cdec798 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.mm @@ -16,15 +16,39 @@ namespace flutter { -FlutterMacOSGLCompositor::FlutterMacOSGLCompositor(FlutterViewController* view_controller, - NSOpenGLContext* open_gl_context) - : view_controller_(view_controller), open_gl_context_(open_gl_context) {} - -FlutterMacOSGLCompositor::~FlutterMacOSGLCompositor() = default; +FlutterMacOSGLCompositor::FlutterMacOSGLCompositor(FlutterViewController* view_controller) + : view_controller_(view_controller), + open_gl_context_(view_controller.flutterView.openGLContext) {} bool FlutterMacOSGLCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { - return CreateBackingStoreUsingSurfaceManager(config, backing_store_out); + FlutterSurfaceManager* surfaceManager = + [[FlutterSurfaceManager alloc] initWithLayer:view_controller_.flutterView.layer + openGLContext:open_gl_context_ + numFramebuffers:1]; + + GLuint fbo = [surfaceManager getFramebuffer]; + GLuint texture = [surfaceManager getTexture]; + + CGSize size = CGSizeMake(config->size.width, config->size.height); + size_t kFlutterSurfaceManagerFrontBuffer = 0; + [surfaceManager backTextureWithIOSurface:kFlutterSurfaceManagerFrontBuffer + size:size + backingTexture:texture + fbo:fbo]; + + backing_store_out->type = kFlutterBackingStoreTypeOpenGL; + backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; + backing_store_out->open_gl.framebuffer.target = GL_RGBA8; + backing_store_out->open_gl.framebuffer.name = fbo; + backing_store_out->open_gl.framebuffer.user_data = (__bridge_retained void*)surfaceManager; + backing_store_out->open_gl.framebuffer.destruction_callback = [](void* user_data) { + if (user_data != nullptr) { + CFRelease(user_data); + } + }; + + return true; } bool FlutterMacOSGLCompositor::CollectBackingStore(const FlutterBackingStore* backing_store) { @@ -40,11 +64,12 @@ switch (layer->type) { case kFlutterLayerContentTypeBackingStore: { FlutterSurfaceManager* surfaceManager = - (__bridge FlutterSurfaceManager*)backing_store->user_data; + (__bridge FlutterSurfaceManager*)backing_store->open_gl.framebuffer.user_data; CGSize size = CGSizeMake(layer->size.width, layer->size.height); [view_controller_.flutterView frameBufferIDForSize:size]; - [surfaceManager setLayerContentWithIOSurface:[surfaceManager getIOSurface]]; + size_t kFlutterSurfaceManagerFrontBuffer = 0; + [surfaceManager setLayerContentWithIOSurface:kFlutterSurfaceManagerFrontBuffer]; break; } case kFlutterLayerContentTypePlatformView: @@ -56,36 +81,6 @@ return present_callback_(); } -bool FlutterMacOSGLCompositor::CreateBackingStoreUsingSurfaceManager( - const FlutterBackingStoreConfig* config, - FlutterBackingStore* backing_store_out) { - FlutterSurfaceManager* surfaceManager = - [[FlutterSurfaceManager alloc] initWithLayer:view_controller_.flutterView.layer - openGLContext:open_gl_context_]; - - GLuint fbo = [surfaceManager getFramebuffer]; - GLuint texture = [surfaceManager getTexture]; - IOSurfaceRef* io_surface_ref = [surfaceManager getIOSurface]; - - CGSize size = CGSizeMake(config->size.width, config->size.height); - - [surfaceManager backTextureWithIOSurface:io_surface_ref size:size backingTexture:texture fbo:fbo]; - - backing_store_out->type = kFlutterBackingStoreTypeOpenGL; - backing_store_out->user_data = (__bridge_retained void*)surfaceManager; - backing_store_out->open_gl.type = kFlutterOpenGLTargetTypeFramebuffer; - backing_store_out->open_gl.framebuffer.target = GL_RGBA8; - backing_store_out->open_gl.framebuffer.name = fbo; - backing_store_out->open_gl.framebuffer.user_data = backing_store_out->user_data; - backing_store_out->open_gl.framebuffer.destruction_callback = [](void* user_data) { - if (user_data != nullptr) { - CFRelease(user_data); - } - }; - - return true; -} - void FlutterMacOSGLCompositor::SetPresentCallback( const FlutterMacOSGLCompositor::PresentCallback& present_callback) { present_callback_ = present_callback; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositorUnittests.mm b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositorUnittests.mm index 6a5ffacbda140..6383a1cd2a6b5 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositorUnittests.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositorUnittests.mm @@ -5,7 +5,7 @@ #import #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterMacOSGLCompositor.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h" #import "flutter/testing/testing.h" namespace flutter::testing { @@ -14,7 +14,7 @@ id mockViewController = CreateMockViewController(nil); std::unique_ptr macos_compositor = - std::make_unique(mockViewController, nil); + std::make_unique(mockViewController); bool flag = false; macos_compositor->SetPresentCallback([f = &flag]() { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h b/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h index 133b85e969d55..ef41f6a6ada2b 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.h @@ -3,7 +3,9 @@ // Manages the IOSurfaces for FlutterView @interface FlutterSurfaceManager : NSObject -- (instancetype)initWithLayer:(CALayer*)layer openGLContext:(NSOpenGLContext*)opengLContext; +- (instancetype)initWithLayer:(CALayer*)containingLayer + openGLContext:(NSOpenGLContext*)openGLContext + numFramebuffers:(int)numFramebuffers; - (void)ensureSurfaceSize:(CGSize)size; - (void)swapBuffers; @@ -16,14 +18,15 @@ - (void)setLayerContent; /** - * Sets the CALayer content to the content of the provided ioSurface. + * Sets the CALayer content to the content of ioSurface at ioSurfaceNum. */ -- (void)setLayerContentWithIOSurface:(IOSurfaceRef*)ioSurface; +// TODO(richardjcai): Fix this and remove setLayerContent. +- (void)setLayerContentWithIOSurface:(int)ioSurfaceNum; /** * Binds the IOSurface to the provided texture/framebuffer. */ -- (void)backTextureWithIOSurface:(IOSurfaceRef*)ioSurface +- (void)backTextureWithIOSurface:(int)ioSurfaceNum size:(CGSize)size backingTexture:(GLuint)texture fbo:(GLuint)fbo; @@ -47,14 +50,4 @@ */ - (uint32_t)getTexture; -/** - * Returns the kFront IOSurfaceRef. - * The IOSurface is backed by the FBO provided by getFramebuffer - * and texture provided by getTexture. The IOSurface is used - * in FlutterMacOSCompositor's Present call. - * The IOSurface is collected when the backing store that uses the - * IOSurface is collected. - */ -- (IOSurfaceRef*)getIOSurface; - @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm b/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm index 6c44db2c5650b..0cb5fa054e45c 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterSurfaceManager.mm @@ -29,7 +29,8 @@ @interface FlutterSurfaceManager () { @implementation FlutterSurfaceManager - (instancetype)initWithLayer:(CALayer*)containingLayer - openGLContext:(NSOpenGLContext*)openGLContext { + openGLContext:(NSOpenGLContext*)openGLContext + numFramebuffers:(int)numFramebuffers { if (self = [super init]) { _containingLayer = containingLayer; _openGLContext = openGLContext; @@ -41,11 +42,12 @@ - (instancetype)initWithLayer:(CALayer*)containingLayer MacOSGLContextSwitch context_switch(openGLContext); - glGenFramebuffers(2, _frameBufferId); - glGenTextures(2, _backingTexture); + glGenFramebuffers(numFramebuffers, _frameBufferId); + glGenTextures(numFramebuffers, _backingTexture); - [self createFramebuffer:_frameBufferId[0] withBackingTexture:_backingTexture[0]]; - [self createFramebuffer:_frameBufferId[1] withBackingTexture:_backingTexture[1]]; + for (int i = 0; i < numFramebuffers; ++i) { + [self createFramebuffer:_frameBufferId[i] withBackingTexture:_backingTexture[1]]; + } } return self; } @@ -69,19 +71,19 @@ - (void)ensureSurfaceSize:(CGSize)size { MacOSGLContextSwitch context_switch(_openGLContext); for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) { - [self backTextureWithIOSurface:&_ioSurface[i] + [self backTextureWithIOSurface:i size:size backingTexture:_backingTexture[i] fbo:_frameBufferId[i]]; } } -- (void)backTextureWithIOSurface:(IOSurfaceRef*)ioSurface +- (void)backTextureWithIOSurface:(int)ioSurfaceNum size:(CGSize)size backingTexture:(GLuint)texture fbo:(GLuint)fbo { - if (ioSurface != nullptr && *ioSurface) { - CFRelease(*ioSurface); + if (_ioSurface[ioSurfaceNum]) { + CFRelease(_ioSurface[ioSurfaceNum]); } unsigned pixelFormat = 'BGRA'; @@ -97,13 +99,13 @@ - (void)backTextureWithIOSurface:(IOSurfaceRef*)ioSurface (id)kIOSurfaceBytesPerRow : @(bytesPerRow), (id)kIOSurfaceAllocSize : @(totalBytes), }; - *ioSurface = IOSurfaceCreate((CFDictionaryRef)options); + _ioSurface[ioSurfaceNum] = IOSurfaceCreate((CFDictionaryRef)options); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture); CGLTexImageIOSurface2D(CGLGetCurrentContext(), GL_TEXTURE_RECTANGLE_ARB, GL_RGBA, int(size.width), - int(size.height), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, *ioSurface, - 0 /* plane */); + int(size.height), GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, + _ioSurface[ioSurfaceNum], 0 /* plane */); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glBindFramebuffer(GL_FRAMEBUFFER, fbo); @@ -115,16 +117,16 @@ - (void)backTextureWithIOSurface:(IOSurfaceRef*)ioSurface } - (void)setLayerContent { - [self setLayerContentWithIOSurface:&_ioSurface[kFlutterSurfaceManagerBackBuffer]]; + [self setLayerContentWithIOSurface:kFlutterSurfaceManagerBackBuffer]; } -- (void)setLayerContentWithIOSurface:(IOSurfaceRef*)ioSurface { +- (void)setLayerContentWithIOSurface:(int)ioSurfaceNum { _contentLayer.frame = _containingLayer.bounds; // The surface is an OpenGL texture, which means it has origin in bottom left corner // and needs to be flipped vertically _contentLayer.transform = CATransform3DMakeScale(1, -1, 1); - [_contentLayer setContents:(__bridge id) * ioSurface]; + [_contentLayer setContents:(__bridge id)_ioSurface[ioSurfaceNum]]; } - (void)swapBuffers { @@ -148,11 +150,10 @@ - (uint32_t)getTexture { return _backingTexture[kFlutterSurfaceManagerFrontBuffer]; } -- (IOSurfaceRef*)getIOSurface { - return &_ioSurface[kFlutterSurfaceManagerFrontBuffer]; -} - - (void)dealloc { + [_contentLayer removeFromSuperlayer]; + glDeleteFramebuffers(kFlutterSurfaceManagerBufferCount, _frameBufferId); + glDeleteTextures(kFlutterSurfaceManagerBufferCount, _backingTexture); for (int i = 0; i < kFlutterSurfaceManagerBufferCount; ++i) { if (_ioSurface[i]) { CFRelease(_ioSurface[i]); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index f39d48bd7caae..9a5f9270cbfca 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -38,7 +38,8 @@ - (instancetype)initWithFrame:(NSRect)frame _resizeSynchronizer = [[FlutterResizeSynchronizer alloc] initWithDelegate:self]; _surfaceManager = [[FlutterSurfaceManager alloc] initWithLayer:self.layer - openGLContext:self.openGLContext]; + openGLContext:self.openGLContext + numFramebuffers:2]; _reshapeListener = reshapeListener; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm index 04816733f6a15..671520f494923 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTest.mm @@ -9,7 +9,7 @@ #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterEngine.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterDartProject_Internal.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h" #include "flutter/testing/testing.h" namespace flutter::testing { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.h b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h similarity index 100% rename from shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.h rename to shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm similarity index 96% rename from shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.mm rename to shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm index 656661e443ed9..04f320ba97030 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm @@ -1,4 +1,4 @@ -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestsUtils.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h" namespace flutter::testing {