Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -2661,6 +2661,10 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewC
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProviderUnittests.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/KeyCodeMap.g.mm
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/KeyCodeMap_Internal.h
FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/MacOSGLContextSwitch.h
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/darwin/macos/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ source_set("flutter_framework_source") {
"framework/Source/FlutterView.mm",
"framework/Source/FlutterViewController.mm",
"framework/Source/FlutterViewController_Internal.h",
"framework/Source/FlutterViewEngineProvider.h",
"framework/Source/FlutterViewEngineProvider.mm",
"framework/Source/FlutterViewProvider.h",
"framework/Source/KeyCodeMap.g.mm",
"framework/Source/MacOSGLContextSwitch.h",
"framework/Source/MacOSGLContextSwitch.mm",
Expand Down Expand Up @@ -202,6 +205,7 @@ executable("flutter_desktop_darwin_unittests") {
"framework/Source/FlutterViewControllerTest.mm",
"framework/Source/FlutterViewControllerTestUtils.h",
"framework/Source/FlutterViewControllerTestUtils.mm",
"framework/Source/FlutterViewEngineProviderUnitTests.mm",
"framework/Source/TestFlutterPlatformView.h",
"framework/Source/TestFlutterPlatformView.mm",
]
Expand Down
21 changes: 17 additions & 4 deletions shell/platform/darwin/macos/framework/Source/FlutterCompositor.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#include <list>

#include "flutter/fml/macros.h"
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h"
#include "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewProvider.h"
#include "flutter/shell/platform/embedder/embedder.h"

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

virtual ~FlutterCompositor() = default;

Expand Down Expand Up @@ -62,7 +68,10 @@ class FlutterCompositor {
typedef enum { kStarted, kPresenting, kEnded } FrameStatus;

protected:
__weak const FlutterViewController* view_controller_;
// Get the view associated with the view ID.
//
// Returns nil if the ID is invalid.
FlutterView* GetView(uint64_t view_id);

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

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

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

// Where the compositor can query FlutterViews. Must not be null.
id<FlutterViewProvider> const view_provider_;

// Callback set by the embedder to be called when the layer tree has been
// correctly set up for this frame.
PresentCallback present_callback_;
Expand Down
18 changes: 11 additions & 7 deletions shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,9 @@

namespace flutter {

FlutterCompositor::FlutterCompositor(FlutterViewController* view_controller) {
FML_CHECK(view_controller != nullptr) << "FlutterViewController* cannot be nullptr";

view_controller_ = view_controller;
FlutterCompositor::FlutterCompositor(id<FlutterViewProvider> view_provider)
: view_provider_(view_provider) {
FML_CHECK(view_provider != nullptr) << "FlutterViewProvider* cannot be nullptr";
}

void FlutterCompositor::SetPresentCallback(
Expand All @@ -35,6 +34,10 @@
return status;
}

FlutterView* FlutterCompositor::GetView(uint64_t view_id) {
return [view_provider_ getView:view_id];
}

void FlutterCompositor::SetFrameStatus(FlutterCompositor::FrameStatus frame_status) {
frame_status_ = frame_status;
}
Expand All @@ -43,14 +46,15 @@
return frame_status_;
}

void FlutterCompositor::InsertCALayerForIOSurface(const IOSurfaceRef& io_surface,
void FlutterCompositor::InsertCALayerForIOSurface(FlutterView* view,
const IOSurfaceRef& io_surface,
CATransform3D transform) {
// FlutterCompositor manages the lifecycle of CALayers.
CALayer* content_layer = [[CALayer alloc] init];
content_layer.transform = transform;
content_layer.frame = view_controller_.flutterView.layer.bounds;
content_layer.frame = view.layer.bounds;
[content_layer setContents:(__bridge id)io_surface];
[view_controller_.flutterView.layer addSublayer:content_layer];
[view.layer addSublayer:content_layer];

active_ca_layers_.push_back(content_layer);
}
Expand Down
10 changes: 7 additions & 3 deletions shell/platform/darwin/macos/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderingBackend.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h"
#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewEngineProvider.h"
#include "flutter/shell/platform/embedder/embedder.h"

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

FlutterViewEngineProvider* _viewProvider;

// FlutterCompositor is copied and used in embedder.cc.
FlutterCompositor _compositor;

Expand Down Expand Up @@ -244,6 +247,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix
_currentMessengerConnection = 1;
_allowHeadlessExecution = allowHeadlessExecution;
_semanticsEnabled = NO;
_viewProvider = [[FlutterViewEngineProvider alloc] initWithEngine:self];

_embedderAPI.struct_size = sizeof(FlutterEngineProcTable);
FlutterEngineGetProcAddresses(&_embedderAPI);
Expand Down Expand Up @@ -437,12 +441,12 @@ - (FlutterCompositor*)createFlutterCompositor {
if ([FlutterRenderingBackend renderUsingMetal]) {
FlutterMetalRenderer* metalRenderer = reinterpret_cast<FlutterMetalRenderer*>(_renderer);
_macOSCompositor = std::make_unique<flutter::FlutterMetalCompositor>(
_viewController, _platformViewController, metalRenderer.device);
_viewProvider, _platformViewController, metalRenderer.device);
} else {
FlutterOpenGLRenderer* openGLRenderer = reinterpret_cast<FlutterOpenGLRenderer*>(_renderer);
[openGLRenderer.openGLContext makeCurrentContext];
_macOSCompositor = std::make_unique<flutter::FlutterGLCompositor>(_viewController,
openGLRenderer.openGLContext);
_macOSCompositor =
std::make_unique<flutter::FlutterGLCompositor>(_viewProvider, openGLRenderer.openGLContext);
}
_macOSCompositor->SetPresentCallback([weakSelf](bool has_flutter_content) {
if (has_flutter_content) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace flutter {
// FlutterGLCompositor is created and destroyed by FlutterEngine.
class FlutterGLCompositor : public FlutterCompositor {
public:
FlutterGLCompositor(FlutterViewController* view_controller,
FlutterGLCompositor(id<FlutterViewProvider> view_provider,
NSOpenGLContext* opengl_context);

virtual ~FlutterGLCompositor() = default;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,17 @@

namespace flutter {

FlutterGLCompositor::FlutterGLCompositor(FlutterViewController* view_controller,
FlutterGLCompositor::FlutterGLCompositor(id<FlutterViewProvider> view_provider,
NSOpenGLContext* opengl_context)
: FlutterCompositor(view_controller), open_gl_context_(opengl_context) {}
: FlutterCompositor(view_provider), open_gl_context_(opengl_context) {}

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

Expand All @@ -36,8 +40,7 @@
// If the backing store is for the first layer, return the fbo for the
// FlutterView.
FlutterOpenGLRenderBackingStore* backingStore =
reinterpret_cast<FlutterOpenGLRenderBackingStore*>(
[view_controller_.flutterView backingStoreForSize:size]);
reinterpret_cast<FlutterOpenGLRenderBackingStore*>([view backingStoreForSize:size]);
backing_store_out->open_gl.framebuffer.name = backingStore.frameBufferID;
} else {
FlutterFrameBufferProvider* fb_provider =
Expand Down Expand Up @@ -75,6 +78,14 @@
}

bool FlutterGLCompositor::Present(const FlutterLayer** layers, size_t layers_count) {
// TODO(dkwingsmt): This class only supports single-view for now. As more
// classes are gradually converted to multi-view, it should get the view ID
// from somewhere.
FlutterView* view = GetView(kFlutterDefaultViewId);
if (!view) {
return false;
}

SetFrameStatus(FrameStatus::kPresenting);

bool has_flutter_content = false;
Expand All @@ -93,7 +104,7 @@

// The surface is an OpenGL texture, which means it has origin in bottom left corner
// and needs to be flipped vertically
InsertCALayerForIOSurface(io_surface, CATransform3DMakeScale(1, -1, 1));
InsertCALayerForIOSurface(view, io_surface, CATransform3DMakeScale(1, -1, 1));
}
has_flutter_content = true;
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,52 @@
// found in the LICENSE file.

#import <Foundation/Foundation.h>
#import <OCMock/OCMock.h>

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

@interface FlutterViewMockProviderGL : NSObject <FlutterViewProvider> {
FlutterView* _defaultView;
}
/**
* Create a FlutterViewMockProviderGL with the provided view as the default view.
*/
- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view;
@end

@implementation FlutterViewMockProviderGL

- (nonnull instancetype)initWithDefaultView:(nonnull FlutterView*)view {
self = [super init];
if (self != nil) {
_defaultView = view;
}
return self;
}

- (nullable FlutterView*)getView:(uint64_t)viewId {
if (viewId == kFlutterDefaultViewId) {
return _defaultView;
}
return nil;
}

@end

namespace flutter::testing {
namespace {

TEST(FlutterGLCompositorTest, TestPresent) {
id mockViewController = CreateMockViewController();
id<FlutterViewProvider> MockViewProvider() {
id viewMock = OCMClassMock([FlutterView class]);
return [[FlutterViewMockProviderGL alloc] initWithDefaultView:viewMock];
}
} // namespace

TEST(FlutterGLCompositorTest, TestPresent) {
std::unique_ptr<flutter::FlutterGLCompositor> macos_compositor =
std::make_unique<FlutterGLCompositor>(mockViewController, nullptr);
std::make_unique<FlutterGLCompositor>(MockViewProvider(), nullptr);

bool flag = false;
macos_compositor->SetPresentCallback([f = &flag](bool has_flutter_content) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace flutter {
class FlutterMetalCompositor : public FlutterCompositor {
public:
explicit FlutterMetalCompositor(
FlutterViewController* view_controller,
id<FlutterViewProvider> view_provider,
FlutterPlatformViewController* platform_views_controller,
id<MTLDevice> mtl_device);

Expand Down Expand Up @@ -46,8 +46,11 @@ class FlutterMetalCompositor : public FlutterCompositor {

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

const id<MTLDevice> mtl_device_;
const FlutterPlatformViewController* platform_views_controller_;
Expand Down
Loading