未验证 提交 0ec3b7d4 编写于 作者: A Amir Hardon 提交者: GitHub

Apply changes to the embedded UIView tree when presenting a frame (#6712)

Also tracks the order of embedded views from frame to frame, and only
removes and reattaches subviews if there is a structural change to the
UIView hierarchy.
上级 92944f72
......@@ -396,10 +396,6 @@
return _shell->Screenshot(type, base64Encode);
}
- (flow::ExternalViewEmbedder*)externalViewEmbedder {
return _platformViewsController.get();
}
#pragma mark - FlutterBinaryMessenger
- (void)sendOnChannel:(NSString*)channel message:(NSData*)message {
......
......@@ -66,8 +66,6 @@ void FlutterPlatformViewsController::OnCreate(FlutterMethodCall* call, FlutterRe
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);
}
......@@ -127,6 +125,33 @@ void FlutterPlatformViewsController::CompositeEmbeddedView(int view_id,
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];
}
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
......
......@@ -26,7 +26,7 @@
namespace shell {
class FlutterPlatformViewsController : public flow::ExternalViewEmbedder {
class FlutterPlatformViewsController {
public:
FlutterPlatformViewsController() = default;
......@@ -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:
......@@ -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);
......
......@@ -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"
......@@ -21,7 +20,7 @@
- (shell::Rasterizer::Screenshot)takeScreenshot:(shell::Rasterizer::ScreenshotType)type
asBase64Encoded:(BOOL)base64Encode;
- (flow::ExternalViewEmbedder*)externalViewEmbedder;
- (shell::FlutterPlatformViewsController*)platformViewsController;
@end
......
......@@ -80,11 +80,11 @@ id<FlutterViewEngineDelegate> _delegate;
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]);
}
}
......
......@@ -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"
......@@ -15,7 +17,7 @@ namespace shell {
class IOSSurface {
public:
IOSSurface();
IOSSurface(FlutterPlatformViewsController& platform_views_controller);
virtual ~IOSSurface();
......@@ -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);
};
......
......@@ -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
......@@ -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;
......@@ -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);
};
......
......@@ -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;
......@@ -55,11 +55,20 @@ bool IOSSurfaceGL::GLContextClearCurrent() {
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
......@@ -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"
......@@ -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;
......@@ -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);
......
......@@ -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();
}
......@@ -123,11 +123,17 @@ bool IOSSurfaceSoftware::PresentBackingStore(sk_sp<SkSurface> backing_store) {
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册