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: 0 additions & 4 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -396,10 +396,6 @@ - (void)performAction:(FlutterTextInputAction)action withClient:(int)client {
return _shell->Screenshot(type, base64Encode);
}

- (flow::ExternalViewEmbedder*)externalViewEmbedder {
return _platformViewsController.get();
}

#pragma mark - FlutterBinaryMessenger

- (void)sendOnChannel:(NSString*)channel message:(NSData*)message {
Expand Down
29 changes: 27 additions & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,6 @@
flutterView:flutter_view_] autorelease];
views_[viewId] = fml::scoped_nsobject<FlutterTouchInterceptingView>([view retain]);

UIView* flutter_view = flutter_view_.get();
[flutter_view addSubview:views_[viewId].get()];
result(nil);
}

Expand Down Expand Up @@ -127,6 +125,33 @@

UIView* view = views_[view_id];
[view setFrame:rect];
composition_order_.push_back(view_id);
}

void FlutterPlatformViewsController::Present() {
if (composition_order_ == active_composition_order_) {
composition_order_.clear();
return;
}
UIView* flutter_view = flutter_view_.get();

// This can be more efficient, instead of removing all views and then re-attaching them,
// we should only remove the views that has been completly removed from the layer tree, and
// reorder the views using UIView's bringSubviewToFront.
// TODO(amirh): make this more efficient.
// https://github.com/flutter/flutter/issues/23793
for (UIView* sub_view in [flutter_view subviews]) {
[sub_view removeFromSuperview];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding and removing subviews will trigger unnecessary layout passes in their view hierarchies. Instead, please iterate over the views in composition order and call bringSubviewToFront:

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So something like, add the view if it has not superview ortherwise just bring it to the front before iterating to the next one in composition order.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boy I'm glad you are reviewing this :)

As discussed for now I'm just leaving a TODO, as right now it's a little hard to test, and this shouldn't happen very often.

}

active_composition_order_.clear();
for (size_t i = 0; i < composition_order_.size(); i++) {
int view_id = composition_order_[i];
[flutter_view addSubview:views_[view_id].get()];
active_composition_order_.push_back(view_id);
}

composition_order_.clear();
}

} // namespace shell
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

