diff --git a/common/settings.h b/common/settings.h index e408454f524..5dcef45a17d 100644 --- a/common/settings.h +++ b/common/settings.h @@ -152,6 +152,9 @@ struct Settings { // Font settings bool use_test_fonts = false; + // Selects the SkParagraph implementation of the text layout engine. + bool enable_skparagraph = false; + // All shells in the process share the same VM. The last shell to shutdown // should typically shut down the VM as well. However, applications depend on // the behavior of "warming-up" the VM by creating a shell that does not do diff --git a/lib/ui/text/paragraph_builder.cc b/lib/ui/text/paragraph_builder.cc index 1cd8f7d65cb..afb809ef32d 100644 --- a/lib/ui/text/paragraph_builder.cc +++ b/lib/ui/text/paragraph_builder.cc @@ -295,14 +295,18 @@ ParagraphBuilder::ParagraphBuilder( ->client() ->GetFontCollection(); + typedef std::unique_ptr (*ParagraphBuilderFactory)( + const txt::ParagraphStyle& style, + std::shared_ptr font_collection); + ParagraphBuilderFactory factory = txt::ParagraphBuilder::CreateTxtBuilder; + #if FLUTTER_ENABLE_SKSHAPER -#define FLUTTER_PARAGRAPH_BUILDER txt::ParagraphBuilder::CreateSkiaBuilder -#else -#define FLUTTER_PARAGRAPH_BUILDER txt::ParagraphBuilder::CreateTxtBuilder + if (UIDartState::Current()->enable_skparagraph()) { + factory = txt::ParagraphBuilder::CreateSkiaBuilder; + } #endif - m_paragraphBuilder = - FLUTTER_PARAGRAPH_BUILDER(style, font_collection.GetFontCollection()); + m_paragraphBuilder = factory(style, font_collection.GetFontCollection()); } ParagraphBuilder::~ParagraphBuilder() = default; diff --git a/lib/ui/ui_dart_state.cc b/lib/ui/ui_dart_state.cc index 3268e50c52b..3def189206a 100644 --- a/lib/ui/ui_dart_state.cc +++ b/lib/ui/ui_dart_state.cc @@ -28,7 +28,8 @@ UIDartState::UIDartState( UnhandledExceptionCallback unhandled_exception_callback, std::shared_ptr isolate_name_server, bool is_root_isolate, - std::shared_ptr volatile_path_tracker) + std::shared_ptr volatile_path_tracker, + bool enable_skparagraph) : task_runners_(std::move(task_runners)), add_callback_(std::move(add_callback)), remove_callback_(std::move(remove_callback)), @@ -43,7 +44,8 @@ UIDartState::UIDartState( logger_prefix_(std::move(logger_prefix)), is_root_isolate_(is_root_isolate), unhandled_exception_callback_(unhandled_exception_callback), - isolate_name_server_(std::move(isolate_name_server)) { + isolate_name_server_(std::move(isolate_name_server)), + enable_skparagraph_(enable_skparagraph) { AddOrRemoveTaskObserver(true /* add */); } @@ -185,4 +187,8 @@ void UIDartState::ReportUnhandledException(const std::string& error, << stack_trace; } +bool UIDartState::enable_skparagraph() const { + return enable_skparagraph_; +} + } // namespace flutter diff --git a/lib/ui/ui_dart_state.h b/lib/ui/ui_dart_state.h index d1f66baeee0..0a3e44a97ca 100644 --- a/lib/ui/ui_dart_state.h +++ b/lib/ui/ui_dart_state.h @@ -77,6 +77,8 @@ class UIDartState : public tonic::DartState { void ReportUnhandledException(const std::string& error, const std::string& stack_trace); + bool enable_skparagraph() const; + template static flutter::SkiaGPUObject CreateGPUObject(sk_sp object) { if (!object) { @@ -103,7 +105,8 @@ class UIDartState : public tonic::DartState { UnhandledExceptionCallback unhandled_exception_callback, std::shared_ptr isolate_name_server, bool is_root_isolate_, - std::shared_ptr volatile_path_tracker); + std::shared_ptr volatile_path_tracker, + bool enable_skparagraph); ~UIDartState() override; @@ -136,6 +139,7 @@ class UIDartState : public tonic::DartState { tonic::DartMicrotaskQueue microtask_queue_; UnhandledExceptionCallback unhandled_exception_callback_; const std::shared_ptr isolate_name_server_; + const bool enable_skparagraph_; void AddOrRemoveTaskObserver(bool add); }; diff --git a/runtime/dart_isolate.cc b/runtime/dart_isolate.cc index 15fe61f30ce..f82e0d4eccd 100644 --- a/runtime/dart_isolate.cc +++ b/runtime/dart_isolate.cc @@ -271,7 +271,8 @@ DartIsolate::DartIsolate( settings.unhandled_exception_callback, DartVMRef::GetIsolateNameServer(), is_root_isolate, - std::move(volatile_path_tracker)), + std::move(volatile_path_tracker), + settings.enable_skparagraph), may_insecurely_connect_to_all_domains_( settings.may_insecurely_connect_to_all_domains), domain_network_policy_(settings.domain_network_policy) { diff --git a/shell/common/switches.cc b/shell/common/switches.cc index c8432493530..b5a15b1e1e2 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -378,6 +378,9 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { settings.use_test_fonts = command_line.HasOption(FlagForSwitch(Switch::UseTestFonts)); + settings.enable_skparagraph = + command_line.HasOption(FlagForSwitch(Switch::EnableSkParagraph)); + std::string all_dart_flags; if (command_line.GetOptionValue(FlagForSwitch(Switch::DartFlags), &all_dart_flags)) { diff --git a/shell/common/switches.h b/shell/common/switches.h index 6f6e2a34b8f..08399b35129 100644 --- a/shell/common/switches.h +++ b/shell/common/switches.h @@ -202,6 +202,9 @@ DEF_SWITCH( DEF_SWITCH(OldGenHeapSize, "old-gen-heap-size", "The size limit in megabytes for the Dart VM old gen heap space.") +DEF_SWITCH(EnableSkParagraph, + "enable-skparagraph", + "Selects the SkParagraph implementation of the text layout engine.") DEF_SWITCHES_END diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 95e96d3473e..aeb39a6d6ce 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -33,6 +33,8 @@ public class FlutterLoader { private static final String OLD_GEN_HEAP_SIZE_META_DATA_KEY = "io.flutter.embedding.android.OldGenHeapSize"; + private static final String ENABLE_SKPARAGRAPH_META_DATA_KEY = + "io.flutter.embedding.android.EnableSkParagraph"; // Must match values in flutter::switches static final String AOT_SHARED_LIBRARY_NAME = "aot-shared-library-name"; @@ -263,6 +265,10 @@ public class FlutterLoader { shellArgs.add("--old-gen-heap-size=" + oldGenHeapSizeMegaBytes); + if (metaData != null && metaData.getBoolean(ENABLE_SKPARAGRAPH_META_DATA_KEY)) { + shellArgs.add("--enable-skparagraph"); + } + long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis; flutterJNI.init( diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index d22a9684f3b..9c50109d16f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -141,6 +141,10 @@ flutter::Settings FLTDefaultSettingsForBundle(NSBundle* bundle) { settings.domain_network_policy = [FlutterDartProject domainNetworkPolicy:appTransportSecurity].UTF8String; + // SkParagraph text layout library + NSNumber* enableSkParagraph = [mainBundle objectForInfoDictionaryKey:@"FLTEnableSkParagraph"]; + settings.enable_skparagraph = (enableSkParagraph != nil) ? enableSkParagraph.boolValue : false; + #if FLUTTER_RUNTIME_MODE == FLUTTER_RUNTIME_MODE_DEBUG // There are no ownership concerns here as all mappings are owned by the // embedder and not the engine.