最近、FlutterフレームワークをオープンソースのRDKソフトウェアプラットフォームを備えたTVボックスに移植することに成功しました。この記事では、私たちが直面した課題について説明し、パフォーマンスを正常に起動して改善するためのソリューションを提案します。
RDKソフトウェアスタックまたはリファレンスデザインキットがOTTアプリケーション、セットトップボックスの音声制御、およびその他の高度なビデオオンデマンド(VoD)機能の開発に積極的に使用されていることを考えると、Flutterがセットトップボックス。はい、それが判明しましたが、通常の場合のように、ニュアンスがあります。
次に、組み込みLinuxプラットフォームでFlutterを移植して実行するプロセスの概要を説明し、リソースが限られているハードウェアとARMプロセッサでGoogleのこのオープンソースSDKがどのように感じられるかを確認します。
Flutter , -. « EFL + Wayland», node.js . , EFL — . node.js event-loop . Flutter .
, : SDK Google . Android. , iOS, Linux Google Fuchsia. :-) Flutter — Dart, JavaScript.
: Flutter - ? , Wayland + OpenGL. neon-? , , UI dart , Linux -.
Flutter Engine - ARM
, . Futter Wayland + OpenGL ES. Flutter Skia, OpenGL ES, .
Flutter ( - RDK), , . , .. - intel x86 . ARM-.
, Flutter Engine:
./flutter/tools/gn \
--embedder-for-target \
--target-os linux \
--linux-cpu arm \
--target-sysroot DEVICE_SYSROOT
--disable-desktop-embeddings \
--arm-float-abi hard
--target-toolchain /usr
--target-triple arm-linux-gnueabihf
--runtime-mode debug
ninja -C out/linux_debug_unopt_arm
: 32- ARM- Linux, --embedder-for-target
--disable-desktop-embeddings
.
clang 9 , .. Flutter, - gcc . — target-sysroot
RDK.
, , . flutter_engine.so .
flutter/dart /. :
flutter --local-engine-src-path PATH_TO_BUILDED_ENGINE_src
--local-engine=host_debug_unopt build bundle
! , , .. x86_64!
gn ninja x86_64! host_debug_unopt.
PATH_TO_BUILDED_ENGINE_src — , engine/src/out.
Flutter Engine embedder, Flutter Skia Dart-. Flutter linux-embedder, , , GTK-embedder, . , - GTK.
, (, , , github.com). GTK, , GTK-.
flutter-? , flutter_engine.so
FlutterEngineRun(FLUTTER_ENGINE_VERSION, &config, &args, display /* userdata */, &engine_);
( flutter bundle) FlutterProjectArgs args FlutterRendererConfig config.
bundle-, flutter-, OpenGL .
// github.com (flutter_application.cc)
, .
, . ? :-)
1.
, — . , egl- , FlutterRendererConfig , — . - . , eglBindAPI eglGetDisplay, nexus- ( BCM). Linux , .
:
egl_display_ = eglGetDisplay(display_);
if (egl_display_ == EGL_NO_DISPLAY) {
LogLastEGLError();
FL_ERROR("Could not access EGL display.");
return false;
}
if (eglInitialize(egl_display_, nullptr, nullptr) != EGL_TRUE) {
LogLastEGLError();
FL_ERROR("Could not initialize EGL display.");
return false;
}
if (eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) {
LogLastEGLError();
FL_ERROR("Could not bind the ES API.");
return false;
}
// github.com (wayland_display.cc) — , .. .
, , - :-).
2.
. , , (debug mode). - , - — , , - EFL+Node.js.
. SDK Flutter AOT, jit, , - Flutter. , .
// — github.com (elf.cc)
vm_snapshot_instructions_ = dlsym(fd, "_kDartVmSnapshotInstructions");
if (vm_snapshot_instructions_ == NULL) {
error_ = strerror(errno);
break;
}
vm_isolate_snapshot_instructions_ = dlsym(fd, "_kDartIsolateSnapshotInstructions");
if (vm_isolate_snapshot_instructions_ == NULL) {
error_ = strerror(errno);
break;
}
vm_snapshot_data_ = dlsym(fd, "_kDartVmSnapshotData");
if (vm_snapshot_data_ == NULL) {
error_ = strerror(errno);
break;
}
vm_isolate_snapshot_data_ = dlsym(fd, "_kDartIsolateSnapshotData");
if (vm_isolate_snapshot_data_ == NULL) {
error_ = strerror(errno);
break;
}
if (vm_snapshot_data_ == NULL ||
vm_snapshot_instructions_ == NULL ||
vm_isolate_snapshot_data_ == NULL ||
vm_isolate_snapshot_instructions_ == NULL) {
return false;
}
*vm_snapshot_data = reinterpret_cast <
const uint8_t * > (vm_snapshot_data_);
*vm_snapshot_instructions = reinterpret_cast <
const uint8_t * > (vm_snapshot_instructions_);
*vm_isolate_snapshot_data = reinterpret_cast <
const uint8_t * > (vm_isolate_snapshot_data_);
*vm_isolate_snapshot_instructions = reinterpret_cast <
const uint8_t * > (vm_isolate_snapshot_instructions_);
FlutterProjectArgs args;
// args
args.vm_snapshot_data = vm_snapshot_data;
args.vm_snapshot_instructions = vm_snapshot_instructions;
args.isolate_snapshot_data = vm_isolate_snapshot_data;
args.isolate_snapshot_instructions = vm_isolate_snapshot_instructions;
, , , AOT- . , dart-:
$HOST_ENGINE/dart-sdk/bin/dart \
--disable-dart-dev \
$HOST_ENGINE/gen/frontend_server.dart.snapshot \
--sdk-root $DEVICE_ENGINE}/flutter_patched_sdk/ \
--target=flutter \
-Ddart.developer.causal_async_stacks=false \
-Ddart.vm.profile=release \
-Ddart.vm.product=release \
--bytecode-options=source-positions \
--aot \
--tfa \
--packages .packages \
--output-dill build/tmp/app.dill \
--depfile build/kernel_snapshot.d \
package:lib/main.dart
$DEVICE_ENGINE/gen_snapshot \
--deterministic \
--snapshot_kind=app-aot-elf \
--elf=build/lib/libapp.so \
--no-causal-async-stacks \
--lazy-async-stacks \
build/tmp/app.dill
, . :
-Ddart.vm.profile=release \
-Ddart.vm.product=release \
, .
output-dill
libapp.so.
$DEVICE_ENGINE $HOST_ENGINE — (ARM) - (x86_64) . , libapp.so 32- ARM-:
$ file libapp.so
libapp.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV),
dynamically linked
---... ! — !
! EFL. .
3.
4. - Linux Android 2—3
, UI-. UI , Linux Android. Flutter .
dart- . ( ). __brcm_cpu_dcache_flush khrn_copy_8888_to_tf32 ( Broadcom/BCM ). - . : :
//...
filter: new ImageFilter.blur(sigmaX: 10.0, sigmaY: 10.0),
//...
— 50-60 fps. , Flutter , - , .
, Flutter . RDK Wayland :
github.com/DEgITx/flutter_wayland
セットトップボックスやスマートテレビ用のソフトウェアの開発と移植における私たちのチームの経験が、プロジェクトで役立ち、Flutterを他のデバイスに移植するための出発点として役立つことを願っています。
[!?]質問やコメントは大歓迎です。彼らは私たちのソフトウェアエンジニアであるAlexeyKasyanchukという記事の著者によって答えられます