namespace shell {

class FlutterPlatformViewsController : public flow::ExternalViewEmbedder {
class FlutterPlatformViewsController {
public:
FlutterPlatformViewsController() = default;

Expand All @@ -36,6 +36,8 @@ class FlutterPlatformViewsController : public flow::ExternalViewEmbedder {

void CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params);

void Present();

void OnMethodCall(FlutterMethodCall* call, FlutterResult& result);

private:
Expand All @@ -44,6 +46,13 @@ class FlutterPlatformViewsController : public flow::ExternalViewEmbedder {
std::map<std::string, fml::scoped_nsobject<NSObject<FlutterPlatformViewFactory>>> factories_;
std::map<int64_t, fml::scoped_nsobject<FlutterTouchInterceptingView>> views_;

// A vector of embedded view IDs according to their composition order.
// The last ID in this vector belond to the that is composited on top of all others.
std::vector<int64_t> composition_order_;

// The latest composition order that was presented in Present().
std::vector<int64_t> active_composition_order_;

void OnCreate(FlutterMethodCall* call, FlutterResult& result);
void OnDispose(FlutterMethodCall* call, FlutterResult& result);
void OnAcceptGesture(FlutterMethodCall* call, FlutterResult& result);
Expand Down
3 changes: 1 addition & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterView.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

#import "FlutterPlatformViews_Internal.h"

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/shell/common/shell.h"
#include "flutter/shell/platform/darwin/ios/ios_surface.h"
Expand All @@ -21,7 +20,7 @@
- (shell::Rasterizer::Screenshot)takeScreenshot:(shell::Rasterizer::ScreenshotType)type
asBase64Encoded:(BOOL)base64Encode;

- (flow::ExternalViewEmbedder*)externalViewEmbedder;
- (shell::FlutterPlatformViewsController*)platformViewsController;

@end

Expand Down
4 changes: 2 additions & 2 deletions shell/platform/darwin/ios/framework/Source/FlutterView.mm
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ + (Class)layerClass {
fml::scoped_nsobject<CAEAGLLayer> eagl_layer(
reinterpret_cast<CAEAGLLayer*>([self.layer retain]));
return std::make_unique<shell::IOSSurfaceGL>(std::move(eagl_layer),
*[_delegate externalViewEmbedder]);
*[_delegate platformViewsController]);
} else {
fml::scoped_nsobject<CALayer> layer(reinterpret_cast<CALayer*>([self.layer retain]));
return std::make_unique<shell::IOSSurfaceSoftware>(std::move(layer),
*[_delegate externalViewEmbedder]);
*[_delegate platformViewsController]);
}
}

Expand Down
10 changes: 9 additions & 1 deletion shell/platform/darwin/ios/ios_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_H_

#import "flutter/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h"

#include <memory>

#include "flutter/fml/macros.h"
Expand All @@ -15,7 +17,7 @@ namespace shell {

class IOSSurface {
public:
IOSSurface();
IOSSurface(FlutterPlatformViewsController& platform_views_controller);

virtual ~IOSSurface();

Expand All @@ -27,6 +29,12 @@ class IOSSurface {

virtual std::unique_ptr<Surface> CreateGPUSurface() = 0;

protected:
FlutterPlatformViewsController& GetPlatformViewsController();

private:
FlutterPlatformViewsController& platform_views_controller_;

public:
FML_DISALLOW_COPY_AND_ASSIGN(IOSSurface);
};
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/darwin/ios/ios_surface.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,12 @@

namespace shell {

IOSSurface::IOSSurface() = default;
IOSSurface::IOSSurface(FlutterPlatformViewsController& platform_views_controller)
: platform_views_controller_(platform_views_controller) {}

IOSSurface::~IOSSurface() = default;

FlutterPlatformViewsController& IOSSurface::GetPlatformViewsController() {
return platform_views_controller_;
}
} // namespace shell
11 changes: 7 additions & 4 deletions shell/platform/darwin/ios/ios_surface_gl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,12 @@

namespace shell {

class IOSSurfaceGL : public IOSSurface, public GPUSurfaceGLDelegate {
class IOSSurfaceGL : public IOSSurface,
public GPUSurfaceGLDelegate,
public flow::ExternalViewEmbedder {
public:
IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
flow::ExternalViewEmbedder& external_view_embedder);
FlutterPlatformViewsController& platform_views_controller);

~IOSSurfaceGL() override;

Expand All @@ -43,11 +45,12 @@ class IOSSurfaceGL : public IOSSurface, public GPUSurfaceGLDelegate {
// |shell::GPUSurfaceGLDelegate|
flow::ExternalViewEmbedder* GetExternalViewEmbedder() override;

// |flow::ExternalViewEmbedder|
void CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override;

private:
IOSGLContext context_;

flow::ExternalViewEmbedder& external_view_embedder_;

FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceGL);
};

Expand Down
17 changes: 13 additions & 4 deletions shell/platform/darwin/ios/ios_surface_gl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
namespace shell {

IOSSurfaceGL::IOSSurfaceGL(fml::scoped_nsobject<CAEAGLLayer> layer,
flow::ExternalViewEmbedder& view_embedder)
: context_(std::move(layer)), external_view_embedder_(view_embedder) {}
FlutterPlatformViewsController& platform_views_controller)
: IOSSurface(platform_views_controller), context_(std::move(layer)) {}

IOSSurfaceGL::~IOSSurfaceGL() = default;

Expand Down Expand Up @@ -55,11 +55,20 @@

bool IOSSurfaceGL::GLContextPresent() {
TRACE_EVENT0("flutter", "IOSSurfaceGL::GLContextPresent");
return IsValid() ? context_.PresentRenderBuffer() : false;
if (!IsValid() || !context_.PresentRenderBuffer()) {
return false;
}

GetPlatformViewsController().Present();
return true;
}

flow::ExternalViewEmbedder* IOSSurfaceGL::GetExternalViewEmbedder() {
return &external_view_embedder_;
return this;
}

void IOSSurfaceGL::CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) {
GetPlatformViewsController().CompositeEmbeddedView(view_id, params);
}

} // namespace shell
11 changes: 8 additions & 3 deletions shell/platform/darwin/ios/ios_surface_software.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#ifndef FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_SOFTWARE_H_
#define FLUTTER_SHELL_PLATFORM_DARWIN_IOS_IOS_SURFACE_SOFTWARE_H_

#include "flutter/flow/embedded_views.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/platform/darwin/scoped_nsobject.h"
#include "flutter/shell/gpu/gpu_surface_software.h"
Expand All @@ -14,10 +15,12 @@

namespace shell {

class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDelegate {
class IOSSurfaceSoftware final : public IOSSurface,
public GPUSurfaceSoftwareDelegate,
public flow::ExternalViewEmbedder {
public:
IOSSurfaceSoftware(fml::scoped_nsobject<CALayer> layer,
flow::ExternalViewEmbedder& view_embedder);
FlutterPlatformViewsController& platform_views_controller);

~IOSSurfaceSoftware() override;

Expand All @@ -42,9 +45,11 @@ class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDel
// |shell::GPUSurfaceSoftwareDelegate|
flow::ExternalViewEmbedder* GetExternalViewEmbedder() override;

// |flow::ExternalViewEmbedder|
void CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) override;

private:
fml::scoped_nsobject<CALayer> layer_;
flow::ExternalViewEmbedder& external_view_embedder_;
sk_sp<SkSurface> sk_surface_;

FML_DISALLOW_COPY_AND_ASSIGN(IOSSurfaceSoftware);
Expand Down
12 changes: 9 additions & 3 deletions shell/platform/darwin/ios/ios_surface_software.mm
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
namespace shell {

IOSSurfaceSoftware::IOSSurfaceSoftware(fml::scoped_nsobject<CALayer> layer,
flow::ExternalViewEmbedder& view_embedder)
: layer_(std::move(layer)), external_view_embedder_(view_embedder) {
FlutterPlatformViewsController& platform_views_controller)
: IOSSurface(platform_views_controller), layer_(std::move(layer)) {
UpdateStorageSizeIfNecessary();
}

Expand Down Expand Up @@ -123,11 +123,17 @@

layer_.get().contents = reinterpret_cast<id>(static_cast<CGImageRef>(pixmap_image));

GetPlatformViewsController().Present();

return true;
}

flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() {
return &external_view_embedder_;
return this;
}
void IOSSurfaceSoftware::CompositeEmbeddedView(int view_id,
const flow::EmbeddedViewParams& params) {
GetPlatformViewsController().CompositeEmbeddedView(view_id, params);
}

} // namespace shell