diff --git a/flow/layers/opacity_layer.cc b/flow/layers/opacity_layer.cc index 7d658b3726e1b10d08487532896b24624012e79a..485126f0813ce1a78e3b74d2f00d55786b219260 100644 --- a/flow/layers/opacity_layer.cc +++ b/flow/layers/opacity_layer.cc @@ -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 && + context.raster_cache) { const SkMatrix& ctm = context.canvas->getTotalMatrix(); RasterCacheResult child_cache = context.raster_cache->Get(layers()[0].get(), ctm); diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index b9737c7e1ca365299ac2d43390929e14eef7ca47..848590beb110d28e54e17a6e5cd13e3bc0c872c9 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -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, diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index edc7df58cb9506a0232ab526b9d84a1eb76ed6ea..33ca6477bd06aae7a2adcac526218092953b46fa 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -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 () @@ -295,13 +296,8 @@ 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. @@ -314,12 +310,41 @@ return std::make_unique(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: " diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h index 52711f1e68b6a4282aa110cc79188ce525481f80..f362d6d7eee34a82ac366b47175d39dddb47620f 100644 --- a/shell/platform/darwin/ios/ios_surface.h +++ b/shell/platform/darwin/ios/ios_surface.h @@ -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); diff --git a/shell/platform/darwin/ios/ios_surface_gl.mm b/shell/platform/darwin/ios/ios_surface_gl.mm index 24f2a3af67c1d3d05b09bcb04c0573088636ca56..92914551760700b52d56fd97c2d8d658e98bba7b 100644 --- a/shell/platform/darwin/ios/ios_surface_gl.mm +++ b/shell/platform/darwin/ios/ios_surface_gl.mm @@ -67,7 +67,11 @@ bool IOSSurfaceGL::GLContextPresent() { } 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) { diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm index a35d806729b83004ace912cb4dd706bc30a2f8c1..bcf57f5cd28d41ad5cb3ec247d6b6963aa5b4c16 100644 --- a/shell/platform/darwin/ios/ios_surface_software.mm +++ b/shell/platform/darwin/ios/ios_surface_software.mm @@ -131,7 +131,11 @@ bool IOSSurfaceSoftware::PresentBackingStore(sk_sp backing_store) { } flow::ExternalViewEmbedder* IOSSurfaceSoftware::GetExternalViewEmbedder() { - return this; + if ([[[NSBundle mainBundle] objectForInfoDictionaryKey:@(kEmbeddedViewsPreview)] boolValue]) { + return this; + } else { + return nullptr; + } } SkCanvas* IOSSurfaceSoftware::CompositeEmbeddedView(int view_id,