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
7 changes: 6 additions & 1 deletion flow/layers/opacity_layer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ void OpacityLayer::Paint(PaintContext& context) const {
RasterCache::GetIntegralTransCTM(context.canvas->getTotalMatrix()));
#endif

if (layers().size() == 1 && context.raster_cache) {
// Embedded platform views are changing the canvas in the middle of the paint
// traversal. To make sure we paint on the right canvas, when the embedded
// platform views preview is enabled (context.view_embedded is not null) we
// don't use the cache.
if (context.view_embedder == nullptr && layers().size() == 1 &&
Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, this ensures that Paint will be called for every layer. However, I would encourage to disable the cache in Preroll instead of Paint. That way, we don't spend time on generating the cache that we're never going to use.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks good point!
My plan here is to eventually only disable it if there's a platform view in the scene (which we can ask the view_embedder only after Preroll), as a safe first step I just always disable it...

context.raster_cache) {
const SkMatrix& ctm = context.canvas->getTotalMatrix();
RasterCacheResult child_cache =
context.raster_cache->Get(layers()[0].get(), ctm);
Expand Down
11 changes: 1 addition & 10 deletions shell/common/rasterizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -162,16 +162,7 @@ bool Rasterizer::DrawToSurface(flow::LayerTree& layer_tree) {

auto canvas = frame->SkiaCanvas();

// External view embedding required that the gpu and platform threads are the
// same. The dynamic merging of these threads is WIP so for now we don't
// populate the view embedder. Once we can merge the threads, we should
// populate the view embedded here with surface_->GetExternalViewEmbedder() if
// the scene contains an external view (and we can probably assert that the
// gpu and platform threads are the same).
//
// TODO(amirh): populate the view embedder once we dynamically merge the
// threads for embedded platform views.
auto external_view_embedder = nullptr;
auto external_view_embedder = surface_->GetExternalViewEmbedder();

auto compositor_frame = compositor_context_->AcquireFrame(
surface_->GetContext(), canvas, external_view_embedder,
Expand Down
51 changes: 38 additions & 13 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterTextInputDelegate.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/FlutterViewController_Internal.h"
#include "flutter/shell/platform/darwin/ios/framework/Source/platform_message_response_darwin.h"
#include "flutter/shell/platform/darwin/ios/ios_surface.h"
#include "flutter/shell/platform/darwin/ios/platform_view_ios.h"

@interface FlutterEngine () <FlutterTextInputDelegate>
Expand Down Expand Up @@ -295,13 +296,8 @@ - (bool)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)libraryURI
threadLabel.UTF8String, // label
shell::ThreadHost::Type::UI | shell::ThreadHost::Type::GPU | shell::ThreadHost::Type::IO};

blink::TaskRunners task_runners(threadLabel.UTF8String, // label
fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform
_threadHost.gpu_thread->GetTaskRunner(), // gpu
_threadHost.ui_thread->GetTaskRunner(), // ui
_threadHost.io_thread->GetTaskRunner() // io
);

bool embedded_views_preview_enabled = [[[NSBundle mainBundle]
objectForInfoDictionaryKey:@(shell::kEmbeddedViewsPreview)] boolValue];
// Lambda captures by pointers to ObjC objects are fine here because the
// create call is
// synchronous.
Expand All @@ -314,12 +310,41 @@ - (bool)runWithEntrypoint:(NSString*)entrypoint libraryURI:(NSString*)libraryURI
return std::make_unique<shell::Rasterizer>(shell.GetTaskRunners());
};

// Create the shell. This is a blocking operation.
_shell = shell::Shell::Create(std::move(task_runners), // task runners
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterzier creation
);
if (embedded_views_preview_enabled) {
// Embedded views requires the gpu and the platform views to be the same.
// The plan is to eventually dynamically merge the threads when there's a
// platform view in the layer tree.
// For now we run in a single threaded configuration.
// TODO(amirh/chinmaygarde): merge only the gpu and platform threads.
// https://github.com/flutter/flutter/issues/23974
// TODO(amirh/chinmaygarde): remove this, and dynamically change the thread configuration.
// https://github.com/flutter/flutter/issues/23975
blink::TaskRunners task_runners(threadLabel.UTF8String, // label
fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform
fml::MessageLoop::GetCurrent().GetTaskRunner(), // gpu
fml::MessageLoop::GetCurrent().GetTaskRunner(), // ui
fml::MessageLoop::GetCurrent().GetTaskRunner() // io
);
// Create the shell. This is a blocking operation.
_shell = shell::Shell::Create(std::move(task_runners), // task runners
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterzier creation
);
} else {
blink::TaskRunners task_runners(threadLabel.UTF8String, // label
fml::MessageLoop::GetCurrent().GetTaskRunner(), // platform
_threadHost.gpu_thread->GetTaskRunner(), // gpu
_threadHost.ui_thread->GetTaskRunner(), // ui
_threadHost.io_thread->GetTaskRunner() // io
);
// Create the shell. This is a blocking operation.
_shell = shell::Shell::Create(std::move(task_runners), // task runners
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterzier creation
);
}

if (_shell == nullptr) {
FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: "
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/darwin/ios/ios_surface.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@

namespace shell {

// The name of the Info.plist flag to enable the embedded iOS views preview.
const char* const kEmbeddedViewsPreview = "io.flutter_embedded_views_preview";

class IOSSurface {
public:
IOSSurface(FlutterPlatformViewsController* platform_views_controller);
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/darwin/ios/ios_surface_gl.mm
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@
}

flow::ExternalViewEmbedder* IOSSurfaceGL::GetExternalViewEmbedder() {
return this;
if ([[[NSBundle mainBundle] objectForInfoDictionaryKey:@(kEmbeddedViewsPreview)] boolValue]) {
return this;
} else {
return nullptr;
}
}

SkCanvas* IOSSurfaceGL::CompositeEmbeddedView(int view_id, const flow::EmbeddedViewParams& params) {
Expand Down
6 changes: 5 additions & 1 deletion shell/platform/darwin/ios/ios_surface_software.mm
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,11 @@
}

flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() {
return this;
if ([[[NSBundle mainBundle] objectForInfoDictionaryKey:@(kEmbeddedViewsPreview)] boolValue]) {
return this;
} else {
return nullptr;
}
}

SkCanvas* IOSSurfaceSoftware::CompositeEmbeddedView(int view_id,
Expand Down