Kami baru-baru ini berhasil memindahkan framework Flutter ke TV box dengan platform perangkat lunak RDK sumber terbuka. Pada artikel ini, kami akan membahas tantangan yang kami hadapi dan menyarankan solusi untuk berhasil meluncurkan dan meningkatkan kinerja.
Mengingat bahwa tumpukan perangkat lunak RDK atau Kit Desain Referensi sekarang secara aktif digunakan untuk mengembangkan aplikasi OTT, kontrol suara untuk set-top box, dan fitur video-on-demand (VoD) lanjutan lainnya, kami ingin melihat apakah Flutter dapat berjalan di dekoder. Ternyata ya, tetapi, seperti biasanya, ada beberapa nuansa.
Selanjutnya, kami akan menjelaskan proses porting dan menjalankan Flutter pada platform Linux yang disematkan selangkah demi selangkah dan melihat bagaimana SDK open source dari Google ini terasa pada perangkat keras dengan sumber daya terbatas dan prosesor ARM.
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
Kami berharap pengalaman tim kami dalam mengembangkan dan mentransfer perangkat lunak untuk dekoder dan Smart TV akan berguna bagi Anda dalam proyek Anda dan akan berfungsi sebagai titik awal untuk mentransfer Flutter ke perangkat lain.
[!?] Pertanyaan dan komentar dipersilakan. Mereka akan dijawab oleh penulis artikel Alexey Kasyanchuk, insinyur perangkat lunak kami