From 1cab54265e736e3c6c0c8c03a4957046423eca79 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 24 May 2021 09:16:56 +0900 Subject: [PATCH 001/178] Fixed bug blocking events from flutter engine for Wayland (#131) Fixed #34, #132 --- .../flutter-drm-eglstream-backend/main.cc | 11 +++--- examples/flutter-drm-gbm-backend/main.cc | 11 +++--- .../flutter-external-texture-plugin/main.cc | 35 ++++++++++++++++++- examples/flutter-wayland-client/main.cc | 35 ++++++++++++++++++- .../main.cc | 35 ++++++++++++++++++- examples/flutter-weston-desktop-shell/main.cc | 35 ++++++++++++++++++- examples/flutter-x11-client/main.cc | 11 +++--- .../window/linuxes_window_wayland.cc | 32 +++++++++++++++-- src/templates/app/linux-drm/main.cc | 11 +++--- .../main.cc | 35 ++++++++++++++++++- src/templates/app/linux-wayland/main.cc | 35 ++++++++++++++++++- src/templates/app/linux-x11/main.cc | 11 +++--- 12 files changed, 264 insertions(+), 33 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index ec4f968d..8153d8b0 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -62,15 +62,16 @@ int main(int argc, char** argv) { { auto next_event_time = std::chrono::steady_clock::time_point::max(); if (wait_duration != std::chrono::nanoseconds::max()) { - auto next_wakeup = - std::max(std::chrono::steady_clock::time_point::max(), + next_event_time = + std::min(next_event_time, std::chrono::steady_clock::time_point::clock::now() + wait_duration); - next_event_time = std::min(next_event_time, next_wakeup); } else { // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13); + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index ec4f968d..8153d8b0 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -62,15 +62,16 @@ int main(int argc, char** argv) { { auto next_event_time = std::chrono::steady_clock::time_point::max(); if (wait_duration != std::chrono::nanoseconds::max()) { - auto next_wakeup = - std::max(std::chrono::steady_clock::time_point::max(), + next_event_time = + std::min(next_event_time, std::chrono::steady_clock::time_point::clock::now() + wait_duration); - next_event_time = std::min(next_event_time, next_wakeup); } else { // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13); + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 284bd7de..537426a8 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -5,9 +5,11 @@ #include #include +#include #include #include #include +#include #include "command_options.h" #include "external_texture_test_plugin.h" @@ -55,8 +57,39 @@ int main(int argc, char** argv) { "ExternalTextureTestPlugin")); // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 459bc04b..b80982a1 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -5,9 +5,11 @@ #include #include +#include #include #include #include +#include #include "command_options.h" @@ -50,8 +52,39 @@ int main(int argc, char** argv) { } // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc index f4c0b56d..6ca65b0e 100644 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -62,8 +64,39 @@ int main(int argc, char** argv) { } // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc index f4c0b56d..6ca65b0e 100644 --- a/examples/flutter-weston-desktop-shell/main.cc +++ b/examples/flutter-weston-desktop-shell/main.cc @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -62,8 +64,39 @@ int main(int argc, char** argv) { } // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 7d099ba4..b80982a1 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -71,15 +71,16 @@ int main(int argc, char** argv) { { auto next_event_time = std::chrono::steady_clock::time_point::max(); if (wait_duration != std::chrono::nanoseconds::max()) { - auto next_wakeup = - std::max(std::chrono::steady_clock::time_point::max(), + next_event_time = + std::min(next_event_time, std::chrono::steady_clock::time_point::clock::now() + wait_duration); - next_event_time = std::min(next_event_time, next_wakeup); } else { // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13); + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc index 10d3e843..a0b235f4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include @@ -702,8 +703,35 @@ bool LinuxesWindowWayland::DispatchEvent() { return false; } - // If Wayland compositor (Weston) terminates, -1 is returned. - return (wl_display_dispatch(wl_display_) != -1); + pollfd fds[] = { + {wl_display_get_fd(wl_display_), POLLIN}, + }; + + // Prepare to call wl_display_read_events. + while (wl_display_prepare_read(wl_display_) != 0) { + // If Wayland compositor terminates, -1 is returned. + auto result = wl_display_dispatch_pending(wl_display_); + if (result == -1) { + return false; + } + } + + // Handle events. + wl_display_flush(wl_display_); + if (poll(fds, 1, 0) > 0) { + int result = wl_display_read_events(wl_display_); + if (result == -1) { + return false; + } + result = wl_display_dispatch_pending(wl_display_); + if (result == -1) { + return false; + } + } else { + wl_display_cancel_read(wl_display_); + } + + return true; } bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { diff --git a/src/templates/app/linux-drm/main.cc b/src/templates/app/linux-drm/main.cc index ec4f968d..8153d8b0 100644 --- a/src/templates/app/linux-drm/main.cc +++ b/src/templates/app/linux-drm/main.cc @@ -62,15 +62,16 @@ int main(int argc, char** argv) { { auto next_event_time = std::chrono::steady_clock::time_point::max(); if (wait_duration != std::chrono::nanoseconds::max()) { - auto next_wakeup = - std::max(std::chrono::steady_clock::time_point::max(), + next_event_time = + std::min(next_event_time, std::chrono::steady_clock::time_point::clock::now() + wait_duration); - next_event_time = std::min(next_event_time, next_wakeup); } else { // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13); + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc index f4c0b56d..6ca65b0e 100644 --- a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc +++ b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc @@ -6,9 +6,11 @@ #include #include +#include #include #include #include +#include int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -62,8 +64,39 @@ int main(int argc, char** argv) { } // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/src/templates/app/linux-wayland/main.cc b/src/templates/app/linux-wayland/main.cc index 459bc04b..b80982a1 100644 --- a/src/templates/app/linux-wayland/main.cc +++ b/src/templates/app/linux-wayland/main.cc @@ -5,9 +5,11 @@ #include #include +#include #include #include #include +#include #include "command_options.h" @@ -50,8 +52,39 @@ int main(int argc, char** argv) { } // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); while (flutter_controller->view()->DispatchEvent()) { - flutter_controller->engine()->ProcessMessages(); + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_controller->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } } return 0; diff --git a/src/templates/app/linux-x11/main.cc b/src/templates/app/linux-x11/main.cc index 7d099ba4..b80982a1 100644 --- a/src/templates/app/linux-x11/main.cc +++ b/src/templates/app/linux-x11/main.cc @@ -71,15 +71,16 @@ int main(int argc, char** argv) { { auto next_event_time = std::chrono::steady_clock::time_point::max(); if (wait_duration != std::chrono::nanoseconds::max()) { - auto next_wakeup = - std::max(std::chrono::steady_clock::time_point::max(), + next_event_time = + std::min(next_event_time, std::chrono::steady_clock::time_point::clock::now() + wait_duration); - next_event_time = std::min(next_event_time, next_wakeup); } else { // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13); + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); From 89b6a49787b852e4f3ac724b3740992519578e91 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 24 May 2021 14:35:45 +0900 Subject: [PATCH 002/178] Add flutter_window class for app template (#133) --- .../cmake/user_build.cmake | 3 + .../command_options.h | 5 ++ .../flutter_window.cc | 74 +++++++++++++++++++ .../flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ .../flutter-drm-eglstream-backend/main.cc | 55 +++----------- .../cmake/user_build.cmake | 3 + .../flutter-drm-gbm-backend/command_options.h | 5 ++ .../flutter-drm-gbm-backend/flutter_window.cc | 74 +++++++++++++++++++ .../flutter-drm-gbm-backend/flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ examples/flutter-drm-gbm-backend/main.cc | 55 +++----------- .../flutter-external-texture-plugin/README.md | 8 +- .../cmake/user_build.cmake | 5 +- .../command_options.h | 5 ++ .../external_texture_test_plugin.cc | 3 +- .../external_texture_test_plugin.h | 6 +- .../flutter_window.cc | 74 +++++++++++++++++++ .../flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 12 +++ .../generated_plugin_registrant.h | 13 ++++ .../flutter-external-texture-plugin/main.cc | 66 +++-------------- .../cmake/user_build.cmake | 3 + .../flutter-wayland-client/command_options.h | 5 ++ .../flutter-wayland-client/flutter_window.cc | 74 +++++++++++++++++++ .../flutter-wayland-client/flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ examples/flutter-wayland-client/main.cc | 61 +++------------ .../cmake/user_build.cmake | 3 + .../flutter_window.cc | 74 +++++++++++++++++++ .../flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ .../main.cc | 58 +++------------ .../cmake/user_build.cmake | 3 + .../flutter_window.cc | 74 +++++++++++++++++++ .../flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ examples/flutter-weston-desktop-shell/main.cc | 58 +++------------ .../flutter-x11-client/cmake/user_build.cmake | 3 + examples/flutter-x11-client/command_options.h | 5 ++ examples/flutter-x11-client/flutter_window.cc | 74 +++++++++++++++++++ examples/flutter-x11-client/flutter_window.h | 32 ++++++++ .../generated_plugin_registrant.cc | 7 ++ .../generated_plugin_registrant.h | 13 ++++ examples/flutter-x11-client/main.cc | 63 ++++------------ src/templates/app/common/command_options.h | 5 ++ src/templates/app/common/flutter_window.cc | 74 +++++++++++++++++++ src/templates/app/common/flutter_window.h | 32 ++++++++ .../app/common/generated_plugin_registrant.cc | 7 ++ .../app/common/generated_plugin_registrant.h | 13 ++++ src/templates/app/linux-drm/main.cc | 55 +++----------- .../main.cc | 58 +++------------ src/templates/app/linux-wayland/main.cc | 61 +++------------ src/templates/app/linux-x11/main.cc | 63 ++++------------ 59 files changed, 1195 insertions(+), 541 deletions(-) create mode 100644 examples/flutter-drm-eglstream-backend/flutter_window.cc create mode 100644 examples/flutter-drm-eglstream-backend/flutter_window.h create mode 100644 examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc create mode 100644 examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h create mode 100644 examples/flutter-drm-gbm-backend/flutter_window.cc create mode 100644 examples/flutter-drm-gbm-backend/flutter_window.h create mode 100644 examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc create mode 100644 examples/flutter-drm-gbm-backend/generated_plugin_registrant.h create mode 100644 examples/flutter-external-texture-plugin/flutter_window.cc create mode 100644 examples/flutter-external-texture-plugin/flutter_window.h create mode 100644 examples/flutter-external-texture-plugin/generated_plugin_registrant.cc create mode 100644 examples/flutter-external-texture-plugin/generated_plugin_registrant.h create mode 100644 examples/flutter-wayland-client/flutter_window.cc create mode 100644 examples/flutter-wayland-client/flutter_window.h create mode 100644 examples/flutter-wayland-client/generated_plugin_registrant.cc create mode 100644 examples/flutter-wayland-client/generated_plugin_registrant.h create mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc create mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h create mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc create mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h create mode 100644 examples/flutter-weston-desktop-shell/flutter_window.cc create mode 100644 examples/flutter-weston-desktop-shell/flutter_window.h create mode 100644 examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc create mode 100644 examples/flutter-weston-desktop-shell/generated_plugin_registrant.h create mode 100644 examples/flutter-x11-client/flutter_window.cc create mode 100644 examples/flutter-x11-client/flutter_window.h create mode 100644 examples/flutter-x11-client/generated_plugin_registrant.cc create mode 100644 examples/flutter-x11-client/generated_plugin_registrant.h create mode 100644 src/templates/app/common/flutter_window.cc create mode 100644 src/templates/app/common/flutter_window.h create mode 100644 src/templates/app/common/generated_plugin_registrant.cc create mode 100644 src/templates/app/common/generated_plugin_registrant.h diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake index bfb83d21..31b403b5 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-drm-eglstream-backend) # source files for user apps. set(USER_APP_SRCS + examples/flutter-drm-eglstream-backend/flutter_window.cc + examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc examples/flutter-drm-eglstream-backend/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-drm-eglstream-backend/command_options.h b/examples/flutter-drm-eglstream-backend/command_options.h index e051a043..2cb5a66c 100644 --- a/examples/flutter-drm-eglstream-backend/command_options.h +++ b/examples/flutter-drm-eglstream-backend/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.cc b/examples/flutter-drm-eglstream-backend/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.h b/examples/flutter-drm-eglstream-backend/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc b/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h b/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 8153d8b0..9a533507 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -25,58 +24,22 @@ int main(int argc, char** argv) { } // The project to run. + const bool show_cursor = !options.Exist("no-cursor"); const auto bundle_path = options.GetValue("bundle"); + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - const bool show_cursor = !options.Exist("no-cursor"); - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, 0, 0, show_cursor, - project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, + 0, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake index 512ced26..5071071f 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-drm-gbm-backend) # source files for user apps. set(USER_APP_SRCS + examples/flutter-drm-gbm-backend/flutter_window.cc + examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc examples/flutter-drm-gbm-backend/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-drm-gbm-backend/command_options.h b/examples/flutter-drm-gbm-backend/command_options.h index e051a043..2cb5a66c 100644 --- a/examples/flutter-drm-gbm-backend/command_options.h +++ b/examples/flutter-drm-gbm-backend/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-drm-gbm-backend/flutter_window.cc b/examples/flutter-drm-gbm-backend/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-drm-gbm-backend/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-drm-gbm-backend/flutter_window.h b/examples/flutter-drm-gbm-backend/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-drm-gbm-backend/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc b/examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-drm-gbm-backend/generated_plugin_registrant.h b/examples/flutter-drm-gbm-backend/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-drm-gbm-backend/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 8153d8b0..9a533507 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -25,58 +24,22 @@ int main(int argc, char** argv) { } // The project to run. + const bool show_cursor = !options.Exist("no-cursor"); const auto bundle_path = options.GetValue("bundle"); + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - const bool show_cursor = !options.Exist("no-cursor"); - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, 0, 0, show_cursor, - project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, + 0, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-external-texture-plugin/README.md b/examples/flutter-external-texture-plugin/README.md index 7ed5f1fc..21247b17 100644 --- a/examples/flutter-external-texture-plugin/README.md +++ b/examples/flutter-external-texture-plugin/README.md @@ -31,18 +31,16 @@ class _MyAppState extends State { int _textureId = 0; @override - void initState() async { + void initState() { super.initState(); - - await initialize(); - setState(() {}); + initialize().then((value) => setState(() {})); } Future initialize() async { late Completer creatingCompleter; try { creatingCompleter = Completer(); - final channel = const MethodChannel('external_texture_test'); + var channel = const MethodChannel('external_texture_test'); final reply = await channel.invokeMapMethod('initialize'); if (reply != null) { diff --git a/examples/flutter-external-texture-plugin/cmake/user_build.cmake b/examples/flutter-external-texture-plugin/cmake/user_build.cmake index 3e495810..636f4d84 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_build.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_build.cmake @@ -5,8 +5,10 @@ set(TARGET flutter-client) # source files for user apps. set(USER_APP_SRCS - examples/flutter-external-texture-plugin/main.cc examples/flutter-external-texture-plugin/external_texture_test_plugin.cc + examples/flutter-external-texture-plugin/flutter_window.cc + examples/flutter-external-texture-plugin/generated_plugin_registrant.cc + examples/flutter-external-texture-plugin/main.cc ) # header files for user apps. @@ -14,6 +16,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-external-texture-plugin/command_options.h b/examples/flutter-external-texture-plugin/command_options.h index e051a043..2cb5a66c 100644 --- a/examples/flutter-external-texture-plugin/command_options.h +++ b/examples/flutter-external-texture-plugin/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc b/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc index 01ccddb2..4f3e4c28 100644 --- a/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc +++ b/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc @@ -1,9 +1,8 @@ #include "external_texture_test_plugin.h" +#include #include -#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" - namespace { static constexpr char kChannelName[] = "external_texture_test"; diff --git a/examples/flutter-external-texture-plugin/external_texture_test_plugin.h b/examples/flutter-external-texture-plugin/external_texture_test_plugin.h index 94a82651..7bb2b8ca 100644 --- a/examples/flutter-external-texture-plugin/external_texture_test_plugin.h +++ b/examples/flutter-external-texture-plugin/external_texture_test_plugin.h @@ -1,8 +1,10 @@ #ifndef EXAMPLES_FLUTTER_EXTERNAL_TEXTURE_PLUGIN_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ #define EXAMPLES_FLUTTER_EXTERNAL_TEXTURE_PLUGIN_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ -#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h" -#include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" +#include +#include + +#include namespace { class ColorBarTexture { diff --git a/examples/flutter-external-texture-plugin/flutter_window.cc b/examples/flutter-external-texture-plugin/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-external-texture-plugin/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-external-texture-plugin/flutter_window.h b/examples/flutter-external-texture-plugin/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-external-texture-plugin/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-external-texture-plugin/generated_plugin_registrant.cc b/examples/flutter-external-texture-plugin/generated_plugin_registrant.cc new file mode 100644 index 00000000..a4b7cc2c --- /dev/null +++ b/examples/flutter-external-texture-plugin/generated_plugin_registrant.cc @@ -0,0 +1,12 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +#include "external_texture_test_plugin.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) { + ExternalTextureTestPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("ExternalTextureTestPlugin")); +} diff --git a/examples/flutter-external-texture-plugin/generated_plugin_registrant.h b/examples/flutter-external-texture-plugin/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-external-texture-plugin/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 537426a8..a5984e09 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -5,14 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" -#include "external_texture_test_plugin.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -31,12 +29,6 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. const bool show_cursor = !options.Exist("no-cursor"); const auto view_mode = options.Exist("fullscreen") @@ -44,53 +36,19 @@ int main(int argc, char** argv) { : flutter::FlutterViewController::ViewMode::kNormal; const auto width = options.GetValue("width"); const auto height = options.GetValue("height"); - auto flutter_controller = std::make_unique( - view_mode, width, height, show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { - return 0; - } - ExternalTextureTestPluginRegisterWithRegistrar( - flutter_controller->engine()->GetRegistrarForPlugin( - "ExternalTextureTestPlugin")); - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } + // The Flutter instance hosted by this window. + FlutterWindow window(project); + if (!window.OnCreate(view_mode, width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-wayland-client/cmake/user_build.cmake b/examples/flutter-wayland-client/cmake/user_build.cmake index 2c73e8cb..e2af29f6 100644 --- a/examples/flutter-wayland-client/cmake/user_build.cmake +++ b/examples/flutter-wayland-client/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-client) # source files for user apps. set(USER_APP_SRCS + examples/flutter-wayland-client/flutter_window.cc + examples/flutter-wayland-client/generated_plugin_registrant.cc examples/flutter-wayland-client/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-wayland-client/command_options.h b/examples/flutter-wayland-client/command_options.h index e051a043..2cb5a66c 100644 --- a/examples/flutter-wayland-client/command_options.h +++ b/examples/flutter-wayland-client/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-wayland-client/flutter_window.cc b/examples/flutter-wayland-client/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-wayland-client/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-wayland-client/flutter_window.h b/examples/flutter-wayland-client/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-wayland-client/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-wayland-client/generated_plugin_registrant.cc b/examples/flutter-wayland-client/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-wayland-client/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-wayland-client/generated_plugin_registrant.h b/examples/flutter-wayland-client/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-wayland-client/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index b80982a1..a5984e09 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -30,12 +29,6 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. const bool show_cursor = !options.Exist("no-cursor"); const auto view_mode = options.Exist("fullscreen") @@ -43,49 +36,19 @@ int main(int argc, char** argv) { : flutter::FlutterViewController::ViewMode::kNormal; const auto width = options.GetValue("width"); const auto height = options.GetValue("height"); - auto flutter_controller = std::make_unique( - view_mode, width, height, show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { - return 0; - } - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } + // The Flutter instance hosted by this window. + FlutterWindow window(project); + if (!window.OnCreate(view_mode, width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake index abba32bf..f4899c2a 100644 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-desktop-shell) # source files for user apps. set(USER_APP_SRCS + examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc + examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc index 6ca65b0e..30b7714e 100644 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc @@ -6,11 +6,11 @@ #include #include -#include #include #include #include -#include + +#include "flutter_window.h" int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -47,57 +47,21 @@ int main(int argc, char** argv) { // weston_config_destroy(config); // The project to run. + constexpr int width = 640; + constexpr int height = 480; + flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - int width = 640; - int height = 480; - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, width, height, - show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, + width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake index 5d24e871..59114abb 100644 --- a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake +++ b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-desktop-shell) # source files for user apps. set(USER_APP_SRCS + examples/flutter-weston-desktop-shell/flutter_window.cc + examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc examples/flutter-weston-desktop-shell/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-weston-desktop-shell/flutter_window.cc b/examples/flutter-weston-desktop-shell/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-weston-desktop-shell/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-weston-desktop-shell/flutter_window.h b/examples/flutter-weston-desktop-shell/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-weston-desktop-shell/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc b/examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-weston-desktop-shell/generated_plugin_registrant.h b/examples/flutter-weston-desktop-shell/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-weston-desktop-shell/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc index 6ca65b0e..30b7714e 100644 --- a/examples/flutter-weston-desktop-shell/main.cc +++ b/examples/flutter-weston-desktop-shell/main.cc @@ -6,11 +6,11 @@ #include #include -#include #include #include #include -#include + +#include "flutter_window.h" int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -47,57 +47,21 @@ int main(int argc, char** argv) { // weston_config_destroy(config); // The project to run. + constexpr int width = 640; + constexpr int height = 480; + flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - int width = 640; - int height = 480; - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, width, height, - show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, + width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/examples/flutter-x11-client/cmake/user_build.cmake b/examples/flutter-x11-client/cmake/user_build.cmake index 8865c9e5..75174811 100644 --- a/examples/flutter-x11-client/cmake/user_build.cmake +++ b/examples/flutter-x11-client/cmake/user_build.cmake @@ -5,6 +5,8 @@ set(TARGET flutter-x11-client) # source files for user apps. set(USER_APP_SRCS + examples/flutter-x11-client/flutter_window.cc + examples/flutter-x11-client/generated_plugin_registrant.cc examples/flutter-x11-client/main.cc ) @@ -13,6 +15,7 @@ set(USER_APP_INCLUDE_DIRS ## Public APIs for developers (Don't edit!). src/client_wrapper/include src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public diff --git a/examples/flutter-x11-client/command_options.h b/examples/flutter-x11-client/command_options.h index e051a043..2cb5a66c 100644 --- a/examples/flutter-x11-client/command_options.h +++ b/examples/flutter-x11-client/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-x11-client/flutter_window.cc b/examples/flutter-x11-client/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/examples/flutter-x11-client/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-x11-client/flutter_window.h b/examples/flutter-x11-client/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/examples/flutter-x11-client/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-x11-client/generated_plugin_registrant.cc b/examples/flutter-x11-client/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/examples/flutter-x11-client/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-x11-client/generated_plugin_registrant.h b/examples/flutter-x11-client/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-x11-client/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index b80982a1..e9095b11 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -29,13 +28,6 @@ int main(int argc, char** argv) { } // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. const bool show_cursor = !options.Exist("no-cursor"); const auto view_mode = options.Exist("fullscreen") @@ -43,49 +35,20 @@ int main(int argc, char** argv) { : flutter::FlutterViewController::ViewMode::kNormal; const auto width = options.GetValue("width"); const auto height = options.GetValue("height"); - auto flutter_controller = std::make_unique( - view_mode, width, height, show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { - return 0; - } + const auto bundle_path = options.GetValue("bundle"); - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } + // The Flutter instance hosted by this window. + FlutterWindow window(project); + if (!window.OnCreate(view_mode, width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/src/templates/app/common/command_options.h b/src/templates/app/common/command_options.h index e051a043..2cb5a66c 100644 --- a/src/templates/app/common/command_options.h +++ b/src/templates/app/common/command_options.h @@ -2,6 +2,9 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + #include #include #include @@ -360,3 +363,5 @@ class CommandOptions { }; } // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/src/templates/app/common/flutter_window.cc b/src/templates/app/common/flutter_window.cc new file mode 100644 index 00000000..e71c246d --- /dev/null +++ b/src/templates/app/common/flutter_window.cc @@ -0,0 +1,74 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include + +#include "generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow(const flutter::DartProject project) + : project_(project) {} + +bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, + int width, int height, bool show_cursor) { + flutter_view_controller_ = std::make_unique( + view_mode, width, height, show_cursor, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait 1/60 [sec] = 13 [msec] if no events. + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds(13)); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/src/templates/app/common/flutter_window.h b/src/templates/app/common/flutter_window.h new file mode 100644 index 00000000..8f8cb092 --- /dev/null +++ b/src/templates/app/common/flutter_window.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow(const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, + int height, bool show_cursor); + void OnDestroy(); + void Run(); + + private: + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/src/templates/app/common/generated_plugin_registrant.cc b/src/templates/app/common/generated_plugin_registrant.cc new file mode 100644 index 00000000..8b1dc31e --- /dev/null +++ b/src/templates/app/common/generated_plugin_registrant.cc @@ -0,0 +1,7 @@ +// +// Generated file. Do not edit. +// + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/src/templates/app/common/generated_plugin_registrant.h b/src/templates/app/common/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/src/templates/app/common/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/src/templates/app/linux-drm/main.cc b/src/templates/app/linux-drm/main.cc index 8153d8b0..9a533507 100644 --- a/src/templates/app/linux-drm/main.cc +++ b/src/templates/app/linux-drm/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -25,58 +24,22 @@ int main(int argc, char** argv) { } // The project to run. + const bool show_cursor = !options.Exist("no-cursor"); const auto bundle_path = options.GetValue("bundle"); + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - const bool show_cursor = !options.Exist("no-cursor"); - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, 0, 0, show_cursor, - project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, + 0, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc index 6ca65b0e..30b7714e 100644 --- a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc +++ b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc @@ -6,11 +6,11 @@ #include #include -#include #include #include #include -#include + +#include "flutter_window.h" int main(int argc, char** argv) { // Works as a weston desktop shell. @@ -47,57 +47,21 @@ int main(int argc, char** argv) { // weston_config_destroy(config); // The project to run. + constexpr int width = 640; + constexpr int height = 480; + flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); // The Flutter instance hosted by this window. - int width = 640; - int height = 480; - auto flutter_controller = std::make_unique( - flutter::FlutterViewController::ViewMode::kFullscreen, width, height, - show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { + FlutterWindow window(project); + if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, + width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } - - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/src/templates/app/linux-wayland/main.cc b/src/templates/app/linux-wayland/main.cc index b80982a1..a5984e09 100644 --- a/src/templates/app/linux-wayland/main.cc +++ b/src/templates/app/linux-wayland/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -30,12 +29,6 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. const bool show_cursor = !options.Exist("no-cursor"); const auto view_mode = options.Exist("fullscreen") @@ -43,49 +36,19 @@ int main(int argc, char** argv) { : flutter::FlutterViewController::ViewMode::kNormal; const auto width = options.GetValue("width"); const auto height = options.GetValue("height"); - auto flutter_controller = std::make_unique( - view_mode, width, height, show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { - return 0; - } - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } + // The Flutter instance hosted by this window. + FlutterWindow window(project); + if (!window.OnCreate(view_mode, width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; } - + window.Run(); + window.OnDestroy(); return 0; } diff --git a/src/templates/app/linux-x11/main.cc b/src/templates/app/linux-x11/main.cc index b80982a1..e9095b11 100644 --- a/src/templates/app/linux-x11/main.cc +++ b/src/templates/app/linux-x11/main.cc @@ -5,13 +5,12 @@ #include #include -#include #include #include #include -#include #include "command_options.h" +#include "flutter_window.h" int main(int argc, char** argv) { commandline::CommandOptions options; @@ -29,13 +28,6 @@ int main(int argc, char** argv) { } // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. const bool show_cursor = !options.Exist("no-cursor"); const auto view_mode = options.Exist("fullscreen") @@ -43,49 +35,20 @@ int main(int argc, char** argv) { : flutter::FlutterViewController::ViewMode::kNormal; const auto width = options.GetValue("width"); const auto height = options.GetValue("height"); - auto flutter_controller = std::make_unique( - view_mode, width, height, show_cursor, project); - - // Ensure that basic setup of the controller was successful. - if (!flutter_controller->engine() || !flutter_controller->view()) { - return 0; - } + const auto bundle_path = options.GetValue("bundle"); - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_controller->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_controller->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } + // The Flutter instance hosted by this window. + FlutterWindow window(project); + if (!window.OnCreate(view_mode, width, height, show_cursor)) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; } - + window.Run(); + window.OnDestroy(); return 0; } From 09458fc2607b5277844e48783bb2c40f78ee8147 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 26 May 2021 12:46:57 +0900 Subject: [PATCH 003/178] Add vsync wayland support (#140) Closed #68 --- cmake/build.cmake | 7 ++ .../flutter_window.cc | 14 ++- .../flutter-drm-gbm-backend/flutter_window.cc | 14 ++- .../flutter_window.cc | 14 ++- .../flutter-wayland-client/flutter_window.cc | 14 ++- .../flutter_window.cc | 14 ++- .../flutter_window.cc | 14 ++- examples/flutter-x11-client/flutter_window.cc | 14 ++- .../include/flutter/flutter_view.h | 3 + .../linux_embedded/flutter_linuxes.cc | 4 + .../linux_embedded/flutter_linuxes_engine.cc | 27 +++- .../linux_embedded/flutter_linuxes_engine.h | 8 ++ .../linux_embedded/flutter_linuxes_view.cc | 9 ++ .../linux_embedded/flutter_linuxes_view.h | 7 ++ .../linux_embedded/public/flutter_linuxes.h | 5 +- .../platform/linux_embedded/vsync_waiter.cc | 38 ++++++ .../platform/linux_embedded/vsync_waiter.h | 35 ++++++ .../window/linuxes_window_drm.h | 3 + .../window/linuxes_window_wayland.cc | 118 ++++++++++++++++-- .../window/linuxes_window_wayland.h | 15 +++ .../window/linuxes_window_x11.cc | 2 + .../window/linuxes_window_x11.h | 3 + .../linux_embedded/window_binding_handler.h | 3 + .../window_binding_handler_delegate.h | 5 + src/templates/app/common/flutter_window.cc | 14 ++- 25 files changed, 352 insertions(+), 52 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/vsync_waiter.cc create mode 100644 src/flutter/shell/platform/linux_embedded/vsync_waiter.h diff --git a/cmake/build.cmake b/cmake/build.cmake index c75a299a..35608e04 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -53,11 +53,17 @@ else() CODE_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c HEADER_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v3-client-protocol.h) + generate_wayland_client_protocol( + PROTOCOL_FILE ${_wayland_protocols_xml_dir}/stable/presentation-time/presentation-time.xml + CODE_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.c + HEADER_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.h) + add_definitions(-DDISPLAY_BACKEND_TYPE_WAYLAND) set(DISPLAY_BACKEND_SRC ${_wayland_protocols_src_dir}/xdg-shell-protocol.c ${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c + ${_wayland_protocols_src_dir}/presentation-time-protocol.c src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc) endif() @@ -105,6 +111,7 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/system_utils.cc src/flutter/shell/platform/linux_embedded/logger.cc src/flutter/shell/platform/linux_embedded/external_texture_gl.cc + src/flutter/shell/platform/linux_embedded/vsync_waiter.cc src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.cc b/examples/flutter-drm-eglstream-backend/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_window.cc +++ b/examples/flutter-drm-eglstream-backend/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-drm-gbm-backend/flutter_window.cc b/examples/flutter-drm-gbm-backend/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-drm-gbm-backend/flutter_window.cc +++ b/examples/flutter-drm-gbm-backend/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-external-texture-plugin/flutter_window.cc b/examples/flutter-external-texture-plugin/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-external-texture-plugin/flutter_window.cc +++ b/examples/flutter-external-texture-plugin/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-wayland-client/flutter_window.cc b/examples/flutter-wayland-client/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-wayland-client/flutter_window.cc +++ b/examples/flutter-wayland-client/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc +++ b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-weston-desktop-shell/flutter_window.cc b/examples/flutter-weston-desktop-shell/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-weston-desktop-shell/flutter_window.cc +++ b/examples/flutter-weston-desktop-shell/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/examples/flutter-x11-client/flutter_window.cc b/examples/flutter-x11-client/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/examples/flutter-x11-client/flutter_window.cc +++ b/examples/flutter-x11-client/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); diff --git a/src/client_wrapper/include/flutter/flutter_view.h b/src/client_wrapper/include/flutter/flutter_view.h index b82c9b5d..343667e2 100644 --- a/src/client_wrapper/include/flutter/flutter_view.h +++ b/src/client_wrapper/include/flutter/flutter_view.h @@ -24,6 +24,9 @@ class FlutterView { // you have to call this every time in the main loop. bool DispatchEvent() { return FlutterDesktopViewDispatchEvent(view_); } + // Returns the display frame rate. + int32_t GetFrameRate() { return FlutterDesktopViewGetFrameRate(view_); } + private: // Handle for interacting with the C API's view. FlutterDesktopViewRef view_ = nullptr; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc index 5f4edd9a..746d291e 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc @@ -136,6 +136,10 @@ bool FlutterDesktopViewDispatchEvent(FlutterDesktopViewRef view) { return ViewFromHandle(view)->DispatchEvent(); } +int32_t FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view) { + return ViewFromHandle(view)->GetFrameRate(); +} + FlutterDesktopEngineRef FlutterDesktopEngineCreate( const FlutterDesktopEngineProperties& engine_properties) { flutter::FlutterProjectBundle project(engine_properties); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc index 27547426..16e8b497 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc @@ -135,6 +135,8 @@ FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project) std::make_unique>( messenger_wrapper_.get(), "flutter/settings", &JsonMessageCodec::GetInstance()); + + vsync_waiter_ = std::make_unique(); } FlutterLinuxesEngine::~FlutterLinuxesEngine() { Stop(); } @@ -204,7 +206,15 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { auto host = static_cast(user_data); return host->HandlePlatformMessage(engine_message); }; - +// todo: add drm/x11 support. +// https://github.com/sony/flutter-embedded-linux/issues/136 +// https://github.com/sony/flutter-embedded-linux/issues/137 +#if defined(DISPLAY_BACKEND_TYPE_WAYLAND) + args.vsync_callback = [](void* user_data, intptr_t baton) -> void { + auto host = static_cast(user_data); + host->vsync_waiter_->NotifyWaitForVsync(baton); + }; +#endif args.custom_task_runners = &custom_task_runners; if (aot_data_) { @@ -362,4 +372,19 @@ bool FlutterLinuxesEngine::MarkExternalTextureFrameAvailable( engine_, texture_id) == kSuccess); } +void FlutterLinuxesEngine::OnVsync(uint64_t last_frame_time_nanos, + uint64_t vsync_interval_time_nanos) { + uint64_t current_time_nanos = embedder_api_.GetCurrentTime(); + uint64_t after_vsync_passed_time_nanos = + (current_time_nanos - last_frame_time_nanos) % vsync_interval_time_nanos; + uint64_t frame_start_time_nanos = + current_time_nanos + + (vsync_interval_time_nanos - after_vsync_passed_time_nanos); + uint64_t frame_target_time_nanos = + frame_start_time_nanos + vsync_interval_time_nanos; + + vsync_waiter_->NotifyVsync(engine_, &embedder_api_, frame_start_time_nanos, + frame_target_time_nanos); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h index 3ef50bd8..139b1183 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h @@ -21,6 +21,7 @@ #include "flutter/shell/platform/linux_embedded/flutter_project_bundle.h" #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" #include "flutter/shell/platform/linux_embedded/task_runner.h" +#include "flutter/shell/platform/linux_embedded/vsync_waiter.h" namespace flutter { @@ -110,6 +111,10 @@ class FlutterLinuxesEngine { // given |texture_id|. bool MarkExternalTextureFrameAvailable(int64_t texture_id); + // Notifies the engine about the vsync event. + void OnVsync(uint64_t last_frame_time_nanos, + uint64_t vsync_interval_time_nanos); + private: // Allows swapping out embedder_api_ calls in tests. friend class EngineEmbedderApiModifier; @@ -158,6 +163,9 @@ class FlutterLinuxesEngine { // is being destroyed. FlutterDesktopOnPluginRegistrarDestroyed plugin_registrar_destruction_callback_ = nullptr; + + // The vsync waiter. + std::unique_ptr vsync_waiter_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 69f3b5f7..2539f997 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -204,6 +204,11 @@ void FlutterLinuxesView::OnScroll(double x, double y, double delta_x, SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); } +void FlutterLinuxesView::OnVsync(uint64_t last_frame_time_nanos, + uint64_t vsync_interval_time_nanos) { + engine_->OnVsync(last_frame_time_nanos, vsync_interval_time_nanos); +} + FlutterLinuxesView::touch_point* FlutterLinuxesView::GgeTouchPoint(int32_t id) { const size_t nmemb = sizeof(touch_event_) / sizeof(struct touch_point); int invalid = -1; @@ -381,4 +386,8 @@ LinuxesRenderSurfaceTarget* FlutterLinuxesView::GetRenderSurfaceTarget() const { FlutterLinuxesEngine* FlutterLinuxesView::GetEngine() { return engine_.get(); } +int32_t FlutterLinuxesView::GetFrameRate() { + return binding_handler_->GetFrameRate(); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h index fc7f2ce1..a0e7e89d 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h @@ -55,6 +55,9 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Returns the engine backing this view. FlutterLinuxesEngine* GetEngine(); + // Returns the frame rate of the display. + int32_t GetFrameRate(); + // Callbacks for clearing context, settings context and swapping buffers. void* ProcResolver(const char* name); bool MakeCurrent(); @@ -115,6 +118,10 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier) override; + // |WindowBindingHandlerDelegate| + void OnVsync(uint64_t frame_start_time_nanos, + uint64_t frame_target_time_nanos) override; + private: // Struct holding the mouse state. The engine doesn't keep track of which // mouse buttons have been pressed, so it's the embedding's responsibility. diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h b/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h index b534988a..c99d8128 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h @@ -109,13 +109,16 @@ FLUTTER_EXPORT void FlutterDesktopViewControllerDestroy( // Its lifetime is the same as the |controller|'s. FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine( FlutterDesktopViewControllerRef controller); -// Returns the view managed by the given controller. +// Returns the view managed by the given controller. FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef controller); FLUTTER_EXPORT bool FlutterDesktopViewDispatchEvent(FlutterDesktopViewRef view); +// Returns the display frame rate by the given controller. +FLUTTER_EXPORT int32_t FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view); + // ========== Engine ========== // Creates a Flutter engine with the given properties. diff --git a/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc b/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc new file mode 100644 index 00000000..01d86316 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc @@ -0,0 +1,38 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/vsync_waiter.h" + +#include + +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +VsyncWaiter::VsyncWaiter() : event_counter_(0) {} + +void VsyncWaiter::NotifyWaitForVsync(intptr_t baton) { + std::lock_guard lk(mutex_); + baton_ = baton; + event_counter_++; +} + +void VsyncWaiter::NotifyVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterEngineProcTable* embedder_api, + uint64_t frame_start_time_nanos, + uint64_t frame_target_time_nanos) { + std::lock_guard lk(mutex_); + if (event_counter_ > 0 && baton_ != 0) { + assert(event_counter_ == 1); + event_counter_--; + auto result = embedder_api->OnVsync(engine, baton_, frame_start_time_nanos, + frame_target_time_nanos); + if (result != kSuccess) { + LINUXES_LOG(ERROR) << "FlutterEngineOnVsync failed: batton = " << baton_; + } + } +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/vsync_waiter.h b/src/flutter/shell/platform/linux_embedded/vsync_waiter.h new file mode 100644 index 00000000..aa0f23be --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/vsync_waiter.h @@ -0,0 +1,35 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_VSYNC_WAITER_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_VSYNC_WAITER_H_ + +#include +#include + +#include "flutter/shell/platform/embedder/embedder.h" + +namespace flutter { + +class VsyncWaiter { + public: + VsyncWaiter(); + ~VsyncWaiter() = default; + + void NotifyWaitForVsync(intptr_t baton); + + void NotifyVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, + FlutterEngineProcTable* embedder_api, + uint64_t frame_start_time_nanos, + uint64_t frame_target_time_nanos); + + private: + intptr_t baton_; + uint32_t event_counter_; + std::mutex mutex_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_VSYNC_WAITER_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h index 2d89cd43..a931e078 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h @@ -173,6 +173,9 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { return {GetCurrentWidth(), GetCurrentHeight()}; } + // |FlutterWindowBindingHandler| + int32_t GetFrameRate() override { return 60000; } + // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override { if (show_cursor_) { diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc index a0b235f4..1406a3c0 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc @@ -67,6 +67,57 @@ const xdg_surface_listener LinuxesWindowWayland::kXdgSurfaceListener = { }, }; +const wp_presentation_listener LinuxesWindowWayland::kWpPresentationListener = { + .clock_id = + [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { + auto self = reinterpret_cast(data); + self->wp_presentation_clk_id_ = clk_id; + LINUXES_LOG(TRACE) << "presentation info: clk_id = " << clk_id; + }, +}; + +const wp_presentation_feedback_listener + LinuxesWindowWayland::kWpPresentationFeedbackListener = { + .sync_output = + [](void* data, + struct wp_presentation_feedback* wp_presentation_feedback, + wl_output* output) {}, + .presented = + [](void* data, + struct wp_presentation_feedback* wp_presentation_feedback, + uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec, + uint32_t refresh, uint32_t seq_hi, uint32_t seq_lo, + uint32_t flags) { + auto self = reinterpret_cast(data); + self->last_frame_time_nanos_ = + (((static_cast(tv_sec_hi) << 32) + tv_sec_lo) * + 1000000000) + + tv_nsec; + self->frame_rate_ = refresh; + }, + .discarded = + [](void* data, + struct wp_presentation_feedback* wp_presentation_feedback) {}, +}; + +const wl_callback_listener LinuxesWindowWayland::kWlSurfaceFrameListener = { + .done = + [](void* data, wl_callback* wl_callback, uint32_t time) { + // The presentation-time is an extended protocol and isn't supported + // by all compositors. This path is for when it wasn't supported. + auto self = reinterpret_cast(data); + if (self->wp_presentation_clk_id_ != UINT32_MAX) { + return; + } + + self->last_frame_time_nanos_ = static_cast(time) * 1000000; + + auto callback = wl_surface_frame(self->native_window_->Surface()); + wl_callback_destroy(wl_callback); + wl_callback_add_listener(callback, &kWlSurfaceFrameListener, data); + }, +}; + const wl_seat_listener LinuxesWindowWayland::kWlSeatListener = { .capabilities = [](void* data, wl_seat* seat, uint32_t caps) -> void { auto self = reinterpret_cast(data); @@ -277,8 +328,14 @@ const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { int32_t height, int32_t refresh) -> void { auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { - LINUXES_LOG(INFO) << "Display output resolution: " << width << "x" - << height; + LINUXES_LOG(INFO) << "Display output info: width = " << width + << ", height = " << height + << ", refresh = " << refresh; + // Some composers send 0 for the refresh value. + if (refresh != 0) { + self->frame_rate_ = refresh; + } + if (self->window_mode_ == FlutterWindowMode::kFullscreen) { self->current_width_ = width; self->current_height_ = height; @@ -501,11 +558,14 @@ LinuxesWindowWayland::LinuxesWindowWayland(FlutterWindowMode window_mode, wl_data_offer_(nullptr), wl_data_source_(nullptr), wl_cursor_theme_(nullptr), + serial_(0), zwp_text_input_manager_v1_(nullptr), zwp_text_input_manager_v3_(nullptr), zwp_text_input_v1_(nullptr), zwp_text_input_v3_(nullptr), - serial_(0) { + wp_presentation_(nullptr), + wp_presentation_clk_id_(UINT32_MAX), + frame_rate_(60000) { window_mode_ = window_mode; current_width_ = width; current_height_ = height; @@ -697,16 +757,14 @@ PhysicalWindowBounds LinuxesWindowWayland::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } +int32_t LinuxesWindowWayland::GetFrameRate() { return frame_rate_; } + bool LinuxesWindowWayland::DispatchEvent() { if (!IsValid()) { LINUXES_LOG(ERROR) << "Wayland display is invalid."; return false; } - pollfd fds[] = { - {wl_display_get_fd(wl_display_), POLLIN}, - }; - // Prepare to call wl_display_read_events. while (wl_display_prepare_read(wl_display_) != 0) { // If Wayland compositor terminates, -1 is returned. @@ -715,14 +773,40 @@ bool LinuxesWindowWayland::DispatchEvent() { return false; } } - - // Handle events. wl_display_flush(wl_display_); + + // Handle Vsync. + { + if (wp_presentation_clk_id_ != UINT32_MAX) { + // This path is used if the presentation-time protocol is supported by the + // compositor. + wp_presentation_feedback_add_listener( + ::wp_presentation_feedback(wp_presentation_, + native_window_->Surface()), + &kWpPresentationFeedbackListener, this); + auto result = wl_display_dispatch_pending(wl_display_); + if (result == -1) { + return false; + } + } + + if (binding_handler_delegate_) { + const uint64_t vsync_interval_time_nanos = 1000000000000 / frame_rate_; + binding_handler_delegate_->OnVsync(last_frame_time_nanos_, + vsync_interval_time_nanos); + } + } + + // Handle Wayland events. + pollfd fds[] = { + {wl_display_get_fd(wl_display_), POLLIN}, + }; if (poll(fds, 1, 0) > 0) { - int result = wl_display_read_events(wl_display_); + auto result = wl_display_read_events(wl_display_); if (result == -1) { return false; } + result = wl_display_dispatch_pending(wl_display_); if (result == -1) { return false; @@ -780,6 +864,9 @@ bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { xdg_toplevel_set_title(xdg_toplevel_, "Flutter"); wl_surface_commit(native_window_->Surface()); + auto* callback = wl_surface_frame(native_window_->Surface()); + wl_callback_add_listener(callback, &kWlSurfaceFrameListener, this); + render_surface_ = std::make_unique(std::make_unique( std::make_unique(wl_display_))); render_surface_->SetNativeWindow(native_window_.get()); @@ -946,6 +1033,7 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, wl_output_ = static_cast( wl_registry_bind(wl_registry, name, &wl_output_interface, 1)); wl_output_add_listener(wl_output_, &kWlOutputListener, this); + return; } if (!strcmp(interface, wl_shm_interface.name)) { @@ -987,6 +1075,16 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, wl_data_device_manager_ = static_cast( wl_registry_bind(wl_registry, name, &wl_data_device_manager_interface, wl_data_device_manager_version_)); + return; + } + + if (!strcmp(interface, wp_presentation_interface.name)) { + constexpr uint32_t kMaxVersion = 1; + wp_presentation_ = static_cast(wl_registry_bind( + wl_registry, name, &wp_presentation_interface, kMaxVersion)); + wp_presentation_add_listener(wp_presentation_, &kWpPresentationListener, + this); + return; } } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h index 9780f859..e23bc06d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h @@ -20,6 +20,7 @@ // These header files are automatically generated by the // wayland-scanner. extern "C" { +#include "wayland/protocol/presentation-time-protocol.h" #include "wayland/protocol/text-input-unstable-v1-client-protocol.h" #include "wayland/protocol/text-input-unstable-v3-client-protocol.h" #include "wayland/protocol/weston-desktop-shell-client-protocol.h" @@ -58,6 +59,9 @@ class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| PhysicalWindowBounds GetPhysicalWindowBounds() override; + // |FlutterWindowBindingHandler| + int32_t GetFrameRate() override; + // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override; @@ -102,6 +106,10 @@ class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { static const wl_data_source_listener kWlDataSourceListener; static const zwp_text_input_v1_listener kZwpTextInputV1Listener; static const zwp_text_input_v3_listener kZwpTextInputV3Listener; + static const wl_callback_listener kWlSurfaceFrameListener; + static const wp_presentation_listener kWpPresentationListener; + static const wp_presentation_feedback_listener + kWpPresentationFeedbackListener; // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. @@ -111,6 +119,7 @@ class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { std::unique_ptr render_surface_; bool display_valid_; + uint32_t last_frame_time_; // Indicates that exists a keyboard show request from Flutter Engine. bool is_requested_show_virtual_keyboard_; @@ -136,6 +145,12 @@ class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { zwp_text_input_v1* zwp_text_input_v1_; zwp_text_input_v3* zwp_text_input_v3_; + // Frame information for Vsync events. + wp_presentation* wp_presentation_; + uint32_t wp_presentation_clk_id_; + uint64_t last_frame_time_nanos_; + int32_t frame_rate_; + CursorInfo cursor_info_; // List of cursor name and wl_cursor supported by Wayland. diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc index 447375b6..76d1338b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc @@ -145,6 +145,8 @@ PhysicalWindowBounds LinuxesWindowX11::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } +int32_t LinuxesWindowX11::GetFrameRate() { return 60000; } + void LinuxesWindowX11::UpdateFlutterCursor(const std::string& cursor_name) { // TODO: implement here } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h index e385436b..ff1b552c 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h @@ -44,6 +44,9 @@ class LinuxesWindowX11 : public LinuxesWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| PhysicalWindowBounds GetPhysicalWindowBounds() override; + // |FlutterWindowBindingHandler| + int32_t GetFrameRate() override; + // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 9d3dfd87..463f6452 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -53,6 +53,9 @@ class WindowBindingHandler { // Returns the bounds of the backing window in physical pixels. virtual PhysicalWindowBounds GetPhysicalWindowBounds() = 0; + // Returns the frame rate of the display. + virtual int32_t GetFrameRate() = 0; + // Sets the cursor that should be used when the mouse is over the Flutter // content. See mouse_cursor.dart for the values and meanings of cursor_name. virtual void UpdateFlutterCursor(const std::string& cursor_name) = 0; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index 4187342f..a01a6cd8 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -74,6 +74,11 @@ class WindowBindingHandlerDelegate { // Typically called by currently configured WindowBindingHandler virtual void OnScroll(double x, double y, double delta_x, double delta_y, int scroll_offset_multiplier) = 0; + + // Notifies delegate that backing window vsync has happened. + // Typically called by currently configured WindowBindingHandler + virtual void OnVsync(uint64_t last_frame_time_nanos, + uint64_t vsync_interval_time_nanos) = 0; }; } // namespace flutter diff --git a/src/templates/app/common/flutter_window.cc b/src/templates/app/common/flutter_window.cc index e71c246d..9ead67f6 100644 --- a/src/templates/app/common/flutter_window.cc +++ b/src/templates/app/common/flutter_window.cc @@ -5,6 +5,8 @@ #include "flutter_window.h" #include +#include +#include #include #include "generated_plugin_registrant.h" @@ -61,11 +63,13 @@ void FlutterWindow::Run() { std::chrono::steady_clock::time_point::clock::now() + wait_duration); } else { - // Wait 1/60 [sec] = 13 [msec] if no events. - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds(13)); + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); } next_flutter_event_time = std::max(next_flutter_event_time, next_event_time); From 10ff080a1215e8af30aa1c797fa36c266ff8bd72 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 26 May 2021 14:54:32 +0900 Subject: [PATCH 004/178] Update README: add description about building for Flutter apps (#142) --- README.md | 10 +++++----- doc/README.md | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0ef6b97c..2b6bacba 100644 --- a/README.md +++ b/README.md @@ -32,11 +32,6 @@ This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux whi | Board / SoC | Vendor | OS / BSP | Backend | Status | | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | -| Desktop (x86_64) | Intel | Ubuntu 18.04 | Wayland | :heavy_check_mark: | -| Desktop (x86_64) | Intel | Ubuntu 18.04 | DRM | :heavy_check_mark: | -| Desktop (x86_64) | Intel | Ubuntu 18.04 | X11 | :heavy_check_mark: | -| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | Wayland | :heavy_check_mark: | -| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | DRM | :heavy_check_mark: | | [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | Wayland | :heavy_check_mark: | | [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | DRM | :heavy_check_mark: ([#1](https://github.com/sony/flutter-embedded-linux/issues/1))| | [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Raspberry Pi Foundation | Ubuntu 20.10 | Wayland | :heavy_check_mark: | @@ -45,6 +40,11 @@ This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux whi | [i.MX 8M Mini EVKB](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-mini-applications-processor:8MMINILPD4-EVK) | NXP | Zeus (kernel 5.4.70) | Wayland | :heavy_check_mark: | | [RB5 Development Kit](https://developer.qualcomm.com/qualcomm-robotics-rb5-kit) | Qualcomm | Ubuntu 18.04.05 | DRM | :heavy_check_mark: | | Zynq | Xilinx | - | - | Not tested | +| Desktop (x86_64) | Intel | Ubuntu 20.04 | Wayland | :heavy_check_mark: | +| Desktop (x86_64) | Intel | Ubuntu 20.04 | DRM | :heavy_check_mark: | +| Desktop (x86_64) | Intel | Ubuntu 20.04 | X11 | :heavy_check_mark: | +| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | Wayland | :heavy_check_mark: | +| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | DRM | :heavy_check_mark: | Note - i.MX 8M platforms don't support applications using EGL on GBM, which means the DRM-GBM backend won't work on i.MX 8M devices. diff --git a/doc/README.md b/doc/README.md index 138d2054..65d25a4f 100644 --- a/doc/README.md +++ b/doc/README.md @@ -176,6 +176,7 @@ See also: [Building Flutter Engine embedder](./building-engine-embedder.md) Here introduce how to build the flutter sample app. #### For x64 targets on x64 hosts / for Arm64 targets on Arm64 hosts +Note that you need to build Flutter apps in the same mode(release/debug) `libflutter_engine.so` was built. It means you need to build Flutter apps in the release mode if you use `libflutter_engine.so` was built in release mode. Build for release mode: ```Shell From af34af49575bb73a30fd4530699a34125c44f4d9 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 27 May 2021 08:43:58 +0900 Subject: [PATCH 005/178] Add FLUTTER_LOG_LEVELS environment var to change logging levels (#143) --- doc/README.md | 13 ++++- .../shell/platform/linux_embedded/logger.cc | 53 +++++++++++++++---- 2 files changed, 55 insertions(+), 11 deletions(-) diff --git a/doc/README.md b/doc/README.md index 65d25a4f..1cac9ea8 100644 --- a/doc/README.md +++ b/doc/README.md @@ -18,7 +18,7 @@ $ sudo apt install clang cmake build-essential pkg-config libegl1-mesa-dev libxk ### Only when using Wayland backend - libwayland -- wayland-protocols (for generating xdg-shell source files) +- wayland-protocols (to generate the source files of Wayland protocols) ```Shell $ sudo apt install libwayland-dev wayland-protocols @@ -211,6 +211,17 @@ Wayland compositor such as Weston must be running before running the program. $ ./flutter-client --bundle=./sample/build/linux/x64/release/bundle ``` +### Logging levels +The logging levels of the embedder are controlled by `FLUTTER_LOG_LEVELS` environment var. If you want to do debugging, set `FLUTTER_LOG_LEVELS`. The default level is `WARNING`. + +```Shell +$ FLUTTER_LOG_LEVELS=TRACE ./flutter-client --bundle= +$ FLUTTER_LOG_LEVELS=INFO ./flutter-client --bundle= +$ FLUTTER_LOG_LEVELS=WARNING ./flutter-client --bundle= +$ FLUTTER_LOG_LEVELS=ERROR ./flutter-client --bundle= +$ FLUTTER_LOG_LEVELS=FATAL ./flutter-client --bundle= +``` + ### Supplement You can switch quickly between debug / profile / release modes for the Flutter app without replacing `libflutter_engine.so` by using `LD_LIBRARY_PATH` when you run the Flutter app. diff --git a/src/flutter/shell/platform/linux_embedded/logger.cc b/src/flutter/shell/platform/linux_embedded/logger.cc index a59125e2..e379453b 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.cc +++ b/src/flutter/shell/platform/linux_embedded/logger.cc @@ -4,37 +4,70 @@ #include "logger.h" +#include +#include + namespace flutter { namespace { -#ifdef FLUTTER_RELEASE -constexpr int kFilterLogLevel = LINUXES_LOG_WARNING; -#else -constexpr int kFilterLogLevel = LINUXES_LOG_TRACE; -#endif +constexpr char kFlutterLogLevelsEnvironmentKey[] = "FLUTTER_LOG_LEVELS"; +constexpr char kFlutterLogLevelTrace[] = "TRACE"; +constexpr char kFlutterLogLevelInfo[] = "INFO"; +constexpr char kFlutterLogLevelWarning[] = "WARNING"; +constexpr char kFlutterLogLevelError[] = "ERROR"; +constexpr char kFlutterLogLevelFatal[] = "FATAL"; +constexpr char kFlutterLogLevelUnknown[] = "UNKNOWN"; + +const char* const kLogLevelNames[LINUXES_LOG_NUM] = { + kFlutterLogLevelTrace, kFlutterLogLevelInfo, kFlutterLogLevelWarning, + kFlutterLogLevelError, kFlutterLogLevelFatal}; -const char* const kLogLevelNames[LINUXES_LOG_NUM] = {"TRACE", "INFO", "WARNING", - "ERROR", "FATAL"}; +const std::unordered_map gLogLevelsMap{ + {kFlutterLogLevelTrace, LINUXES_LOG_TRACE}, + {kFlutterLogLevelInfo, LINUXES_LOG_INFO}, + {kFlutterLogLevelWarning, LINUXES_LOG_WARNING}, + {kFlutterLogLevelError, LINUXES_LOG_ERROR}, + {kFlutterLogLevelFatal, LINUXES_LOG_FATAL}, +}; + +int gFilterLogLevel = -1; + +int GetCurrentLogLevel() { + if (gFilterLogLevel == -1) { + auto env_log_level = std::getenv(kFlutterLogLevelsEnvironmentKey); + if (!env_log_level || (env_log_level[0] == '\0')) { + gFilterLogLevel = LINUXES_LOG_WARNING; + } else { + if (gLogLevelsMap.find(env_log_level) != gLogLevelsMap.end()) { + gFilterLogLevel = gLogLevelsMap.at(env_log_level); + } else { + gFilterLogLevel = LINUXES_LOG_WARNING; + } + } + } + return gFilterLogLevel; +} const char* GetLogLevelName(int level) { if (LINUXES_LOG_TRACE <= level && level < LINUXES_LOG_NUM) return kLogLevelNames[level]; - return "UNKNOWN"; + return kFlutterLogLevelUnknown; } } // namespace Logger::Logger(int level, const char* file, int line) : level_(level) { - if (level_ < kFilterLogLevel) { + if (level_ < GetCurrentLogLevel()) { return; } + stream_ << "[" << GetLogLevelName(level_) << "]"; stream_ << "[" << file << "(" << line << ")] "; } Logger::~Logger() { - if (level_ < kFilterLogLevel) { + if (level_ < GetCurrentLogLevel()) { return; } From cb3af6882dfb4c854f93ca2b13cad5605608b4dc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 28 May 2021 16:47:30 +0900 Subject: [PATCH 006/178] Add log output of flutter apps (#146) --- .../platform/linux_embedded/flutter_linuxes_engine.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc index 16e8b497..db506e95 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc @@ -224,6 +224,15 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { args.custom_dart_entrypoint = entrypoint; } + args.log_message_callback = [](const char* tag, const char* message, + void* user_data) { + std::string str_tag(tag); + if (str_tag.size() > 0) { + std::cout << str_tag << ": "; + } + std::cout << message << std::endl; + }; + auto renderer_config = GetRendererConfig(); auto result = embedder_api_.Run(FLUTTER_ENGINE_VERSION, &renderer_config, &args, this, &engine_); From 2b2487e71357f931b947baef05e1ea46d42f930d Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 28 May 2021 16:52:43 +0900 Subject: [PATCH 007/178] Update .gclient file to not download other than Linux deps (#147) --- doc/building-engine-embedder.md | 8 ++++++++ .../recipes-graphics/flutter-engine/flutter-engine.bb | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/doc/building-engine-embedder.md b/doc/building-engine-embedder.md index cd0450bc..d572fd4e 100644 --- a/doc/building-engine-embedder.md +++ b/doc/building-engine-embedder.md @@ -35,6 +35,10 @@ solutions = [ "custom_deps": {}, "deps_file": "DEPS", "safesync_url": "", + "custom_vars": { + "download_android_deps": False, + "download_windows_deps": False, + }, }, ] ``` @@ -58,6 +62,10 @@ solutions = [ "custom_deps": {}, "deps_file": "DEPS", "safesync_url": "", + "custom_vars": { + "download_android_deps": False, + "download_windows_deps": False, + }, }, ] ``` diff --git a/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb b/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb index 960f7c2e..fcd4cf51 100755 --- a/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb +++ b/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb @@ -45,6 +45,10 @@ do_configure() { "custom_deps": {}, "deps_file": "DEPS", "safesync_url": "", + "custom_vars": { + "download_android_deps": False, + "download_windows_deps": False, + }, }, ]' > .gclient gclient sync From 2c35ca9912a0e88e0530be2c7599685d4eeee6df Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 30 May 2021 08:52:11 +0900 Subject: [PATCH 008/178] Update the engine common library (#148) --- .../client_wrapper/include/flutter/encodable_value.h | 2 ++ .../platform/common/client_wrapper/standard_codec.cc | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h index a4c7ac40..870cfc80 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h @@ -110,6 +110,7 @@ using EncodableValueVariant = std::variant, EncodableList, EncodableMap, + std::vector, CustomEncodableValue>; } // namespace internal @@ -158,6 +159,7 @@ using EncodableValueVariant = std::variant -> Float64List // EncodableList -> List // EncodableMap -> Map +// std::vector -> Float32List class EncodableValue : public internal::EncodableValueVariant { public: // Rely on std::variant for most of the constructors/operators. diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index 3e86879b..a7725088 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -41,6 +41,7 @@ enum class EncodedType { kFloat64List, kList, kMap, + kFloat32List, }; // Returns the encoded type that should be written when serializing |value|. @@ -70,6 +71,8 @@ EncodedType EncodedTypeForValue(const EncodableValue& value) { return EncodedType::kList; case 11: return EncodedType::kMap; + case 12: + return EncodedType::kFloat32List; } assert(false); return EncodedType::kNull; @@ -150,7 +153,11 @@ void StandardCodecSerializer::WriteValue(const EncodableValue& value, } break; } - case 12: + case 12: { + WriteVector(std::get>(value), stream); + break; + } + case 13: std::cerr << "Unhandled custom type in StandardCodecSerializer::WriteValue. " << "Custom types require codec extensions." << std::endl; @@ -210,6 +217,9 @@ EncodableValue StandardCodecSerializer::ReadValueOfType( } return EncodableValue(map_value); } + case EncodedType::kFloat32List: { + return ReadVector(stream); + } } std::cerr << "Unknown type in StandardCodecSerializer::ReadValueOfType: " << static_cast(type) << std::endl; From 7fa593568f118198907d4d3c38757a094f65b3bc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 31 May 2021 08:40:37 +0900 Subject: [PATCH 009/178] Bugfix: multi-touch doesn't work correctly (#149) --- .../shell/platform/linux_embedded/flutter_linuxes_view.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 2539f997..1fb5a400 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -104,7 +104,7 @@ void FlutterLinuxesView::OnTouchDown(uint32_t time, int32_t id, double x, .timestamp = time, .x = x, .y = y, - .device = kFlutterPointerDeviceKindTouch, + .device = id, .signal_kind = kFlutterPointerSignalKindNone, .scroll_delta_x = 0, .scroll_delta_y = 0, @@ -127,7 +127,7 @@ void FlutterLinuxesView::OnTouchUp(uint32_t time, int32_t id) { .timestamp = time, .x = point->x, .y = point->y, - .device = kFlutterPointerDeviceKindTouch, + .device = id, .signal_kind = kFlutterPointerSignalKindNone, .scroll_delta_x = 0, .scroll_delta_y = 0, @@ -154,7 +154,7 @@ void FlutterLinuxesView::OnTouchMotion(uint32_t time, int32_t id, double x, .timestamp = time, .x = x, .y = y, - .device = kFlutterPointerDeviceKindTouch, + .device = id, .signal_kind = kFlutterPointerSignalKindNone, .scroll_delta_x = 0, .scroll_delta_y = 0, From 0d21b7b189521ca47d1f8a205bfe46acb247babc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 31 May 2021 08:43:21 +0900 Subject: [PATCH 010/178] Bugfix setting of frame rate for Wayland (#151) Closed #150 --- .../platform/linux_embedded/window/linuxes_window_wayland.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc index 1406a3c0..c8b1369a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc @@ -11,6 +11,7 @@ #include #include +#include #include #include "flutter/shell/platform/linux_embedded/logger.h" @@ -93,7 +94,8 @@ const wp_presentation_feedback_listener (((static_cast(tv_sec_hi) << 32) + tv_sec_lo) * 1000000000) + tv_nsec; - self->frame_rate_ = refresh; + self->frame_rate_ = + static_cast(std::round(1000000000000.0 / refresh)); }, .discarded = [](void* data, From 3922ec8ab1d338f3e93261d072e90ada8dc51f81 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 31 May 2021 11:09:06 +0900 Subject: [PATCH 011/178] Add lifecycle plugin (#152) --- cmake/build.cmake | 1 + .../linux_embedded/flutter_linuxes_view.cc | 2 + .../linux_embedded/flutter_linuxes_view.h | 4 ++ .../shell/platform/linux_embedded/logger.cc | 6 ++- .../shell/platform/linux_embedded/logger.h | 11 ++--- .../linux_embedded/plugin/key_event_plugin.cc | 1 - .../linux_embedded/plugin/lifecycle_plugin.cc | 44 +++++++++++++++++++ .../linux_embedded/plugin/lifecycle_plugin.h | 34 ++++++++++++++ 8 files changed, 95 insertions(+), 8 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc create mode 100644 src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h diff --git a/cmake/build.cmake b/cmake/build.cmake index 35608e04..830620b3 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -115,6 +115,7 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc + src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 1fb5a400..66f8035e 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -48,6 +48,8 @@ void FlutterLinuxesView::SetEngine( internal_plugin_messenger, binding_handler_.get()); cursor_handler_ = std::make_unique( internal_plugin_messenger, binding_handler_.get()); + lifecycle_handler_ = + std::make_unique(internal_plugin_messenger); PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h index a0e7e89d..5efb40de 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h @@ -14,6 +14,7 @@ #include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" #include "flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/platform_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h" @@ -237,6 +238,9 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Handler for cursor events. std::unique_ptr cursor_handler_; + // Handler for app lifecycle events. + std::unique_ptr lifecycle_handler_; + // Currently configured WindowBindingHandler for view. std::unique_ptr binding_handler_; diff --git a/src/flutter/shell/platform/linux_embedded/logger.cc b/src/flutter/shell/platform/linux_embedded/logger.cc index e379453b..b22a86c3 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.cc +++ b/src/flutter/shell/platform/linux_embedded/logger.cc @@ -13,6 +13,7 @@ namespace { constexpr char kFlutterLogLevelsEnvironmentKey[] = "FLUTTER_LOG_LEVELS"; constexpr char kFlutterLogLevelTrace[] = "TRACE"; +constexpr char kFlutterLogLevelDebug[] = "DEBUG"; constexpr char kFlutterLogLevelInfo[] = "INFO"; constexpr char kFlutterLogLevelWarning[] = "WARNING"; constexpr char kFlutterLogLevelError[] = "ERROR"; @@ -20,11 +21,12 @@ constexpr char kFlutterLogLevelFatal[] = "FATAL"; constexpr char kFlutterLogLevelUnknown[] = "UNKNOWN"; const char* const kLogLevelNames[LINUXES_LOG_NUM] = { - kFlutterLogLevelTrace, kFlutterLogLevelInfo, kFlutterLogLevelWarning, - kFlutterLogLevelError, kFlutterLogLevelFatal}; + kFlutterLogLevelTrace, kFlutterLogLevelDebug, kFlutterLogLevelInfo, + kFlutterLogLevelWarning, kFlutterLogLevelError, kFlutterLogLevelFatal}; const std::unordered_map gLogLevelsMap{ {kFlutterLogLevelTrace, LINUXES_LOG_TRACE}, + {kFlutterLogLevelDebug, LINUXES_LOG_DEBUG}, {kFlutterLogLevelInfo, LINUXES_LOG_INFO}, {kFlutterLogLevelWarning, LINUXES_LOG_WARNING}, {kFlutterLogLevelError, LINUXES_LOG_ERROR}, diff --git a/src/flutter/shell/platform/linux_embedded/logger.h b/src/flutter/shell/platform/linux_embedded/logger.h index bebf0667..62da328e 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.h +++ b/src/flutter/shell/platform/linux_embedded/logger.h @@ -13,11 +13,12 @@ namespace flutter { constexpr int LINUXES_LOG_TRACE = 0; -constexpr int LINUXES_LOG_INFO = 1; -constexpr int LINUXES_LOG_WARNING = 2; -constexpr int LINUXES_LOG_ERROR = 3; -constexpr int LINUXES_LOG_FATAL = 4; -constexpr int LINUXES_LOG_NUM = 5; +constexpr int LINUXES_LOG_DEBUG = 1; +constexpr int LINUXES_LOG_INFO = 2; +constexpr int LINUXES_LOG_WARNING = 3; +constexpr int LINUXES_LOG_ERROR = 4; +constexpr int LINUXES_LOG_FATAL = 5; +constexpr int LINUXES_LOG_NUM = 6; #define __LOG_FILE_NAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) diff --git a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc index d3be410a..854c74f6 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc @@ -13,7 +13,6 @@ #include #include "flutter/shell/platform/common/json_message_codec.h" -#include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc new file mode 100644 index 00000000..e7c8fa09 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc @@ -0,0 +1,44 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h" + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h" +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +namespace { +constexpr char kChannelName[] = "flutter/lifecycle"; +constexpr char kInactive[] = "AppLifecycleState.inactive"; +constexpr char kResumed[] = "AppLifecycleState.resumed"; +constexpr char kPaused[] = "AppLifecycleState.paused"; +constexpr char kDetached[] = "AppLifecycleState.detached"; +} // namespace + +LifecyclePlugin::LifecyclePlugin(BinaryMessenger* messenger) + : channel_(std::make_unique>( + messenger, kChannelName, &StandardMessageCodec::GetInstance())) {} + +void LifecyclePlugin::OnInactive() const { + LINUXES_LOG(DEBUG) << "App lifecycle changed to inactive state."; + channel_->Send(EncodableValue(std::string(kInactive))); +} + +void LifecyclePlugin::OnResumed() const { + LINUXES_LOG(DEBUG) << "App lifecycle changed to resumed state."; + channel_->Send(EncodableValue(std::string(kResumed))); +} + +void LifecyclePlugin::OnPaused() const { + LINUXES_LOG(DEBUG) << "App lifecycle changed to paused state."; + channel_->Send(EncodableValue(std::string(kPaused))); +} + +void LifecyclePlugin::OnDetached() const { + LINUXES_LOG(DEBUG) << "App lifecycle changed to detached state."; + channel_->Send(EncodableValue(std::string(kDetached))); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h b/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h new file mode 100644 index 00000000..0abefe20 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h @@ -0,0 +1,34 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ + +#include + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" + +namespace flutter { + +class LifecyclePlugin { + public: + LifecyclePlugin(BinaryMessenger* messenger); + ~LifecyclePlugin() = default; + + void OnInactive() const; + + void OnResumed() const; + + void OnPaused() const; + + void OnDetached() const; + + private: + std::unique_ptr> channel_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ From c78bf67053143723e839ff20bc0bed68d7ffcb3f Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 31 May 2021 14:15:55 +0900 Subject: [PATCH 012/178] Add navigation plugin (#153) --- cmake/build.cmake | 7 +-- .../linux_embedded/flutter_linuxes_view.cc | 2 + .../linux_embedded/flutter_linuxes_view.h | 4 ++ .../plugin/navigation_plugin.cc | 53 +++++++++++++++++++ .../linux_embedded/plugin/navigation_plugin.h | 35 ++++++++++++ 5 files changed, 98 insertions(+), 3 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc create mode 100644 src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h diff --git a/cmake/build.cmake b/cmake/build.cmake index 830620b3..1003416a 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -113,12 +113,13 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/external_texture_gl.cc src/flutter/shell/platform/linux_embedded/vsync_waiter.cc src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc - src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc + src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc + src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc + src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc + src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc src/flutter/shell/platform/linux_embedded/surface/context_egl.cc src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 66f8035e..3b4deae5 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -50,6 +50,8 @@ void FlutterLinuxesView::SetEngine( internal_plugin_messenger, binding_handler_.get()); lifecycle_handler_ = std::make_unique(internal_plugin_messenger); + navigation_handler_ = + std::make_unique(internal_plugin_messenger); PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h index 5efb40de..8a0d6f28 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h @@ -16,6 +16,7 @@ #include "flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/platform_plugin.h" #include "flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h" #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" @@ -241,6 +242,9 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Handler for app lifecycle events. std::unique_ptr lifecycle_handler_; + // Handler for flutter/navigation channel. + std::unique_ptr navigation_handler_; + // Currently configured WindowBindingHandler for view. std::unique_ptr binding_handler_; diff --git a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc new file mode 100644 index 00000000..06b75595 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc @@ -0,0 +1,53 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h" + +#include "flutter/shell/platform/common/json_method_codec.h" +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +namespace { +constexpr char kChannelName[] = "flutter/navigation"; + +constexpr char kSetInitialRouteMethod[] = "setInitialRoute"; +constexpr char kPushRouteMethod[] = "pushRoute"; +constexpr char kPopRouteMethod[] = "popRoute"; +} // namespace + +NavigationPlugin::NavigationPlugin(BinaryMessenger* messenger) + : channel_(std::make_unique>( + messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())) {} + +void NavigationPlugin::SetInitialRoute(std::string route) const { + LINUXES_LOG(DEBUG) << "SetInitialRoute = " << route; + + auto args = std::make_unique(rapidjson::kObjectType); + args->Parse("\"" + route + "\""); + if (args->HasParseError()) { + LINUXES_LOG(ERROR) << "Failed to parse the initial route: " << route; + return ; + } + channel_->InvokeMethod(kSetInitialRouteMethod, std::move(args)); +} + +void NavigationPlugin::PushRoute(std::string route) const { + LINUXES_LOG(DEBUG) << "PushRoute = " << route; + + auto args = std::make_unique(rapidjson::kObjectType); + args->Parse("\"" + route + "\""); + if (args->HasParseError()) { + LINUXES_LOG(ERROR) << "Failed to parse the route: " << route; + return ; + } + channel_->InvokeMethod(kPushRouteMethod, std::move(args)); +} + +void NavigationPlugin::PopRoute() const { + LINUXES_LOG(DEBUG) << "PopRoute"; + channel_->InvokeMethod(kPopRouteMethod, nullptr); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h b/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h new file mode 100644 index 00000000..07676548 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h @@ -0,0 +1,35 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ + +#include + +#include +#include + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h" + +namespace flutter { + +class NavigationPlugin { + public: + NavigationPlugin(BinaryMessenger* messenger); + ~NavigationPlugin() = default; + + void SetInitialRoute(std::string initial_route) const; + + void PushRoute(std::string route) const; + + void PopRoute() const; + + private: + std::unique_ptr> channel_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ From e4ef5b6363fb07acde4f92e0594cd859547b84f9 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 31 May 2021 16:30:53 +0900 Subject: [PATCH 013/178] Rename plugin directory (#154) --- cmake/build.cmake | 14 +++++++------- .../platform/linux_embedded/flutter_linuxes_view.h | 12 ++++++------ .../{plugin => plugins}/key_event_plugin.cc | 4 ++-- .../{plugin => plugins}/key_event_plugin.h | 6 +++--- .../{plugin => plugins}/keyboard_glfw_util.cc | 2 +- .../{plugin => plugins}/keyboard_glfw_util.h | 6 +++--- .../{plugin => plugins}/lifecycle_plugin.cc | 2 +- .../{plugin => plugins}/lifecycle_plugin.h | 6 +++--- .../{plugin => plugins}/mouse_cursor_plugin.cc | 2 +- .../{plugin => plugins}/mouse_cursor_plugin.h | 6 +++--- .../{plugin => plugins}/navigation_plugin.cc | 2 +- .../{plugin => plugins}/navigation_plugin.h | 6 +++--- .../{plugin => plugins}/platform_plugin.cc | 2 +- .../{plugin => plugins}/platform_plugin.h | 6 +++--- .../{plugin => plugins}/text_input_plugin.cc | 4 ++-- .../{plugin => plugins}/text_input_plugin.h | 6 +++--- 16 files changed, 43 insertions(+), 43 deletions(-) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/key_event_plugin.cc (97%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/key_event_plugin.h (86%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/keyboard_glfw_util.cc (99%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/keyboard_glfw_util.h (66%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/lifecycle_plugin.cc (95%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/lifecycle_plugin.h (76%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/mouse_cursor_plugin.cc (96%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/mouse_cursor_plugin.h (84%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/navigation_plugin.cc (95%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/navigation_plugin.h (77%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/platform_plugin.cc (97%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/platform_plugin.h (83%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/text_input_plugin.cc (98%) rename src/flutter/shell/platform/linux_embedded/{plugin => plugins}/text_input_plugin.h (89%) diff --git a/cmake/build.cmake b/cmake/build.cmake index 1003416a..1f3f3de5 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -113,13 +113,13 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/external_texture_gl.cc src/flutter/shell/platform/linux_embedded/vsync_waiter.cc src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc - src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc - src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc - src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc + src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc src/flutter/shell/platform/linux_embedded/surface/context_egl.cc src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h index 8a0d6f28..f30bbf35 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h @@ -13,12 +13,12 @@ #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" -#include "flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h" -#include "flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h" -#include "flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h" -#include "flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h" -#include "flutter/shell/platform/linux_embedded/plugin/platform_plugin.h" -#include "flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/platform_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h" #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc similarity index 97% rename from src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc index 854c74f6..60b52697 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin//key_event_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h" #include #include @@ -13,7 +13,7 @@ #include #include "flutter/shell/platform/common/json_message_codec.h" -#include "flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h" +#include "flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h similarity index 86% rename from src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h index b71ce937..6de36a45 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/key_event_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEY_EVENT_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEY_EVENT_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEY_EVENT_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEY_EVENT_PLUGIN_H_ #include #include @@ -49,4 +49,4 @@ class KeyeventPlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEY_EVENT_PLUGIN_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEY_EVENT_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc similarity index 99% rename from src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc rename to src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc index ad463668..2940790b 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h" +#include "flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h" #include #include diff --git a/src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h similarity index 66% rename from src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h rename to src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h index e07cbc46..06b133f0 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/keyboard_glfw_util.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEYBOARD_GLFW_UTIL_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEYBOARD_GLFW_UTIL_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEYBOARD_GLFW_UTIL_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEYBOARD_GLFW_UTIL_H_ #include @@ -17,4 +17,4 @@ uint32_t GetGlfwKeycode(uint32_t xkb_keycode); } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_KEYBOARD_GLFW_UTIL_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_KEYBOARD_GLFW_UTIL_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc similarity index 95% rename from src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc index e7c8fa09..e4765a30 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h" #include "flutter/shell/platform/linux_embedded/logger.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h similarity index 76% rename from src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h index 0abefe20..f93881c2 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/lifecycle_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_LIFECYCLE_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_LIFECYCLE_PLUGIN_H_ #include @@ -31,4 +31,4 @@ class LifecyclePlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_LIFECYCLE_PLUGIN_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_LIFECYCLE_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc similarity index 96% rename from src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc index 931dd0e4..957f71b5 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h similarity index 84% rename from src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h index 4dc28784..174947b7 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/mouse_cursor_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_MOUSE_CURSOR_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_MOUSE_CURSOR_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_MOUSE_CURSOR_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_MOUSE_CURSOR_PLUGIN_H_ #include @@ -36,4 +36,4 @@ class MouseCursorPlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_MOUSE_CURSOR_PLUGIN_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_MOUSE_CURSOR_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc similarity index 95% rename from src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc index 06b75595..013a4c91 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h" #include "flutter/shell/platform/common/json_method_codec.h" #include "flutter/shell/platform/linux_embedded/logger.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h similarity index 77% rename from src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h index 07676548..4d7ac29b 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/navigation_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_NAVIGATION_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_NAVIGATION_PLUGIN_H_ #include @@ -32,4 +32,4 @@ class NavigationPlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_NAVIGATION_PLUGIN_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_NAVIGATION_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc similarity index 97% rename from src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc index 64651a7f..2d6de395 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/platform_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/platform_plugin.h" #include "flutter/shell/platform/common/json_method_codec.h" diff --git a/src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.h similarity index 83% rename from src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.h index 4f45763a..4f0eb82a 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/platform_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_PLATFORM_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_PLATFORM_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_PLUGIN_H_ #include @@ -35,4 +35,4 @@ class PlatformPlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_PLATFORM_PLUGIN_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc similarity index 98% rename from src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc rename to src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc index d665d49a..5c89f72a 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h" #include @@ -238,4 +238,4 @@ void TextInputPlugin::EnterPressed(TextInputModel* model) { channel_->InvokeMethod(kPerformActionMethod, std::move(args)); } -} // namespace flutter \ No newline at end of file +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h similarity index 89% rename from src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h rename to src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h index 64964d97..af9caf27 100644 --- a/src/flutter/shell/platform/linux_embedded/plugin/text_input_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_TEXT_INPUT_PLUGIN_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_TEXT_INPUT_PLUGIN_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_TEXT_INPUT_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_TEXT_INPUT_PLUGIN_H_ #include @@ -58,4 +58,4 @@ class TextInputPlugin { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGIN_TEXT_INPUT_PLUGIN_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_TEXT_INPUT_PLUGIN_H_ From 6f94a02683bedcd91e6557d4b7cd2e6931dfa8b1 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 2 Jun 2021 10:27:56 +0900 Subject: [PATCH 014/178] Add platform views plugin as a first implementation (#155) --- cmake/build.cmake | 1 + .../linux_embedded/flutter_linuxes.cc | 8 +- .../linux_embedded/flutter_linuxes_view.cc | 8 + .../linux_embedded/flutter_linuxes_view.h | 10 ++ .../plugins/platform_views_plugin.cc | 169 ++++++++++++++++++ .../plugins/platform_views_plugin.h | 72 ++++++++ .../public/flutter_platform_views.h | 77 ++++++++ 7 files changed, 344 insertions(+), 1 deletion(-) create mode 100644 src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc create mode 100644 src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h create mode 100644 src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h diff --git a/cmake/build.cmake b/cmake/build.cmake index 1f3f3de5..e1b860bf 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -119,6 +119,7 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc + src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc src/flutter/shell/platform/linux_embedded/surface/context_egl.cc src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc index 746d291e..491d5cb1 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc @@ -11,7 +11,6 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" -#include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" #include "flutter/shell/platform/linux_embedded/flutter_linuxes_view.h" @@ -259,3 +258,10 @@ bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( return TextureRegistrarFromHandle(texture_registrar) ->MarkTextureFrameAvailable(texture_id); } + +void FlutterDesktopRegisterPlatformViewFactory( + FlutterDesktopPluginRegistrarRef registrar, const char* view_type, + std::unique_ptr view_factory) { + registrar->engine->view()->RegisterPlatformViewFactory( + view_type, std::move(view_factory)); +} diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 3b4deae5..5b663f60 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -52,12 +52,20 @@ void FlutterLinuxesView::SetEngine( std::make_unique(internal_plugin_messenger); navigation_handler_ = std::make_unique(internal_plugin_messenger); + platform_views_handler_ = + std::make_unique(internal_plugin_messenger); PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, binding_handler_->GetDpiScale()); } +void FlutterLinuxesView::RegisterPlatformViewFactory( + const char* view_type, + std::unique_ptr factory) { + platform_views_handler_->RegisterViewFactory(view_type, std::move(factory)); +} + void FlutterLinuxesView::OnWindowSizeChanged(size_t width, size_t height) const { if (!GetRenderSurfaceTarget()->OnScreenSurfaceResize(width, height)) { diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h index f30bbf35..b4394f63 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h @@ -18,8 +18,10 @@ #include "flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/platform_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h" #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_platform_views.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" @@ -44,6 +46,11 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // engine. void SetEngine(std::unique_ptr engine); + // Registers a factory of the platform view. + void RegisterPlatformViewFactory( + const char* view_type, + std::unique_ptr factory); + // Creates rendering surface for Flutter engine to draw into. // Should be called before calling FlutterEngineRun using this view. bool CreateRenderSurface(); @@ -245,6 +252,9 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Handler for flutter/navigation channel. std::unique_ptr navigation_handler_; + // Handler for flutter/platform_views channel. + std::unique_ptr platform_views_handler_; + // Currently configured WindowBindingHandler for view. std::unique_ptr binding_handler_; diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc new file mode 100644 index 00000000..a0ff45b8 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -0,0 +1,169 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h" + +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +namespace { +constexpr char kChannelName[] = "flutter/platform_views"; + +constexpr char kCreateMethod[] = "create"; +constexpr char kDisposeMethod[] = "dispose"; +constexpr char kResizeMethod[] = "resize"; +constexpr char kSetDirectionMethod[] = "setDirection"; +constexpr char kClearFocusMethod[] = "clearFocus"; +constexpr char kTouchMethod[] = "touch"; +constexpr char kAcceptGestureMethod[] = "acceptGesture"; +constexpr char kRejectGestureMethod[] = "rejectGesture"; +constexpr char kEnterMethod[] = "enter"; +constexpr char kExitMethod[] = "exit"; + +constexpr char kViewTypeKey[] = "viewType"; +constexpr char kIdKey[] = "id"; +constexpr char kWidthKey[] = "width"; +constexpr char kHeightKey[] = "height"; +constexpr char kParamsKey[] = "params"; +} // namespace + +PlatformViewsPlugin::PlatformViewsPlugin(BinaryMessenger* messenger) + : channel_( + std::make_unique>( + messenger, kChannelName, + &flutter::StandardMethodCodec::GetInstance())), + current_view_id_(-1) { + channel_->SetMethodCallHandler( + [this](const flutter::MethodCall& call, + std::unique_ptr> + result) { HandleMethodCall(call, std::move(result)); }); +} + +PlatformViewsPlugin::~PlatformViewsPlugin() { + for (auto& itr : platform_views_) { + delete itr.second; + } + platform_views_.clear(); + + for (auto& itr : platform_view_factories_) { + itr.second->Dispose(); + } + platform_view_factories_.clear(); +} + +void PlatformViewsPlugin::RegisterViewFactory( + const char* view_type, + std::unique_ptr factory) { + if (platform_view_factories_.find(view_type) != + platform_view_factories_.end()) { + LINUXES_LOG(ERROR) << "Platform Views factory is already registered: " + << view_type; + return; + } + platform_view_factories_[view_type] = std::move(factory); +} + +void PlatformViewsPlugin::HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result) { + const auto& method = method_call.method_name(); + const auto& arguments = *method_call.arguments(); + + // todo: support all of the methods on the platform views. + if (method.compare(kCreateMethod) == 0) { + PlatformViewsCreate(arguments, std::move(result)); + } else if (method.compare(kDisposeMethod) == 0) { + PlatformViewsDispose(arguments, std::move(result)); + } else if (method.compare(kResizeMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kSetDirectionMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kClearFocusMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kTouchMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kAcceptGestureMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kRejectGestureMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kEnterMethod) == 0) { + result->NotImplemented(); + } else if (method.compare(kExitMethod) == 0) { + result->NotImplemented(); + } else { + LINUXES_LOG(WARNING) << "Platform Views unexpected method is called: " + << method; + result->NotImplemented(); + } +} + +void PlatformViewsPlugin::PlatformViewsCreate( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto view_type = LookupEncodableMap(arguments, kViewTypeKey); + if (view_type.empty()) { + result->Error("Couldn't find the view type in the arguments"); + return; + } + auto view_id = LookupEncodableMap(arguments, kIdKey); + if (!view_id) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + auto view_width = LookupEncodableMap(arguments, kWidthKey); + if (!view_width) { + result->Error("Couldn't find width in the arguments"); + return; + } + auto view_height = LookupEncodableMap(arguments, kHeightKey); + if (!view_height) { + result->Error("Couldn't find height in the arguments"); + return; + } + LINUXES_LOG(DEBUG) << "Create the platform view: view_type = " << view_type + << ", id = " << view_id << ", width = " << view_width + << ", height = " << view_height; + + if (platform_view_factories_.find(view_type) == + platform_view_factories_.end()) { + result->Error("Couldn't find the view type"); + return; + } + + auto params = LookupEncodableMap>(arguments, kParamsKey); + auto view = platform_view_factories_[view_type]->Create(view_id, view_width, + view_height, params); + if (view) { + platform_views_[view_id] = view; + if (platform_views_.find(current_view_id_) != platform_views_.end()) { + platform_views_[current_view_id_]->SetFocus(false); + } + current_view_id_ = view_id; + + result->Success(flutter::EncodableValue(view->GetTextureId())); + } else { + result->Error("Failed to create a platform view"); + } +} + +void PlatformViewsPlugin::PlatformViewsDispose( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto view_id = LookupEncodableMap(arguments, kIdKey); + if (!view_id) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + + LINUXES_LOG(DEBUG) << "Dispose the platform view: id = " << view_id; + if (platform_views_.find(view_id) == platform_views_.end()) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + platform_views_[view_id]->Dispose(); + result->Success(); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h new file mode 100644 index 00000000..2530481f --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h @@ -0,0 +1,72 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_VIEWS_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_VIEWS_PLUGIN_H_ + +#include +#include + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_method_codec.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_platform_views.h" + +namespace flutter { + +class PlatformViewsPlugin { + public: + PlatformViewsPlugin(BinaryMessenger* messenger); + ~PlatformViewsPlugin(); + + // Registers a factory of the platform view. + void RegisterViewFactory( + const char* view_type, + std::unique_ptr factory); + + private: + // Called when a method is called on |channel_|; + void HandleMethodCall( + const flutter::MethodCall& method_call, + std::unique_ptr> result); + + // Decodes and gets a value from an argument of MethodCall. + template + T LookupEncodableMap(const flutter::EncodableValue& map, const char* key) { + auto values = std::get(map); + auto value = values[flutter::EncodableValue(key)]; + if (!std::holds_alternative(value)) { + return T(); + } + return std::get(value); + } + + // Called when "create" method is called + void PlatformViewsCreate( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + + // Called when "dispose" method is called + void PlatformViewsDispose( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + + // Method channel instance. + std::unique_ptr> channel_; + + // Factory of PlatformView class. + std::unordered_map> + platform_view_factories_; + + // Instances of platform views. + std::unordered_map platform_views_; + + // Shows the id of current view. + int current_view_id_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_PLATFORM_VIEWS_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h new file mode 100644 index 00000000..8efbf2f9 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h @@ -0,0 +1,77 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PUBLIC_FLUTTER_PLATFORM_VIEWS_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PUBLIC_FLUTTER_PLATFORM_VIEWS_H_ + +#include +#include + +#include + +#include "flutter_export.h" +#include "flutter_messenger.h" +#include "plugin_registrar.h" + +class FlutterDesktopPlatformView { + public: + FlutterDesktopPlatformView(flutter::PluginRegistrar* registrar, int view_id) + : registrar_(registrar), + view_id_(view_id), + texture_id_(-1), + focused_(false) {} + virtual ~FlutterDesktopPlatformView() {} + + flutter::PluginRegistrar* GetPluginRegistrar() { return registrar_; } + + virtual void Dispose() = 0; + + int GetViewId() const { return view_id_; } + + void SetFocus(bool focus) { focused_ = focus; } + + bool IsFocused() const { return focused_; } + + void SetTextureId(int texture_id) { texture_id_ = texture_id; } + + int GetTextureId() const { return texture_id_; } + + private: + flutter::PluginRegistrar* registrar_; + int view_id_; + int texture_id_; + bool focused_; +}; + +class FlutterDesktopPlatformViewFactory { + public: + FlutterDesktopPlatformViewFactory(flutter::PluginRegistrar* registrar) + : registrar_(registrar) {} + virtual ~FlutterDesktopPlatformViewFactory() {} + + flutter::PluginRegistrar* GetPluginRegistrar() const { return registrar_; } + + virtual FlutterDesktopPlatformView* Create( + int view_id, double width, double height, + const std::vector& params) = 0; + + virtual void Dispose() = 0; + + private: + flutter::PluginRegistrar* registrar_; +}; + +#if defined(__cplusplus) +extern "C" { +#endif + +void FlutterDesktopRegisterPlatformViewFactory( + FlutterDesktopPluginRegistrarRef registrar, const char* view_type, + std::unique_ptr view_factory); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PUBLIC_FLUTTER_PLATFORM_VIEWS_H_ From 1b14243ae5f37eacd31e9e8bd9e2c3d5dc15cc7b Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Jun 2021 22:19:34 +0900 Subject: [PATCH 015/178] Migrate README document to Wiki (#158) Closed #144 --- README.md | 6 +- doc/README.md | 273 -------------------------------- doc/building-engine-embedder.md | 148 ----------------- doc/debugging.md | 48 ------ meta-flutter/README.md | 2 +- 5 files changed, 4 insertions(+), 473 deletions(-) delete mode 100644 doc/README.md delete mode 100644 doc/building-engine-embedder.md delete mode 100644 doc/debugging.md diff --git a/README.md b/README.md index 2b6bacba..9dd49712 100644 --- a/README.md +++ b/README.md @@ -55,12 +55,12 @@ Note [Weston](https://gitlab.freedesktop.org/wayland/weston/-/blob/master/README.md) | :heavy_check_mark: | [Sway](https://swaywm.org/) | :heavy_check_mark: | [Wayfire](https://wayfire.org/) | :heavy_check_mark: | [Gnome](https://www.gnome.org/) | :heavy_check_mark: | [Phosh](https://source.puri.sm/Librem5/phosh) | :heavy_check_mark: | | [Cage](https://www.hjdskes.nl/projects/cage/) | :heavy_check_mark: | [Lomiri](https://lomiri.com/) | :heavy_check_mark: | [Plasma Wayland](https://community.kde.org/Plasma/Wayland) | :heavy_check_mark: | [Plasma Mobile](https://www.plasma-mobile.org/) | :heavy_check_mark: | [GlacierUX](https://wiki.merproject.org/wiki/Nemo/Glacier) | :heavy_check_mark: | +## Documentation +Documentation for this embedder is summarised on the [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). + ## Contributing **Now, we cannot accept any Pull Request (PR).** Because We are building a system (e.g. CLA) to accept PRs, so please wait for a while the system is getting ready! However, we are always welcome to report bugs and request new features by creating issues. With the assumption, our final goal of this software openly is to be merged this embedder into [Flutter Engine](https://github.com/flutter/engine) after getting feedbacks. And [Google CLA](https://cla.developers.google.com/about/google-corporate) will be required when we do that in the future. Therefore, we cannot easily accept an external PR. However, you can free to create issues for reporting bugs and requesting new features. See also: [Contributing to the Flutter engine](https://github.com/flutter/engine/blob/master/CONTRIBUTING.md) - -## Documentation -Documentation for this embedder is under the [doc](./doc/README.md) directory. diff --git a/doc/README.md b/doc/README.md deleted file mode 100644 index 1cac9ea8..00000000 --- a/doc/README.md +++ /dev/null @@ -1,273 +0,0 @@ -# Documentation - -## 1. Install libraries -You need to install the following dependent libraries to build and run. Here introduce how to install the libraries on Debian-based systems like Ubuntu. - -### Mandatory -- clang (for building) -- cmake (for building) -- build-essential (for building) -- pkg-config (for building) -- EGL -- xkbcommon -- OpenGL ES (>=2.0) - -```Shell -$ sudo apt install clang cmake build-essential pkg-config libegl1-mesa-dev libxkbcommon-dev libgles2-mesa-dev -``` - -### Only when using Wayland backend -- libwayland -- wayland-protocols (to generate the source files of Wayland protocols) - -```Shell -$ sudo apt install libwayland-dev wayland-protocols -``` - -### Only when using weston desktop-shell -- weston (>=8.0.0) -- libweston-*-dev - -```Shell -$ sudo apt install weston libweston-8-dev -``` - -### Only when using DRM backend -- libdrm -- libgbm -- libinput -- libudev -- libsystemd - -```Shell -$ sudo apt install libdrm-dev libgbm-dev libinput-dev libudev-dev libsystemd-dev -``` - -### Only when using x11 backend -- x11 - -```Shell -$ sudo apt install libx11-dev -``` - -### Install Flutter Engine library -This embedder requres `libflutter_engine.so` (Flutter embedder library). You need to install it in `` to build. See: [Building Flutter Engine embedder](./building-engine-embedder.md) - -Or you can download a specific pre-built Flutter Engine from Google's infra by the following steps, but it's limited to **debug mode** and **x64** targets. - -Step 1) Check the version (SHA) of the channel you want to use. -- [master channel](https://raw.githubusercontent.com/flutter/flutter/master/bin/internal/engine.version) -- [dev channel](https://raw.githubusercontent.com/flutter/flutter/dev/bin/internal/engine.version) -- [beta channel](https://raw.githubusercontent.com/flutter/flutter/beta/bin/internal/engine.version) -- [stable channel](https://raw.githubusercontent.com/flutter/flutter/stable/bin/internal/engine.version) - -You can also get the version from `${path_to_flutter_sdk_install}/flutter/bin/internal/engine.version` of the Flutter SDK which you are currently using. - -Step 2) Download Flutter Engine embedder library. Note that replace `FLUTTER_ENGINE` with the SHA of the Flutter engine you want to use. -```Shell -$ curl -O https://storage.googleapis.com/flutter_infra/flutter/FLUTTER_ENGINE/linux-x64/linux-x64-embedder -``` - -Step 3) Install the library. Note that the downloaded library is only **debug mode** and for **x64** targets. -```Shell -$ unzip ./linux-x64-embedder -$ cp ./libflutter_engine.so -``` - -## 2. Examples -There are sample projects in [`examples`](../examples) directory. You can also comunicate with Dart code by using the plugin APIs with the same specifications as with Flutter desktops for Windows. - -## 3. Building - -### 3.1. Self-build - -### Build for Wayland backend (Stand-alone Wayland app) - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-wayland-client .. -$ cmake --build . -``` - -### Build for Wayland backend (Weston desktop-shell) -This binary will run as a desktop-shell by setting `weston.ini` when Weston starts. See [Settings of weston.ini file](#7-settings-of-westonini-file-only-when-using-weston-desktop-shell). - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-weston-desktop-shell .. -$ cmake --build . -``` - -### Build for DRM backend - -#### Use GBM - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-drm-gbm-backend .. -$ cmake --build . -``` - -#### Use EGLStream - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-drm-eglstream-backend .. -$ cmake --build . -``` - -### Build for x11 backend (Stand-alone X11 app) -Basically, the x11 backend is just only for debugging and developing Flutter apps on desktops. And it's still being implemented now. - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-x11-client .. -$ cmake --build . -``` - -### 3.2. Cross-build -You need to create a toolchain file to cross compile using the Yocto SDK for aarch64 on x64 hosts. [toolchain-template.cmake](../cmake/cross-toolchain-aarch64-template.cmake) is the templete file for aarch64 toolchain. Also, you need to modify appropriately for your environment if you want to use the template file. -```Shell -$ cmake -DUSER_PROJECT_PATH= -DCMAKE_TOOLCHAIN_FILE= .. -``` - -### 3.3. Yocto-build -If you want to build using Yocto, see: [meta-flutter](../meta-flutter/) - -### How to debug the embedder -You need to build the embedder with `CMAKE_BUILD_TYPE=Debug` option if you want to debug the embedder. Using this option, you can get gather logs and debug them with debuggers such as gdb / lldb. - -```Shell -$ cmake -DUSER_PROJECT_PATH= -DCMAKE_BUILD_TYPE=Debug .. -``` - -### User configuration parameters (CMAKE options) -Please edit `cmake/user_config.cmake` file. - -| Option | Description | -| ------------- | ------------- | -| BACKEND_TYPE | Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type (The default setting is WAYLAND) | -| DESKTOP_SHELL | Work as Weston desktop-shell | -| USE_VIRTUAL_KEYBOARD | Use Virtual Keyboard (Only available when you choose Wayland backend) | -| USE_GLES3 | Use OpenGLES3 instead of OpenGLES2 | - -## 4. Building Flutter app - -### Install Flutter SDK -See also: [Desktop support for Flutter](https://flutter.dev/desktop) - -```Shell -$ git clone https://github.com/flutter/flutter -$ sudo mv flutter /opt/ -$ export PATH=$PATH:/opt/flutter/bin -$ flutter config --enable-linux-desktop -$ flutter doctor -``` - -Please note that you must use the same version (channel) that you built Flutter embedder for. I recommend that you use the latest version of the master channel for both the SDK and Flutter Engine. -See also: [Building Flutter Engine embedder](./building-engine-embedder.md) - -### Build Flutter app -Here introduce how to build the flutter sample app. - -#### For x64 targets on x64 hosts / for Arm64 targets on Arm64 hosts -Note that you need to build Flutter apps in the same mode(release/debug) `libflutter_engine.so` was built. It means you need to build Flutter apps in the release mode if you use `libflutter_engine.so` was built in release mode. - -Build for release mode: -```Shell -$ flutter create sample -$ cd sample/$ cd sample/ -$ flutter build linux -$ cd .. -``` - -Build for debug mode: -```Shell -$ flutter build linux --debug -``` - -#### For Arm64 targets on x64 hosts -Comming soon. We are contributing to support this now. See: https://github.com/flutter/flutter/issues/74929 - -#### FYI: only in debug mode -If you want to work Flutter apps in debug mode, you can also do the following steps on both x64 and arm64 hosts. In debug mode, the Flutter bundle artifacts are not architecturally different between x64 and arm64. - -```Shell -$ flutter build bundle --asset-dir=./bundle/data/flutter_assets -$ cp /bin/cache/artifacts/engine/linux-*/icudtl.dat ./bundle/data -``` - -## 5. Running Flutter app - -### Run with Wayland backend -Wayland compositor such as Weston must be running before running the program. - -```Shell -$ ./flutter-client --bundle=./sample/build/linux/x64/release/bundle -``` - -### Logging levels -The logging levels of the embedder are controlled by `FLUTTER_LOG_LEVELS` environment var. If you want to do debugging, set `FLUTTER_LOG_LEVELS`. The default level is `WARNING`. - -```Shell -$ FLUTTER_LOG_LEVELS=TRACE ./flutter-client --bundle= -$ FLUTTER_LOG_LEVELS=INFO ./flutter-client --bundle= -$ FLUTTER_LOG_LEVELS=WARNING ./flutter-client --bundle= -$ FLUTTER_LOG_LEVELS=ERROR ./flutter-client --bundle= -$ FLUTTER_LOG_LEVELS=FATAL ./flutter-client --bundle= -``` - -### Supplement -You can switch quickly between debug / profile / release modes for the Flutter app without replacing `libflutter_engine.so` by using `LD_LIBRARY_PATH` when you run the Flutter app. - -```Shell -$ LD_LIBRARY_PATH= ./flutter-client --bundle= - -# e.g. Run in debug mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/debug/ ./flutter-client --bundle=./sample/build/linux/x64/debug/bundle - -# e.g. Run in profile mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/profile/ ./flutter-client --bundle=./sample/build/linux/x64/profile/bundle - -# e.g. Run in release mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/release/ ./flutter-client --bundle=./sample/build/linux/x64/release/bundle -``` - -### Run with DRM backend -You need to switch from GUI which is running X11 or Wayland to the Character User Interface (CUI). In addition, `FLUTTER_DRM_DEVICE` must be set properly. The default value is `/dev/dri/card0`. - -```Shell -$ Ctrl + Alt + F3 # Switching to CUI -$ sudo FLUTTER_DRM_DEVICE="/dev/dri/card1" --bundle=./sample/build/linux/x64/release/bundle -``` - -If you want to switch back from CUI to GUI, run `Ctrl + Alt + F2` keys in a terminal. - -#### Note -You need to run this program by a user who has the permission to access the input devices(/dev/input/xxx), if you use the DRM backend. Generally, it is a root user or a user who belongs to an input group. - -## 6. Debugging Flutter apps -You can do debugging Flutter apps. Please see: [How to debug Flutter apps](./debugging.md) - -## 7. Settings of weston.ini file (Only when using Weston desktop-shell) -Sets the following parameters when this embedder works as a desktop-shell on Weston. Sample file can be found [examples/config/weston.ini](../examples/config/weston.ini). See also `man weston.ini`. - -### shell section -Specifies the path to the binary file to start as the shell when Weston starts. - -| Field | Description | -| ------------- | ------------- | -| client | /flutter-desktop-shell | - -### extended section -An extended section for this embedder. The entries that can appear in this section are: - -| Field | Description | -| ------------- | ------------- | -| show-cursor | Set whether to show mouse cursor (boolean) | -| flutter-project-path | Set an absolute path or relative path from the binary file to Flutter project path (string) | diff --git a/doc/building-engine-embedder.md b/doc/building-engine-embedder.md deleted file mode 100644 index d572fd4e..00000000 --- a/doc/building-engine-embedder.md +++ /dev/null @@ -1,148 +0,0 @@ -# How to build Flutter Engine embedder - -See also: -- [Custom Flutter Engine Embedders](https://github.com/flutter/flutter/wiki/Custom-Flutter-Engine-Embedders) -- [Custom Flutter Engine Embedding in AOT Mode](https://github.com/flutter/flutter/wiki/Custom-Flutter-Engine-Embedding-in-AOT-Mode) - -## 1. Install build tools - -``` -$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git -$ export PATH=$PATH:$(pwd)/depot_tools -``` - -### Python 2 - -Python 2 is required to build. If you default installation is Python 3 you could workaround this by using virtualenv: - -```Shell -$ virtualenv .env -p python2 -$ source .env/bin/activate -``` - -See also: https://github.com/dart-lang/sdk/wiki/Building#python-2 - -## 2. Create .gclient file - -### When using the latest version of Flutter Engine - -```yaml -solutions = [ - { - "managed": False, - "name": "src/flutter", - "url": "https://github.com/flutter/engine.git", - "custom_deps": {}, - "deps_file": "DEPS", - "safesync_url": "", - "custom_vars": { - "download_android_deps": False, - "download_windows_deps": False, - }, - }, -] -``` - -### When using a specific version of Flutter Engine - -You can check the current engine version (commit id / SHA): -- [master channel](https://raw.githubusercontent.com/flutter/flutter/master/bin/internal/engine.version) -- [dev channel](https://raw.githubusercontent.com/flutter/flutter/dev/bin/internal/engine.version) -- [beta channel](https://raw.githubusercontent.com/flutter/flutter/beta/bin/internal/engine.version) -- [stable channel](https://raw.githubusercontent.com/flutter/flutter/stable/bin/internal/engine.version) - -You can also get the engine version from `${path_to_flutter_sdk_install}/flutter/bin/internal/engine.version` of the Flutter SDK which you are currently using. - -```yaml -solutions = [ - { - "managed": False, - "name": "src/flutter", - "url": "https://github.com/flutter/engine.git@FLUTTER_ENGINE", - "custom_deps": {}, - "deps_file": "DEPS", - "safesync_url": "", - "custom_vars": { - "download_android_deps": False, - "download_windows_deps": False, - }, - }, -] -``` -Note: Replace `FLUTTER_ENGINE` with the commid it of the Flutter engine you want to use. - -## 3. Get source files - -```Shell -$ gclient sync -``` - -## 4. Build embedder - -```Shell -$ cd src -``` - -### arm64 targets with debug mode - -```Shell -$ ./flutter/tools/gn --target-os linux --linux-cpu arm64 --runtime-mode debug --unoptimized --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/linux_debug_unopt_arm64 -``` - -### arm64 targets with profile mode - -```Shell -$ ./flutter/tools/gn --target-os linux --linux-cpu arm64 --runtime-mode profile --no-lto --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/linux_profile_arm64 -``` - -### arm64 targets with release mode - -```Shell -$ ./flutter/tools/gn --target-os linux --linux-cpu arm64 --runtime-mode release --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/linux_release_arm64 -``` - -### x64 targets with debug mode - -```Shell -$ ./flutter/tools/gn --runtime-mode debug --unoptimized --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/host_debug_unopt -``` - -### x64 targets with profile mode - -```Shell -$ ./flutter/tools/gn --runtime-mode profile --no-lto --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/host_profile -``` - -### x64 targets with release mode - -```Shell -$ ./flutter/tools/gn --runtime-mode release --embedder-for-target --disable-desktop-embeddings -$ ninja -C out/host_release -``` - -## 5. Install embedder library - -```Shell -$ cp ./out/${path to your selected target and mode}/libflutter_engine.so -``` - -### Supplement -You need to install `libflutter_engine.so` in `` to build. But you can switch quickly between debug / profile / release modes for the Flutter app without replacing `libflutter_engine.so` by using `LD_LIBRARY_PATH` when you run the Flutter app. - -```Shell -$ LD_LIBRARY_PATH= ./flutter-client - -# e.g. Run in debug mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/debug/ ./flutter-client ./sample/build/linux/x64/debug/bundle - -# e.g. Run in profile mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/profile/ ./flutter-client ./sample/build/linux/x64/profile/bundle - -# e.g. Run in release mode -$ LD_LIBRARY_PATH=/usr/lib/flutter_engine/release/ ./flutter-client ./sample/build/linux/x64/release/bundle -``` diff --git a/doc/debugging.md b/doc/debugging.md deleted file mode 100644 index e7a5c065..00000000 --- a/doc/debugging.md +++ /dev/null @@ -1,48 +0,0 @@ -# How to debug Flutter apps -It is possible to do most things, including source-level debugging, profiling and hot reload when you debug Flutter apps on this embedder. Note that you need to use `libflutter_engine.so` built with **debug mode**. - -## Getting the Observatory port - -You will find the following message in the console when you run Flutter apps. You need to attach a debugger to this port when you want to debug it. **Note that the URI changes every time after launching**. - -```Shell -flutter: Observatory listening on http://127.0.0.1:40409/k8IUol2dnPI=/ -``` -## Debugging - -### Command line - -```Shell -$ cd / -$ flutter attach --device-id=flutter-tester --debug-uri http://127.0.0.1:40409/k8IUol2dnPI=/ -``` - -### How to use command line options in the Dart VM -You can use the environment variables such as `FLUTTER_ENGINE_SWITCHES`, `FLUTTER_ENGINE_SWITCH_*` to use Dart VM command line options. If you want to fix always same observatory URI, you can use the following command. Note that this option is only available in debug mode. See also: [How to debug the embedder](./README.md#how-to-debug-the-embedder) - -```Shell -$ FLUTTER_ENGINE_SWITCHES=2 \ - FLUTTER_ENGINE_SWITCH_1="observatory-port=12345" \ - FLUTTER_ENGINE_SWITCH_2="disable-service-auth-codes" \ - ./flutter-x11-clinet --bundle=sample/build/linux/x64/debug/bundle -flutter: Observatory listening on http://127.0.0.1:12345/ -``` - -### VS Code - -Create a [launch.json file](https://code.visualstudio.com/docs/editor/debugging#_launch-configurations) like the following. - -```Json -{ - "version": "0.2.0" - "configurations": [ - { - "type": "dart", - "name": "Flutter Embedded Linux Attach", - "request": "attach", - "deviceId": "flutter-tester", - "observatoryUri": "http://127.0.0.1:40409/k8IUol2dnPI=/" - } - ] -} -``` diff --git a/meta-flutter/README.md b/meta-flutter/README.md index bc07bfda..5f2949d2 100644 --- a/meta-flutter/README.md +++ b/meta-flutter/README.md @@ -110,4 +110,4 @@ $ export CC=${CLANGCC} $ export CXX=${CLANGCXX} ``` -After doing that, you can build the embedder as normal like self-building on hosts. It means you don't need to be aware of cross-building. See: [3.1. Self-build](../doc/README.md) +After doing that, you can build the embedder as normal like self-building on hosts. It means you don't need to be aware of cross-building. See: [self-build](https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#self-build) From 215daaa71c96899e49f9486f42f5f069f6db6792 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Jun 2021 22:42:37 +0900 Subject: [PATCH 016/178] Change the downloading path of pre-build Flutter Engine in the CI (#159) * Change the downloading path of libflutter_engine.so * Update build-test.yml --- .github/workflows/build-test.yml | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 7734cc1e..0a8fce7d 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -22,12 +22,16 @@ jobs: run: cmake -E make_directory ${{github.workspace}}/build - name: Install Flutter Engine library + #run: | + # echo `curl https://raw.githubusercontent.com/flutter/flutter/master/bin/internal/engine.version` > embedder.version + # export FLUTTER_ENGINE=`cat embedder.version` + # curl -O https://storage.googleapis.com/flutter_infra/flutter/${FLUTTER_ENGINE}/linux-x64/linux-x64-embedder + # ls + # unzip linux-x64-embedder + # mv libflutter_engine.so ${{github.workspace}}/build run: | - echo `curl https://raw.githubusercontent.com/flutter/flutter/master/bin/internal/engine.version` > embedder.version - export FLUTTER_ENGINE=`cat embedder.version` - curl -O https://storage.googleapis.com/flutter_infra/flutter/${FLUTTER_ENGINE}/linux-x64/linux-x64-embedder - ls - unzip linux-x64-embedder + curl -L https://github.com/sony/flutter-embedded-linux/releases/download/939fb62b30/linux-x64-release.zip > linux-x64-release.zip + unzip linux-x64-release.zip mv libflutter_engine.so ${{github.workspace}}/build - name: Configure CMake for wayland client From 08eda20282771cd67ecf1181686f46eb89aee62c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Jun 2021 22:56:04 +0900 Subject: [PATCH 017/178] Update README: change the order in the document (#160) --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 9dd49712..7f9d5aee 100644 --- a/README.md +++ b/README.md @@ -25,11 +25,13 @@ We would be grateful if you could give us feedback on bugs and new feature reque - API compatibility with Flutter desktop for Windows and GLFW - APIs such as MethodChannel and EventChannel are completely the same with them +## Documentation +Documentation for this software is summarised on the [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). + ## Supported platforms This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. ### Tested devices - | Board / SoC | Vendor | OS / BSP | Backend | Status | | :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | | [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | Wayland | :heavy_check_mark: | @@ -55,9 +57,6 @@ Note [Weston](https://gitlab.freedesktop.org/wayland/weston/-/blob/master/README.md) | :heavy_check_mark: | [Sway](https://swaywm.org/) | :heavy_check_mark: | [Wayfire](https://wayfire.org/) | :heavy_check_mark: | [Gnome](https://www.gnome.org/) | :heavy_check_mark: | [Phosh](https://source.puri.sm/Librem5/phosh) | :heavy_check_mark: | | [Cage](https://www.hjdskes.nl/projects/cage/) | :heavy_check_mark: | [Lomiri](https://lomiri.com/) | :heavy_check_mark: | [Plasma Wayland](https://community.kde.org/Plasma/Wayland) | :heavy_check_mark: | [Plasma Mobile](https://www.plasma-mobile.org/) | :heavy_check_mark: | [GlacierUX](https://wiki.merproject.org/wiki/Nemo/Glacier) | :heavy_check_mark: | -## Documentation -Documentation for this embedder is summarised on the [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). - ## Contributing **Now, we cannot accept any Pull Request (PR).** Because We are building a system (e.g. CLA) to accept PRs, so please wait for a while the system is getting ready! However, we are always welcome to report bugs and request new features by creating issues. From d8b1f9618529bf4ba2691918c0d6b72d60296706 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Jun 2021 23:16:05 +0900 Subject: [PATCH 018/178] Update cpp shared library and embedder (#161) --- .../platform/common/client_wrapper/standard_codec.cc | 12 ++++++------ src/flutter/shell/platform/embedder/embedder.h | 8 ++++++++ 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index a7725088..e37e4a18 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -71,7 +71,7 @@ EncodedType EncodedTypeForValue(const EncodableValue& value) { return EncodedType::kList; case 11: return EncodedType::kMap; - case 12: + case 13: return EncodedType::kFloat32List; } assert(false); @@ -153,15 +153,15 @@ void StandardCodecSerializer::WriteValue(const EncodableValue& value, } break; } - case 12: { - WriteVector(std::get>(value), stream); - break; - } - case 13: + case 12: std::cerr << "Unhandled custom type in StandardCodecSerializer::WriteValue. " << "Custom types require codec extensions." << std::endl; break; + case 13: { + WriteVector(std::get>(value), stream); + break; + } } } diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 8a1ce19d..c630c61b 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -572,6 +572,14 @@ typedef struct { size_t left; /// Vertical physical location of the top of the window on the screen. size_t top; + /// Top inset of window. + double physical_view_inset_top; + /// Right inset of window. + double physical_view_inset_right; + /// Bottom inset of window. + double physical_view_inset_bottom; + /// Left inset of window. + double physical_view_inset_left; } FlutterWindowMetricsEvent; /// The phase of the pointer event. From f3870d2f0e28b32dc68a0e7257e9b026e8907ccf Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 7 Jun 2021 14:11:33 +0900 Subject: [PATCH 019/178] Add commpand-line option for the onscreen keyboard (#162) Closed #135 --- CMakeLists.txt | 1 - cmake/build.cmake | 5 -- examples/README.md | 1 - .../cmake/user_config.cmake | 3 +- .../flutter_window.cc | 11 +-- .../flutter_window.h | 8 +- .../flutter-drm-eglstream-backend/main.cc | 11 ++- .../cmake/user_config.cmake | 3 +- .../flutter-drm-gbm-backend/flutter_window.cc | 11 +-- .../flutter-drm-gbm-backend/flutter_window.h | 8 +- examples/flutter-drm-gbm-backend/main.cc | 11 ++- .../cmake/user_config.cmake | 3 +- .../flutter_window.cc | 11 +-- .../flutter_window.h | 8 +- .../flutter-external-texture-plugin/main.cc | 15 +++- .../cmake/user_config.cmake | 3 +- .../flutter-wayland-client/flutter_window.cc | 11 +-- .../flutter-wayland-client/flutter_window.h | 8 +- examples/flutter-wayland-client/main.cc | 15 +++- .../README.md | 12 --- .../cmake/user_build.cmake | 29 ------- .../cmake/user_config.cmake | 8 -- .../flutter_window.cc | 78 ------------------- .../flutter_window.h | 32 -------- .../generated_plugin_registrant.cc | 7 -- .../generated_plugin_registrant.h | 13 ---- .../main.cc | 67 ---------------- .../cmake/user_config.cmake | 3 +- .../flutter_window.cc | 11 +-- .../flutter_window.h | 8 +- examples/flutter-weston-desktop-shell/main.cc | 13 +++- .../cmake/user_config.cmake | 3 +- examples/flutter-x11-client/flutter_window.cc | 11 +-- examples/flutter-x11-client/flutter_window.h | 8 +- examples/flutter-x11-client/main.cc | 11 ++- src/client_wrapper/flutter_view_controller.cc | 21 ++--- .../include/flutter/flutter_view_controller.h | 26 ++++++- .../linux_embedded/flutter_linuxes.cc | 14 +--- .../linux_embedded/public/flutter_linuxes.h | 29 ++++--- .../linux_embedded/window/linuxes_window.h | 15 +--- .../window/linuxes_window_drm.h | 77 +++++++++--------- .../window/linuxes_window_wayland.cc | 49 ++++++------ .../window/linuxes_window_wayland.h | 3 +- .../window/linuxes_window_x11.cc | 21 +++-- .../window/linuxes_window_x11.h | 3 +- src/templates/app/common/flutter_window.cc | 11 +-- src/templates/app/common/flutter_window.h | 8 +- src/templates/app/linux-drm/main.cc | 11 ++- .../main.cc | 13 +++- src/templates/app/linux-wayland/main.cc | 15 +++- src/templates/app/linux-x11/main.cc | 11 ++- 51 files changed, 316 insertions(+), 472 deletions(-) delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/README.md delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_config.cmake delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h delete mode 100644 examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 99b8cfd5..0d40b2e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,6 @@ set(CMAKE_CXX_STANDARD 17) # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) -option(USE_VIRTUAL_KEYBOARD "Use virtual keyboard" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) # Load the user project. diff --git a/cmake/build.cmake b/cmake/build.cmake index e1b860bf..72f2ce15 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -79,11 +79,6 @@ if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) set(WAYLAND_PROTOCOL_SRC ${WAYLAND_PROTOCOL_SRC} src/wayland/protocol/weston-desktop-shell-protocol.c) endif() -# Use virtual keybard(on-screen keyboard). -if(USE_VIRTUAL_KEYBOARD) - add_definitions(-DUSE_VIRTUAL_KEYBOARD) -endif() - # OpenGL ES version. if(USE_GLES3) add_definitions(-DUSE_GLES3) diff --git a/examples/README.md b/examples/README.md index 26f864c1..9f7c23f8 100644 --- a/examples/README.md +++ b/examples/README.md @@ -6,7 +6,6 @@ These are an example of how to use embedded Linux embedding for Flutter. ## Examples - [flutter-wayland-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-wayland-client): Wayland client app - [flutter-weston-desktop-shell](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-weston-desktop-shell): Works on Weston desktop-shell -- [flutter-weston-desktop-shell-virtual-keyboard](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-weston-desktop-shell-virtual-keyboard): Works on Weston desktop-shell with the virtual keyboard - [flutter-drm-gbm-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-gbm-backend): Fullscreen app on DRM backend with GBM - [flutter-drm-eglstream-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-eglstream-backend): Fullscreen app on DRM backend with EGLStream - [flutter-x11-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-x11-client): X11 client app diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake index f923ce62..7a2a5a59 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-EGLSTREAM) set(DESKTOP_SHELL OFF) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.cc b/examples/flutter-drm-eglstream-backend/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_window.cc +++ b/examples/flutter-drm-eglstream-backend/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.h b/examples/flutter-drm-eglstream-backend/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_window.h +++ b/examples/flutter-drm-eglstream-backend/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 9a533507..3ea7b882 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -32,10 +32,15 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.view_mode = + flutter::FlutterViewController::ViewMode::kFullscreen; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = false; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, - 0, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake index abb08e0d..4bcb9b48 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-GBM) set(DESKTOP_SHELL OFF) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-drm-gbm-backend/flutter_window.cc b/examples/flutter-drm-gbm-backend/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-drm-gbm-backend/flutter_window.cc +++ b/examples/flutter-drm-gbm-backend/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-drm-gbm-backend/flutter_window.h b/examples/flutter-drm-gbm-backend/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-drm-gbm-backend/flutter_window.h +++ b/examples/flutter-drm-gbm-backend/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 9a533507..3ea7b882 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -32,10 +32,15 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.view_mode = + flutter::FlutterViewController::ViewMode::kFullscreen; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = false; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, - 0, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/examples/flutter-external-texture-plugin/cmake/user_config.cmake b/examples/flutter-external-texture-plugin/cmake/user_config.cmake index 919c51d2..9432b4fa 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_config.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(DESKTOP_SHELL OFF) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-external-texture-plugin/flutter_window.cc b/examples/flutter-external-texture-plugin/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-external-texture-plugin/flutter_window.cc +++ b/examples/flutter-external-texture-plugin/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-external-texture-plugin/flutter_window.h b/examples/flutter-external-texture-plugin/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-external-texture-plugin/flutter_window.h +++ b/examples/flutter-external-texture-plugin/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index a5984e09..4559c3c9 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -19,6 +19,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -30,6 +32,8 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); + const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const auto view_mode = options.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen @@ -42,9 +46,16 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(view_mode, width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/examples/flutter-wayland-client/cmake/user_config.cmake b/examples/flutter-wayland-client/cmake/user_config.cmake index 919c51d2..9432b4fa 100644 --- a/examples/flutter-wayland-client/cmake/user_config.cmake +++ b/examples/flutter-wayland-client/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(DESKTOP_SHELL OFF) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-wayland-client/flutter_window.cc b/examples/flutter-wayland-client/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-wayland-client/flutter_window.cc +++ b/examples/flutter-wayland-client/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-wayland-client/flutter_window.h b/examples/flutter-wayland-client/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-wayland-client/flutter_window.h +++ b/examples/flutter-wayland-client/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index a5984e09..4559c3c9 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -19,6 +19,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -30,6 +32,8 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); + const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const auto view_mode = options.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen @@ -42,9 +46,16 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(view_mode, width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/README.md b/examples/flutter-weston-desktop-shell-virtual-keyboard/README.md deleted file mode 100644 index 12a15ede..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Overview - -This is the example of Wayland backend + weston desktop-shell + virtual keyboard. - -## Building (Wayland backend weston desktop-shell) - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-weston-desktop-shell-virtual-keyboard .. -$ cmake --build . -``` diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake deleted file mode 100644 index f4899c2a..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_build.cmake +++ /dev/null @@ -1,29 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# user binary name. -set(TARGET flutter-desktop-shell) - -# source files for user apps. -set(USER_APP_SRCS - examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc - examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc - examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc -) - -# header files for user apps. -set(USER_APP_INCLUDE_DIRS - ## Public APIs for developers (Don't edit!). - src/client_wrapper/include - src/flutter/shell/platform/common/client_wrapper - src/flutter/shell/platform/common/client_wrapper/include - src/flutter/shell/platform/common/client_wrapper/include/flutter - src/flutter/shell/platform/common/public - src/flutter/shell/platform/linux_embedded/public - src/public/include - ## header file include path for user apps. - examples/flutter-weston-desktop-shell-virtual-keyboard -) - -# link libraries for user apps. -set(USER_APP_LIBRARIES -) diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_config.cmake b/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_config.cmake deleted file mode 100644 index 089b2504..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/cmake/user_config.cmake +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options -set(BACKEND_TYPE WAYLAND) -set(DESKTOP_SHELL ON) -set(USE_VIRTUAL_KEYBOARD ON) -set(USE_GLES3 OFF) diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc deleted file mode 100644 index 9ead67f6..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter_window.h" - -#include -#include -#include -#include - -#include "generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} - -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { - flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); - - // Ensure that basic setup of the controller was successful. - if (!flutter_view_controller_->engine() || - !flutter_view_controller_->view()) { - return false; - } - - // Register Flutter plugins. - RegisterPlugins(flutter_view_controller_->engine()); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_view_controller_) { - flutter_view_controller_ = nullptr; - } -} - -void FlutterWindow::Run() { - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_view_controller_->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait for the next frame if no events. - auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); - next_event_time = std::min( - next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds( - static_cast(std::trunc(1000000.0 / frame_rate)))); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } -} diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h b/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h deleted file mode 100644 index 8f8cb092..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/flutter_window.h +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_WINDOW_ -#define FLUTTER_WINDOW_ - -#include -#include - -#include - -class FlutterWindow { - public: - explicit FlutterWindow(const flutter::DartProject project); - ~FlutterWindow() = default; - - // Prevent copying. - FlutterWindow(FlutterWindow const&) = delete; - FlutterWindow& operator=(FlutterWindow const&) = delete; - - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); - void OnDestroy(); - void Run(); - - private: - flutter::DartProject project_; - std::unique_ptr flutter_view_controller_; -}; - -#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc deleted file mode 100644 index 8b1dc31e..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.cc +++ /dev/null @@ -1,7 +0,0 @@ -// -// Generated file. Do not edit. -// - -#include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h b/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h deleted file mode 100644 index a31c23cd..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/generated_plugin_registrant.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated file. Do not edit. -// - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc b/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc deleted file mode 100644 index 30b7714e..00000000 --- a/examples/flutter-weston-desktop-shell-virtual-keyboard/main.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include -#include - -#include -#include -#include - -#include "flutter_window.h" - -int main(int argc, char** argv) { - // Works as a weston desktop shell. - bool show_cursor; - auto config_file = weston_config_get_name_from_env(); - auto config = weston_config_parse(config_file); - auto s = weston_config_get_section(config, "flutter_linux_wayland", nullptr, - nullptr); - char* path = nullptr; - if (s) { - weston_config_section_get_bool(s, "show-cursor", &show_cursor, true); - weston_config_section_get_string( - s, "flutter-project-path", &path, - "../../sample-app/sample/build/linux/x64/release/bundle"); - } - - std::wstring fl_path; - if (path != nullptr) { - // convert char* to wstring. - std::string str(path); - std::wstring ws_temp(str.begin(), str.end()); - if (!ws_temp.empty()) { - fl_path = ws_temp; - } - - free(path); - } - - // libweston-6 does not export weston_config_destroy(). - // So run free() instead. - if (config) { - free(config); - } - // weston_config_destroy(config); - - // The project to run. - constexpr int width = 640; - constexpr int height = 480; - - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, - width, height, show_cursor)) { - std::cerr << "Failed to create a Flutter window." << std::endl; - return 0; - } - window.Run(); - window.OnDestroy(); - return 0; -} diff --git a/examples/flutter-weston-desktop-shell/cmake/user_config.cmake b/examples/flutter-weston-desktop-shell/cmake/user_config.cmake index eecee1af..aa81327d 100644 --- a/examples/flutter-weston-desktop-shell/cmake/user_config.cmake +++ b/examples/flutter-weston-desktop-shell/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) set(DESKTOP_SHELL ON) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-weston-desktop-shell/flutter_window.cc b/examples/flutter-weston-desktop-shell/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-weston-desktop-shell/flutter_window.cc +++ b/examples/flutter-weston-desktop-shell/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-weston-desktop-shell/flutter_window.h b/examples/flutter-weston-desktop-shell/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-weston-desktop-shell/flutter_window.h +++ b/examples/flutter-weston-desktop-shell/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc index 30b7714e..bd8407f1 100644 --- a/examples/flutter-weston-desktop-shell/main.cc +++ b/examples/flutter-weston-desktop-shell/main.cc @@ -54,10 +54,17 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = + flutter::FlutterViewController::ViewMode::kFullscreen; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = true; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, - width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/examples/flutter-x11-client/cmake/user_config.cmake b/examples/flutter-x11-client/cmake/user_config.cmake index 30624406..417f2103 100644 --- a/examples/flutter-x11-client/cmake/user_config.cmake +++ b/examples/flutter-x11-client/cmake/user_config.cmake @@ -1,8 +1,7 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/doc/README.md#user-configuration-parameters-cmake-options +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE X11) set(DESKTOP_SHELL OFF) -set(USE_VIRTUAL_KEYBOARD OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-x11-client/flutter_window.cc b/examples/flutter-x11-client/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/examples/flutter-x11-client/flutter_window.cc +++ b/examples/flutter-x11-client/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/examples/flutter-x11-client/flutter_window.h b/examples/flutter-x11-client/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/examples/flutter-x11-client/flutter_window.h +++ b/examples/flutter-x11-client/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index e9095b11..6dfb5fb8 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -42,9 +42,16 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = false; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(view_mode, width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index b8e10f13..dcbf3f5a 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -9,18 +9,21 @@ namespace flutter { -FlutterViewController::FlutterViewController(ViewMode view_mode, int width, - int height, bool show_cursor, - const DartProject& project) { +FlutterViewController::FlutterViewController( + const ViewProperties& view_properties, const DartProject& project) { engine_ = std::make_unique(project); FlutterDesktopViewProperties c_view_properties = {}; - c_view_properties.width = width; - c_view_properties.height = height; - c_view_properties.windw_display_mode = (view_mode == ViewMode::kFullscreen) - ? FlutterWindowMode::kFullscreen - : FlutterWindowMode::kNormal; - c_view_properties.show_cursor = show_cursor; + c_view_properties.width = view_properties.width; + c_view_properties.height = view_properties.height; + c_view_properties.view_mode = + (view_properties.view_mode == ViewMode::kFullscreen) + ? FlutterDesktopViewMode::kFullscreen + : FlutterDesktopViewMode::kNormal; + c_view_properties.use_mouse_cursor = view_properties.use_mouse_cursor; + c_view_properties.use_onscreen_keyboard = + view_properties.use_onscreen_keyboard; + controller_ = FlutterDesktopViewControllerCreate(c_view_properties, engine_->RelinquishEngine()); if (!controller_) { diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index d6c43612..d8464c20 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -25,18 +25,38 @@ namespace flutter { // methods in the C API directly, as this class will do that internally. class FlutterViewController { public: - // The View screen size mode. enum ViewMode { + // Shows the Flutter view by user specific size. kNormal = 0, + // Shows always the Flutter view by fullscreen. kFullscreen = 1, }; + // Properties for configuring a Flutter view instance. + typedef struct { + // View width. + int width; + + // View height. + int height; + + // View display mode. If you set kFullscreen, the parameters of both `width` + // and `height` will be ignored. + ViewMode view_mode; + + // Uses mouse cursor. + bool use_mouse_cursor; + + // Uses the on-screen keyboard. + bool use_onscreen_keyboard; + } ViewProperties; + // Creates a FlutterView that can be parented into a Windows View hierarchy // either using HWNDs or in the future into a CoreWindow, or using compositor. // // |dart_project| will be used to configure the engine backing this view. - explicit FlutterViewController(ViewMode view_mode, int width, int height, - bool show_cursor, const DartProject& project); + explicit FlutterViewController(const ViewProperties& view_properties, + const DartProject& project); virtual ~FlutterViewController(); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc index 491d5cb1..531e6a29 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc @@ -78,21 +78,15 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( #if defined(DISPLAY_BACKEND_TYPE_DRM_GBM) std::make_unique>( - view_properties.windw_display_mode, view_properties.width, - view_properties.height, view_properties.show_cursor); + view_properties); #elif defined(DISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) std::make_unique< flutter::LinuxesWindowDrm>( - view_properties.windw_display_mode, view_properties.width, - view_properties.height, view_properties.show_cursor); + view_properties); #elif defined(DISPLAY_BACKEND_TYPE_X11) - std::make_unique( - view_properties.windw_display_mode, view_properties.width, - view_properties.height, view_properties.show_cursor); + std::make_unique(view_properties); #else - std::make_unique( - view_properties.windw_display_mode, view_properties.width, - view_properties.height, view_properties.show_cursor); + std::make_unique(view_properties); #endif auto state = std::make_unique(); diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h b/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h index c99d8128..6ba19b84 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h @@ -54,27 +54,31 @@ typedef struct { const char** dart_entrypoint_argv; } FlutterDesktopEngineProperties; -// The Window display mode. -enum FlutterWindowMode { - // Show the Flutter view by user specific size. +// The View display mode. +enum FlutterDesktopViewMode { + // Shows the Flutter view by user specific size. kNormal = 0, - // Show always the Flutter view by fullscreen. + // Shows always the Flutter view by fullscreen. kFullscreen = 1, }; // Properties for configuring a Flutter view instance. typedef struct { - // Window display mode. - FlutterWindowMode windw_display_mode; - - // Window width. + // View width. int width; - // Window height. + // View height. int height; - // Show mouse cursor. - bool show_cursor; + // View display mode. If you set kFullscreen, the parameters of both `width` + // and `height` will be ignored. + FlutterDesktopViewMode view_mode; + + // Uses mouse cursor. + bool use_mouse_cursor; + + // Uses the on-screen keyboard. + bool use_onscreen_keyboard; } FlutterDesktopViewProperties; // ========== View Controller ========== @@ -117,7 +121,8 @@ FlutterDesktopViewControllerGetView(FlutterDesktopViewControllerRef controller); FLUTTER_EXPORT bool FlutterDesktopViewDispatchEvent(FlutterDesktopViewRef view); // Returns the display frame rate by the given controller. -FLUTTER_EXPORT int32_t FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view); +FLUTTER_EXPORT int32_t +FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view); // ========== Engine ========== diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h index c3d344c6..874f661b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h @@ -17,21 +17,14 @@ class LinuxesWindow { protected: virtual bool IsValid() const = 0; - uint32_t GetCurrentWidth() const { return current_width_; } - uint32_t GetCurrentHeight() const { return current_height_; } + uint32_t GetCurrentWidth() const { return view_properties_.width; } - double current_scale_ = 1.0; - - int32_t current_width_ = -1; - int32_t current_height_ = -1; - - bool show_cursor_; - - FlutterWindowMode window_mode_; + uint32_t GetCurrentHeight() const { return view_properties_.height; } + FlutterDesktopViewProperties view_properties_; + double current_scale_ = 1.0; double pointer_x_ = 0; double pointer_y_ = 0; - std::string clipboard_data_ = ""; }; diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h index a931e078..db42bd03 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h @@ -29,13 +29,9 @@ constexpr char kDrmDeviceDefaultFilename[] = "/dev/dri/card0"; template class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { public: - LinuxesWindowDrm(FlutterWindowMode window_mode, int32_t width, int32_t height, - bool show_cursor) + LinuxesWindowDrm(FlutterDesktopViewProperties view_properties) : display_valid_(false), is_pending_cursor_add_event_(false) { - window_mode_ = window_mode; - current_width_ = width; - current_height_ = height; - show_cursor_ = show_cursor; + view_properties_ = view_properties; auto udev = udev_new(); if (!udev) { @@ -130,15 +126,15 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { return false; } - if (window_mode_ != FlutterWindowMode::kFullscreen) { + if (view_properties_.view_mode != FlutterDesktopViewMode::kFullscreen) { LINUXES_LOG(WARNING) << "Normal mode is not supported, use fullscreen mode."; - window_mode_ = FlutterWindowMode::kFullscreen; + view_properties_.view_mode = FlutterDesktopViewMode::kFullscreen; } - current_width_ = native_window_->Width(); - current_height_ = native_window_->Height(); - LINUXES_LOG(INFO) << "Display output resolution: " << current_width_ << "x" - << current_height_; + view_properties_.width = native_window_->Width(); + view_properties_.height = native_window_->Height(); + LINUXES_LOG(INFO) << "Display output resolution: " << view_properties_.width + << "x" << view_properties_.height; if (is_pending_cursor_add_event_) { native_window_->ShowCursor(pointer_x_, pointer_y_); @@ -178,7 +174,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override { - if (show_cursor_) { + if (view_properties_.use_mouse_cursor) { native_window_->UpdateCursor(cursor_name, pointer_x_, pointer_y_); } } @@ -290,16 +286,16 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { if (self->IsUdevEventHotplug(*device) && self->native_window_->ConfigureDisplay()) { - if (self->current_width_ != self->native_window_->Width() || - self->current_height_ != self->native_window_->Height()) { - self->current_width_ = self->native_window_->Width(); - self->current_height_ = self->native_window_->Height(); + if (self->view_properties_.width != self->native_window_->Width() || + self->view_properties_.height != self->native_window_->Height()) { + self->view_properties_.width = self->native_window_->Width(); + self->view_properties_.height = self->native_window_->Height(); LINUXES_LOG(INFO) << "Display output resolution: " - << self->current_width_ << "x" - << self->current_height_; + << self->view_properties_.width << "x" + << self->view_properties_.height; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnWindowSizeChanged( - self->current_width_, self->current_height_); + self->view_properties_.width, self->view_properties_.height); } } } @@ -389,8 +385,9 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { libinput_event_destroy(event); } - if (self->show_cursor_ && ((self->pointer_x_ != previous_pointer_x) || - (self->pointer_y_ != previous_pointer_y))) { + if (self->view_properties_.use_mouse_cursor && + ((self->pointer_x_ != previous_pointer_x) || + (self->pointer_y_ != previous_pointer_y))) { self->native_window_->MoveCursor(self->pointer_x_, self->pointer_y_); } @@ -399,8 +396,8 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { void OnDeviceAdded(libinput_event* event) { auto device = libinput_event_get_device(event); - if ((show_cursor_) && - (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))) { + if (view_properties_.use_mouse_cursor && + libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) { // When launching the application, either route will be used depending on // the timing. if (native_window_) { @@ -413,8 +410,8 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { void OnDeviceRemoved(libinput_event* event) { auto device = libinput_event_get_device(event); - if (show_cursor_ && - (libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER))) { + if (view_properties_.use_mouse_cursor && + libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) { native_window_->DismissCursor(); } } @@ -438,12 +435,12 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto new_pointer_x = pointer_x_ + dx; new_pointer_x = std::max(0.0, new_pointer_x); - new_pointer_x = - std::min(static_cast(current_width_ - 1), new_pointer_x); + new_pointer_x = std::min(static_cast(view_properties_.width - 1), + new_pointer_x); auto new_pointer_y = pointer_y_ + dy; new_pointer_y = std::max(0.0, new_pointer_y); - new_pointer_y = - std::min(static_cast(current_height_ - 1), new_pointer_y); + new_pointer_y = std::min(static_cast(view_properties_.height - 1), + new_pointer_y); binding_handler_delegate_->OnPointerMove(new_pointer_x, new_pointer_y); pointer_x_ = new_pointer_x; @@ -455,9 +452,9 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); auto x = libinput_event_pointer_get_absolute_x_transformed( - pointer_event, current_width_); + pointer_event, view_properties_.width); auto y = libinput_event_pointer_get_absolute_y_transformed( - pointer_event, current_height_); + pointer_event, view_properties_.height); binding_handler_delegate_->OnPointerMove(x, y); pointer_x_ = x; @@ -524,10 +521,10 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto touch_event = libinput_event_get_touch_event(event); auto time = libinput_event_touch_get_time(touch_event); auto slot = libinput_event_touch_get_seat_slot(touch_event); - auto x = - libinput_event_touch_get_x_transformed(touch_event, current_width_); - auto y = - libinput_event_touch_get_y_transformed(touch_event, current_height_); + auto x = libinput_event_touch_get_x_transformed(touch_event, + view_properties_.width); + auto y = libinput_event_touch_get_y_transformed(touch_event, + view_properties_.height); binding_handler_delegate_->OnTouchDown(time, slot, x, y); } } @@ -546,10 +543,10 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto touch_event = libinput_event_get_touch_event(event); auto time = libinput_event_touch_get_time(touch_event); auto slot = libinput_event_touch_get_seat_slot(touch_event); - auto x = - libinput_event_touch_get_x_transformed(touch_event, current_width_); - auto y = - libinput_event_touch_get_y_transformed(touch_event, current_height_); + auto x = libinput_event_touch_get_x_transformed(touch_event, + view_properties_.width); + auto y = libinput_event_touch_get_y_transformed(touch_event, + view_properties_.height); binding_handler_delegate_->OnTouchMotion(time, slot, x, y); } } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc index c8b1369a..3077ed32 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc @@ -157,7 +157,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; - if (self->show_cursor_) { + if (self->view_properties_.use_mouse_cursor) { self->cursor_info_.pointer = wl_pointer; self->cursor_info_.serial = serial; } @@ -338,9 +338,10 @@ const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { self->frame_rate_ = refresh; } - if (self->window_mode_ == FlutterWindowMode::kFullscreen) { - self->current_width_ = width; - self->current_height_ = height; + if (self->view_properties_.view_mode == + FlutterDesktopViewMode::kFullscreen) { + self->view_properties_.width = width; + self->view_properties_.height = height; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnWindowSizeChanged(width, height); } @@ -544,9 +545,8 @@ const wl_data_source_listener LinuxesWindowWayland::kWlDataSourceListener = { uint32_t dnd_action) -> void {}, }; -LinuxesWindowWayland::LinuxesWindowWayland(FlutterWindowMode window_mode, - int32_t width, int32_t height, - bool show_cursor) +LinuxesWindowWayland::LinuxesWindowWayland( + FlutterDesktopViewProperties view_properties) : cursor_info_({"", 0, nullptr}), display_valid_(false), is_requested_show_virtual_keyboard_(false), @@ -568,10 +568,7 @@ LinuxesWindowWayland::LinuxesWindowWayland(FlutterWindowMode window_mode, wp_presentation_(nullptr), wp_presentation_clk_id_(UINT32_MAX), frame_rate_(60000) { - window_mode_ = window_mode; - current_width_ = width; - current_height_ = height; - show_cursor_ = show_cursor; + view_properties_ = view_properties; wl_display_ = wl_display_connect(nullptr); if (!wl_display_) { @@ -836,14 +833,14 @@ bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { return false; } - if (window_mode_ == FlutterWindowMode::kFullscreen) { - width = current_width_; - height = current_height_; + if (view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen) { + width = view_properties_.width; + height = view_properties_.height; } LINUXES_LOG(TRACE) << "Created the Wayland surface: " << width << "x" << height; - if (show_cursor_) { + if (view_properties_.use_mouse_cursor) { wl_cursor_surface_ = wl_compositor_create_surface(wl_compositor_); if (!wl_cursor_surface_) { LINUXES_LOG(ERROR) @@ -909,7 +906,7 @@ void LinuxesWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { } void LinuxesWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { - if (show_cursor_) { + if (view_properties_.use_mouse_cursor) { if (cursor_name.compare(cursor_info_.cursor_name) == 0) { return; } @@ -1039,7 +1036,7 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, } if (!strcmp(interface, wl_shm_interface.name)) { - if (show_cursor_) { + if (view_properties_.use_mouse_cursor) { wl_shm_ = static_cast( wl_registry_bind(wl_registry, name, &wl_shm_interface, 1)); wl_cursor_theme_ = wl_cursor_theme_load(nullptr, 32, wl_shm_); @@ -1052,21 +1049,23 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, return; } -#ifdef USE_VIRTUAL_KEYBOARD if (!strcmp(interface, kZwpTextInputManagerV1)) { - zwp_text_input_manager_v1_ = - static_cast(wl_registry_bind( - wl_registry, name, &zwp_text_input_manager_v1_interface, 1)); + if (view_properties_.use_onscreen_keyboard) { + zwp_text_input_manager_v1_ = + static_cast(wl_registry_bind( + wl_registry, name, &zwp_text_input_manager_v1_interface, 1)); + } return; } if (!strcmp(interface, kZwpTextInputManagerV3)) { - zwp_text_input_manager_v3_ = - static_cast(wl_registry_bind( - wl_registry, name, &zwp_text_input_manager_v3_interface, 1)); + if (view_properties_.use_onscreen_keyboard) { + zwp_text_input_manager_v3_ = + static_cast(wl_registry_bind( + wl_registry, name, &zwp_text_input_manager_v3_interface, 1)); + } return; } -#endif if (!strcmp(interface, wl_data_device_manager_interface.name)) { // Save the version of wl_data_device_manager because the release method of diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h index e23bc06d..6ed2f11b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h @@ -31,8 +31,7 @@ namespace flutter { class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { public: - LinuxesWindowWayland(FlutterWindowMode window_mode, int32_t width, - int32_t height, bool show_cursor); + LinuxesWindowWayland(FlutterDesktopViewProperties view_properties); ~LinuxesWindowWayland(); // |LinuxesWindow| diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc index 76d1338b..1df767b0 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc @@ -13,12 +13,9 @@ namespace flutter { -LinuxesWindowX11::LinuxesWindowX11(FlutterWindowMode window_mode, int32_t width, - int32_t height, bool show_cursor) { - window_mode_ = window_mode; - current_width_ = width; - current_height_ = height; - show_cursor_ = show_cursor; +LinuxesWindowX11::LinuxesWindowX11( + FlutterDesktopViewProperties view_properties) { + view_properties_ = view_properties; display_ = XOpenDisplay(NULL); if (!display_) { @@ -85,13 +82,13 @@ bool LinuxesWindowX11::DispatchEvent() { } break; case ConfigureNotify: { - if (((event.xconfigure.width != current_width_) || - (event.xconfigure.height != current_height_))) { - current_width_ = event.xconfigure.width; - current_height_ = event.xconfigure.height; + if (((event.xconfigure.width != view_properties_.width) || + (event.xconfigure.height != view_properties_.height))) { + view_properties_.width = event.xconfigure.width; + view_properties_.height = event.xconfigure.height; if (binding_handler_delegate_) { - binding_handler_delegate_->OnWindowSizeChanged(current_width_, - current_height_); + binding_handler_delegate_->OnWindowSizeChanged( + view_properties_.width, view_properties_.height); } } } break; diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h index ff1b552c..86fe9697 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h @@ -16,8 +16,7 @@ namespace flutter { class LinuxesWindowX11 : public LinuxesWindow, public WindowBindingHandler { public: - LinuxesWindowX11(FlutterWindowMode window_mode, int32_t width, int32_t height, - bool show_cursor); + LinuxesWindowX11(FlutterDesktopViewProperties view_properties); ~LinuxesWindowX11(); // |LinuxesWindow| diff --git a/src/templates/app/common/flutter_window.cc b/src/templates/app/common/flutter_window.cc index 9ead67f6..9775d89b 100644 --- a/src/templates/app/common/flutter_window.cc +++ b/src/templates/app/common/flutter_window.cc @@ -11,13 +11,14 @@ #include "generated_plugin_registrant.h" -FlutterWindow::FlutterWindow(const flutter::DartProject project) - : project_(project) {} +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} -bool FlutterWindow::OnCreate(flutter::FlutterViewController::ViewMode view_mode, - int width, int height, bool show_cursor) { +bool FlutterWindow::OnCreate() { flutter_view_controller_ = std::make_unique( - view_mode, width, height, show_cursor, project_); + view_properties_, project_); // Ensure that basic setup of the controller was successful. if (!flutter_view_controller_->engine() || diff --git a/src/templates/app/common/flutter_window.h b/src/templates/app/common/flutter_window.h index 8f8cb092..20b9cb88 100644 --- a/src/templates/app/common/flutter_window.h +++ b/src/templates/app/common/flutter_window.h @@ -12,19 +12,21 @@ class FlutterWindow { public: - explicit FlutterWindow(const flutter::DartProject project); + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); ~FlutterWindow() = default; // Prevent copying. FlutterWindow(FlutterWindow const&) = delete; FlutterWindow& operator=(FlutterWindow const&) = delete; - bool OnCreate(flutter::FlutterViewController::ViewMode view_mode, int width, - int height, bool show_cursor); + bool OnCreate(); void OnDestroy(); void Run(); private: + flutter::FlutterViewController::ViewProperties view_properties_; flutter::DartProject project_; std::unique_ptr flutter_view_controller_; }; diff --git a/src/templates/app/linux-drm/main.cc b/src/templates/app/linux-drm/main.cc index 9a533507..3ea7b882 100644 --- a/src/templates/app/linux-drm/main.cc +++ b/src/templates/app/linux-drm/main.cc @@ -32,10 +32,15 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.view_mode = + flutter::FlutterViewController::ViewMode::kFullscreen; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = false; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, 0, - 0, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc index 30b7714e..bd8407f1 100644 --- a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc +++ b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc @@ -54,10 +54,17 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = + flutter::FlutterViewController::ViewMode::kFullscreen; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = true; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(flutter::FlutterViewController::ViewMode::kFullscreen, - width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/src/templates/app/linux-wayland/main.cc b/src/templates/app/linux-wayland/main.cc index a5984e09..4559c3c9 100644 --- a/src/templates/app/linux-wayland/main.cc +++ b/src/templates/app/linux-wayland/main.cc @@ -19,6 +19,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -30,6 +32,8 @@ int main(int argc, char** argv) { // The project to run. const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); + const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const auto view_mode = options.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen @@ -42,9 +46,16 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(view_mode, width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } diff --git a/src/templates/app/linux-x11/main.cc b/src/templates/app/linux-x11/main.cc index e9095b11..6dfb5fb8 100644 --- a/src/templates/app/linux-x11/main.cc +++ b/src/templates/app/linux-x11/main.cc @@ -42,9 +42,16 @@ int main(int argc, char** argv) { auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = false; + // The Flutter instance hosted by this window. - FlutterWindow window(project); - if (!window.OnCreate(view_mode, width, height, show_cursor)) { + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } From de6ed354977d3e3dcc6bcd3dc8f1ed79bba74820 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 10 Jun 2021 10:59:15 +0900 Subject: [PATCH 020/178] Bugfix offscreen surface for wayland (#164) Closed #163 --- .../linux_embedded/window/native_window_wayland.cc | 13 ++++++++++++- .../linux_embedded/window/native_window_wayland.h | 1 + 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc index c61cf2c7..5a40621f 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc @@ -25,7 +25,13 @@ NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, // The offscreen (resource) surface will not be mapped, but needs to be a // wl_surface because ONLY window EGL surfaces are supported on Wayland. - window_offscreen_ = wl_egl_window_create(surface_, 1, 1); + surface_offscreen_ = wl_compositor_create_surface(compositor); + if (!surface_offscreen_) { + LINUXES_LOG(ERROR) << "Failed to create the compositor surface for off-screen."; + return; + } + + window_offscreen_ = wl_egl_window_create(surface_offscreen_, 1, 1); if (!window_offscreen_) { LINUXES_LOG(ERROR) << "Failed to create the EGL window for offscreen."; return; @@ -51,6 +57,11 @@ NativeWindowWayland::~NativeWindowWayland() { wl_surface_destroy(surface_); surface_ = nullptr; } + + if (surface_offscreen_) { + wl_surface_destroy(surface_offscreen_); + surface_offscreen_ = nullptr; + } } bool NativeWindowWayland::Resize(const size_t width, const size_t height) { diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h index 5e9aa790..c8cc41d2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h @@ -24,6 +24,7 @@ class NativeWindowWayland : public NativeWindow { private: wl_surface* surface_ = nullptr; + wl_surface* surface_offscreen_ = nullptr; }; } // namespace flutter From e3d8f78b9fb9101b2638b19b2c67878e1c281348 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 11 Jun 2021 10:53:30 +0900 Subject: [PATCH 021/178] Replace LINUXES_LOG to ELINUX_LOG (#167) --- .../linux_embedded/flutter_linuxes_engine.cc | 20 +++--- .../linux_embedded/flutter_linuxes_view.cc | 2 +- .../linux_embedded/flutter_project_bundle.cc | 6 +- .../shell/platform/linux_embedded/logger.cc | 22 +++---- .../shell/platform/linux_embedded/logger.h | 18 +++--- .../plugins/keyboard_glfw_util.cc | 2 +- .../plugins/lifecycle_plugin.cc | 8 +-- .../plugins/navigation_plugin.cc | 14 ++-- .../plugins/platform_views_plugin.cc | 16 ++--- .../linux_embedded/surface/context_egl.cc | 32 +++++----- .../surface/context_egl_stream.cc | 12 ++-- .../linux_embedded/surface/environment_egl.h | 14 ++-- .../surface/environment_egl_stream.cc | 14 ++-- .../surface/linuxes_egl_surface.cc | 10 +-- .../linux_embedded/surface/linuxes_surface.cc | 4 +- .../platform/linux_embedded/vsync_waiter.cc | 2 +- .../window/linuxes_window_drm.h | 64 +++++++++---------- .../window/linuxes_window_wayland.cc | 44 ++++++------- .../window/linuxes_window_x11.cc | 6 +- .../window/native_window_drm.cc | 16 ++--- .../window/native_window_drm_eglstream.cc | 22 +++---- .../window/native_window_drm_gbm.cc | 26 ++++---- .../window/native_window_wayland.cc | 27 ++++---- .../window/native_window_x11.cc | 4 +- 24 files changed, 204 insertions(+), 201 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc index db506e95..31f56ed9 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc @@ -108,12 +108,12 @@ FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project) std::this_thread::get_id(), embedder_api_.GetCurrentTime, [this](const auto* task) { if (!engine_) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Cannot post an engine task when engine is not running."; return; } if (embedder_api_.RunTask(engine_, task) != kSuccess) { - LINUXES_LOG(ERROR) << "Failed to post an engine task."; + ELINUX_LOG(ERROR) << "Failed to post an engine task."; } }); @@ -143,7 +143,7 @@ FlutterLinuxesEngine::~FlutterLinuxesEngine() { Stop(); } bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { if (!project_->HasValidPaths()) { - LINUXES_LOG(ERROR) << "Missing or unresolvable paths to assets."; + ELINUX_LOG(ERROR) << "Missing or unresolvable paths to assets."; return false; } std::string assets_path_string = project_->assets_path(); @@ -151,7 +151,7 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { if (embedder_api_.RunsAOTCompiledDartCode()) { aot_data_ = project_->LoadAotData(embedder_api_); if (!aot_data_) { - LINUXES_LOG(ERROR) << "Unable to start engine without AOT data."; + ELINUX_LOG(ERROR) << "Unable to start engine without AOT data."; return false; } } @@ -237,7 +237,7 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { auto result = embedder_api_.Run(FLUTTER_ENGINE_VERSION, &renderer_config, &args, this, &engine_); if (result != kSuccess || engine_ == nullptr) { - LINUXES_LOG(ERROR) << "Failed to start Flutter engine: error " << result; + ELINUX_LOG(ERROR) << "Failed to start Flutter engine: error " << result; return false; } @@ -292,7 +292,7 @@ bool FlutterLinuxesEngine::SendPlatformMessage( embedder_api_.PlatformMessageCreateResponseHandle( engine_, reply, user_data, &response_handle); if (result != kSuccess) { - LINUXES_LOG(ERROR) << "Failed to create response handle\n"; + ELINUX_LOG(ERROR) << "Failed to create response handle\n"; return false; } } @@ -323,9 +323,9 @@ void FlutterLinuxesEngine::SendPlatformMessageResponse( void FlutterLinuxesEngine::HandlePlatformMessage( const FlutterPlatformMessage* engine_message) { if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) { - LINUXES_LOG(ERROR) << "Invalid message size received. Expected: " - << sizeof(FlutterPlatformMessage) << " but received " - << engine_message->struct_size; + ELINUX_LOG(ERROR) << "Invalid message size received. Expected: " + << sizeof(FlutterPlatformMessage) << " but received " + << engine_message->struct_size; return; } @@ -353,7 +353,7 @@ void FlutterLinuxesEngine::SendSystemSettings() { auto result = embedder_api_.UpdateLocales(engine_, flutter_locale_list.data(), flutter_locale_list.size()); if (result != kSuccess) { - LINUXES_LOG(ERROR) << "Failed to set up Flutter locales."; + ELINUX_LOG(ERROR) << "Failed to set up Flutter locales."; } rapidjson::Document settings(rapidjson::kObjectType); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc index 5b663f60..b1659526 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc @@ -69,7 +69,7 @@ void FlutterLinuxesView::RegisterPlatformViewFactory( void FlutterLinuxesView::OnWindowSizeChanged(size_t width, size_t height) const { if (!GetRenderSurfaceTarget()->OnScreenSurfaceResize(width, height)) { - LINUXES_LOG(ERROR) << "Failed to change surface size."; + ELINUX_LOG(ERROR) << "Failed to change surface size."; return; } SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc index 1ffbf152..bd974261 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc @@ -47,7 +47,7 @@ FlutterProjectBundle::FlutterProjectBundle( aot_library_path_.compare(0, 1, "/") != 0)) { auto executable_location = GetExecutableDirectory(); if (executable_location.empty()) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Unable to find executable location to resolve resource paths."; } else { assets_path_ = executable_location + "/" + assets_path_; @@ -68,7 +68,7 @@ bool FlutterProjectBundle::HasValidPaths() { UniqueAotDataPtr FlutterProjectBundle::LoadAotData( const FlutterEngineProcTable& engine_procs) { if (aot_library_path_.empty()) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Attempted to load AOT data, but no aot_library_path was provided."; return nullptr; } @@ -79,7 +79,7 @@ UniqueAotDataPtr FlutterProjectBundle::LoadAotData( FlutterEngineAOTData data = nullptr; auto result = engine_procs.CreateAOTData(&source, &data); if (result != kSuccess) { - LINUXES_LOG(ERROR) << "Failed to load AOT data from: " << aot_library_path_; + ELINUX_LOG(ERROR) << "Failed to load AOT data from: " << aot_library_path_; return nullptr; } return UniqueAotDataPtr(data); diff --git a/src/flutter/shell/platform/linux_embedded/logger.cc b/src/flutter/shell/platform/linux_embedded/logger.cc index b22a86c3..200230ae 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.cc +++ b/src/flutter/shell/platform/linux_embedded/logger.cc @@ -20,17 +20,17 @@ constexpr char kFlutterLogLevelError[] = "ERROR"; constexpr char kFlutterLogLevelFatal[] = "FATAL"; constexpr char kFlutterLogLevelUnknown[] = "UNKNOWN"; -const char* const kLogLevelNames[LINUXES_LOG_NUM] = { +const char* const kLogLevelNames[ELINUX_LOG_NUM] = { kFlutterLogLevelTrace, kFlutterLogLevelDebug, kFlutterLogLevelInfo, kFlutterLogLevelWarning, kFlutterLogLevelError, kFlutterLogLevelFatal}; const std::unordered_map gLogLevelsMap{ - {kFlutterLogLevelTrace, LINUXES_LOG_TRACE}, - {kFlutterLogLevelDebug, LINUXES_LOG_DEBUG}, - {kFlutterLogLevelInfo, LINUXES_LOG_INFO}, - {kFlutterLogLevelWarning, LINUXES_LOG_WARNING}, - {kFlutterLogLevelError, LINUXES_LOG_ERROR}, - {kFlutterLogLevelFatal, LINUXES_LOG_FATAL}, + {kFlutterLogLevelTrace, ELINUX_LOG_TRACE}, + {kFlutterLogLevelDebug, ELINUX_LOG_DEBUG}, + {kFlutterLogLevelInfo, ELINUX_LOG_INFO}, + {kFlutterLogLevelWarning, ELINUX_LOG_WARNING}, + {kFlutterLogLevelError, ELINUX_LOG_ERROR}, + {kFlutterLogLevelFatal, ELINUX_LOG_FATAL}, }; int gFilterLogLevel = -1; @@ -39,12 +39,12 @@ int GetCurrentLogLevel() { if (gFilterLogLevel == -1) { auto env_log_level = std::getenv(kFlutterLogLevelsEnvironmentKey); if (!env_log_level || (env_log_level[0] == '\0')) { - gFilterLogLevel = LINUXES_LOG_WARNING; + gFilterLogLevel = ELINUX_LOG_WARNING; } else { if (gLogLevelsMap.find(env_log_level) != gLogLevelsMap.end()) { gFilterLogLevel = gLogLevelsMap.at(env_log_level); } else { - gFilterLogLevel = LINUXES_LOG_WARNING; + gFilterLogLevel = ELINUX_LOG_WARNING; } } } @@ -52,7 +52,7 @@ int GetCurrentLogLevel() { } const char* GetLogLevelName(int level) { - if (LINUXES_LOG_TRACE <= level && level < LINUXES_LOG_NUM) + if (ELINUX_LOG_TRACE <= level && level < ELINUX_LOG_NUM) return kLogLevelNames[level]; return kFlutterLogLevelUnknown; } @@ -76,7 +76,7 @@ Logger::~Logger() { stream_ << std::endl; std::cerr << stream_.str(); std::cerr.flush(); - if (level_ >= LINUXES_LOG_FATAL) { + if (level_ >= ELINUX_LOG_FATAL) { abort(); } } diff --git a/src/flutter/shell/platform/linux_embedded/logger.h b/src/flutter/shell/platform/linux_embedded/logger.h index 62da328e..5eb1d7d7 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.h +++ b/src/flutter/shell/platform/linux_embedded/logger.h @@ -12,19 +12,19 @@ namespace flutter { -constexpr int LINUXES_LOG_TRACE = 0; -constexpr int LINUXES_LOG_DEBUG = 1; -constexpr int LINUXES_LOG_INFO = 2; -constexpr int LINUXES_LOG_WARNING = 3; -constexpr int LINUXES_LOG_ERROR = 4; -constexpr int LINUXES_LOG_FATAL = 5; -constexpr int LINUXES_LOG_NUM = 6; +constexpr int ELINUX_LOG_TRACE = 0; +constexpr int ELINUX_LOG_DEBUG = 1; +constexpr int ELINUX_LOG_INFO = 2; +constexpr int ELINUX_LOG_WARNING = 3; +constexpr int ELINUX_LOG_ERROR = 4; +constexpr int ELINUX_LOG_FATAL = 5; +constexpr int ELINUX_LOG_NUM = 6; #define __LOG_FILE_NAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) -#define LINUXES_LOG(level) \ - Logger(LINUXES_LOG_##level, __LOG_FILE_NAME__, __LINE__).stream() +#define ELINUX_LOG(level) \ + Logger(ELINUX_LOG_##level, __LOG_FILE_NAME__, __LINE__).stream() class Logger { public: diff --git a/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc index 2940790b..92a3f0de 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc @@ -309,7 +309,7 @@ uint32_t GetGlfwKeycode(uint32_t xkb_keycode) { keycode_to_glfwkey_map.end()) { return keycode_to_glfwkey_map.at(xkb_keycode); } - LINUXES_LOG(ERROR) << "Unknown keycode: " << xkb_keycode; + ELINUX_LOG(ERROR) << "Unknown keycode: " << xkb_keycode; return xkb_keycode; } diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc index e4765a30..6ea582f2 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc @@ -22,22 +22,22 @@ LifecyclePlugin::LifecyclePlugin(BinaryMessenger* messenger) messenger, kChannelName, &StandardMessageCodec::GetInstance())) {} void LifecyclePlugin::OnInactive() const { - LINUXES_LOG(DEBUG) << "App lifecycle changed to inactive state."; + ELINUX_LOG(DEBUG) << "App lifecycle changed to inactive state."; channel_->Send(EncodableValue(std::string(kInactive))); } void LifecyclePlugin::OnResumed() const { - LINUXES_LOG(DEBUG) << "App lifecycle changed to resumed state."; + ELINUX_LOG(DEBUG) << "App lifecycle changed to resumed state."; channel_->Send(EncodableValue(std::string(kResumed))); } void LifecyclePlugin::OnPaused() const { - LINUXES_LOG(DEBUG) << "App lifecycle changed to paused state."; + ELINUX_LOG(DEBUG) << "App lifecycle changed to paused state."; channel_->Send(EncodableValue(std::string(kPaused))); } void LifecyclePlugin::OnDetached() const { - LINUXES_LOG(DEBUG) << "App lifecycle changed to detached state."; + ELINUX_LOG(DEBUG) << "App lifecycle changed to detached state."; channel_->Send(EncodableValue(std::string(kDetached))); } diff --git a/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc index 013a4c91..35c07e02 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc @@ -22,31 +22,31 @@ NavigationPlugin::NavigationPlugin(BinaryMessenger* messenger) messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())) {} void NavigationPlugin::SetInitialRoute(std::string route) const { - LINUXES_LOG(DEBUG) << "SetInitialRoute = " << route; + ELINUX_LOG(DEBUG) << "SetInitialRoute = " << route; auto args = std::make_unique(rapidjson::kObjectType); args->Parse("\"" + route + "\""); if (args->HasParseError()) { - LINUXES_LOG(ERROR) << "Failed to parse the initial route: " << route; - return ; + ELINUX_LOG(ERROR) << "Failed to parse the initial route: " << route; + return; } channel_->InvokeMethod(kSetInitialRouteMethod, std::move(args)); } void NavigationPlugin::PushRoute(std::string route) const { - LINUXES_LOG(DEBUG) << "PushRoute = " << route; + ELINUX_LOG(DEBUG) << "PushRoute = " << route; auto args = std::make_unique(rapidjson::kObjectType); args->Parse("\"" + route + "\""); if (args->HasParseError()) { - LINUXES_LOG(ERROR) << "Failed to parse the route: " << route; - return ; + ELINUX_LOG(ERROR) << "Failed to parse the route: " << route; + return; } channel_->InvokeMethod(kPushRouteMethod, std::move(args)); } void NavigationPlugin::PopRoute() const { - LINUXES_LOG(DEBUG) << "PopRoute"; + ELINUX_LOG(DEBUG) << "PopRoute"; channel_->InvokeMethod(kPopRouteMethod, nullptr); } diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc index a0ff45b8..2a618882 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -58,8 +58,8 @@ void PlatformViewsPlugin::RegisterViewFactory( std::unique_ptr factory) { if (platform_view_factories_.find(view_type) != platform_view_factories_.end()) { - LINUXES_LOG(ERROR) << "Platform Views factory is already registered: " - << view_type; + ELINUX_LOG(ERROR) << "Platform Views factory is already registered: " + << view_type; return; } platform_view_factories_[view_type] = std::move(factory); @@ -93,8 +93,8 @@ void PlatformViewsPlugin::HandleMethodCall( } else if (method.compare(kExitMethod) == 0) { result->NotImplemented(); } else { - LINUXES_LOG(WARNING) << "Platform Views unexpected method is called: " - << method; + ELINUX_LOG(WARNING) << "Platform Views unexpected method is called: " + << method; result->NotImplemented(); } } @@ -122,9 +122,9 @@ void PlatformViewsPlugin::PlatformViewsCreate( result->Error("Couldn't find height in the arguments"); return; } - LINUXES_LOG(DEBUG) << "Create the platform view: view_type = " << view_type - << ", id = " << view_id << ", width = " << view_width - << ", height = " << view_height; + ELINUX_LOG(DEBUG) << "Create the platform view: view_type = " << view_type + << ", id = " << view_id << ", width = " << view_width + << ", height = " << view_height; if (platform_view_factories_.find(view_type) == platform_view_factories_.end()) { @@ -157,7 +157,7 @@ void PlatformViewsPlugin::PlatformViewsDispose( return; } - LINUXES_LOG(DEBUG) << "Dispose the platform view: id = " << view_id; + ELINUX_LOG(DEBUG) << "Dispose the platform view: id = " << view_id; if (platform_views_.find(view_id) == platform_views_.end()) { result->Error("Couldn't find the view id in the arguments"); return; diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index 5fbd1f4e..c3c41a86 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -28,13 +28,13 @@ ContextEgl::ContextEgl(std::unique_ptr environment, }; if (eglChooseConfig(environment_->Display(), attribs, &config_, 1, &config_count) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to choose EGL surface config: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: " + << get_egl_error_cause(); return; } if (config_count == 0 || config_ == nullptr) { - LINUXES_LOG(ERROR) << "No matching configs: " << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "No matching configs: " << get_egl_error_cause(); return; } @@ -43,16 +43,16 @@ ContextEgl::ContextEgl(std::unique_ptr environment, context_ = eglCreateContext(environment_->Display(), config_, EGL_NO_CONTEXT, attribs); if (context_ == EGL_NO_CONTEXT) { - LINUXES_LOG(ERROR) << "Failed to create an onscreen context: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to create an onscreen context: " + << get_egl_error_cause(); return; } resource_context_ = eglCreateContext(environment_->Display(), config_, context_, attribs); if (resource_context_ == EGL_NO_CONTEXT) { - LINUXES_LOG(ERROR) << "Failed to create an offscreen resouce context: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to create an offscreen resouce context: " + << get_egl_error_cause(); return; } } @@ -66,8 +66,8 @@ std::unique_ptr ContextEgl::CreateOnscreenSurface( EGLSurface surface = eglCreateWindowSurface(environment_->Display(), config_, window->Window(), attribs); if (surface == EGL_NO_SURFACE) { - LINUXES_LOG(ERROR) << "Failed to create EGL window surface: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to create EGL window surface: " + << get_egl_error_cause(); } return std::make_unique(surface, environment_->Display(), context_); @@ -87,8 +87,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( EGLSurface surface = eglCreatePbufferSurface(environment_->Display(), config_, attribs); if (surface == EGL_NO_SURFACE) { - LINUXES_LOG(WARNING) << "Failed to create EGL off-screen surface." - << "(" << get_egl_error_cause() << ")"; + ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." + << "(" << get_egl_error_cause() << ")"; } #else // eglCreatePbufferSurface isn't supported on both Wayland and GBM. @@ -97,8 +97,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( EGLSurface surface = eglCreateWindowSurface( environment_->Display(), config_, window->WindowOffscreen(), attribs); if (surface == EGL_NO_SURFACE) { - LINUXES_LOG(WARNING) << "Failed to create EGL off-screen surface." - << "(" << get_egl_error_cause() << ")"; + ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." + << "(" << get_egl_error_cause() << ")"; } #endif return std::make_unique(surface, environment_->Display(), @@ -113,8 +113,8 @@ bool ContextEgl::ClearCurrent() const { } if (eglMakeCurrent(environment_->Display(), EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to clear EGL context: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to clear EGL context: " + << get_egl_error_cause(); return false; } return true; @@ -123,7 +123,7 @@ bool ContextEgl::ClearCurrent() const { void* ContextEgl::GlProcResolver(const char* name) const { auto address = eglGetProcAddress(name); if (!address) { - LINUXES_LOG(ERROR) << "Failed eglGetProcAddress: " << name; + ELINUX_LOG(ERROR) << "Failed eglGetProcAddress: " << name; return nullptr; } return reinterpret_cast(address); diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc index 8d916e89..aa654996 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc @@ -17,7 +17,7 @@ ContextEglStream::ContextEglStream( } if (!SetEglExtensionFunctionPointers()) { - LINUXES_LOG(ERROR) << "Failed to set extension function pointers"; + ELINUX_LOG(ERROR) << "Failed to set extension function pointers"; valid_ = false; } } @@ -35,21 +35,21 @@ std::unique_ptr ContextEglStream::CreateOnscreenSurface( if (eglGetOutputLayersEXT_(environment_->Display(), layer_attribs, &layer, 1, &layer_count) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to get EGL output layers"; + ELINUX_LOG(ERROR) << "Failed to get EGL output layers"; } if (layer_count == 0 || layer == nullptr) { - LINUXES_LOG(ERROR) << "No matching layers"; + ELINUX_LOG(ERROR) << "No matching layers"; } EGLint stream_attribs[] = {EGL_NONE}; auto stream = eglCreateStreamKHR_(environment_->Display(), stream_attribs); if (stream == EGL_NO_STREAM_KHR) { - LINUXES_LOG(ERROR) << "Failed to create EGL stream"; + ELINUX_LOG(ERROR) << "Failed to create EGL stream"; } if (eglStreamConsumerOutputEXT_(environment_->Display(), stream, layer) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to create EGL stream consumer output"; + ELINUX_LOG(ERROR) << "Failed to create EGL stream consumer output"; } EGLint surface_attribs[] = { @@ -62,7 +62,7 @@ std::unique_ptr ContextEglStream::CreateOnscreenSurface( auto surface = eglCreateStreamProducerSurfaceKHR_( environment_->Display(), config_, stream, surface_attribs); if (surface == EGL_NO_SURFACE) { - LINUXES_LOG(ERROR) << "Failed to create EGL stream producer surface"; + ELINUX_LOG(ERROR) << "Failed to create EGL stream producer surface"; } return std::make_unique(surface, environment_->Display(), context_); diff --git a/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h b/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h index d7b4f7bf..6f126eb8 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h @@ -18,8 +18,8 @@ class EnvironmentEgl { : display_(EGL_NO_DISPLAY), valid_(false) { display_ = eglGetDisplay(platform_display); if (display_ == EGL_NO_DISPLAY) { - LINUXES_LOG(ERROR) << "Failed to get the EGL display: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to get the EGL display: " + << get_egl_error_cause(); return; } @@ -31,8 +31,8 @@ class EnvironmentEgl { ~EnvironmentEgl() { if (display_ != EGL_NO_DISPLAY) { if (eglTerminate(display_) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to terminate the EGL display: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to terminate the EGL display: " + << get_egl_error_cause(); } display_ = EGL_NO_DISPLAY; } @@ -40,13 +40,13 @@ class EnvironmentEgl { bool InitializeEgl() const { if (eglInitialize(display_, nullptr, nullptr) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to initialize the EGL display: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to initialize the EGL display: " + << get_egl_error_cause(); return false; } if (eglBindAPI(EGL_OPENGL_ES_API) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to bind EGL API: " << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to bind EGL API: " << get_egl_error_cause(); return false; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc index b5af4088..8810f372 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc @@ -12,19 +12,19 @@ namespace flutter { EnvironmentEglStream::EnvironmentEglStream() : EnvironmentEgl() { if (!SetEglExtensionFunctionPointers()) { - LINUXES_LOG(ERROR) << "Failed to set extension function pointers"; + ELINUX_LOG(ERROR) << "Failed to set extension function pointers"; return; } auto device = GetEglDevice(); if (device == EGL_NO_DEVICE_EXT) { - LINUXES_LOG(ERROR) << "Couldn't find EGL device"; + ELINUX_LOG(ERROR) << "Couldn't find EGL device"; return; } display_ = eglGetPlatformDisplayEXT_(EGL_PLATFORM_DEVICE_EXT, device, NULL); if (display_ == EGL_NO_DISPLAY) { - LINUXES_LOG(ERROR) << "Failed to get the EGL display"; + ELINUX_LOG(ERROR) << "Failed to get the EGL display"; return; } @@ -46,23 +46,23 @@ bool EnvironmentEglStream::SetEglExtensionFunctionPointers() { EGLDeviceEXT EnvironmentEglStream::GetEglDevice() { EGLint num_devices; if (eglQueryDevicesEXT_(0, NULL, &num_devices) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to query EGL devices"; + ELINUX_LOG(ERROR) << "Failed to query EGL devices"; return EGL_NO_DEVICE_EXT; } if (num_devices < 1) { - LINUXES_LOG(ERROR) << "No EGL devices found"; + ELINUX_LOG(ERROR) << "No EGL devices found"; return EGL_NO_DEVICE_EXT; } auto devices = static_cast( std::calloc(num_devices, sizeof(EGLDeviceEXT))); if (!devices) { - LINUXES_LOG(ERROR) << "Failed to allocate memory"; + ELINUX_LOG(ERROR) << "Failed to allocate memory"; return EGL_NO_DEVICE_EXT; } if (eglQueryDevicesEXT_(num_devices, devices, &num_devices) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to query EGL devices"; + ELINUX_LOG(ERROR) << "Failed to query EGL devices"; std::free(devices); return EGL_NO_DEVICE_EXT; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc index faf18b67..88a20d3c 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc @@ -16,7 +16,7 @@ LinuxesEGLSurface::LinuxesEGLSurface(EGLSurface surface, EGLDisplay display, LinuxesEGLSurface::~LinuxesEGLSurface() { if (surface_ != EGL_NO_SURFACE) { if (eglDestroySurface(display_, surface_) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to destory surface"; + ELINUX_LOG(ERROR) << "Failed to destory surface"; } surface_ = EGL_NO_SURFACE; } @@ -26,8 +26,8 @@ bool LinuxesEGLSurface::IsValid() const { return surface_ != EGL_NO_SURFACE; } bool LinuxesEGLSurface::MakeCurrent() const { if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to make the EGL context current: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to make the EGL context current: " + << get_egl_error_cause(); return false; } return true; @@ -35,8 +35,8 @@ bool LinuxesEGLSurface::MakeCurrent() const { bool LinuxesEGLSurface::SwapBuffers() const { if (eglSwapBuffers(display_, surface_) != EGL_TRUE) { - LINUXES_LOG(ERROR) << "Failed to swap the EGL buffer: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "Failed to swap the EGL buffer: " + << get_egl_error_cause(); return false; } return true; diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc index 63f1f973..81a92e56 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc @@ -31,7 +31,7 @@ bool Surface::SetNativeWindow(NativeWindow* window) { bool Surface::OnScreenSurfaceResize(const size_t width, const size_t height) { if (!native_window_->Resize(width, height)) { - LINUXES_LOG(ERROR) << "Failed to resize."; + ELINUX_LOG(ERROR) << "Failed to resize."; return false; } @@ -39,7 +39,7 @@ bool Surface::OnScreenSurfaceResize(const size_t width, const size_t height) { DestroyOnScreenContext(); onscreen_surface_ = context_->CreateOnscreenSurface(native_window_); if (!onscreen_surface_->IsValid()) { - LINUXES_LOG(WARNING) << "Failed to recreate on-screen surface."; + ELINUX_LOG(WARNING) << "Failed to recreate on-screen surface."; onscreen_surface_ = nullptr; return false; } diff --git a/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc b/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc index 01d86316..d6be9db4 100644 --- a/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc +++ b/src/flutter/shell/platform/linux_embedded/vsync_waiter.cc @@ -30,7 +30,7 @@ void VsyncWaiter::NotifyVsync(FLUTTER_API_SYMBOL(FlutterEngine) engine, auto result = embedder_api->OnVsync(engine, baton_, frame_start_time_nanos, frame_target_time_nanos); if (result != kSuccess) { - LINUXES_LOG(ERROR) << "FlutterEngineOnVsync failed: batton = " << baton_; + ELINUX_LOG(ERROR) << "FlutterEngineOnVsync failed: batton = " << baton_; } } } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h index db42bd03..d7642d6b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h @@ -35,12 +35,12 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto udev = udev_new(); if (!udev) { - LINUXES_LOG(ERROR) << "Failed to create udev instance."; + ELINUX_LOG(ERROR) << "Failed to create udev instance."; return; } libinput_ = libinput_udev_create_context(&kLibinputInterface, NULL, udev); if (!libinput_) { - LINUXES_LOG(ERROR) << "Failed to create libinput instance."; + ELINUX_LOG(ERROR) << "Failed to create libinput instance."; udev_unref(udev); return; } @@ -49,20 +49,20 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { constexpr char kSeatId[] = "seat0"; auto ret = libinput_udev_assign_seat(libinput_, kSeatId); if (ret != 0) { - LINUXES_LOG(ERROR) << "Failed to assign udev seat to libinput instance."; + ELINUX_LOG(ERROR) << "Failed to assign udev seat to libinput instance."; return; } ret = sd_event_new(&libinput_event_loop_); if (ret < 0) { - LINUXES_LOG(ERROR) << "Failed to create libinput event loop."; + ELINUX_LOG(ERROR) << "Failed to create libinput event loop."; return; } ret = sd_event_add_io(libinput_event_loop_, NULL, libinput_get_fd(libinput_), EPOLLIN | EPOLLRDHUP | EPOLLPRI, OnLibinputEvent, this); if (ret < 0) { - LINUXES_LOG(ERROR) << "Failed to listen for user input."; + ELINUX_LOG(ERROR) << "Failed to listen for user input."; libinput_event_loop_ = sd_event_unref(libinput_event_loop_); return; } @@ -105,18 +105,18 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { bool CreateRenderSurface(int32_t width, int32_t height) override { auto device_filename = std::getenv(kFlutterDrmDeviceEnvironmentKey); if ((!device_filename) || (device_filename[0] == '\0')) { - LINUXES_LOG(WARNING) << kFlutterDrmDeviceEnvironmentKey - << " is not set, use " << kDrmDeviceDefaultFilename; + ELINUX_LOG(WARNING) << kFlutterDrmDeviceEnvironmentKey + << " is not set, use " << kDrmDeviceDefaultFilename; device_filename = const_cast(kDrmDeviceDefaultFilename); } native_window_ = std::make_unique(device_filename); if (!native_window_->IsValid()) { - LINUXES_LOG(ERROR) << "Failed to create the native window"; + ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; } if (!RegisterUdevDrmEventLoop(device_filename)) { - LINUXES_LOG(ERROR) << "Failed to register udev drm event loop."; + ELINUX_LOG(ERROR) << "Failed to register udev drm event loop."; return false; } display_valid_ = true; @@ -127,14 +127,14 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { } if (view_properties_.view_mode != FlutterDesktopViewMode::kFullscreen) { - LINUXES_LOG(WARNING) + ELINUX_LOG(WARNING) << "Normal mode is not supported, use fullscreen mode."; view_properties_.view_mode = FlutterDesktopViewMode::kFullscreen; } view_properties_.width = native_window_->Width(); view_properties_.height = native_window_->Height(); - LINUXES_LOG(INFO) << "Display output resolution: " << view_properties_.width - << "x" << view_properties_.height; + ELINUX_LOG(INFO) << "Display output resolution: " << view_properties_.width + << "x" << view_properties_.height; if (is_pending_cursor_add_event_) { native_window_->ShowCursor(pointer_x_, pointer_y_); @@ -198,7 +198,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { void* user_data) -> int { auto ret = open(path, flags | O_CLOEXEC); if (ret == -1) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Failed to open " << path << ", error: " << strerror(errno); } return ret; @@ -209,14 +209,14 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { bool RegisterUdevDrmEventLoop(const std::string& device_filename) { auto udev = udev_new(); if (!udev) { - LINUXES_LOG(ERROR) << "Failed to create udev instance."; + ELINUX_LOG(ERROR) << "Failed to create udev instance."; return false; } constexpr char kUdevMonitorSystemUdev[] = "udev"; udev_monitor_ = udev_monitor_new_from_netlink(udev, kUdevMonitorSystemUdev); if (!udev_monitor_) { - LINUXES_LOG(ERROR) << "Failed to create udev monitor."; + ELINUX_LOG(ERROR) << "Failed to create udev monitor."; udev_unref(udev); return false; } @@ -224,7 +224,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { constexpr char kUdevMonitorSubsystemDrm[] = "drm"; if (udev_monitor_filter_add_match_subsystem_devtype( udev_monitor_, kUdevMonitorSubsystemDrm, NULL) < 0) { - LINUXES_LOG(ERROR) << "Failed to filter udev monitor."; + ELINUX_LOG(ERROR) << "Failed to filter udev monitor."; udev_unref(udev); return false; } @@ -232,7 +232,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { constexpr char kFileNameSeparator[] = "/"; auto pos = device_filename.find_last_of(kFileNameSeparator); if (pos == std::string::npos) { - LINUXES_LOG(ERROR) << "Failed to get device name position."; + ELINUX_LOG(ERROR) << "Failed to get device name position."; udev_unref(udev); return false; } @@ -241,14 +241,14 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto device = udev_device_new_from_subsystem_sysname( udev, kUdevMonitorSubsystemDrm, device_name.c_str()); if (!device) { - LINUXES_LOG(ERROR) << "Failed to get device from " << device_name; + ELINUX_LOG(ERROR) << "Failed to get device from " << device_name; udev_unref(udev); return false; } auto sysnum = udev_device_get_sysnum(device); if (!sysnum) { - LINUXES_LOG(ERROR) << "Failed to get device id."; + ELINUX_LOG(ERROR) << "Failed to get device id."; udev_unref(udev); return false; } @@ -256,19 +256,19 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { udev_unref(udev); if (sd_event_new(&udev_drm_event_loop_) < 0) { - LINUXES_LOG(ERROR) << "Failed to create udev drm event loop."; + ELINUX_LOG(ERROR) << "Failed to create udev drm event loop."; return false; } if (sd_event_add_io( udev_drm_event_loop_, NULL, udev_monitor_get_fd(udev_monitor_), EPOLLIN | EPOLLRDHUP | EPOLLPRI, OnUdevDrmEvent, this) < 0) { - LINUXES_LOG(ERROR) << "Failed to listen for udev drm event."; + ELINUX_LOG(ERROR) << "Failed to listen for udev drm event."; return false; } if (udev_monitor_enable_receiving(udev_monitor_) < 0) { - LINUXES_LOG(ERROR) << "Failed to enable udev monitor receiving."; + ELINUX_LOG(ERROR) << "Failed to enable udev monitor receiving."; return false; } @@ -280,7 +280,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto self = reinterpret_cast(data); auto device = udev_monitor_receive_device(self->udev_monitor_); if (!device) { - LINUXES_LOG(ERROR) << "Failed to receive udev device."; + ELINUX_LOG(ERROR) << "Failed to receive udev device."; return -1; } @@ -290,9 +290,9 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { self->view_properties_.height != self->native_window_->Height()) { self->view_properties_.width = self->native_window_->Width(); self->view_properties_.height = self->native_window_->Height(); - LINUXES_LOG(INFO) << "Display output resolution: " - << self->view_properties_.width << "x" - << self->view_properties_.height; + ELINUX_LOG(INFO) << "Display output resolution: " + << self->view_properties_.width << "x" + << self->view_properties_.height; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnWindowSizeChanged( self->view_properties_.width, self->view_properties_.height); @@ -307,10 +307,10 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { bool IsUdevEventHotplug(udev_device& device) { auto sysnum = udev_device_get_sysnum(&device); if (!sysnum) { - LINUXES_LOG(ERROR) << "Failed to get device id."; + ELINUX_LOG(ERROR) << "Failed to get device id."; return false; } else if (std::atoi(sysnum) != drm_device_id_) { - LINUXES_LOG(ERROR) << "Not expected device id."; + ELINUX_LOG(ERROR) << "Not expected device id."; return false; } @@ -318,7 +318,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto value = udev_device_get_property_value(&device, kUdevPropertyKeyHotplug); if (!value) { - LINUXES_LOG(ERROR) << "Failed to get udev device property value."; + ELINUX_LOG(ERROR) << "Failed to get udev device property value."; return false; } @@ -331,7 +331,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { auto self = reinterpret_cast(data); auto ret = libinput_dispatch(self->libinput_); if (ret < 0) { - LINUXES_LOG(ERROR) << "Failed to dispatch libinput events."; + ELINUX_LOG(ERROR) << "Failed to dispatch libinput events."; return -ret; } @@ -486,7 +486,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { flutter_button = kFlutterPointerButtonMouseForward; break; default: - LINUXES_LOG(ERROR) << "Not expected button input: " << button; + ELINUX_LOG(ERROR) << "Not expected button input: " << button; return; } @@ -576,7 +576,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { value = libinput_event_pointer_get_axis_value(pointer_event, axis); break; default: - LINUXES_LOG(ERROR) << "Not expected axis source: " << source; + ELINUX_LOG(ERROR) << "Not expected axis source: " << source; return; } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc index 3077ed32..98541568 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc @@ -73,7 +73,7 @@ const wp_presentation_listener LinuxesWindowWayland::kWpPresentationListener = { [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { auto self = reinterpret_cast(data); self->wp_presentation_clk_id_ = clk_id; - LINUXES_LOG(TRACE) << "presentation info: clk_id = " << clk_id; + ELINUX_LOG(TRACE) << "presentation info: clk_id = " << clk_id; }, }; @@ -214,7 +214,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { flutter_button = kFlutterPointerButtonMouseForward; break; default: - LINUXES_LOG(ERROR) << "Not expected button input: " << button; + ELINUX_LOG(ERROR) << "Not expected button input: " << button; return; } @@ -330,9 +330,9 @@ const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { int32_t height, int32_t refresh) -> void { auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { - LINUXES_LOG(INFO) << "Display output info: width = " << width - << ", height = " << height - << ", refresh = " << refresh; + ELINUX_LOG(INFO) << "Display output info: width = " << width + << ", height = " << height + << ", refresh = " << refresh; // Some composers send 0 for the refresh value. if (refresh != 0) { self->frame_rate_ = refresh; @@ -351,7 +351,7 @@ const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { .done = [](void* data, wl_output* wl_output) -> void {}, .scale = [](void* data, wl_output* wl_output, int32_t scale) -> void { auto self = reinterpret_cast(data); - LINUXES_LOG(INFO) << "Display output scale: " << scale; + ELINUX_LOG(INFO) << "Display output scale: " << scale; self->current_scale_ = scale; }, }; @@ -521,7 +521,7 @@ const wl_data_source_listener LinuxesWindowWayland::kWlDataSourceListener = { .send = [](void* data, wl_data_source* wl_data_source, const char* mime_type, int32_t fd) -> void { if (strcmp(mime_type, kClipboardMimeTypeText)) { - LINUXES_LOG(ERROR) << "Not expected mime_type: " << mime_type; + ELINUX_LOG(ERROR) << "Not expected mime_type: " << mime_type; return; } auto self = reinterpret_cast(data); @@ -572,13 +572,13 @@ LinuxesWindowWayland::LinuxesWindowWayland( wl_display_ = wl_display_connect(nullptr); if (!wl_display_) { - LINUXES_LOG(ERROR) << "Failed to connect to the Wayland display."; + ELINUX_LOG(ERROR) << "Failed to connect to the Wayland display."; return; } wl_registry_ = wl_display_get_registry(wl_display_); if (!wl_registry_) { - LINUXES_LOG(ERROR) << "Failed to get the wayland registry."; + ELINUX_LOG(ERROR) << "Failed to get the wayland registry."; return; } @@ -598,7 +598,7 @@ LinuxesWindowWayland::LinuxesWindowWayland( zwp_text_input_v3_ = zwp_text_input_manager_v3_get_text_input( zwp_text_input_manager_v3_, wl_seat_); if (!zwp_text_input_v3_) { - LINUXES_LOG(ERROR) << "Failed to create the text input manager v3."; + ELINUX_LOG(ERROR) << "Failed to create the text input manager v3."; return; } zwp_text_input_v3_add_listener(zwp_text_input_v3_, @@ -607,7 +607,7 @@ LinuxesWindowWayland::LinuxesWindowWayland( zwp_text_input_v1_ = zwp_text_input_manager_v1_create_text_input( zwp_text_input_manager_v1_); if (!zwp_text_input_v1_) { - LINUXES_LOG(ERROR) << "Failed to create text input manager v1."; + ELINUX_LOG(ERROR) << "Failed to create text input manager v1."; return; } zwp_text_input_v1_add_listener(zwp_text_input_v1_, @@ -760,7 +760,7 @@ int32_t LinuxesWindowWayland::GetFrameRate() { return frame_rate_; } bool LinuxesWindowWayland::DispatchEvent() { if (!IsValid()) { - LINUXES_LOG(ERROR) << "Wayland display is invalid."; + ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; } @@ -819,17 +819,17 @@ bool LinuxesWindowWayland::DispatchEvent() { bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { if (!display_valid_) { - LINUXES_LOG(ERROR) << "Wayland display is invalid."; + ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; } if (!wl_compositor_) { - LINUXES_LOG(ERROR) << "Wl_compositor is invalid"; + ELINUX_LOG(ERROR) << "Wl_compositor is invalid"; return false; } if (!xdg_wm_base_) { - LINUXES_LOG(ERROR) << "Xdg-shell is invalid"; + ELINUX_LOG(ERROR) << "Xdg-shell is invalid"; return false; } @@ -838,12 +838,12 @@ bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { height = view_properties_.height; } - LINUXES_LOG(TRACE) << "Created the Wayland surface: " << width << "x" - << height; + ELINUX_LOG(TRACE) << "Created the Wayland surface: " << width << "x" + << height; if (view_properties_.use_mouse_cursor) { wl_cursor_surface_ = wl_compositor_create_surface(wl_compositor_); if (!wl_cursor_surface_) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Failed to create the compositor surface for cursor."; return false; } @@ -855,7 +855,7 @@ bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { xdg_surface_ = xdg_wm_base_get_xdg_surface(xdg_wm_base_, native_window_->Surface()); if (!xdg_surface_) { - LINUXES_LOG(ERROR) << "Failed to get the xdg surface."; + ELINUX_LOG(ERROR) << "Failed to get the xdg surface."; return false; } xdg_surface_add_listener(xdg_surface_, &kXdgSurfaceListener, this); @@ -1041,7 +1041,7 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, wl_registry_bind(wl_registry, name, &wl_shm_interface, 1)); wl_cursor_theme_ = wl_cursor_theme_load(nullptr, 32, wl_shm_); if (!wl_cursor_theme_) { - LINUXES_LOG(ERROR) << "Failed to load cursor theme."; + ELINUX_LOG(ERROR) << "Failed to load cursor theme."; return; } CreateSupportedWlCursorList(); @@ -1113,7 +1113,7 @@ void LinuxesWindowWayland::CreateSupportedWlCursorList() { auto wl_cursor = wl_cursor_theme_get_cursor(wl_cursor_theme_, theme.c_str()); if (!wl_cursor) { - LINUXES_LOG(ERROR) << "Unsupported cursor theme: " << theme.c_str(); + ELINUX_LOG(ERROR) << "Unsupported cursor theme: " << theme.c_str(); continue; } supported_wl_cursor_list_[theme] = wl_cursor; @@ -1173,7 +1173,7 @@ wl_cursor* LinuxesWindowWayland::GetWlCursor(const std::string& cursor_name) { } } - LINUXES_LOG(ERROR) << "Unsupported cursor: " << cursor_name.c_str(); + ELINUX_LOG(ERROR) << "Unsupported cursor: " << cursor_name.c_str(); return supported_wl_cursor_list_[kWlCursorThemeLeftPtr]; } diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc index 1df767b0..d10f059d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc @@ -19,7 +19,7 @@ LinuxesWindowX11::LinuxesWindowX11( display_ = XOpenDisplay(NULL); if (!display_) { - LINUXES_LOG(ERROR) << "Failed to open display."; + ELINUX_LOG(ERROR) << "Failed to open display."; return; } @@ -112,7 +112,7 @@ bool LinuxesWindowX11::CreateRenderSurface(int32_t width, int32_t height) { native_window_ = std::make_unique( display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), width, height); if (!native_window_->IsValid()) { - LINUXES_LOG(ERROR) << "Failed to create the native window"; + ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; } @@ -180,7 +180,7 @@ void LinuxesWindowX11::HandlePointerButtonEvent(uint32_t button, flutter_button = kFlutterPointerButtonMouseForward; break; default: - LINUXES_LOG(ERROR) << "Not expected button input: " << button; + ELINUX_LOG(ERROR) << "Not expected button input: " << button; return; } if (button_pressed) { diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index 31e17d08..cf9c48ff 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -18,7 +18,7 @@ namespace flutter { NativeWindowDrm::NativeWindowDrm(const char* device_filename) { drm_device_ = open(device_filename, O_RDWR | O_CLOEXEC); if (drm_device_ == -1) { - LINUXES_LOG(ERROR) << "Couldn't open " << device_filename; + ELINUX_LOG(ERROR) << "Couldn't open " << device_filename; return; } @@ -40,7 +40,7 @@ bool NativeWindowDrm::MoveCursor(double x, double y) { drmModeMoveCursor(drm_device_, drm_crtc_->crtc_id, x - cursor_hotspot_.first, y - cursor_hotspot_.second); if (result < 0) { - LINUXES_LOG(ERROR) << "Couldn't move the mouse cursor: " << result; + ELINUX_LOG(ERROR) << "Couldn't move the mouse cursor: " << result; return false; } return true; @@ -49,13 +49,13 @@ bool NativeWindowDrm::MoveCursor(double x, double y) { bool NativeWindowDrm::ConfigureDisplay() { auto resources = drmModeGetResources(drm_device_); if (!resources) { - LINUXES_LOG(ERROR) << "Couldn't get resources"; + ELINUX_LOG(ERROR) << "Couldn't get resources"; return false; } auto connector = FindConnector(resources); if (!connector) { - LINUXES_LOG(ERROR) << "Couldn't find any connectors"; + ELINUX_LOG(ERROR) << "Couldn't find any connectors"; drmModeFreeResources(resources); return false; } @@ -64,11 +64,11 @@ bool NativeWindowDrm::ConfigureDisplay() { drm_mode_info_ = connector->modes[0]; width_ = drm_mode_info_.hdisplay; height_ = drm_mode_info_.vdisplay; - LINUXES_LOG(INFO) << "resolution: " << width_ << "x" << height_; + ELINUX_LOG(INFO) << "resolution: " << width_ << "x" << height_; auto* encoder = FindEncoder(resources, connector); if (!encoder) { - LINUXES_LOG(ERROR) << "Couldn't find any encoders"; + ELINUX_LOG(ERROR) << "Couldn't find any encoders"; drmModeFreeConnector(connector); drmModeFreeResources(resources); return false; @@ -157,8 +157,8 @@ const uint32_t* NativeWindowDrm::GetCursorData(const std::string& cursor_name) { if (!cursor_data) { if (!cursor_name.empty()) { - LINUXES_LOG(WARNING) << "Unsupported cursor: " << cursor_name.c_str() - << ", use LeftPtr cursor."; + ELINUX_LOG(WARNING) << "Unsupported cursor: " << cursor_name.c_str() + << ", use LeftPtr cursor."; } cursor_data = kCursorDataLeftPtr; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc index 3eeda0b7..b5449ae5 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc @@ -55,11 +55,11 @@ NativeWindowDrmEglstream::~NativeWindowDrmEglstream() { bool NativeWindowDrmEglstream::Resize(const size_t width, const size_t height) { if (!valid_) { - LINUXES_LOG(ERROR) << "Failed to resize the window."; + ELINUX_LOG(ERROR) << "Failed to resize the window."; return false; } - LINUXES_LOG(ERROR) << "Not supported now."; + ELINUX_LOG(ERROR) << "Not supported now."; return false; } @@ -96,25 +96,25 @@ std::unique_ptr NativeWindowDrmEglstream::CreateRenderSurface() { bool NativeWindowDrmEglstream::ConfigureDisplayAdditional() { if (!SetDrmClientCapabilities()) { - LINUXES_LOG(ERROR) << "Couldn't set drm client capability"; + ELINUX_LOG(ERROR) << "Couldn't set drm client capability"; return false; } auto plane_resources = drmModeGetPlaneResources(drm_device_); if (!plane_resources) { - LINUXES_LOG(ERROR) << "Couldn't get plane resources"; + ELINUX_LOG(ERROR) << "Couldn't get plane resources"; return false; } drm_plane_id_ = FindPrimaryPlaneId(plane_resources); drmModeFreePlaneResources(plane_resources); if (drm_plane_id_ == -1) { - LINUXES_LOG(ERROR) << "Couldn't find a plane."; + ELINUX_LOG(ERROR) << "Couldn't find a plane."; return false; } auto atomic = drmModeAtomicAlloc(); if (!atomic) { - LINUXES_LOG(ERROR) << "Couldn't allocate atomic"; + ELINUX_LOG(ERROR) << "Couldn't allocate atomic"; return false; } int result = -1; @@ -124,7 +124,7 @@ bool NativeWindowDrmEglstream::ConfigureDisplayAdditional() { } drmModeAtomicFree(atomic); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to commit an atomic property change request"; + ELINUX_LOG(ERROR) << "Failed to commit an atomic property change request"; return false; } @@ -133,11 +133,11 @@ bool NativeWindowDrmEglstream::ConfigureDisplayAdditional() { bool NativeWindowDrmEglstream::SetDrmClientCapabilities() { if (drmSetClientCap(drm_device_, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1) != 0) { - LINUXES_LOG(ERROR) << "Couldn't set DRM_CLIENT_CAP_UNIVERSAL_PLANES"; + ELINUX_LOG(ERROR) << "Couldn't set DRM_CLIENT_CAP_UNIVERSAL_PLANES"; return false; } if (drmSetClientCap(drm_device_, DRM_CLIENT_CAP_ATOMIC, 1) != 0) { - LINUXES_LOG(ERROR) << "Couldn't set DRM_CLIENT_CAP_ATOMIC"; + ELINUX_LOG(ERROR) << "Couldn't set DRM_CLIENT_CAP_ATOMIC"; return false; } return true; @@ -187,7 +187,7 @@ bool NativeWindowDrmEglstream::AssignAtomicRequest(drmModeAtomicReqPtr atomic) { if (drmModeCreatePropertyBlob(drm_device_, &drm_mode_info_, sizeof(drm_mode_info_), &drm_property_blob_) != 0) { - LINUXES_LOG(ERROR) << "Failed to create property blob"; + ELINUX_LOG(ERROR) << "Failed to create property blob"; return false; } @@ -244,7 +244,7 @@ bool NativeWindowDrmEglstream::AssignAtomicPropertyValue( if (std::strcmp(table[j].name, property->name) == 0) { if (drmModeAtomicAddProperty(atomic, id, property->prop_id, table[j].value) < 0) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Failed to add " << table[j].name << " property"; drmModeFreeProperty(property); drmModeFreeObjectProperties(properties); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index 43eb7f28..8775bb99 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -26,7 +26,7 @@ NativeWindowDrmGbm::NativeWindowDrmGbm(const char* device_filename) } if (!drmIsMaster(drm_device_)) { - LINUXES_LOG(ERROR) + ELINUX_LOG(ERROR) << "Couldn't become the DRM master. Please confirm if another display " "backend such as X11 and Wayland is not running."; valid_ = false; @@ -35,7 +35,7 @@ NativeWindowDrmGbm::NativeWindowDrmGbm(const char* device_filename) gbm_device_ = gbm_create_device(drm_device_); if (!gbm_device_) { - LINUXES_LOG(ERROR) << "Couldn't create the GBM device."; + ELINUX_LOG(ERROR) << "Couldn't create the GBM device."; valid_ = false; return; } @@ -86,7 +86,7 @@ bool NativeWindowDrmGbm::ShowCursor(double x, double y) { gbm_bo_get_handle(gbm_cursor_bo_).u32, kCursorBufferWidth, kCursorBufferHeight); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; return false; } return true; @@ -112,7 +112,7 @@ bool NativeWindowDrmGbm::UpdateCursor(const std::string& cursor_name, double x, gbm_bo_get_handle(gbm_cursor_bo_).u32, kCursorBufferWidth, kCursorBufferHeight); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; return false; } return true; @@ -121,7 +121,7 @@ bool NativeWindowDrmGbm::UpdateCursor(const std::string& cursor_name, double x, bool NativeWindowDrmGbm::DismissCursor() { auto result = drmModeSetCursor(drm_device_, drm_crtc_->crtc_id, 0, 0, 0); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to set cursor buffer. (" << result << ")"; return false; } return true; @@ -138,7 +138,7 @@ bool NativeWindowDrmGbm::IsNeedRecreateSurfaceAfterResize() const { bool NativeWindowDrmGbm::Resize(const size_t width, const size_t height) { if (!valid_) { - LINUXES_LOG(ERROR) << "Failed to resize the window."; + ELINUX_LOG(ERROR) << "Failed to resize the window."; return false; } @@ -148,7 +148,7 @@ bool NativeWindowDrmGbm::Resize(const size_t width, const size_t height) { return false; } - LINUXES_LOG(INFO) << "resize: " << width << "x" << height; + ELINUX_LOG(INFO) << "resize: " << width << "x" << height; drmModeRmFB(drm_device_, gbm_previous_fb_); gbm_surface_release_buffer(static_cast(window_), gbm_previous_bo_); @@ -171,12 +171,12 @@ void NativeWindowDrmGbm::SwapBuffers() { int result = drmModeAddFB(drm_device_, width, height, 24, 32, stride, handle, &fb); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to add a framebuffer. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to add a framebuffer. (" << result << ")"; } result = drmModeSetCrtc(drm_device_, drm_crtc_->crtc_id, fb, 0, 0, &drm_connector_id_, 1, &drm_mode_info_); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to set crct mode. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to set crct mode. (" << result << ")"; } if (gbm_previous_bo_) { @@ -193,7 +193,7 @@ bool NativeWindowDrmGbm::CreateGbmSurface() { drm_mode_info_.vdisplay, GBM_FORMAT_ARGB8888, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (!window_) { - LINUXES_LOG(ERROR) << "Failed to create the gbm surface."; + ELINUX_LOG(ERROR) << "Failed to create the gbm surface."; valid_ = false; return false; } @@ -201,7 +201,7 @@ bool NativeWindowDrmGbm::CreateGbmSurface() { window_offscreen_ = gbm_surface_create(gbm_device_, 1, 1, GBM_FORMAT_ARGB8888, GBM_BO_USE_RENDERING); if (!window_offscreen_) { - LINUXES_LOG(ERROR) << "Failed to create the gbm surface for offscreen."; + ELINUX_LOG(ERROR) << "Failed to create the gbm surface for offscreen."; return false; } @@ -214,7 +214,7 @@ bool NativeWindowDrmGbm::CreateCursorBuffer(const std::string& cursor_name) { kCursorBufferHeight, GBM_FORMAT_ARGB8888, GBM_BO_USE_CURSOR | GBM_BO_USE_WRITE); if (!gbm_cursor_bo_) { - LINUXES_LOG(ERROR) << "Failed to create cursor buffer"; + ELINUX_LOG(ERROR) << "Failed to create cursor buffer"; return false; } } @@ -228,7 +228,7 @@ bool NativeWindowDrmGbm::CreateCursorBuffer(const std::string& cursor_name) { auto result = gbm_bo_write(gbm_cursor_bo_, buf, sizeof(buf)); if (result != 0) { - LINUXES_LOG(ERROR) << "Failed to write cursor data. (" << result << ")"; + ELINUX_LOG(ERROR) << "Failed to write cursor data. (" << result << ")"; return false; } return true; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc index 5a40621f..6f5aa398 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc @@ -13,28 +13,31 @@ NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, const size_t height) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { - LINUXES_LOG(ERROR) << "Failed to create the compositor surface."; + ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; return; } window_ = wl_egl_window_create(surface_, width, height); if (!window_) { - LINUXES_LOG(ERROR) << "Failed to create the EGL window."; + ELINUX_LOG(ERROR) << "Failed to create the EGL window."; return; } // The offscreen (resource) surface will not be mapped, but needs to be a // wl_surface because ONLY window EGL surfaces are supported on Wayland. - surface_offscreen_ = wl_compositor_create_surface(compositor); - if (!surface_offscreen_) { - LINUXES_LOG(ERROR) << "Failed to create the compositor surface for off-screen."; - return; - } + { + surface_offscreen_ = wl_compositor_create_surface(compositor); + if (!surface_offscreen_) { + ELINUX_LOG(ERROR) + << "Failed to create the compositor surface for off-screen."; + return; + } - window_offscreen_ = wl_egl_window_create(surface_offscreen_, 1, 1); - if (!window_offscreen_) { - LINUXES_LOG(ERROR) << "Failed to create the EGL window for offscreen."; - return; + window_offscreen_ = wl_egl_window_create(surface_offscreen_, 1, 1); + if (!window_offscreen_) { + ELINUX_LOG(ERROR) << "Failed to create the EGL window for offscreen."; + return; + } } width_ = width; @@ -66,7 +69,7 @@ NativeWindowWayland::~NativeWindowWayland() { bool NativeWindowWayland::Resize(const size_t width, const size_t height) { if (!valid_) { - LINUXES_LOG(ERROR) << "Failed to resize the window."; + ELINUX_LOG(ERROR) << "Failed to resize the window."; return false; } wl_egl_window_resize(window_, width, height, 0, 0); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc index 883626c3..310d7b47 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc @@ -28,7 +28,7 @@ NativeWindowX11::NativeWindowX11(Display* display, VisualID visual_id, auto* visual = XGetVisualInfo(display, VisualIDMask, &visualTemplate, &visualsCount); if (!visual) { - LINUXES_LOG(ERROR) << "Failed to get Visual info."; + ELINUX_LOG(ERROR) << "Failed to get Visual info."; return; } @@ -46,7 +46,7 @@ NativeWindowX11::NativeWindowX11(Display* display, VisualID visual_id, height, 0, visual->depth, InputOutput, visual->visual, CWBorderPixel | CWColormap | CWEventMask, &windowAttribs); if (!window_) { - LINUXES_LOG(ERROR) << "Failed to the create window."; + ELINUX_LOG(ERROR) << "Failed to the create window."; return; } From cf38b6d2533a5bd2da441d9701082cd34a69ce4e Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 11 Jun 2021 14:56:52 +0900 Subject: [PATCH 022/178] Update LICENSE: correction leakage (#169) --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1d33397b..9feb6cc7 100644 --- a/LICENSE +++ b/LICENSE @@ -9,7 +9,7 @@ are permitted provided that the following conditions are met: copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - * Neither the name of Google Inc. nor the names of its + * Neither the name of the Flutter Authors nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. From 85212c20b65af6abf3e7839698d01081ab6440e4 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 12 Jun 2021 06:19:05 +0900 Subject: [PATCH 023/178] Migrate meta-flutter to another repo (#170) --- meta-flutter/README.md | 113 ------------------ meta-flutter/conf/layer.conf | 12 -- .../flutter-embedded-linux/dependency.inc | 7 -- .../flutter-drm-eglstream-backend.bb | 20 ---- .../flutter-drm-gbm-backend.bb | 20 ---- .../flutter-wayland-client.bb | 18 --- .../flutter-embedded-linux/repository.inc | 11 -- .../flutter-embedded-linux/tasks.inc | 7 -- .../flutter-engine/flutter-engine.bb | 73 ----------- .../flutter-engine/gn-args-utils.inc | 12 -- 10 files changed, 293 deletions(-) delete mode 100644 meta-flutter/README.md delete mode 100644 meta-flutter/conf/layer.conf delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/dependency.inc delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-eglstream-backend.bb delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-gbm-backend.bb delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-wayland-client.bb delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/repository.inc delete mode 100644 meta-flutter/recipes-graphics/flutter-embedded-linux/tasks.inc delete mode 100755 meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb delete mode 100755 meta-flutter/recipes-graphics/flutter-engine/gn-args-utils.inc diff --git a/meta-flutter/README.md b/meta-flutter/README.md deleted file mode 100644 index 5f2949d2..00000000 --- a/meta-flutter/README.md +++ /dev/null @@ -1,113 +0,0 @@ -# meta-flutter for Yocto Project -Recipe file examples for Yocto Project. In this README, we explain how to build for Arm64 using `core-image-weston` which is one of Yocto Images, and `dunfell` which is one of LTS Yocto versions. See also: https://docs.yoctoproject.org/ - - -## Setup environment -There are two ways to build using Yocto. One is a build using bitbake and the other is a build using Yocto SDK. - -### Building Yocto -Downloading `Poky` and `meta-clang`, `meta-flutter` source code: -```Shell -$ git clone git://git.yoctoproject.org/poky.git -b dunfell -$ git clone https://github.com/kraj/meta-clang -b dunfell -$ git clone https://github.com/sony/flutter-embedded-linux.git -``` - -Setup the build environment using `oe-init-build-env` script in Poky. -```Shell -$ source poky/oe-init-build-env build -``` - -Set your target machine in your `conf/local.conf`: -``` -MACHINE ?= "qemuarm64" -``` - -Add meta-clang layer into `conf/bblayers.conf`. -```Shell -$ bitbake-layers add-layer ../meta-clang -``` - -Add meta-flutter layer into `conf/bblayers.conf`. -```Shell -$ bitbake-layers add-layer ../flutter-embedded-linux/meta-flutter -``` - -### Building Yocto SDK (Only when using cross-building with Yocto SDK) -Add the following in your `conf/local.conf`: -``` -CLANGSDK = "1" -``` -See also: [Adding clang in generated SDK toolchain](https://github.com/kraj/meta-clang/blob/master/README.md#adding-clang-in-generated-sdk-toolchain) - -Build Yocto SDK for cross-building. -```Shell -$ bitbake core-image-weston -c populate_sdk -``` -See also: [SDK building an sdk installer](https://www.yoctoproject.org/docs/2.1/sdk-manual/sdk-manual.html#sdk-building-an-sdk-installer) - -Install Yocto SDK. -```Shell -$ ./tmp/deploy/sdk/poky-glibc-x86_64-core-image-weston-aarch64-qemuarm64-toolchain-3.1.7.sh -``` - -## Cross-building with bitbake -### Flutter Engine (libflutter_engine.so) -Build target is fixed to Linux and Arm64, and Flutter Engine version is also fixed in the recipe file. - -#### Flutter Engine version -``` -ENGINE_VERSION ?= "f5b97d0b23a3905e9b5b69aa873afcb52f550aaf" -``` - -When creating a Flutter project, you will need to use the following version of the Flutter SDK. -`Flutter 2.3.0-1.0.pre.269` - -If you want to change the version of the Flutter engine, change to the appropriate version of the Flutter SDK and add the following to `conf/local.conf`: -``` -ENGINE_VERSION_pn-flutter-engine = "" -``` - -Flutter Engine is built with release mode by default. If you want to change the build mode, you can change it to add the following in your `conf/local.conf`: -#### Flutter Engine mode -``` -# e.g. debug mode -PACKAGECONFIG_pn-flutter-engine = "debug-mode" -``` - -### Wayland backend -```Shell -$ bitbake flutter-wayland-client -``` - -### DRM-GBM backend -`libsystemd` is required to build this backend. Put the following in your `conf/local.conf`: -``` -DESTRO_FEATURES_append = " systemd" -``` -See also: [Using systemd for the Main Image and Using SysVinit for the Rescue Image](https://www.yoctoproject.org/docs/current/mega-manual/mega-manual.html#using-systemd-for-the-main-image-and-using-sysvinit-for-the-rescue-image) - -```Shell -$ bitbake flutter-drm-gbm-backend -``` - -### DRM-EGLStream backend -You need to install libsystemd in the same way with the DRM-GBM backend. - -```Shell -$ bitbake flutter-drm-eglstream-backend -``` - -## Cross-building with Yocto SDK -Setup the cross-building toolchain environment using a script that you built and installed. -```Shell -$ source /opt/poky/3.1.7/environment-setup-aarch64-poky-linux -``` - -Set the following environment vars to cross-build using clang. -```Shell -$ export CC=${CLANGCC} -$ export CXX=${CLANGCXX} -``` - -After doing that, you can build the embedder as normal like self-building on hosts. It means you don't need to be aware of cross-building. See: [self-build](https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#self-build) diff --git a/meta-flutter/conf/layer.conf b/meta-flutter/conf/layer.conf deleted file mode 100644 index d64bfcc3..00000000 --- a/meta-flutter/conf/layer.conf +++ /dev/null @@ -1,12 +0,0 @@ -# We have a conf and classes directory, add to BBPATH -BBPATH .= ":${LAYERDIR}" - -# We have recipes-* directories, add to BBFILES -BBFILES += "${LAYERDIR}/recipes-*/*/*.bb \ - ${LAYERDIR}/recipes-*/*/*.bbappend" - -BBFILE_COLLECTIONS += "meta-flutter" -BBFILE_PATTERN_meta-flutter = "^${LAYERDIR}/" -BBFILE_PRIORITY_meta-flutter = "6" - -LAYERDEPENDS_meta-flutter = "core" diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/dependency.inc b/meta-flutter/recipes-graphics/flutter-embedded-linux/dependency.inc deleted file mode 100644 index 0a76c8e3..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/dependency.inc +++ /dev/null @@ -1,7 +0,0 @@ -TOOLCHAIN = "clang" -DEPENDS += "libxkbcommon \ - virtual/libgles2 \ - virtual/egl \ - flutter-engine" - -inherit pkgconfig cmake features_check diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-eglstream-backend.bb b/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-eglstream-backend.bb deleted file mode 100644 index 00d7c150..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-eglstream-backend.bb +++ /dev/null @@ -1,20 +0,0 @@ -SUMMARY = "Flutter embedding for embedded Linux with DRM-EGLStream backend" -DESCRIPTION = "Build the flutter-drm-eglstream-backend project" - -require repository.inc -require dependency.inc - -DEPENDS += "libdrm \ - virtual/mesa \ - libinput \ - udev \ - systemd" - -EXTRA_OECMAKE = "-DUSER_PROJECT_PATH=examples/flutter-drm-eglstream-backend" - -do_install() { - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/build/flutter-drm-eglstream-backend ${D}${bindir} -} - -require tasks.inc diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-gbm-backend.bb b/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-gbm-backend.bb deleted file mode 100644 index b43b522c..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-drm-gbm-backend.bb +++ /dev/null @@ -1,20 +0,0 @@ -SUMMARY = "Flutter embedding for embedded Linux with DRM-GBM backend" -DESCRIPTION = "Build the flutter-drm-gbm-backend project" - -require repository.inc -require dependency.inc - -DEPENDS += "libdrm \ - virtual/mesa \ - libinput \ - udev \ - systemd" - -EXTRA_OECMAKE = "-DUSER_PROJECT_PATH=examples/flutter-drm-gbm-backend" - -do_install() { - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/build/flutter-drm-gbm-backend ${D}${bindir} -} - -require tasks.inc diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-wayland-client.bb b/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-wayland-client.bb deleted file mode 100644 index 5120aeb2..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/flutter-wayland-client.bb +++ /dev/null @@ -1,18 +0,0 @@ -SUMMARY = "Flutter embedding for embedded Linux with Wayland backend" -DESCRIPTION = "Build the flutter-wayland-client project" - -require repository.inc -require dependency.inc - -DEPENDS += "wayland \ - wayland-protocols \ - wayland-native" - -EXTRA_OECMAKE = "-DUSER_PROJECT_PATH=examples/flutter-wayland-client" - -do_install() { - install -d ${D}${bindir} - install -m 0755 ${WORKDIR}/build/flutter-client ${D}${bindir} -} - -require tasks.inc diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/repository.inc b/meta-flutter/recipes-graphics/flutter-embedded-linux/repository.inc deleted file mode 100644 index 2387d0cd..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/repository.inc +++ /dev/null @@ -1,11 +0,0 @@ -AUTHOR = "Sony Group Corporation" -HOMEPAGE = "https://github.com/sony/flutter-embedded-linux" -BUGTRACKER = "https://github.com/sony/flutter-embedded-linux/issues" - -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://LICENSE;md5=79ca841e7b9e09b0401186f2aa334adf" - -SRC_URI = "git://github.com/sony/flutter-embedded-linux.git;protocol=https" -SRCREV = "${AUTOREV}" -S = "${WORKDIR}/git" - diff --git a/meta-flutter/recipes-graphics/flutter-embedded-linux/tasks.inc b/meta-flutter/recipes-graphics/flutter-embedded-linux/tasks.inc deleted file mode 100644 index bcd8096c..00000000 --- a/meta-flutter/recipes-graphics/flutter-embedded-linux/tasks.inc +++ /dev/null @@ -1,7 +0,0 @@ -do_configure_prepend() { - install -d ${S}/build - install -m 0644 ${STAGING_LIBDIR}/libflutter_engine.so ${S}/build/ -} -do_configure_prepend[depends] += "flutter-engine:do_populate_sysroot" - -FILES_${PN} = "${bindir}" diff --git a/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb b/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb deleted file mode 100755 index fcd4cf51..00000000 --- a/meta-flutter/recipes-graphics/flutter-engine/flutter-engine.bb +++ /dev/null @@ -1,73 +0,0 @@ -AUTHOR = "Sony Group Corporation" -LICENSE = "BSD-3-Clause" -LIC_FILES_CHKSUM = "file://LICENSE;md5=c2c05f9bdd5fc0b458037c2d1fb8d95e" - -SRC_URI = "git://chromium.googlesource.com/chromium/tools/depot_tools.git;protocol=https" -SRCREV = "da768751d43b1f287bf99bea703ea13e2eedcf4d" - -S = "${WORKDIR}/git" - -inherit pkgconfig -# TODO: Add dependent packages. -DEPENDS = "freetype" - -GN_TOOLS_PYTHON2_PATH ??= "bootstrap-3.8.0.chromium.8_bin/python/bin" - -require gn-args-utils.inc - -ENGINE_VERSION ?= "f5b97d0b23a3905e9b5b69aa873afcb52f550aaf" -PACKAGECONFIG ?= "release-mode" -PACKAGECONFIG[debug-mode] = "--runtime-mode debug --unoptimized" -PACKAGECONFIG[profile-mode] = "--runtime-mode profile --no-lto" -PACKAGECONFIG[release-mode] = "--runtime-mode release" - -GN_TARGET_OS = "linux" -GN_TARGET_ARCH = "arm64" - -GN_ARGS = "--target-sysroot ${STAGING_DIR_TARGET}${PACKAGECONFIG_CONFARGS}" -GN_ARGS_append = " --target-os ${GN_TARGET_OS}" -GN_ARGS_append = " --linux-cpu ${GN_TARGET_ARCH}" -GN_ARGS_append = " --embedder-for-target" -GN_ARGS_append = " --disable-desktop-embeddings" -ARTIFACT_DIR = "${@get_engine_artifact_dir(d)}" - -do_configure() { - # To disable auto update. - export DEPOT_TOOLS_UPDATE=0 - export PATH=${S}:${S}/${GN_TOOLS_PYTHON2_PATH}:$PATH - - cd ${WORKDIR} - echo 'solutions = [ - { - "managed" : False, - "name" : "src/flutter", - "url" : "https://github.com/flutter/engine.git@$%7BENGINE_VERSION%7D", - "custom_deps": {}, - "deps_file": "DEPS", - "safesync_url": "", - "custom_vars": { - "download_android_deps": False, - "download_windows_deps": False, - }, - }, - ]' > .gclient - gclient sync - - cd ${WORKDIR}/src - ./flutter/tools/gn ${GN_ARGS} -} - -do_compile() { - export PATH=${S}:${S}/${GN_TOOLS_PYTHON2_PATH}:$PATH - - cd ${WORKDIR}/src - ninja -C ${ARTIFACT_DIR} -} - -do_install() { - install -d ${D}${libdir} - install -m 0755 ${WORKDIR}/src/${ARTIFACT_DIR}/libflutter_engine.so ${D}${libdir} -} - -FILES_${PN} = "${libdir}" -FILES_${PN}-dev = "${includedir}" diff --git a/meta-flutter/recipes-graphics/flutter-engine/gn-args-utils.inc b/meta-flutter/recipes-graphics/flutter-engine/gn-args-utils.inc deleted file mode 100755 index e0c17587..00000000 --- a/meta-flutter/recipes-graphics/flutter-engine/gn-args-utils.inc +++ /dev/null @@ -1,12 +0,0 @@ -def get_engine_artifact_dir(d): - gn_args = d.getVar("GN_ARGS") - - artifact_dir = 'out/' - if 'debug' in gn_args: - artifact_dir += 'linux_debug_unopt_arm64' - elif 'profile' in gn_args: - artifact_dir += 'linux_profile_arm64' - else: - artifact_dir += 'linux_release_arm64' - - return artifact_dir \ No newline at end of file From 85e1fe598642b45644d592c537a3edf82402a1a5 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 15 Jun 2021 11:17:50 +0900 Subject: [PATCH 024/178] Refactoring: change from linuxes to elinux - step1 (#171) --- cmake/build.cmake | 6 +++--- .../platform/linux_embedded/surface/context_egl.cc | 12 ++++++------ .../platform/linux_embedded/surface/context_egl.h | 6 +++--- .../linux_embedded/surface/context_egl_stream.cc | 6 +++--- .../linux_embedded/surface/context_egl_stream.h | 4 ++-- ...inuxes_egl_surface.cc => elinux_egl_surface.cc} | 14 +++++++------- ...{linuxes_egl_surface.h => elinux_egl_surface.h} | 12 ++++++------ .../surface/{linuxes_surface.cc => surface.cc} | 2 +- .../surface/{linuxes_surface.h => surface.h} | 6 +++--- .../{linuxes_surface_gl.cc => surface_gl.cc} | 2 +- .../surface/{linuxes_surface_gl.h => surface_gl.h} | 4 ++-- ...surface_gl_delegate.h => surface_gl_delegate.h} | 0 .../linux_embedded/window/linuxes_window_drm.h | 2 +- .../linux_embedded/window/linuxes_window_wayland.h | 2 +- .../linux_embedded/window/linuxes_window_x11.h | 2 +- .../linux_embedded/window/native_window_drm.h | 2 +- .../linux_embedded/window_binding_handler.h | 2 +- 17 files changed, 42 insertions(+), 42 deletions(-) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_egl_surface.cc => elinux_egl_surface.cc} (70%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_egl_surface.h => elinux_egl_surface.h} (56%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_surface.cc => surface.cc} (95%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_surface.h => surface.h} (86%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_surface_gl.cc => surface_gl.cc} (91%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_surface_gl.h => surface_gl.h} (86%) rename src/flutter/shell/platform/linux_embedded/surface/{linuxes_surface_gl_delegate.h => surface_gl_delegate.h} (100%) diff --git a/cmake/build.cmake b/cmake/build.cmake index 72f2ce15..ad5a616f 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -118,9 +118,9 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc src/flutter/shell/platform/linux_embedded/surface/context_egl.cc src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc - src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc - src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc - src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.cc + src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc + src/flutter/shell/platform/linux_embedded/surface/surface.cc + src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc ${DISPLAY_BACKEND_SRC} ${WAYLAND_PROTOCOL_SRC} ## The following file were copied from: diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index c3c41a86..85c4a31e 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -60,7 +60,7 @@ ContextEgl::ContextEgl(std::unique_ptr environment, valid_ = true; } -std::unique_ptr ContextEgl::CreateOnscreenSurface( +std::unique_ptr ContextEgl::CreateOnscreenSurface( NativeWindow* window) const { const EGLint attribs[] = {EGL_NONE}; EGLSurface surface = eglCreateWindowSurface(environment_->Display(), config_, @@ -69,11 +69,11 @@ std::unique_ptr ContextEgl::CreateOnscreenSurface( ELINUX_LOG(ERROR) << "Failed to create EGL window surface: " << get_egl_error_cause(); } - return std::make_unique(surface, environment_->Display(), - context_); + return std::make_unique(surface, environment_->Display(), + context_); } -std::unique_ptr ContextEgl::CreateOffscreenSurface( +std::unique_ptr ContextEgl::CreateOffscreenSurface( NativeWindow* window) const { #if defined(DISPLAY_BACKEND_TYPE_X11) || \ defined(DISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) @@ -101,8 +101,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( << "(" << get_egl_error_cause() << ")"; } #endif - return std::make_unique(surface, environment_->Display(), - resource_context_); + return std::make_unique(surface, environment_->Display(), + resource_context_); } bool ContextEgl::IsValid() const { return valid_; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.h b/src/flutter/shell/platform/linux_embedded/surface/context_egl.h index d4cadf3c..b443e191 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.h @@ -9,8 +9,8 @@ #include +#include "flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h" #include "flutter/shell/platform/linux_embedded/surface/environment_egl.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h" #include "flutter/shell/platform/linux_embedded/window/native_window.h" namespace flutter { @@ -21,10 +21,10 @@ class ContextEgl { EGLint egl_surface_type = EGL_WINDOW_BIT); ~ContextEgl() = default; - virtual std::unique_ptr CreateOnscreenSurface( + virtual std::unique_ptr CreateOnscreenSurface( NativeWindow* window) const; - std::unique_ptr CreateOffscreenSurface( + std::unique_ptr CreateOffscreenSurface( NativeWindow* window_resource) const; bool IsValid() const; diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc index aa654996..40822ccb 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc @@ -22,7 +22,7 @@ ContextEglStream::ContextEglStream( } } -std::unique_ptr ContextEglStream::CreateOnscreenSurface( +std::unique_ptr ContextEglStream::CreateOnscreenSurface( NativeWindow* window) const { EGLint layer_count = 0; EGLOutputLayerEXT layer; @@ -64,8 +64,8 @@ std::unique_ptr ContextEglStream::CreateOnscreenSurface( if (surface == EGL_NO_SURFACE) { ELINUX_LOG(ERROR) << "Failed to create EGL stream producer surface"; } - return std::make_unique(surface, environment_->Display(), - context_); + return std::make_unique(surface, environment_->Display(), + context_); } bool ContextEglStream::SetEglExtensionFunctionPointers() { diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.h b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.h index a360022d..4727bb81 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.h +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.h @@ -9,8 +9,8 @@ #include #include "flutter/shell/platform/linux_embedded/surface/context_egl.h" +#include "flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h" #include "flutter/shell/platform/linux_embedded/surface/environment_egl_stream.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h" namespace flutter { @@ -20,7 +20,7 @@ class ContextEglStream : public ContextEgl { ~ContextEglStream() = default; // |ContextEgl| - std::unique_ptr CreateOnscreenSurface( + std::unique_ptr CreateOnscreenSurface( NativeWindow* window) const override; private: diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc similarity index 70% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc rename to src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 88a20d3c..fc77eeb6 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h" +#include "flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h" #include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/surface/egl_utils.h" namespace flutter { -LinuxesEGLSurface::LinuxesEGLSurface(EGLSurface surface, EGLDisplay display, - EGLContext context) +ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, + EGLContext context) : surface_(surface), display_(display), context_(context){}; -LinuxesEGLSurface::~LinuxesEGLSurface() { +ELinuxEGLSurface::~ELinuxEGLSurface() { if (surface_ != EGL_NO_SURFACE) { if (eglDestroySurface(display_, surface_) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to destory surface"; @@ -22,9 +22,9 @@ LinuxesEGLSurface::~LinuxesEGLSurface() { } } -bool LinuxesEGLSurface::IsValid() const { return surface_ != EGL_NO_SURFACE; } +bool ELinuxEGLSurface::IsValid() const { return surface_ != EGL_NO_SURFACE; } -bool LinuxesEGLSurface::MakeCurrent() const { +bool ELinuxEGLSurface::MakeCurrent() const { if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to make the EGL context current: " << get_egl_error_cause(); @@ -33,7 +33,7 @@ bool LinuxesEGLSurface::MakeCurrent() const { return true; } -bool LinuxesEGLSurface::SwapBuffers() const { +bool ELinuxEGLSurface::SwapBuffers() const { if (eglSwapBuffers(display_, surface_) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to swap the EGL buffer: " << get_egl_error_cause(); diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h similarity index 56% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h rename to src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h index e7105b9a..452a7df7 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h @@ -2,18 +2,18 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_LINUXES_EGL_SURFACE_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_LINUXES_EGL_SURFACE_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ELINUX_EGL_SURFACE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ELINUX_EGL_SURFACE_H_ #include namespace flutter { -class LinuxesEGLSurface { +class ELinuxEGLSurface { public: // Note that EGLSurface will be destroyed in this class's destructor. - LinuxesEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context); - ~LinuxesEGLSurface(); + ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context); + ~ELinuxEGLSurface(); bool IsValid() const; @@ -29,4 +29,4 @@ class LinuxesEGLSurface { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_LINUXES_EGL_SURFACE_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ELINUX_EGL_SURFACE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/surface.cc similarity index 95% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc rename to src/flutter/shell/platform/linux_embedded/surface/surface.cc index 81a92e56..d67e5f72 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface.h" +#include "flutter/shell/platform/linux_embedded/surface/surface.h" #include "flutter/shell/platform/linux_embedded/logger.h" diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.h b/src/flutter/shell/platform/linux_embedded/surface/surface.h similarity index 86% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.h rename to src/flutter/shell/platform/linux_embedded/surface/surface.h index a01168f0..0612b685 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface.h @@ -8,7 +8,7 @@ #include #include "flutter/shell/platform/linux_embedded/surface/context_egl.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_egl_surface.h" +#include "flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h" #include "flutter/shell/platform/linux_embedded/window/native_window.h" namespace flutter { @@ -39,8 +39,8 @@ class Surface { protected: std::unique_ptr context_; NativeWindow* native_window_ = nullptr; - std::unique_ptr onscreen_surface_ = nullptr; - std::unique_ptr offscreen_surface_ = nullptr; + std::unique_ptr onscreen_surface_ = nullptr; + std::unique_ptr offscreen_surface_ = nullptr; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc similarity index 91% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.cc rename to src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc index 225e1064..314c5025 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h similarity index 86% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h rename to src/flutter/shell/platform/linux_embedded/surface/surface_gl.h index c38b65ee..79e78271 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h @@ -8,8 +8,8 @@ #include #include "flutter/shell/platform/linux_embedded/surface/context_egl.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl_delegate.h" +#include "flutter/shell/platform/linux_embedded/surface/surface.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl_delegate.h b/src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h similarity index 100% rename from src/flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl_delegate.h rename to src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h index d7642d6b..c159f839 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h @@ -14,7 +14,7 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_drm.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h index 6ed2f11b..89907122 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h @@ -12,7 +12,7 @@ #include #include -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_wayland.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h index 86fe9697..34f3fa21 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h @@ -7,7 +7,7 @@ #include -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_x11.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index ebaf8c9a..e2c96270 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -9,7 +9,7 @@ #include -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/native_window.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 463f6452..74ed1cda 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -9,7 +9,7 @@ #include #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" -#include "flutter/shell/platform/linux_embedded/surface/linuxes_surface_gl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" namespace flutter { From e8a0f426f9b673e58c8e83b257862de22ff6e0f9 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 16 Jun 2021 09:12:54 +0900 Subject: [PATCH 025/178] Refactoring: change from linuxes to elinux - step2 (#172) --- cmake/build.cmake | 4 +- .../linux_embedded/flutter_linuxes.cc | 16 +- .../{linuxes_window.h => elinux_window.h} | 12 +- ...nuxes_window_drm.h => elinux_window_drm.h} | 20 +-- ...ow_wayland.cc => elinux_window_wayland.cc} | 148 +++++++++--------- ...ndow_wayland.h => elinux_window_wayland.h} | 16 +- ...xes_window_x11.cc => elinux_window_x11.cc} | 39 +++-- ...nuxes_window_x11.h => elinux_window_x11.h} | 16 +- 8 files changed, 135 insertions(+), 136 deletions(-) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window.h => elinux_window.h} (68%) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window_drm.h => elinux_window_drm.h} (97%) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window_wayland.cc => elinux_window_wayland.cc} (88%) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window_wayland.h => elinux_window_wayland.h} (90%) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window_x11.cc => elinux_window_x11.cc} (79%) rename src/flutter/shell/platform/linux_embedded/window/{linuxes_window_x11.h => elinux_window_x11.h} (80%) diff --git a/cmake/build.cmake b/cmake/build.cmake index ad5a616f..0cda9202 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -31,7 +31,7 @@ elseif(${BACKEND_TYPE} STREQUAL "DRM-EGLSTREAM") elseif(${BACKEND_TYPE} STREQUAL "X11") add_definitions(-DDISPLAY_BACKEND_TYPE_X11) set(DISPLAY_BACKEND_SRC - src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc + src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc) else() include(cmake/generate_wayland_protocols.cmake) @@ -64,7 +64,7 @@ else() ${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c ${_wayland_protocols_src_dir}/presentation-time-protocol.c - src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc + src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc) endif() diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc index 531e6a29..5af1258c 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc @@ -17,15 +17,15 @@ #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" #if defined(DISPLAY_BACKEND_TYPE_DRM_GBM) -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_drm.h" #include "flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h" #elif defined(DISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_drm.h" #include "flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h" #elif defined(DISPLAY_BACKEND_TYPE_X11) -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_x11.h" #else -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h" #endif static_assert(FLUTTER_ENGINE_VERSION == 1, ""); @@ -77,16 +77,16 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( std::unique_ptr window_wrapper = #if defined(DISPLAY_BACKEND_TYPE_DRM_GBM) - std::make_unique>( + std::make_unique>( view_properties); #elif defined(DISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) std::make_unique< - flutter::LinuxesWindowDrm>( + flutter::ELinuxWindowDrm>( view_properties); #elif defined(DISPLAY_BACKEND_TYPE_X11) - std::make_unique(view_properties); + std::make_unique(view_properties); #else - std::make_unique(view_properties); + std::make_unique(view_properties); #endif auto state = std::make_unique(); diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h similarity index 68% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window.h rename to src/flutter/shell/platform/linux_embedded/window/elinux_window.h index 874f661b..b4360708 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ #include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" namespace flutter { -class LinuxesWindow { +class ELinuxWindow { public: - LinuxesWindow() = default; - virtual ~LinuxesWindow() = default; + ELinuxWindow() = default; + virtual ~ELinuxWindow() = default; protected: virtual bool IsValid() const = 0; @@ -30,4 +30,4 @@ class LinuxesWindow { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h similarity index 97% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h rename to src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index c159f839..3c6b8a37 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_DRM_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_DRM_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_DRM_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_DRM_H_ #include #include @@ -15,7 +15,7 @@ #include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" -#include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_drm.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" @@ -27,9 +27,9 @@ constexpr char kDrmDeviceDefaultFilename[] = "/dev/dri/card0"; } // namespace template -class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { +class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { public: - LinuxesWindowDrm(FlutterDesktopViewProperties view_properties) + ELinuxWindowDrm(FlutterDesktopViewProperties view_properties) : display_valid_(false), is_pending_cursor_add_event_(false) { view_properties_ = view_properties; @@ -68,7 +68,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { } } - ~LinuxesWindowDrm() { + ~ELinuxWindowDrm() { if (udev_drm_event_loop_) { sd_event_unref(udev_drm_event_loop_); } @@ -84,7 +84,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { display_valid_ = false; } - // |LinuxesWindow| + // |ELinuxWindow| bool IsValid() const override { if (!display_valid_ || !native_window_ || !render_surface_ || !native_window_->IsValid() || !render_surface_->IsValid()) { @@ -277,7 +277,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { static int OnUdevDrmEvent(sd_event_source* source, int fd, uint32_t revents, void* data) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); auto device = udev_monitor_receive_device(self->udev_monitor_); if (!device) { ELINUX_LOG(ERROR) << "Failed to receive udev device."; @@ -328,7 +328,7 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { static int OnLibinputEvent(sd_event_source* source, int fd, uint32_t revents, void* data) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); auto ret = libinput_dispatch(self->libinput_); if (ret < 0) { ELINUX_LOG(ERROR) << "Failed to dispatch libinput events."; @@ -608,4 +608,4 @@ class LinuxesWindowDrm : public LinuxesWindow, public WindowBindingHandler { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_DRM_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_DRM_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc similarity index 88% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc rename to src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 98541568..821706e3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h" #include #include @@ -42,43 +42,43 @@ constexpr char kCursorNameNone[] = "none"; constexpr char kClipboardMimeTypeText[] = "text/plain"; } // namespace -const wl_registry_listener LinuxesWindowWayland::kWlRegistryListener = { +const wl_registry_listener ELinuxWindowWayland::kWlRegistryListener = { .global = [](void* data, wl_registry* wl_registry, uint32_t name, const char* interface, uint32_t version) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->WlRegistryHandler(wl_registry, name, interface, version); }, .global_remove = [](void* data, wl_registry* wl_registry, uint32_t name) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->WlUnRegistryHandler(wl_registry, name); }, }; -const xdg_wm_base_listener LinuxesWindowWayland::kXdgWmBaseListener = { +const xdg_wm_base_listener ELinuxWindowWayland::kXdgWmBaseListener = { .ping = [](void* data, xdg_wm_base* xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); }, }; -const xdg_surface_listener LinuxesWindowWayland::kXdgSurfaceListener = { +const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { .configure = [](void* data, xdg_surface* xdg_surface, uint32_t serial) { xdg_surface_ack_configure(xdg_surface, serial); }, }; -const wp_presentation_listener LinuxesWindowWayland::kWpPresentationListener = { +const wp_presentation_listener ELinuxWindowWayland::kWpPresentationListener = { .clock_id = [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->wp_presentation_clk_id_ = clk_id; ELINUX_LOG(TRACE) << "presentation info: clk_id = " << clk_id; }, }; const wp_presentation_feedback_listener - LinuxesWindowWayland::kWpPresentationFeedbackListener = { + ELinuxWindowWayland::kWpPresentationFeedbackListener = { .sync_output = [](void* data, struct wp_presentation_feedback* wp_presentation_feedback, @@ -89,7 +89,7 @@ const wp_presentation_feedback_listener uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec, uint32_t refresh, uint32_t seq_hi, uint32_t seq_lo, uint32_t flags) { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->last_frame_time_nanos_ = (((static_cast(tv_sec_hi) << 32) + tv_sec_lo) * 1000000000) + @@ -102,12 +102,12 @@ const wp_presentation_feedback_listener struct wp_presentation_feedback* wp_presentation_feedback) {}, }; -const wl_callback_listener LinuxesWindowWayland::kWlSurfaceFrameListener = { +const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { .done = [](void* data, wl_callback* wl_callback, uint32_t time) { // The presentation-time is an extended protocol and isn't supported // by all compositors. This path is for when it wasn't supported. - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->wp_presentation_clk_id_ != UINT32_MAX) { return; } @@ -120,9 +120,9 @@ const wl_callback_listener LinuxesWindowWayland::kWlSurfaceFrameListener = { }, }; -const wl_seat_listener LinuxesWindowWayland::kWlSeatListener = { +const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { .capabilities = [](void* data, wl_seat* seat, uint32_t caps) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if ((caps & WL_SEAT_CAPABILITY_POINTER) && !self->wl_pointer_) { self->wl_pointer_ = wl_seat_get_pointer(seat); @@ -151,11 +151,11 @@ const wl_seat_listener LinuxesWindowWayland::kWlSeatListener = { }, }; -const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { +const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { .enter = [](void* data, wl_pointer* wl_pointer, uint32_t serial, wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->view_properties_.use_mouse_cursor) { self->cursor_info_.pointer = wl_pointer; @@ -172,7 +172,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { }, .leave = [](void* data, wl_pointer* pointer, uint32_t serial, wl_surface* surface) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnPointerLeave(); @@ -182,7 +182,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { }, .motion = [](void* data, wl_pointer* pointer, uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); double y = wl_fixed_to_double(surface_y); @@ -193,7 +193,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { }, .button = [](void* data, wl_pointer* pointer, uint32_t serial, uint32_t time, uint32_t button, uint32_t status) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { FlutterPointerMouseButtons flutter_button; @@ -229,7 +229,7 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { }, .axis = [](void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, wl_fixed_t value) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double delta = wl_fixed_to_double(value); constexpr int32_t kScrollOffsetMultiplier = 20; @@ -242,11 +242,11 @@ const wl_pointer_listener LinuxesWindowWayland::kWlPointerListener = { }, }; -const wl_touch_listener LinuxesWindowWayland::kWlTouchListener = { +const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { .down = [](void* data, wl_touch* wl_touch, uint32_t serial, uint32_t time, wl_surface* surface, int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); @@ -256,7 +256,7 @@ const wl_touch_listener LinuxesWindowWayland::kWlTouchListener = { }, .up = [](void* data, wl_touch* wl_touch, uint32_t serial, uint32_t time, int32_t id) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnTouchUp(time, id); @@ -264,7 +264,7 @@ const wl_touch_listener LinuxesWindowWayland::kWlTouchListener = { }, .motion = [](void* data, wl_touch* wl_touch, uint32_t time, int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); double y = wl_fixed_to_double(surface_y); @@ -273,17 +273,17 @@ const wl_touch_listener LinuxesWindowWayland::kWlTouchListener = { }, .frame = [](void* data, wl_touch* wl_touch) -> void {}, .cancel = [](void* data, wl_touch* wl_touch) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnTouchCancel(); } }, }; -const wl_keyboard_listener LinuxesWindowWayland::kWlKeyboardListener = { +const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { .keymap = [](void* data, wl_keyboard* wl_keyboard, uint32_t format, int fd, uint32_t size) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnKeyMap(format, fd, size); @@ -291,17 +291,17 @@ const wl_keyboard_listener LinuxesWindowWayland::kWlKeyboardListener = { }, .enter = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, wl_surface* surface, wl_array* keys) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; }, .leave = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, wl_surface* surface) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; }, .key = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, uint32_t time, uint32_t key, uint32_t state) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnKey( @@ -311,7 +311,7 @@ const wl_keyboard_listener LinuxesWindowWayland::kWlKeyboardListener = { .modifiers = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnKeyModifiers( mods_depressed, mods_latched, mods_locked, group); @@ -321,14 +321,14 @@ const wl_keyboard_listener LinuxesWindowWayland::kWlKeyboardListener = { int delay) -> void {}, }; -const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { +const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { .geometry = [](void* data, wl_output* wl_output, int32_t x, int32_t y, int32_t physical_width, int32_t physical_height, int32_t subpixel, const char* make, const char* model, int32_t output_transform) -> void {}, .mode = [](void* data, wl_output* wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { ELINUX_LOG(INFO) << "Display output info: width = " << width << ", height = " << height @@ -350,17 +350,17 @@ const wl_output_listener LinuxesWindowWayland::kWlOutputListener = { }, .done = [](void* data, wl_output* wl_output) -> void {}, .scale = [](void* data, wl_output* wl_output, int32_t scale) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); ELINUX_LOG(INFO) << "Display output scale: " << scale; self->current_scale_ = scale; }, }; -const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = +const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = { .enter = [](void* data, zwp_text_input_v1* zwp_text_input_v1, wl_surface* surface) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); // If there is no input data, the backspace key cannot be used, // so set dummy data. if (self->zwp_text_input_v1_) { @@ -369,7 +369,7 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = } }, .leave = [](void* data, zwp_text_input_v1* zwp_text_input_v1) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->zwp_text_input_v1_) { zwp_text_input_v1_hide_input_panel(self->zwp_text_input_v1_); } @@ -382,7 +382,7 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = .preedit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, const char* text, const char* commit) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); } @@ -402,7 +402,7 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = .commit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, const char* text) -> void { // commit_string is notified only when the space key is pressed. - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); } @@ -418,7 +418,7 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = .delete_surrounding_text = [](void* data, zwp_text_input_v1* zwp_text_input_v1, int32_t index, uint32_t length) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnVirtualSpecialKey(KEY_BACKSPACE); } @@ -432,7 +432,7 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = .keysym = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, uint32_t time, uint32_t sym, uint32_t state, uint32_t modifiers) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if ((state == WL_KEYBOARD_KEY_STATE_PRESSED) && (self->binding_handler_delegate_)) { switch (sym) { @@ -465,13 +465,13 @@ const zwp_text_input_v1_listener LinuxesWindowWayland::kZwpTextInputV1Listener = uint32_t serial, uint32_t direction) -> void {}, }; -const zwp_text_input_v3_listener LinuxesWindowWayland::kZwpTextInputV3Listener = +const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = { .enter = [](void* data, zwp_text_input_v3* zwp_text_input_v3, wl_surface* surface) -> void { // To appear the on-screen keyboard when the user returns to a Flutter // app which needs to show the on-screen keyboard. - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->is_requested_show_virtual_keyboard_) { self->ShowVirtualKeyboard(); } @@ -483,7 +483,7 @@ const zwp_text_input_v3_listener LinuxesWindowWayland::kZwpTextInputV3Listener = int32_t cursor_end) -> void {}, .commit_string = [](void* data, zwp_text_input_v3* zwp_text_input_v3, const char* text) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); } @@ -495,7 +495,7 @@ const zwp_text_input_v3_listener LinuxesWindowWayland::kZwpTextInputV3Listener = uint32_t serial) -> void {}, }; -const wl_data_device_listener LinuxesWindowWayland::kWlDataDeviceListener = { +const wl_data_device_listener ELinuxWindowWayland::kWlDataDeviceListener = { .data_offer = [](void* data, wl_data_device* wl_data_device, wl_data_offer* offer) -> void {}, .enter = [](void* data, wl_data_device* wl_data_device, uint32_t serial, @@ -507,7 +507,7 @@ const wl_data_device_listener LinuxesWindowWayland::kWlDataDeviceListener = { .drop = [](void* data, wl_data_device* wl_data_device) -> void {}, .selection = [](void* data, wl_data_device* wl_data_device, wl_data_offer* offer) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); if (self->wl_data_offer_) { wl_data_offer_destroy(self->wl_data_offer_); } @@ -515,7 +515,7 @@ const wl_data_device_listener LinuxesWindowWayland::kWlDataDeviceListener = { }, }; -const wl_data_source_listener LinuxesWindowWayland::kWlDataSourceListener = { +const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { .target = [](void* data, wl_data_source* wl_data_source, const char* mime_type) -> void {}, .send = [](void* data, wl_data_source* wl_data_source, @@ -524,14 +524,14 @@ const wl_data_source_listener LinuxesWindowWayland::kWlDataSourceListener = { ELINUX_LOG(ERROR) << "Not expected mime_type: " << mime_type; return; } - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); // Write the copied data to the clipboard. write(fd, self->clipboard_data_.c_str(), strlen(self->clipboard_data_.c_str())); close(fd); }, .cancelled = [](void* data, wl_data_source* wl_data_source) -> void { - auto self = reinterpret_cast(data); + auto self = reinterpret_cast(data); self->clipboard_data_ = ""; if (self->wl_data_source_) { wl_data_source_destroy(self->wl_data_source_); @@ -545,7 +545,7 @@ const wl_data_source_listener LinuxesWindowWayland::kWlDataSourceListener = { uint32_t dnd_action) -> void {}, }; -LinuxesWindowWayland::LinuxesWindowWayland( +ELinuxWindowWayland::ELinuxWindowWayland( FlutterDesktopViewProperties view_properties) : cursor_info_({"", 0, nullptr}), display_valid_(false), @@ -624,7 +624,7 @@ LinuxesWindowWayland::LinuxesWindowWayland( display_valid_ = true; } -LinuxesWindowWayland::~LinuxesWindowWayland() { +ELinuxWindowWayland::~ELinuxWindowWayland() { display_valid_ = false; if (weston_desktop_shell_) { @@ -741,24 +741,24 @@ LinuxesWindowWayland::~LinuxesWindowWayland() { } } -void LinuxesWindowWayland::SetView(WindowBindingHandlerDelegate* window) { +void ELinuxWindowWayland::SetView(WindowBindingHandlerDelegate* window) { binding_handler_delegate_ = window; } -LinuxesRenderSurfaceTarget* LinuxesWindowWayland::GetRenderSurfaceTarget() +LinuxesRenderSurfaceTarget* ELinuxWindowWayland::GetRenderSurfaceTarget() const { return render_surface_.get(); } -double LinuxesWindowWayland::GetDpiScale() { return current_scale_; } +double ELinuxWindowWayland::GetDpiScale() { return current_scale_; } -PhysicalWindowBounds LinuxesWindowWayland::GetPhysicalWindowBounds() { +PhysicalWindowBounds ELinuxWindowWayland::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } -int32_t LinuxesWindowWayland::GetFrameRate() { return frame_rate_; } +int32_t ELinuxWindowWayland::GetFrameRate() { return frame_rate_; } -bool LinuxesWindowWayland::DispatchEvent() { +bool ELinuxWindowWayland::DispatchEvent() { if (!IsValid()) { ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; @@ -817,7 +817,7 @@ bool LinuxesWindowWayland::DispatchEvent() { return true; } -bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { +bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { if (!display_valid_) { ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; @@ -873,7 +873,7 @@ bool LinuxesWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { return true; } -void LinuxesWindowWayland::DestroyRenderSurface() { +void ELinuxWindowWayland::DestroyRenderSurface() { // destroy the main surface before destroying the client window on Wayland. { render_surface_ = nullptr; @@ -891,7 +891,7 @@ void LinuxesWindowWayland::DestroyRenderSurface() { } } -void LinuxesWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { +void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { // Not supported virtual keyboard. if (!(zwp_text_input_v1_ || zwp_text_input_v3_) || !wl_seat_) { return; @@ -905,7 +905,7 @@ void LinuxesWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { } } -void LinuxesWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { +void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { if (view_properties_.use_mouse_cursor) { if (cursor_name.compare(cursor_info_.cursor_name) == 0) { return; @@ -939,7 +939,7 @@ void LinuxesWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { } } -std::string LinuxesWindowWayland::GetClipboardData() { +std::string ELinuxWindowWayland::GetClipboardData() { std::string str = ""; if (wl_data_offer_) { @@ -965,7 +965,7 @@ std::string LinuxesWindowWayland::GetClipboardData() { return str; } -void LinuxesWindowWayland::SetClipboardData(const std::string& data) { +void ELinuxWindowWayland::SetClipboardData(const std::string& data) { clipboard_data_ = data; if (wl_data_device_manager_) { if (wl_data_source_) { @@ -985,7 +985,7 @@ void LinuxesWindowWayland::SetClipboardData(const std::string& data) { } } -bool LinuxesWindowWayland::IsValid() const { +bool ELinuxWindowWayland::IsValid() const { if (!display_valid_ || !native_window_ || !render_surface_ || !native_window_->IsValid() || !render_surface_->IsValid()) { return false; @@ -993,10 +993,10 @@ bool LinuxesWindowWayland::IsValid() const { return true; } -void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, - uint32_t name, - const char* interface, - uint32_t version) { +void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, + uint32_t name, + const char* interface, + uint32_t version) { if (!strcmp(interface, wl_compositor_interface.name)) { wl_compositor_ = static_cast( wl_registry_bind(wl_registry, name, &wl_compositor_interface, 1)); @@ -1089,10 +1089,10 @@ void LinuxesWindowWayland::WlRegistryHandler(wl_registry* wl_registry, } } -void LinuxesWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry, - uint32_t name) {} +void ELinuxWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry, + uint32_t name) {} -void LinuxesWindowWayland::CreateSupportedWlCursorList() { +void ELinuxWindowWayland::CreateSupportedWlCursorList() { std::vector wl_cursor_themes{ kWlCursorThemeLeftPtr, kWlCursorThemeBottomLeftCorner, @@ -1120,7 +1120,7 @@ void LinuxesWindowWayland::CreateSupportedWlCursorList() { } } -wl_cursor* LinuxesWindowWayland::GetWlCursor(const std::string& cursor_name) { +wl_cursor* ELinuxWindowWayland::GetWlCursor(const std::string& cursor_name) { // Convert the cursor theme name from Flutter's cursor value to Wayland's one. // However, Wayland has not all cursor themes corresponding to Flutter. // If there is no Wayland's cursor theme corresponding to the Flutter's cursor @@ -1177,7 +1177,7 @@ wl_cursor* LinuxesWindowWayland::GetWlCursor(const std::string& cursor_name) { return supported_wl_cursor_list_[kWlCursorThemeLeftPtr]; } -void LinuxesWindowWayland::ShowVirtualKeyboard() { +void ELinuxWindowWayland::ShowVirtualKeyboard() { if (zwp_text_input_v3_) { // I'm not sure the reason, but enable needs to be called twice. zwp_text_input_v3_enable(zwp_text_input_v3_); @@ -1198,7 +1198,7 @@ void LinuxesWindowWayland::ShowVirtualKeyboard() { } } -void LinuxesWindowWayland::DismissVirtualKeybaord() { +void ELinuxWindowWayland::DismissVirtualKeybaord() { if (zwp_text_input_v3_) { zwp_text_input_v3_disable(zwp_text_input_v3_); zwp_text_input_v3_commit(zwp_text_input_v3_); diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h similarity index 90% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h rename to src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 89907122..df247505 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_WAYLAND_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_WAYLAND_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_WAYLAND_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_WAYLAND_H_ #include #include @@ -13,7 +13,7 @@ #include #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" -#include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_wayland.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" @@ -29,12 +29,12 @@ extern "C" { namespace flutter { -class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { +class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { public: - LinuxesWindowWayland(FlutterDesktopViewProperties view_properties); - ~LinuxesWindowWayland(); + ELinuxWindowWayland(FlutterDesktopViewProperties view_properties); + ~ELinuxWindowWayland(); - // |LinuxesWindow| + // |ELinuxWindow| bool IsValid() const override; // |FlutterWindowBindingHandler| @@ -167,4 +167,4 @@ class LinuxesWindowWayland : public LinuxesWindow, public WindowBindingHandler { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_WAYLAND_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_WAYLAND_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc similarity index 79% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc rename to src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index d10f059d..92a8fd8d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window_x11.h" #include #include @@ -13,8 +13,7 @@ namespace flutter { -LinuxesWindowX11::LinuxesWindowX11( - FlutterDesktopViewProperties view_properties) { +ELinuxWindowX11::ELinuxWindowX11(FlutterDesktopViewProperties view_properties) { view_properties_ = view_properties; display_ = XOpenDisplay(NULL); @@ -26,7 +25,7 @@ LinuxesWindowX11::LinuxesWindowX11( display_valid_ = true; } -LinuxesWindowX11::~LinuxesWindowX11() { +ELinuxWindowX11::~ELinuxWindowX11() { display_valid_ = false; if (display_) { XSetCloseDownMode(display_, DestroyAll); @@ -34,7 +33,7 @@ LinuxesWindowX11::~LinuxesWindowX11() { } } -bool LinuxesWindowX11::IsValid() const { +bool ELinuxWindowX11::IsValid() const { if (!display_valid_ || !native_window_ || !render_surface_ || !native_window_->IsValid() || !render_surface_->IsValid()) { return false; @@ -42,7 +41,7 @@ bool LinuxesWindowX11::IsValid() const { return true; } -bool LinuxesWindowX11::DispatchEvent() { +bool ELinuxWindowX11::DispatchEvent() { while (XPending(display_)) { XEvent event; XNextEvent(display_, &event); @@ -105,7 +104,7 @@ bool LinuxesWindowX11::DispatchEvent() { return true; } -bool LinuxesWindowX11::CreateRenderSurface(int32_t width, int32_t height) { +bool ELinuxWindowX11::CreateRenderSurface(int32_t width, int32_t height) { auto context_egl = std::make_unique(std::make_unique(display_)); @@ -122,45 +121,45 @@ bool LinuxesWindowX11::CreateRenderSurface(int32_t width, int32_t height) { return true; } -void LinuxesWindowX11::DestroyRenderSurface() { +void ELinuxWindowX11::DestroyRenderSurface() { // destroy the main surface before destroying the client window on X11. render_surface_ = nullptr; native_window_ = nullptr; } -void LinuxesWindowX11::SetView(WindowBindingHandlerDelegate* window) { +void ELinuxWindowX11::SetView(WindowBindingHandlerDelegate* window) { binding_handler_delegate_ = window; } -LinuxesRenderSurfaceTarget* LinuxesWindowX11::GetRenderSurfaceTarget() const { +LinuxesRenderSurfaceTarget* ELinuxWindowX11::GetRenderSurfaceTarget() const { return render_surface_.get(); } -double LinuxesWindowX11::GetDpiScale() { return current_scale_; } +double ELinuxWindowX11::GetDpiScale() { return current_scale_; } -PhysicalWindowBounds LinuxesWindowX11::GetPhysicalWindowBounds() { +PhysicalWindowBounds ELinuxWindowX11::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } -int32_t LinuxesWindowX11::GetFrameRate() { return 60000; } +int32_t ELinuxWindowX11::GetFrameRate() { return 60000; } -void LinuxesWindowX11::UpdateFlutterCursor(const std::string& cursor_name) { +void ELinuxWindowX11::UpdateFlutterCursor(const std::string& cursor_name) { // TODO: implement here } -void LinuxesWindowX11::UpdateVirtualKeyboardStatus(const bool show) { +void ELinuxWindowX11::UpdateVirtualKeyboardStatus(const bool show) { // currently not supported. } -std::string LinuxesWindowX11::GetClipboardData() { return clipboard_data_; } +std::string ELinuxWindowX11::GetClipboardData() { return clipboard_data_; } -void LinuxesWindowX11::SetClipboardData(const std::string& data) { +void ELinuxWindowX11::SetClipboardData(const std::string& data) { clipboard_data_ = data; } -void LinuxesWindowX11::HandlePointerButtonEvent(uint32_t button, - bool button_pressed, int16_t x, - int16_t y) { +void ELinuxWindowX11::HandlePointerButtonEvent(uint32_t button, + bool button_pressed, int16_t x, + int16_t y) { if (binding_handler_delegate_) { FlutterPointerMouseButtons flutter_button; switch (button) { diff --git a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h similarity index 80% rename from src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h rename to src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 34f3fa21..00480b4f 100644 --- a/src/flutter/shell/platform/linux_embedded/window/linuxes_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -2,24 +2,24 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_X11_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_X11_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_X11_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_X11_H_ #include #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" -#include "flutter/shell/platform/linux_embedded/window/linuxes_window.h" +#include "flutter/shell/platform/linux_embedded/window/elinux_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_x11.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" namespace flutter { -class LinuxesWindowX11 : public LinuxesWindow, public WindowBindingHandler { +class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { public: - LinuxesWindowX11(FlutterDesktopViewProperties view_properties); - ~LinuxesWindowX11(); + ELinuxWindowX11(FlutterDesktopViewProperties view_properties); + ~ELinuxWindowX11(); - // |LinuxesWindow| + // |ELinuxWindow| bool IsValid() const override; // |FlutterWindowBindingHandler| @@ -76,4 +76,4 @@ class LinuxesWindowX11 : public LinuxesWindow, public WindowBindingHandler { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_LINUXES_WINDOW_X11_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_X11_H_ From 902ea91592b03569e0c93d48c63ac0e7925b06a3 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 16 Jun 2021 16:10:28 +0900 Subject: [PATCH 026/178] Refactoring: change from linuxes to elinux - step3 (#173) --- CMakeLists.txt | 2 +- cmake/build.cmake | 8 +- .../include/flutter/flutter_engine.h | 2 +- .../include/flutter/flutter_view.h | 2 +- .../include/flutter/flutter_view_controller.h | 2 +- .../{flutter_linuxes.cc => flutter_elinux.cc} | 34 +++--- ...xes_engine.cc => flutter_elinux_engine.cc} | 62 +++++----- ...nuxes_engine.h => flutter_elinux_engine.h} | 34 +++--- ...linuxes_state.h => flutter_elinux_state.h} | 16 +-- ...cc => flutter_elinux_texture_registrar.cc} | 16 +-- ...r.h => flutter_elinux_texture_registrar.h} | 18 ++- ...linuxes_view.cc => flutter_elinux_view.cc} | 109 +++++++++--------- ...r_linuxes_view.h => flutter_elinux_view.h} | 32 ++--- .../linux_embedded/flutter_project_bundle.h | 2 +- .../{flutter_linuxes.h => flutter_elinux.h} | 0 .../linux_embedded/window/elinux_window.h | 2 +- .../linux_embedded/window/elinux_window_drm.h | 2 +- .../window/elinux_window_wayland.cc | 3 +- .../window/elinux_window_wayland.h | 2 +- .../window/elinux_window_x11.cc | 2 +- .../linux_embedded/window/elinux_window_x11.h | 2 +- .../linux_embedded/window_binding_handler.h | 8 +- 22 files changed, 177 insertions(+), 183 deletions(-) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes.cc => flutter_elinux.cc} (88%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_engine.cc => flutter_elinux_engine.cc} (86%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_engine.h => flutter_elinux_engine.h} (84%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_state.h => flutter_elinux_state.h} (73%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_texture_registrar.cc => flutter_elinux_texture_registrar.cc} (80%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_texture_registrar.h => flutter_elinux_texture_registrar.h} (71%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_view.cc => flutter_elinux_view.cc} (75%) rename src/flutter/shell/platform/linux_embedded/{flutter_linuxes_view.h => flutter_elinux_view.h} (89%) rename src/flutter/shell/platform/linux_embedded/public/{flutter_linuxes.h => flutter_elinux.h} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d40b2e0..765b4e6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) -project("flutter_linuxes" LANGUAGES CXX C) +project("flutter_elinux" LANGUAGES CXX C) # We only support clang, so the build will be faild if you try to build with gcc compiler instead of it. if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) diff --git a/cmake/build.cmake b/cmake/build.cmake index 0cda9202..d3a0cf4e 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -98,16 +98,16 @@ add_executable(${TARGET} ${USER_APP_SRCS} src/client_wrapper/flutter_engine.cc src/client_wrapper/flutter_view_controller.cc - src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc - src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc - src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc + src/flutter/shell/platform/linux_embedded/flutter_elinux.cc + src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc + src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc src/flutter/shell/platform/linux_embedded/task_runner.cc src/flutter/shell/platform/linux_embedded/system_utils.cc src/flutter/shell/platform/linux_embedded/logger.cc src/flutter/shell/platform/linux_embedded/external_texture_gl.cc src/flutter/shell/platform/linux_embedded/vsync_waiter.cc - src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc + src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc diff --git a/src/client_wrapper/include/flutter/flutter_engine.h b/src/client_wrapper/include/flutter/flutter_engine.h index df51d88b..4cb7f1d7 100644 --- a/src/client_wrapper/include/flutter/flutter_engine.h +++ b/src/client_wrapper/include/flutter/flutter_engine.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_ENBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_ENBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_ENGINE_H_ -#include +#include #include #include diff --git a/src/client_wrapper/include/flutter/flutter_view.h b/src/client_wrapper/include/flutter/flutter_view.h index 343667e2..31a0b436 100644 --- a/src/client_wrapper/include/flutter/flutter_view.h +++ b/src/client_wrapper/include/flutter/flutter_view.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_H_ -#include +#include namespace flutter { diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index d8464c20..a4a9c118 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_CLIENT_WRAPPER_INCLUDE_FLUTTER_FLUTTER_VIEW_CONTROLLER_H_ -#include +#include #include #include diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc similarity index 88% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc rename to src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 5af1258c..e8633d10 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" #include #include @@ -11,9 +11,9 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_view.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_state.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" #if defined(DISPLAY_BACKEND_TYPE_DRM_GBM) @@ -31,36 +31,36 @@ static_assert(FLUTTER_ENGINE_VERSION == 1, ""); // Returns the engine corresponding to the given opaque API handle. -static flutter::FlutterLinuxesEngine* EngineFromHandle( +static flutter::FlutterELinuxEngine* EngineFromHandle( FlutterDesktopEngineRef ref) { - return reinterpret_cast(ref); + return reinterpret_cast(ref); } // Returns the opaque API handle for the given engine instance. static FlutterDesktopEngineRef HandleForEngine( - flutter::FlutterLinuxesEngine* engine) { + flutter::FlutterELinuxEngine* engine) { return reinterpret_cast(engine); } // Returns the view corresponding to the given opaque API handle. -static flutter::FlutterLinuxesView* ViewFromHandle(FlutterDesktopViewRef ref) { - return reinterpret_cast(ref); +static flutter::FlutterELinuxView* ViewFromHandle(FlutterDesktopViewRef ref) { + return reinterpret_cast(ref); } // Returns the opaque API handle for the given view instance. -static FlutterDesktopViewRef HandleForView(flutter::FlutterLinuxesView* view) { +static FlutterDesktopViewRef HandleForView(flutter::FlutterELinuxView* view) { return reinterpret_cast(view); } // Returns the texture registrar corresponding to the given opaque API handle. -static flutter::FlutterLinuxesTextureRegistrar* TextureRegistrarFromHandle( +static flutter::FlutterELinuxTextureRegistrar* TextureRegistrarFromHandle( FlutterDesktopTextureRegistrarRef ref) { - return reinterpret_cast(ref); + return reinterpret_cast(ref); } // Returns the opaque API handle for the given texture registrar instance. static FlutterDesktopTextureRegistrarRef HandleForTextureRegistrar( - flutter::FlutterLinuxesTextureRegistrar* registrar) { + flutter::FlutterELinuxTextureRegistrar* registrar) { return reinterpret_cast(registrar); } @@ -91,14 +91,14 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( auto state = std::make_unique(); state->view = - std::make_unique(std::move(window_wrapper)); + std::make_unique(std::move(window_wrapper)); if (!state->view->CreateRenderSurface()) { return nullptr; } // Take ownership of the engine, starting it if necessary. state->view->SetEngine( - std::unique_ptr(EngineFromHandle(engine))); + std::unique_ptr(EngineFromHandle(engine))); if (!state->view->GetEngine()->running()) { if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) { return nullptr; @@ -136,12 +136,12 @@ int32_t FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view) { FlutterDesktopEngineRef FlutterDesktopEngineCreate( const FlutterDesktopEngineProperties& engine_properties) { flutter::FlutterProjectBundle project(engine_properties); - auto engine = std::make_unique(project); + auto engine = std::make_unique(project); return HandleForEngine(engine.release()); } bool FlutterDesktopEngineDestroy(FlutterDesktopEngineRef engine_ref) { - flutter::FlutterLinuxesEngine* engine = EngineFromHandle(engine_ref); + flutter::FlutterELinuxEngine* engine = EngineFromHandle(engine_ref); bool result = true; if (engine->running()) { result = engine->Stop(); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc similarity index 86% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 31f56ed9..eb8510f3 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" #include @@ -12,7 +12,7 @@ #include "flutter/shell/platform/common/client_wrapper/binary_messenger_impl.h" #include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h" #include "flutter/shell/platform/common/json_message_codec.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_view.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" #include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/system_utils.h" #include "flutter/shell/platform/linux_embedded/task_runner.h" @@ -22,35 +22,35 @@ namespace flutter { namespace { // Creates and returns a FlutterRendererConfig that renders to the view (if any) -// of a FlutterLinuxesEngine, which should be the user_data received by the +// of a FlutterELinuxEngine, which should be the user_data received by the // render callbacks. FlutterRendererConfig GetRendererConfig() { FlutterRendererConfig config = {}; config.type = kOpenGL; config.open_gl.struct_size = sizeof(config.open_gl); config.open_gl.make_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return false; } return host->view()->MakeCurrent(); }; config.open_gl.clear_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return false; } return host->view()->ClearCurrent(); }; config.open_gl.present = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return false; } return host->view()->Present(); }; config.open_gl.fbo_callback = [](void* user_data) -> uint32_t { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return false; } @@ -58,14 +58,14 @@ FlutterRendererConfig GetRendererConfig() { }; config.open_gl.gl_proc_resolver = [](void* user_data, const char* name) -> void* { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return nullptr; } return host->view()->ProcResolver(name); }; config.open_gl.make_resource_current = [](void* user_data) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->view()) { return false; } @@ -74,7 +74,7 @@ FlutterRendererConfig GetRendererConfig() { config.open_gl.gl_external_texture_frame_callback = [](void* user_data, int64_t texture_id, size_t width, size_t height, FlutterOpenGLTexture* texture) -> bool { - auto host = static_cast(user_data); + auto host = static_cast(user_data); if (!host->texture_registrar()) { return false; } @@ -98,7 +98,7 @@ static FlutterDesktopMessage ConvertToDesktopMessage( } // namespace -FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project) +FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) : project_(std::make_unique(project)), aot_data_(nullptr) { embedder_api_.struct_size = sizeof(FlutterEngineProcTable); @@ -126,7 +126,7 @@ FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project) messenger_wrapper_ = std::make_unique(messenger_.get()); message_dispatcher_ = std::make_unique(messenger_.get()); - texture_registrar_ = std::make_unique(this); + texture_registrar_ = std::make_unique(this); // Set up internal channels. // TODO: Replace this with an embedder.h API. See @@ -139,9 +139,9 @@ FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project) vsync_waiter_ = std::make_unique(); } -FlutterLinuxesEngine::~FlutterLinuxesEngine() { Stop(); } +FlutterELinuxEngine::~FlutterELinuxEngine() { Stop(); } -bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { +bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { if (!project_->HasValidPaths()) { ELINUX_LOG(ERROR) << "Missing or unresolvable paths to assets."; return false; @@ -203,7 +203,7 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { args.platform_message_callback = [](const FlutterPlatformMessage* engine_message, void* user_data) -> void { - auto host = static_cast(user_data); + auto host = static_cast(user_data); return host->HandlePlatformMessage(engine_message); }; // todo: add drm/x11 support. @@ -211,7 +211,7 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { // https://github.com/sony/flutter-embedded-linux/issues/137 #if defined(DISPLAY_BACKEND_TYPE_WAYLAND) args.vsync_callback = [](void* user_data, intptr_t baton) -> void { - auto host = static_cast(user_data); + auto host = static_cast(user_data); host->vsync_waiter_->NotifyWaitForVsync(baton); }; #endif @@ -246,7 +246,7 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) { return true; } -bool FlutterLinuxesEngine::Stop() { +bool FlutterELinuxEngine::Stop() { if (engine_) { if (plugin_registrar_destruction_callback_) { plugin_registrar_destruction_callback_(plugin_registrar_.get()); @@ -258,32 +258,32 @@ bool FlutterLinuxesEngine::Stop() { return false; } -void FlutterLinuxesEngine::SetView(FlutterLinuxesView* view) { view_ = view; } +void FlutterELinuxEngine::SetView(FlutterELinuxView* view) { view_ = view; } // Returns the currently configured Plugin Registrar. -FlutterDesktopPluginRegistrarRef FlutterLinuxesEngine::GetRegistrar() { +FlutterDesktopPluginRegistrarRef FlutterELinuxEngine::GetRegistrar() { return plugin_registrar_.get(); } -void FlutterLinuxesEngine::SetPluginRegistrarDestructionCallback( +void FlutterELinuxEngine::SetPluginRegistrarDestructionCallback( FlutterDesktopOnPluginRegistrarDestroyed callback) { plugin_registrar_destruction_callback_ = callback; } -void FlutterLinuxesEngine::SendWindowMetricsEvent( +void FlutterELinuxEngine::SendWindowMetricsEvent( const FlutterWindowMetricsEvent& event) { if (engine_) { embedder_api_.SendWindowMetricsEvent(engine_, &event); } } -void FlutterLinuxesEngine::SendPointerEvent(const FlutterPointerEvent& event) { +void FlutterELinuxEngine::SendPointerEvent(const FlutterPointerEvent& event) { if (engine_) { embedder_api_.SendPointerEvent(engine_, &event, 1); } } -bool FlutterLinuxesEngine::SendPlatformMessage( +bool FlutterELinuxEngine::SendPlatformMessage( const char* channel, const uint8_t* message, const size_t message_size, const FlutterDesktopBinaryReply reply, void* user_data) { FlutterPlatformMessageResponseHandle* response_handle = nullptr; @@ -314,13 +314,13 @@ bool FlutterLinuxesEngine::SendPlatformMessage( return message_result == kSuccess; } -void FlutterLinuxesEngine::SendPlatformMessageResponse( +void FlutterELinuxEngine::SendPlatformMessageResponse( const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, size_t data_length) { embedder_api_.SendPlatformMessageResponse(engine_, handle, data, data_length); } -void FlutterLinuxesEngine::HandlePlatformMessage( +void FlutterELinuxEngine::HandlePlatformMessage( const FlutterPlatformMessage* engine_message) { if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) { ELINUX_LOG(ERROR) << "Invalid message size received. Expected: " @@ -335,11 +335,11 @@ void FlutterLinuxesEngine::HandlePlatformMessage( message, [this] {}, [this] {}); } -void FlutterLinuxesEngine::ReloadSystemFonts() { +void FlutterELinuxEngine::ReloadSystemFonts() { embedder_api_.ReloadSystemFonts(engine_); } -void FlutterLinuxesEngine::SendSystemSettings() { +void FlutterELinuxEngine::SendSystemSettings() { auto languages = flutter::GetPreferredLanguageInfo(); auto flutter_locales = flutter::ConvertToFlutterLocale(languages); @@ -365,23 +365,23 @@ void FlutterLinuxesEngine::SendSystemSettings() { settings_channel_->Send(settings); } -bool FlutterLinuxesEngine::RegisterExternalTexture(int64_t texture_id) { +bool FlutterELinuxEngine::RegisterExternalTexture(int64_t texture_id) { return (embedder_api_.RegisterExternalTexture(engine_, texture_id) == kSuccess); } -bool FlutterLinuxesEngine::UnregisterExternalTexture(int64_t texture_id) { +bool FlutterELinuxEngine::UnregisterExternalTexture(int64_t texture_id) { return (embedder_api_.UnregisterExternalTexture(engine_, texture_id) == kSuccess); } -bool FlutterLinuxesEngine::MarkExternalTextureFrameAvailable( +bool FlutterELinuxEngine::MarkExternalTextureFrameAvailable( int64_t texture_id) { return (embedder_api_.MarkExternalTextureFrameAvailable( engine_, texture_id) == kSuccess); } -void FlutterLinuxesEngine::OnVsync(uint64_t last_frame_time_nanos, +void FlutterELinuxEngine::OnVsync(uint64_t last_frame_time_nanos, uint64_t vsync_interval_time_nanos) { uint64_t current_time_nanos = embedder_api_.GetCurrentTime(); uint64_t after_vsync_passed_time_nanos = diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h similarity index 84% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 139b1183..9824e5cc 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_ENGINE_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_ENGINE_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_ENGINE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_ENGINE_H_ #include @@ -16,25 +16,25 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_state.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h" #include "flutter/shell/platform/linux_embedded/flutter_project_bundle.h" -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" #include "flutter/shell/platform/linux_embedded/task_runner.h" #include "flutter/shell/platform/linux_embedded/vsync_waiter.h" namespace flutter { -class FlutterLinuxesView; +class FlutterELinuxView; -class FlutterLinuxesEngine { +class FlutterELinuxEngine { public: - explicit FlutterLinuxesEngine(const FlutterProjectBundle& project); - virtual ~FlutterLinuxesEngine(); + explicit FlutterELinuxEngine(const FlutterProjectBundle& project); + virtual ~FlutterELinuxEngine(); // Prevent copying. - FlutterLinuxesEngine(FlutterLinuxesEngine const&) = delete; - FlutterLinuxesEngine& operator=(FlutterLinuxesEngine const&) = delete; + FlutterELinuxEngine(FlutterELinuxEngine const&) = delete; + FlutterELinuxEngine& operator=(FlutterELinuxEngine const&) = delete; // Starts running the engine with the given entrypoint. If null, defaults to // main(). @@ -51,11 +51,11 @@ class FlutterLinuxesEngine { bool Stop(); // Sets the view that is displaying this engine's content. - void SetView(FlutterLinuxesView* view); + void SetView(FlutterELinuxView* view); // The view displaying this engine's content, if any. This will be null for // headless engines. - FlutterLinuxesView* view() { return view_; } + FlutterELinuxView* view() { return view_; } // Returns the currently configured Plugin Registrar. FlutterDesktopPluginRegistrarRef GetRegistrar(); @@ -72,7 +72,7 @@ class FlutterLinuxesEngine { TaskRunner* task_runner() { return task_runner_.get(); } - FlutterLinuxesTextureRegistrar* texture_registrar() { + FlutterELinuxTextureRegistrar* texture_registrar() { return texture_registrar_.get(); } @@ -136,7 +136,7 @@ class FlutterLinuxesEngine { UniqueAotDataPtr aot_data_; // The view displaying the content running in this engine, if any. - FlutterLinuxesView* view_ = nullptr; + FlutterELinuxView* view_ = nullptr; // Task runner for tasks posted from the engine. std::unique_ptr task_runner_; @@ -154,7 +154,7 @@ class FlutterLinuxesEngine { std::unique_ptr plugin_registrar_; // The texture registrar. - std::unique_ptr texture_registrar_; + std::unique_ptr texture_registrar_; // The MethodChannel used for communication with the Flutter engine. std::unique_ptr> settings_channel_; @@ -170,4 +170,4 @@ class FlutterLinuxesEngine { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_ENGINE_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_ENGINE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_state.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h similarity index 73% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_state.h rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h index b361e82f..92a9d582 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_state.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_STATE_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_STATE_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ #include @@ -17,29 +17,29 @@ // in favor of objects that own and manage the relevant functionality. namespace flutter { -struct FlutterLinuxesEngine; -struct FlutterLinuxesView; +struct FlutterELinuxEngine; +struct FlutterELinuxView; } // namespace flutter // Wrapper to distinguish the view controller ref from the view ref given out // in the C API. struct FlutterDesktopViewControllerState { // The view that backs this state object. - std::unique_ptr view; + std::unique_ptr view; }; // Wrapper to distinguish the plugin registrar ref from the engine ref given out // in the C API. struct FlutterDesktopPluginRegistrar { // The engine that owns this state object. - flutter::FlutterLinuxesEngine* engine = nullptr; + flutter::FlutterELinuxEngine* engine = nullptr; }; // Wrapper to distinguish the messenger ref from the engine ref given out // in the C API. struct FlutterDesktopMessenger { // The engine that owns this state object. - flutter::FlutterLinuxesEngine* engine = nullptr; + flutter::FlutterELinuxEngine* engine = nullptr; }; -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_STATE_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc similarity index 80% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc index d1c8235a..8899c5fc 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" #include #include namespace flutter { -FlutterLinuxesTextureRegistrar::FlutterLinuxesTextureRegistrar( - FlutterLinuxesEngine* engine) +FlutterELinuxTextureRegistrar::FlutterELinuxTextureRegistrar( + FlutterELinuxEngine* engine) : engine_(engine) {} -int64_t FlutterLinuxesTextureRegistrar::RegisterTexture( +int64_t FlutterELinuxTextureRegistrar::RegisterTexture( const FlutterDesktopTextureInfo* texture_info) { if (texture_info->type != kFlutterDesktopPixelBufferTexture) { std::cerr << "Attempted to register texture of unsupport type." @@ -45,7 +45,7 @@ int64_t FlutterLinuxesTextureRegistrar::RegisterTexture( return texture_id; } -bool FlutterLinuxesTextureRegistrar::UnregisterTexture(int64_t texture_id) { +bool FlutterELinuxTextureRegistrar::UnregisterTexture(int64_t texture_id) { { std::lock_guard lock(map_mutex_); auto it = textures_.find(texture_id); @@ -61,7 +61,7 @@ bool FlutterLinuxesTextureRegistrar::UnregisterTexture(int64_t texture_id) { return true; } -bool FlutterLinuxesTextureRegistrar::MarkTextureFrameAvailable( +bool FlutterELinuxTextureRegistrar::MarkTextureFrameAvailable( int64_t texture_id) { engine_->task_runner()->RunNowOrPostTask([engine = engine_, texture_id]() { engine->MarkExternalTextureFrameAvailable(texture_id); @@ -69,7 +69,7 @@ bool FlutterLinuxesTextureRegistrar::MarkTextureFrameAvailable( return true; } -bool FlutterLinuxesTextureRegistrar::PopulateTexture( +bool FlutterELinuxTextureRegistrar::PopulateTexture( int64_t texture_id, size_t width, size_t height, diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h similarity index 71% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.h rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h index 84ff5873..511f2cb5 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_texture_registrar.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_TEXTURE_REGISTRAR_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_TEXTURE_REGISTRAR_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_TEXTURE_REGISTRAR_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_TEXTURE_REGISTRAR_H_ #include #include @@ -13,13 +13,13 @@ namespace flutter { -class FlutterLinuxesEngine; +class FlutterELinuxEngine; // An object managing the registration of an external texture. // Thread safety: All member methods are thread safe. -class FlutterLinuxesTextureRegistrar { +class FlutterELinuxTextureRegistrar { public: - explicit FlutterLinuxesTextureRegistrar(FlutterLinuxesEngine* engine); + explicit FlutterELinuxTextureRegistrar(FlutterELinuxEngine* engine); // Registers a texture described by the given |texture_info| object. // Returns the non-zero, positive texture id or -1 on error. @@ -36,13 +36,11 @@ class FlutterLinuxesTextureRegistrar { // Attempts to populate the given |texture| by copying the // contents of the texture identified by |texture_id|. // Returns true on success. - bool PopulateTexture(int64_t texture_id, - size_t width, - size_t height, + bool PopulateTexture(int64_t texture_id, size_t width, size_t height, FlutterOpenGLTexture* texture); private: - FlutterLinuxesEngine* engine_ = nullptr; + FlutterELinuxEngine* engine_ = nullptr; // All registered textures, keyed by their IDs. std::unordered_map> @@ -52,4 +50,4 @@ class FlutterLinuxesTextureRegistrar { }; // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_TEXTURE_REGISTRAR_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_TEXTURE_REGISTRAR_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc similarity index 75% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index b1659526..869439ac 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_view.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" #include @@ -10,14 +10,14 @@ namespace flutter { -FlutterLinuxesView::FlutterLinuxesView( +FlutterELinuxView::FlutterELinuxView( std::unique_ptr window_binding) { // Take the binding handler, and give it a pointer back to self. binding_handler_ = std::move(window_binding); binding_handler_->SetView(this); } -FlutterLinuxesView::~FlutterLinuxesView() { +FlutterELinuxView::~FlutterELinuxView() { // Need to stop running the Engine before destroying surface. if (engine_) { engine_->Stop(); @@ -25,12 +25,11 @@ FlutterLinuxesView::~FlutterLinuxesView() { DestroyRenderSurface(); } -bool FlutterLinuxesView::DispatchEvent() { +bool FlutterELinuxView::DispatchEvent() { return binding_handler_->DispatchEvent(); } -void FlutterLinuxesView::SetEngine( - std::unique_ptr engine) { +void FlutterELinuxView::SetEngine(std::unique_ptr engine) { engine_ = std::move(engine); engine_->SetView(this); @@ -60,14 +59,13 @@ void FlutterLinuxesView::SetEngine( binding_handler_->GetDpiScale()); } -void FlutterLinuxesView::RegisterPlatformViewFactory( +void FlutterELinuxView::RegisterPlatformViewFactory( const char* view_type, std::unique_ptr factory) { platform_views_handler_->RegisterViewFactory(view_type, std::move(factory)); } -void FlutterLinuxesView::OnWindowSizeChanged(size_t width, - size_t height) const { +void FlutterELinuxView::OnWindowSizeChanged(size_t width, size_t height) const { if (!GetRenderSurfaceTarget()->OnScreenSurfaceResize(width, height)) { ELINUX_LOG(ERROR) << "Failed to change surface size."; return; @@ -75,11 +73,11 @@ void FlutterLinuxesView::OnWindowSizeChanged(size_t width, SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); } -void FlutterLinuxesView::OnPointerMove(double x, double y) { +void FlutterELinuxView::OnPointerMove(double x, double y) { SendPointerMove(x, y); } -void FlutterLinuxesView::OnPointerDown( +void FlutterELinuxView::OnPointerDown( double x, double y, FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; @@ -88,8 +86,8 @@ void FlutterLinuxesView::OnPointerDown( } } -void FlutterLinuxesView::OnPointerUp( - double x, double y, FlutterPointerMouseButtons flutter_button) { +void FlutterELinuxView::OnPointerUp(double x, double y, + FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; SetMouseButtons(mouse_buttons); @@ -97,10 +95,10 @@ void FlutterLinuxesView::OnPointerUp( } } -void FlutterLinuxesView::OnPointerLeave() { SendPointerLeave(); } +void FlutterELinuxView::OnPointerLeave() { SendPointerLeave(); } -void FlutterLinuxesView::OnTouchDown(uint32_t time, int32_t id, double x, - double y) { +void FlutterELinuxView::OnTouchDown(uint32_t time, int32_t id, double x, + double y) { auto* point = GgeTouchPoint(id); if (!point) { return; @@ -126,7 +124,7 @@ void FlutterLinuxesView::OnTouchDown(uint32_t time, int32_t id, double x, engine_->SendPointerEvent(event); } -void FlutterLinuxesView::OnTouchUp(uint32_t time, int32_t id) { +void FlutterELinuxView::OnTouchUp(uint32_t time, int32_t id) { auto* point = GgeTouchPoint(id); if (!point) { return; @@ -149,8 +147,8 @@ void FlutterLinuxesView::OnTouchUp(uint32_t time, int32_t id) { engine_->SendPointerEvent(event); } -void FlutterLinuxesView::OnTouchMotion(uint32_t time, int32_t id, double x, - double y) { +void FlutterELinuxView::OnTouchMotion(uint32_t time, int32_t id, double x, + double y) { auto* point = GgeTouchPoint(id); if (!point) { return; @@ -176,13 +174,13 @@ void FlutterLinuxesView::OnTouchMotion(uint32_t time, int32_t id, double x, engine_->SendPointerEvent(event); } -void FlutterLinuxesView::OnTouchCancel() {} +void FlutterELinuxView::OnTouchCancel() {} -void FlutterLinuxesView::OnKeyMap(uint32_t format, int fd, uint32_t size) { +void FlutterELinuxView::OnKeyMap(uint32_t format, int fd, uint32_t size) { keyboard_handler_->OnKeymap(format, fd, size); } -void FlutterLinuxesView::OnKey(uint32_t key, bool pressed) { +void FlutterELinuxView::OnKey(uint32_t key, bool pressed) { keyboard_handler_->OnKey(key, pressed); if (pressed) { auto code_point = keyboard_handler_->GetCodePoint(key); @@ -192,36 +190,35 @@ void FlutterLinuxesView::OnKey(uint32_t key, bool pressed) { } } -void FlutterLinuxesView::OnKeyModifiers(uint32_t mods_depressed, - uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { +void FlutterELinuxView::OnKeyModifiers(uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, uint32_t group) { keyboard_handler_->OnModifiers(mods_depressed, mods_latched, mods_locked, group); } -void FlutterLinuxesView::OnVirtualKey(uint32_t code_point) { +void FlutterELinuxView::OnVirtualKey(uint32_t code_point) { // Since the keycode cannot be specified, set an invalid value(0). constexpr uint32_t kCharKey = 0; textinput_handler_->OnKeyPressed(kCharKey, code_point); } -void FlutterLinuxesView::OnVirtualSpecialKey(uint32_t keycode) { +void FlutterELinuxView::OnVirtualSpecialKey(uint32_t keycode) { auto code_point = keyboard_handler_->GetCodePoint(keycode); textinput_handler_->OnKeyPressed(keycode, code_point); } -void FlutterLinuxesView::OnScroll(double x, double y, double delta_x, - double delta_y, - int scroll_offset_multiplier) { +void FlutterELinuxView::OnScroll(double x, double y, double delta_x, + double delta_y, int scroll_offset_multiplier) { SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); } -void FlutterLinuxesView::OnVsync(uint64_t last_frame_time_nanos, - uint64_t vsync_interval_time_nanos) { +void FlutterELinuxView::OnVsync(uint64_t last_frame_time_nanos, + uint64_t vsync_interval_time_nanos) { engine_->OnVsync(last_frame_time_nanos, vsync_interval_time_nanos); } -FlutterLinuxesView::touch_point* FlutterLinuxesView::GgeTouchPoint(int32_t id) { +FlutterELinuxView::touch_point* FlutterELinuxView::GgeTouchPoint(int32_t id) { const size_t nmemb = sizeof(touch_event_) / sizeof(struct touch_point); int invalid = -1; for (size_t i = 0; i < nmemb; ++i) { @@ -241,8 +238,8 @@ FlutterLinuxesView::touch_point* FlutterLinuxesView::GgeTouchPoint(int32_t id) { } // Sends new size information to FlutterEngine. -void FlutterLinuxesView::SendWindowMetrics(size_t width, size_t height, - double dpiScale) const { +void FlutterELinuxView::SendWindowMetrics(size_t width, size_t height, + double dpiScale) const { FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); event.width = width; @@ -251,7 +248,7 @@ void FlutterLinuxesView::SendWindowMetrics(size_t width, size_t height, engine_->SendWindowMetricsEvent(event); } -void FlutterLinuxesView::SendInitialBounds() { +void FlutterELinuxView::SendInitialBounds() { PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, binding_handler_->GetDpiScale()); @@ -259,7 +256,7 @@ void FlutterLinuxesView::SendInitialBounds() { // Set's |event_data|'s phase to either kMove or kHover depending on the current // primary mouse button state. -void FlutterLinuxesView::SetEventPhaseFromCursorButtonState( +void FlutterELinuxView::SetEventPhaseFromCursorButtonState( FlutterPointerEvent* event_data) const { // For details about this logic, see FlutterPointerPhase in the embedder.h // file. @@ -271,7 +268,7 @@ void FlutterLinuxesView::SetEventPhaseFromCursorButtonState( : FlutterPointerPhase::kDown; } -void FlutterLinuxesView::SendPointerMove(double x, double y) { +void FlutterELinuxView::SendPointerMove(double x, double y) { FlutterPointerEvent event = {}; event.x = x; event.y = y; @@ -279,7 +276,7 @@ void FlutterLinuxesView::SendPointerMove(double x, double y) { SendPointerEventWithData(event); } -void FlutterLinuxesView::SendPointerDown(double x, double y) { +void FlutterELinuxView::SendPointerDown(double x, double y) { FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); event.x = x; @@ -288,7 +285,7 @@ void FlutterLinuxesView::SendPointerDown(double x, double y) { SetMouseFlutterStateDown(true); } -void FlutterLinuxesView::SendPointerUp(double x, double y) { +void FlutterELinuxView::SendPointerUp(double x, double y) { FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); event.x = x; @@ -299,15 +296,15 @@ void FlutterLinuxesView::SendPointerUp(double x, double y) { } } -void FlutterLinuxesView::SendPointerLeave() { +void FlutterELinuxView::SendPointerLeave() { FlutterPointerEvent event = {}; event.phase = FlutterPointerPhase::kRemove; SendPointerEventWithData(event); } -void FlutterLinuxesView::SendScroll(double x, double y, double delta_x, - double delta_y, - int scroll_offset_multiplier) { +void FlutterELinuxView::SendScroll(double x, double y, double delta_x, + double delta_y, + int scroll_offset_multiplier) { FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); event.signal_kind = FlutterPointerSignalKind::kFlutterPointerSignalKindScroll; @@ -318,7 +315,7 @@ void FlutterLinuxesView::SendScroll(double x, double y, double delta_x, SendPointerEventWithData(event); } -void FlutterLinuxesView::SendPointerEventWithData( +void FlutterELinuxView::SendPointerEventWithData( const FlutterPointerEvent& event_data) { // If sending anything other than an add, and the pointer isn't already added, // synthesize an add to satisfy Flutter's expectations about events. @@ -359,46 +356,46 @@ void FlutterLinuxesView::SendPointerEventWithData( } } -void* FlutterLinuxesView::ProcResolver(const char* name) { +void* FlutterELinuxView::ProcResolver(const char* name) { return GetRenderSurfaceTarget()->GlProcResolver(name); } -bool FlutterLinuxesView::MakeCurrent() { +bool FlutterELinuxView::MakeCurrent() { return GetRenderSurfaceTarget()->GLContextMakeCurrent(); } -bool FlutterLinuxesView::ClearCurrent() { +bool FlutterELinuxView::ClearCurrent() { return GetRenderSurfaceTarget()->GLContextClearCurrent(); } -bool FlutterLinuxesView::Present() { +bool FlutterELinuxView::Present() { return GetRenderSurfaceTarget()->GLContextPresent(0); } -uint32_t FlutterLinuxesView::GetOnscreenFBO() { +uint32_t FlutterELinuxView::GetOnscreenFBO() { return GetRenderSurfaceTarget()->GLContextFBO(); } -bool FlutterLinuxesView::MakeResourceCurrent() { +bool FlutterELinuxView::MakeResourceCurrent() { return GetRenderSurfaceTarget()->ResourceContextMakeCurrent(); } -bool FlutterLinuxesView::CreateRenderSurface() { +bool FlutterELinuxView::CreateRenderSurface() { PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); return binding_handler_->CreateRenderSurface(bounds.width, bounds.height); } -void FlutterLinuxesView::DestroyRenderSurface() { +void FlutterELinuxView::DestroyRenderSurface() { binding_handler_->DestroyRenderSurface(); } -LinuxesRenderSurfaceTarget* FlutterLinuxesView::GetRenderSurfaceTarget() const { +ELinuxRenderSurfaceTarget* FlutterELinuxView::GetRenderSurfaceTarget() const { return binding_handler_->GetRenderSurfaceTarget(); } -FlutterLinuxesEngine* FlutterLinuxesView::GetEngine() { return engine_.get(); } +FlutterELinuxEngine* FlutterELinuxView::GetEngine() { return engine_.get(); } -int32_t FlutterLinuxesView::GetFrameRate() { +int32_t FlutterELinuxView::GetFrameRate() { return binding_handler_->GetFrameRate(); } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h similarity index 89% rename from src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h rename to src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index b4394f63..b3eb1645 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_linuxes_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_VIEW_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_VIEW_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_VIEW_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_VIEW_H_ #include #include @@ -11,8 +11,8 @@ #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_engine.h" -#include "flutter/shell/platform/linux_embedded/flutter_linuxes_state.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_state.h" #include "flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.h" @@ -20,23 +20,23 @@ #include "flutter/shell/platform/linux_embedded/plugins/platform_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h" -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" #include "flutter/shell/platform/linux_embedded/public/flutter_platform_views.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" namespace flutter { -class FlutterLinuxesView : public WindowBindingHandlerDelegate { +class FlutterELinuxView : public WindowBindingHandlerDelegate { public: - // Creates a FlutterLinuxesView with the given implementator of + // Creates a FlutterELinuxView with the given implementator of // WindowBindingHandler. // // In order for object to render Flutter content the SetEngine method must be - // called with a valid FlutterLinuxesEngine instance. - FlutterLinuxesView(std::unique_ptr window_binding); + // called with a valid FlutterELinuxEngine instance. + FlutterELinuxView(std::unique_ptr window_binding); - ~FlutterLinuxesView(); + ~FlutterELinuxView(); // Dispatches window events such as mouse and keyboard inputs. For Wayland, // you have to call this every time in the main loop. @@ -44,7 +44,7 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Configures the window instance with an instance of a running Flutter // engine. - void SetEngine(std::unique_ptr engine); + void SetEngine(std::unique_ptr engine); // Registers a factory of the platform view. void RegisterPlatformViewFactory( @@ -58,11 +58,11 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { // Destroys current rendering surface if one has been allocated. void DestroyRenderSurface(); - // Return the currently configured LinuxesRenderSurfaceTarget. - LinuxesRenderSurfaceTarget* GetRenderSurfaceTarget() const; + // Return the currently configured ELinuxRenderSurfaceTarget. + ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const; // Returns the engine backing this view. - FlutterLinuxesEngine* GetEngine(); + FlutterELinuxEngine* GetEngine(); // Returns the frame rate of the display. int32_t GetFrameRate(); @@ -226,7 +226,7 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } // The engine associated with this view. - std::unique_ptr engine_; + std::unique_ptr engine_; // Keeps track of mouse state in relation to the window. MouseState mouse_state_; @@ -264,4 +264,4 @@ class FlutterLinuxesView : public WindowBindingHandlerDelegate { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_LINUXES_VIEW_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_VIEW_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h index 0e014066..fdec398d 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h @@ -10,7 +10,7 @@ #include #include "flutter/shell/platform/embedder/embedder.h" -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h similarity index 100% rename from src/flutter/shell/platform/linux_embedded/public/flutter_linuxes.h rename to src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index b4360708..476bcf98 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" namespace flutter { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 3c6b8a37..3c120999 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -157,7 +157,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - LinuxesRenderSurfaceTarget* GetRenderSurfaceTarget() const override { + ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const override { return render_surface_.get(); } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 821706e3..d2525abf 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -745,8 +745,7 @@ void ELinuxWindowWayland::SetView(WindowBindingHandlerDelegate* window) { binding_handler_delegate_ = window; } -LinuxesRenderSurfaceTarget* ELinuxWindowWayland::GetRenderSurfaceTarget() - const { +ELinuxRenderSurfaceTarget* ELinuxWindowWayland::GetRenderSurfaceTarget() const { return render_surface_.get(); } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index df247505..70150e5b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -50,7 +50,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void SetView(WindowBindingHandlerDelegate* view) override; // |FlutterWindowBindingHandler| - LinuxesRenderSurfaceTarget* GetRenderSurfaceTarget() const override; + ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const override; // |FlutterWindowBindingHandler| double GetDpiScale() override; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 92a8fd8d..c5ba48d3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -131,7 +131,7 @@ void ELinuxWindowX11::SetView(WindowBindingHandlerDelegate* window) { binding_handler_delegate_ = window; } -LinuxesRenderSurfaceTarget* ELinuxWindowX11::GetRenderSurfaceTarget() const { +ELinuxRenderSurfaceTarget* ELinuxWindowX11::GetRenderSurfaceTarget() const { return render_surface_.get(); } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 00480b4f..2a972fb5 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -35,7 +35,7 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { void SetView(WindowBindingHandlerDelegate* view) override; // |FlutterWindowBindingHandler| - LinuxesRenderSurfaceTarget* GetRenderSurfaceTarget() const override; + ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const override; // |FlutterWindowBindingHandler| double GetDpiScale() override; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 74ed1cda..56957f92 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -8,7 +8,7 @@ #include #include -#include "flutter/shell/platform/linux_embedded/public/flutter_linuxes.h" +#include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h" @@ -22,7 +22,7 @@ struct PhysicalWindowBounds { size_t height; }; -using LinuxesRenderSurfaceTarget = SurfaceGl; +using ELinuxRenderSurfaceTarget = SurfaceGl; // Abstract class for binding Linux embedded platform windows to Flutter views. class WindowBindingHandler { @@ -39,9 +39,9 @@ class WindowBindingHandler { // Destroy a surface which is currently used. virtual void DestroyRenderSurface() = 0; - // Returns a valid LinuxesRenderSurfaceTarget representing the backing + // Returns a valid ELinuxRenderSurfaceTarget representing the backing // window. - virtual LinuxesRenderSurfaceTarget* GetRenderSurfaceTarget() const = 0; + virtual ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const = 0; // Sets the delegate used to communicate state changes from window to view // such as key presses, mouse position updates etc. From 8fafc5641b11e9a5a7549479d5698669dadd54a3 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Jun 2021 09:21:05 +0900 Subject: [PATCH 027/178] Add flutter plugin interface (#175) --- CMakeLists.txt | 10 ++++--- cmake/build.cmake | 9 ++++--- cmake/cross-toolchain-aarch64-template.cmake | 6 ++--- ...oss-toolchain-aarch64-yocto-template.cmake | 8 +++--- cmake/install.cmake | 25 ++++++++++++++++++ .../cmake/user_build.cmake | 4 +-- .../generated_plugin_registrant.cc | 5 +++- .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 22 ++++++++++++++++ .../flutter_window.cc | 2 +- .../cmake/user_build.cmake | 4 +-- .../generated_plugin_registrant.cc | 5 +++- .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 22 ++++++++++++++++ .../flutter-drm-gbm-backend/flutter_window.cc | 2 +- .../cmake/user_build.cmake | 5 ++-- .../generated_plugin_registrant.cc | 4 ++- .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 23 ++++++++++++++++ .../elinux/CMakeLists.txt | 26 +++++++++++++++++++ .../elinux}/external_texture_test_plugin.cc | 2 +- .../external_texture_test_plugin.h | 6 ++--- .../flutter_window.cc | 2 +- .../cmake/user_build.cmake | 4 +-- .../flutter}/generated_plugin_registrant.cc | 5 +++- .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 22 ++++++++++++++++ .../flutter-wayland-client/flutter_window.cc | 2 +- .../cmake/user_build.cmake | 5 ++-- .../flutter}/generated_plugin_registrant.cc | 5 +++- .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 22 ++++++++++++++++ .../flutter_window.cc | 2 +- .../flutter-x11-client/cmake/user_build.cmake | 4 +-- .../flutter/generated_plugin_registrant.cc | 10 +++++++ .../generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 22 ++++++++++++++++ examples/flutter-x11-client/flutter_window.cc | 2 +- .../generated_plugin_registrant.cc | 7 ----- .../flutter/generated_plugin_registrant.cc | 10 +++++++ .../generated_plugin_registrant.h | 0 .../common/flutter/generated_plugins.cmake | 22 ++++++++++++++++ src/templates/app/common/flutter_window.cc | 2 +- .../app/common/generated_plugin_registrant.cc | 7 ----- 44 files changed, 289 insertions(+), 56 deletions(-) create mode 100644 cmake/install.cmake rename examples/flutter-drm-eglstream-backend/{ => flutter}/generated_plugin_registrant.cc (50%) rename examples/flutter-drm-eglstream-backend/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-drm-eglstream-backend/flutter/generated_plugins.cmake rename examples/flutter-drm-gbm-backend/{ => flutter}/generated_plugin_registrant.cc (50%) rename examples/flutter-drm-gbm-backend/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-drm-gbm-backend/flutter/generated_plugins.cmake rename examples/flutter-external-texture-plugin/{ => flutter}/generated_plugin_registrant.cc (75%) rename examples/flutter-external-texture-plugin/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-external-texture-plugin/flutter/generated_plugins.cmake create mode 100644 examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/CMakeLists.txt rename examples/flutter-external-texture-plugin/{ => flutter/plugins/external_texture_test/elinux}/external_texture_test_plugin.cc (98%) rename examples/flutter-external-texture-plugin/{ => flutter/plugins/external_texture_test/elinux/include/external_texture_test}/external_texture_test_plugin.h (83%) rename examples/{flutter-weston-desktop-shell => flutter-wayland-client/flutter}/generated_plugin_registrant.cc (50%) rename examples/flutter-wayland-client/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-wayland-client/flutter/generated_plugins.cmake rename examples/{flutter-wayland-client => flutter-weston-desktop-shell/flutter}/generated_plugin_registrant.cc (50%) rename examples/flutter-weston-desktop-shell/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake create mode 100644 examples/flutter-x11-client/flutter/generated_plugin_registrant.cc rename examples/flutter-x11-client/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 examples/flutter-x11-client/flutter/generated_plugins.cmake delete mode 100644 examples/flutter-x11-client/generated_plugin_registrant.cc create mode 100644 src/templates/app/common/flutter/generated_plugin_registrant.cc rename src/templates/app/common/{ => flutter}/generated_plugin_registrant.h (100%) create mode 100644 src/templates/app/common/flutter/generated_plugins.cmake delete mode 100644 src/templates/app/common/generated_plugin_registrant.cc diff --git a/CMakeLists.txt b/CMakeLists.txt index 765b4e6c..e08a73ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,14 @@ cmake_minimum_required(VERSION 3.10) -project("flutter_elinux" LANGUAGES CXX C) # We only support clang, so the build will be faild if you try to build with gcc compiler instead of it. if(NOT DEFINED CMAKE_TOOLCHAIN_FILE) - set(CMAKE_C_COMPILER clang) - set(CMAKE_CXX_COMPILER clang++) + set(CMAKE_C_COMPILER clang) + set(CMAKE_CXX_COMPILER clang++) endif() set(CMAKE_CXX_STANDARD 17) +project("flutter_elinux" LANGUAGES CXX C) + # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) @@ -27,3 +28,6 @@ include(cmake/rapidjson.cmake) # Build for target. include(cmake/build.cmake) + +# Install the bundle. +include(cmake/install.cmake) diff --git a/cmake/build.cmake b/cmake/build.cmake index d3a0cf4e..8c2c95d2 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -162,7 +162,7 @@ target_include_directories(${TARGET} ) set(CMAKE_SKIP_RPATH true) -set(FLUTTER_EMBEDDER_LIB ${CMAKE_CURRENT_SOURCE_DIR}/build/libflutter_engine.so) +set(FLUTTER_EMBEDDER_LIB ${PROJECT_BINARY_DIR}/libflutter_engine.so) target_link_libraries(${TARGET} PRIVATE ${XKBCOMMON_LIBRARIES} @@ -184,8 +184,8 @@ target_link_libraries(${TARGET} if(${BACKEND_TYPE} MATCHES "DRM-(GBM|EGLSTREAM)") target_link_libraries(${TARGET} - PRIVATE - Threads::Threads + PRIVATE + Threads::Threads ) endif() @@ -193,3 +193,6 @@ target_compile_options(${TARGET} PUBLIC ${EGL_CFLAGS} ) + +# Generated plugin build rules +include(${USER_PROJECT_PATH}/flutter/generated_plugins.cmake) diff --git a/cmake/cross-toolchain-aarch64-template.cmake b/cmake/cross-toolchain-aarch64-template.cmake index 0be57f16..d766d449 100644 --- a/cmake/cross-toolchain-aarch64-template.cmake +++ b/cmake/cross-toolchain-aarch64-template.cmake @@ -3,11 +3,12 @@ cmake_minimum_required(VERSION 3.10) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) -# Specify the sysroot. You need to modify appropriately for your environment +# Specify the sysroot. +# You need to modify appropriately for your environment. set(target_sysroot ) set(CMAKE_SYSROOT ${target_sysroot}) -# Specify the cross compiler +# Specify the cross compiler. set(triple aarch64-linux-gnu) set(CMAKE_C_COMPILER_TARGET ${triple}) set(CMAKE_C_COMPILER clang) @@ -19,4 +20,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - diff --git a/cmake/cross-toolchain-aarch64-yocto-template.cmake b/cmake/cross-toolchain-aarch64-yocto-template.cmake index d6d69ed0..3bdc0dad 100644 --- a/cmake/cross-toolchain-aarch64-yocto-template.cmake +++ b/cmake/cross-toolchain-aarch64-yocto-template.cmake @@ -3,9 +3,12 @@ cmake_minimum_required(VERSION 3.10) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR aarch64) -# Specify the sysroot. You need to modify appropriately for your environment +# Specify the sysroot. +# You need to modify appropriately for your environment. set(target_sysroot "") -# Specify the cross compiler. You need to modify appropriately for your environment + +# Specify the cross compiler. +# You need to modify appropriately for your environment. set(toolchain "") set(CMAKE_SYSROOT ${target_sysroot}) @@ -21,4 +24,3 @@ set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - diff --git a/cmake/install.cmake b/cmake/install.cmake new file mode 100644 index 00000000..6711f4dc --- /dev/null +++ b/cmake/install.cmake @@ -0,0 +1,25 @@ +cmake_minimum_required(VERSION 3.10) + +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(FILES "${FLUTTER_EMBEDDER_LIB}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime +) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime + ) +endif() diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake index 31b403b5..f8ad2082 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake @@ -5,8 +5,8 @@ set(TARGET flutter-drm-eglstream-backend) # source files for user apps. set(USER_APP_SRCS + examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.cc examples/flutter-drm-eglstream-backend/flutter_window.cc - examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc examples/flutter-drm-eglstream-backend/main.cc ) @@ -25,4 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES "") +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc b/examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.cc similarity index 50% rename from examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc rename to examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.cc index 8b1dc31e..7e6e6c2d 100644 --- a/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.cc +++ b/examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.cc @@ -2,6 +2,9 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -void RegisterPlugins(flutter::PluginRegistry* registry) {} +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h b/examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-drm-eglstream-backend/generated_plugin_registrant.h rename to examples/flutter-drm-eglstream-backend/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-drm-eglstream-backend/flutter/generated_plugins.cmake b/examples/flutter-drm-eglstream-backend/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-drm-eglstream-backend/flutter_window.cc b/examples/flutter-drm-eglstream-backend/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_window.cc +++ b/examples/flutter-drm-eglstream-backend/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake index 5071071f..445581e1 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake @@ -5,8 +5,8 @@ set(TARGET flutter-drm-gbm-backend) # source files for user apps. set(USER_APP_SRCS + examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.cc examples/flutter-drm-gbm-backend/flutter_window.cc - examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc examples/flutter-drm-gbm-backend/main.cc ) @@ -25,4 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES "") +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc b/examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.cc similarity index 50% rename from examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc rename to examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.cc index 8b1dc31e..7e6e6c2d 100644 --- a/examples/flutter-drm-gbm-backend/generated_plugin_registrant.cc +++ b/examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.cc @@ -2,6 +2,9 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -void RegisterPlugins(flutter::PluginRegistry* registry) {} +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/examples/flutter-drm-gbm-backend/generated_plugin_registrant.h b/examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-drm-gbm-backend/generated_plugin_registrant.h rename to examples/flutter-drm-gbm-backend/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-drm-gbm-backend/flutter/generated_plugins.cmake b/examples/flutter-drm-gbm-backend/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/examples/flutter-drm-gbm-backend/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-drm-gbm-backend/flutter_window.cc b/examples/flutter-drm-gbm-backend/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-drm-gbm-backend/flutter_window.cc +++ b/examples/flutter-drm-gbm-backend/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-external-texture-plugin/cmake/user_build.cmake b/examples/flutter-external-texture-plugin/cmake/user_build.cmake index 636f4d84..092926f2 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_build.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_build.cmake @@ -5,9 +5,8 @@ set(TARGET flutter-client) # source files for user apps. set(USER_APP_SRCS - examples/flutter-external-texture-plugin/external_texture_test_plugin.cc + examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.cc examples/flutter-external-texture-plugin/flutter_window.cc - examples/flutter-external-texture-plugin/generated_plugin_registrant.cc examples/flutter-external-texture-plugin/main.cc ) @@ -26,4 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES "") +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-external-texture-plugin/generated_plugin_registrant.cc b/examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.cc similarity index 75% rename from examples/flutter-external-texture-plugin/generated_plugin_registrant.cc rename to examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.cc index a4b7cc2c..7b30517d 100644 --- a/examples/flutter-external-texture-plugin/generated_plugin_registrant.cc +++ b/examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.cc @@ -2,9 +2,11 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -#include "external_texture_test_plugin.h" +#include void RegisterPlugins(flutter::PluginRegistry* registry) { ExternalTextureTestPluginRegisterWithRegistrar( diff --git a/examples/flutter-external-texture-plugin/generated_plugin_registrant.h b/examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-external-texture-plugin/generated_plugin_registrant.h rename to examples/flutter-external-texture-plugin/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-external-texture-plugin/flutter/generated_plugins.cmake b/examples/flutter-external-texture-plugin/flutter/generated_plugins.cmake new file mode 100644 index 00000000..a17b7381 --- /dev/null +++ b/examples/flutter-external-texture-plugin/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + external_texture_test +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/CMakeLists.txt b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/CMakeLists.txt new file mode 100644 index 00000000..e84bfcc5 --- /dev/null +++ b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/CMakeLists.txt @@ -0,0 +1,26 @@ +cmake_minimum_required(VERSION 3.10) + +set(PROJECT_NAME "external_texture_test") +set(PLUGIN_NAME "${PROJECT_NAME}_plugin") +project(${PROJECT_NAME} LANGUAGES CXX) + +add_library(${PLUGIN_NAME} + SHARED + "${PLUGIN_NAME}.cc" +) + +target_compile_definitions(${PLUGIN_NAME} + PRIVATE + FLUTTER_PLUGIN_IMPL +) + +target_include_directories(${PLUGIN_NAME} + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +target_include_directories(${PLUGIN_NAME} + PRIVATE + ${CMAKE_SOURCE_DIR}/src/flutter/shell/platform/common/client_wrapper/include + ${CMAKE_SOURCE_DIR}/src/flutter/shell/platform/common/public +) diff --git a/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/external_texture_test_plugin.cc similarity index 98% rename from examples/flutter-external-texture-plugin/external_texture_test_plugin.cc rename to examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/external_texture_test_plugin.cc index 4f3e4c28..4d8367b8 100644 --- a/examples/flutter-external-texture-plugin/external_texture_test_plugin.cc +++ b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/external_texture_test_plugin.cc @@ -1,4 +1,4 @@ -#include "external_texture_test_plugin.h" +#include "include/external_texture_test/external_texture_test_plugin.h" #include #include diff --git a/examples/flutter-external-texture-plugin/external_texture_test_plugin.h b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/include/external_texture_test/external_texture_test_plugin.h similarity index 83% rename from examples/flutter-external-texture-plugin/external_texture_test_plugin.h rename to examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/include/external_texture_test/external_texture_test_plugin.h index 7bb2b8ca..f55b8591 100644 --- a/examples/flutter-external-texture-plugin/external_texture_test_plugin.h +++ b/examples/flutter-external-texture-plugin/flutter/plugins/external_texture_test/elinux/include/external_texture_test/external_texture_test_plugin.h @@ -1,5 +1,5 @@ -#ifndef EXAMPLES_FLUTTER_EXTERNAL_TEXTURE_PLUGIN_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ -#define EXAMPLES_FLUTTER_EXTERNAL_TEXTURE_PLUGIN_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ +#ifndef PLUGINS_EXTERNAL_TEXTURE_TEST_ELINUX_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ +#define PLUGINS_EXTERNAL_TEXTURE_TEST_ELINUX_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ #include #include @@ -46,4 +46,4 @@ class ExternalTextureTestPlugin : public flutter::Plugin { void ExternalTextureTestPluginRegisterWithRegistrar( FlutterDesktopPluginRegistrarRef registrar); -#endif // EXAMPLES_FLUTTER_EXTERNAL_TEXTURE_PLUGIN_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ +#endif // PLUGINS_EXTERNAL_TEXTURE_TEST_ELINUX_EXTERNAL_TEXTURE_TEST_PLUGIN_H_ diff --git a/examples/flutter-external-texture-plugin/flutter_window.cc b/examples/flutter-external-texture-plugin/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-external-texture-plugin/flutter_window.cc +++ b/examples/flutter-external-texture-plugin/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-wayland-client/cmake/user_build.cmake b/examples/flutter-wayland-client/cmake/user_build.cmake index e2af29f6..213a3444 100644 --- a/examples/flutter-wayland-client/cmake/user_build.cmake +++ b/examples/flutter-wayland-client/cmake/user_build.cmake @@ -5,8 +5,8 @@ set(TARGET flutter-client) # source files for user apps. set(USER_APP_SRCS + examples/flutter-wayland-client/flutter/generated_plugin_registrant.cc examples/flutter-wayland-client/flutter_window.cc - examples/flutter-wayland-client/generated_plugin_registrant.cc examples/flutter-wayland-client/main.cc ) @@ -25,4 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES "") +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc b/examples/flutter-wayland-client/flutter/generated_plugin_registrant.cc similarity index 50% rename from examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc rename to examples/flutter-wayland-client/flutter/generated_plugin_registrant.cc index 8b1dc31e..7e6e6c2d 100644 --- a/examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc +++ b/examples/flutter-wayland-client/flutter/generated_plugin_registrant.cc @@ -2,6 +2,9 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -void RegisterPlugins(flutter::PluginRegistry* registry) {} +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/examples/flutter-wayland-client/generated_plugin_registrant.h b/examples/flutter-wayland-client/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-wayland-client/generated_plugin_registrant.h rename to examples/flutter-wayland-client/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-wayland-client/flutter/generated_plugins.cmake b/examples/flutter-wayland-client/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/examples/flutter-wayland-client/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-wayland-client/flutter_window.cc b/examples/flutter-wayland-client/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-wayland-client/flutter_window.cc +++ b/examples/flutter-wayland-client/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake index 59114abb..a8af88a3 100644 --- a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake +++ b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake @@ -5,8 +5,8 @@ set(TARGET flutter-desktop-shell) # source files for user apps. set(USER_APP_SRCS + examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc examples/flutter-weston-desktop-shell/flutter_window.cc - examples/flutter-weston-desktop-shell/generated_plugin_registrant.cc examples/flutter-weston-desktop-shell/main.cc ) @@ -25,5 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES -) +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-wayland-client/generated_plugin_registrant.cc b/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc similarity index 50% rename from examples/flutter-wayland-client/generated_plugin_registrant.cc rename to examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc index 8b1dc31e..7e6e6c2d 100644 --- a/examples/flutter-wayland-client/generated_plugin_registrant.cc +++ b/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc @@ -2,6 +2,9 @@ // Generated file. Do not edit. // +// clang-format off + #include "generated_plugin_registrant.h" -void RegisterPlugins(flutter::PluginRegistry* registry) {} +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/examples/flutter-weston-desktop-shell/generated_plugin_registrant.h b/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-weston-desktop-shell/generated_plugin_registrant.h rename to examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake b/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-weston-desktop-shell/flutter_window.cc b/examples/flutter-weston-desktop-shell/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-weston-desktop-shell/flutter_window.cc +++ b/examples/flutter-weston-desktop-shell/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-x11-client/cmake/user_build.cmake b/examples/flutter-x11-client/cmake/user_build.cmake index 75174811..a2a7c54a 100644 --- a/examples/flutter-x11-client/cmake/user_build.cmake +++ b/examples/flutter-x11-client/cmake/user_build.cmake @@ -5,8 +5,8 @@ set(TARGET flutter-x11-client) # source files for user apps. set(USER_APP_SRCS + examples/flutter-x11-client/flutter/generated_plugin_registrant.cc examples/flutter-x11-client/flutter_window.cc - examples/flutter-x11-client/generated_plugin_registrant.cc examples/flutter-x11-client/main.cc ) @@ -25,4 +25,4 @@ set(USER_APP_INCLUDE_DIRS ) # link libraries for user apps. -set(USER_APP_LIBRARIES "") +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-x11-client/flutter/generated_plugin_registrant.cc b/examples/flutter-x11-client/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000..7e6e6c2d --- /dev/null +++ b/examples/flutter-x11-client/flutter/generated_plugin_registrant.cc @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/examples/flutter-x11-client/generated_plugin_registrant.h b/examples/flutter-x11-client/flutter/generated_plugin_registrant.h similarity index 100% rename from examples/flutter-x11-client/generated_plugin_registrant.h rename to examples/flutter-x11-client/flutter/generated_plugin_registrant.h diff --git a/examples/flutter-x11-client/flutter/generated_plugins.cmake b/examples/flutter-x11-client/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/examples/flutter-x11-client/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-x11-client/flutter_window.cc b/examples/flutter-x11-client/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/examples/flutter-x11-client/flutter_window.cc +++ b/examples/flutter-x11-client/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/examples/flutter-x11-client/generated_plugin_registrant.cc b/examples/flutter-x11-client/generated_plugin_registrant.cc deleted file mode 100644 index 8b1dc31e..00000000 --- a/examples/flutter-x11-client/generated_plugin_registrant.cc +++ /dev/null @@ -1,7 +0,0 @@ -// -// Generated file. Do not edit. -// - -#include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) {} diff --git a/src/templates/app/common/flutter/generated_plugin_registrant.cc b/src/templates/app/common/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000..7e6e6c2d --- /dev/null +++ b/src/templates/app/common/flutter/generated_plugin_registrant.cc @@ -0,0 +1,10 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +void RegisterPlugins(flutter::PluginRegistry* registry) { +} diff --git a/src/templates/app/common/generated_plugin_registrant.h b/src/templates/app/common/flutter/generated_plugin_registrant.h similarity index 100% rename from src/templates/app/common/generated_plugin_registrant.h rename to src/templates/app/common/flutter/generated_plugin_registrant.h diff --git a/src/templates/app/common/flutter/generated_plugins.cmake b/src/templates/app/common/flutter/generated_plugins.cmake new file mode 100644 index 00000000..fcbf0d6e --- /dev/null +++ b/src/templates/app/common/flutter/generated_plugins.cmake @@ -0,0 +1,22 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/src/templates/app/common/flutter_window.cc b/src/templates/app/common/flutter_window.cc index 9775d89b..0c5b6397 100644 --- a/src/templates/app/common/flutter_window.cc +++ b/src/templates/app/common/flutter_window.cc @@ -9,7 +9,7 @@ #include #include -#include "generated_plugin_registrant.h" +#include "flutter/generated_plugin_registrant.h" FlutterWindow::FlutterWindow( const flutter::FlutterViewController::ViewProperties view_properties, diff --git a/src/templates/app/common/generated_plugin_registrant.cc b/src/templates/app/common/generated_plugin_registrant.cc deleted file mode 100644 index 8b1dc31e..00000000 --- a/src/templates/app/common/generated_plugin_registrant.cc +++ /dev/null @@ -1,7 +0,0 @@ -// -// Generated file. Do not edit. -// - -#include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) {} From 14857f3b23821c6bc9e7a0034f7f488ff0566868 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Jun 2021 10:51:30 +0900 Subject: [PATCH 028/178] Temporarily disable Vsync callback (#177) See: https://github.com/sony/flutter-embedded-linux/issues/176 --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index eb8510f3..13c69c39 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -206,6 +206,10 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { auto host = static_cast(user_data); return host->HandlePlatformMessage(engine_message); }; +// todo: disable vsync temporarily because flutter apps will freeze when we use +// this interface. See also: +// https://github.com/sony/flutter-embedded-linux/issues/176 +#if 0 // todo: add drm/x11 support. // https://github.com/sony/flutter-embedded-linux/issues/136 // https://github.com/sony/flutter-embedded-linux/issues/137 @@ -214,6 +218,7 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { auto host = static_cast(user_data); host->vsync_waiter_->NotifyWaitForVsync(baton); }; +#endif #endif args.custom_task_runners = &custom_task_runners; @@ -382,7 +387,7 @@ bool FlutterELinuxEngine::MarkExternalTextureFrameAvailable( } void FlutterELinuxEngine::OnVsync(uint64_t last_frame_time_nanos, - uint64_t vsync_interval_time_nanos) { + uint64_t vsync_interval_time_nanos) { uint64_t current_time_nanos = embedder_api_.GetCurrentTime(); uint64_t after_vsync_passed_time_nanos = (current_time_nanos - last_frame_time_nanos) % vsync_interval_time_nanos; From 07c5bd215a89e55c0fe25a9147d8813bf6547b5a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Jun 2021 15:32:07 +0900 Subject: [PATCH 029/178] Fix build error in yocto (#178) --- cmake/build.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/build.cmake b/cmake/build.cmake index 8c2c95d2..48291e3c 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -162,7 +162,7 @@ target_include_directories(${TARGET} ) set(CMAKE_SKIP_RPATH true) -set(FLUTTER_EMBEDDER_LIB ${PROJECT_BINARY_DIR}/libflutter_engine.so) +set(FLUTTER_EMBEDDER_LIB ${CMAKE_CURRENT_SOURCE_DIR}/build/libflutter_engine.so) target_link_libraries(${TARGET} PRIVATE ${XKBCOMMON_LIBRARIES} From 1f55fb6f66930a1ac7659693c8ab3a1e600e7d41 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 21 Jun 2021 15:03:44 +0900 Subject: [PATCH 030/178] Add simple window titlebar for Wayland (#180) --- cmake/build.cmake | 4 +- .../flutter-drm-eglstream-backend/main.cc | 1 + examples/flutter-drm-gbm-backend/main.cc | 1 + .../flutter-external-texture-plugin/main.cc | 4 + examples/flutter-wayland-client/main.cc | 4 + examples/flutter-weston-desktop-shell/main.cc | 1 + examples/flutter-x11-client/main.cc | 1 + src/client_wrapper/flutter_view_controller.cc | 2 + .../include/flutter/flutter_view_controller.h | 4 + .../linux_embedded/public/flutter_elinux.h | 4 + .../surface/surface_decoration.cc | 69 +++++++++++++++ .../surface/surface_decoration.h | 58 +++++++++++++ .../window/elinux_window_wayland.cc | 86 +++++++++++++++++++ .../window/elinux_window_wayland.h | 10 +++ .../native_window_wayland_decoration.cc | 71 +++++++++++++++ .../window/native_window_wayland_decoration.h | 35 ++++++++ src/templates/app/linux-drm/main.cc | 1 + .../main.cc | 1 + src/templates/app/linux-wayland/main.cc | 4 + src/templates/app/linux-x11/main.cc | 1 + 20 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc create mode 100644 src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h diff --git a/cmake/build.cmake b/cmake/build.cmake index 48291e3c..9142d524 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -65,7 +65,8 @@ else() ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c ${_wayland_protocols_src_dir}/presentation-time-protocol.c src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc - src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc) + src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc + src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc) endif() # desktop-shell for weston. @@ -121,6 +122,7 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc src/flutter/shell/platform/linux_embedded/surface/surface.cc src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc + src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc ${DISPLAY_BACKEND_SRC} ${WAYLAND_PROTOCOL_SRC} ## The following file were copied from: diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 3ea7b882..edbe7616 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { flutter::FlutterViewController::ViewMode::kFullscreen; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = false; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 3ea7b882..edbe7616 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { flutter::FlutterViewController::ViewMode::kFullscreen; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = false; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 4559c3c9..73e4c941 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -21,6 +21,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); + options.AddWithoutValue("window-decoration", "d", "Enable window decorations", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -33,6 +35,7 @@ int main(int argc, char** argv) { const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const bool use_window_decoration = options.Exist("window-decoration"); const auto view_mode = options.Exist("fullscreen") @@ -52,6 +55,7 @@ int main(int argc, char** argv) { view_properties.view_mode = view_mode; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + view_properties.use_window_decoration = use_window_decoration; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 4559c3c9..73e4c941 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -21,6 +21,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); + options.AddWithoutValue("window-decoration", "d", "Enable window decorations", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -33,6 +35,7 @@ int main(int argc, char** argv) { const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const bool use_window_decoration = options.Exist("window-decoration"); const auto view_mode = options.Exist("fullscreen") @@ -52,6 +55,7 @@ int main(int argc, char** argv) { view_properties.view_mode = view_mode; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + view_properties.use_window_decoration = use_window_decoration; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc index bd8407f1..acbd179b 100644 --- a/examples/flutter-weston-desktop-shell/main.cc +++ b/examples/flutter-weston-desktop-shell/main.cc @@ -61,6 +61,7 @@ int main(int argc, char** argv) { flutter::FlutterViewController::ViewMode::kFullscreen; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = true; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 6dfb5fb8..9512dea5 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -48,6 +48,7 @@ int main(int argc, char** argv) { view_properties.view_mode = view_mode; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = false; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index dcbf3f5a..afd61d08 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -23,6 +23,8 @@ FlutterViewController::FlutterViewController( c_view_properties.use_mouse_cursor = view_properties.use_mouse_cursor; c_view_properties.use_onscreen_keyboard = view_properties.use_onscreen_keyboard; + c_view_properties.use_window_decoration = + view_properties.use_window_decoration; controller_ = FlutterDesktopViewControllerCreate(c_view_properties, engine_->RelinquishEngine()); diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index a4a9c118..0d9926df 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -49,6 +49,10 @@ class FlutterViewController { // Uses the on-screen keyboard. bool use_onscreen_keyboard; + + // Uses the window decoration such as toolbar and max/min buttons. + // This option is only active for Wayland backend. + bool use_window_decoration; } ViewProperties; // Creates a FlutterView that can be parented into a Windows View hierarchy diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 6ba19b84..134624d1 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -79,6 +79,10 @@ typedef struct { // Uses the on-screen keyboard. bool use_onscreen_keyboard; + + // Uses the window decoration such as toolbar and max/min buttons. + // This option is only active for Wayland backend. + bool use_window_decoration; } FlutterDesktopViewProperties; // ========== View Controller ========== diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc new file mode 100644 index 00000000..b4c7bb4e --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc @@ -0,0 +1,69 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/surface/surface_decoration.h" + +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +SurfaceDecoration::SurfaceDecoration(std::unique_ptr context) { + context_ = std::move(context); +} + +bool SurfaceDecoration::IsValid() const { return context_->IsValid(); }; + +bool SurfaceDecoration::SetNativeWindow(NativeWindow* window) { + native_window_ = window; + + surface_ = context_->CreateOnscreenSurface(native_window_); + if (!surface_->IsValid()) { + return false; + } + + return true; +}; + +bool SurfaceDecoration::Resize(const size_t width, const size_t height) { + if (!native_window_->Resize(width, height)) { + ELINUX_LOG(ERROR) << "Failed to resize."; + return false; + } + + if (native_window_->IsNeedRecreateSurfaceAfterResize()) { + DestroyContext(); + surface_ = context_->CreateOnscreenSurface(native_window_); + if (!surface_->IsValid()) { + ELINUX_LOG(WARNING) << "Failed to recreate decoration surface."; + surface_ = nullptr; + return false; + } + } + return true; +}; + +void SurfaceDecoration::DestroyContext() { + context_->ClearCurrent(); + surface_ = nullptr; +}; + +bool SurfaceDecoration::GLContextMakeCurrent() const { + return surface_->MakeCurrent(); +} + +bool SurfaceDecoration::GLContextClearCurrent() const { + return context_->ClearCurrent(); +} + +bool SurfaceDecoration::GLContextPresent(uint32_t fbo_id) const { + return surface_->SwapBuffers(); +} + +uint32_t SurfaceDecoration::GLContextFBO() const { return 0; } + +void* SurfaceDecoration::GlProcResolver(const char* name) const { + return context_->GlProcResolver(name); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h new file mode 100644 index 00000000..243a3ee1 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h @@ -0,0 +1,58 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_DECORATION_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_DECORATION_H_ + +#include + +#include "flutter/shell/platform/linux_embedded/surface/context_egl.h" +#include "flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h" +#include "flutter/shell/platform/linux_embedded/window/native_window.h" + +namespace flutter { + +// Surface for window decorations such as a toolbar and max/min buttons. +class SurfaceDecoration : public SurfaceGlDelegate { + public: + SurfaceDecoration(std::unique_ptr context); + ~SurfaceDecoration() = default; + + // Shows a surface is valid or not. + bool IsValid() const; + + // Sets a netive platform's window. + bool SetNativeWindow(NativeWindow* window); + + // Changes an decoration surface size. + bool Resize(const size_t width, const size_t height); + + // Clears and destroys current decoration context. + void DestroyContext(); + + // |SurfaceGlDelegate| + bool GLContextMakeCurrent() const override; + + // |SurfaceGlDelegate| + bool GLContextClearCurrent() const override; + + // |SurfaceGlDelegate| + bool GLContextPresent(uint32_t fbo_id) const override; + + // |SurfaceGlDelegate| + uint32_t GLContextFBO() const override; + + // |SurfaceGlDelegate| + void* GlProcResolver(const char* name) const override; + + protected: + std::unique_ptr context_; + NativeWindow* native_window_ = nullptr; + std::unique_ptr surface_ = nullptr; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_DECORATION_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index d2525abf..64334734 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -4,6 +4,13 @@ #include "flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h" +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif + #include #include #include @@ -20,6 +27,10 @@ namespace flutter { namespace { +typedef void (*glClearColorProc)(GLfloat red, GLfloat green, GLfloat blue, + GLfloat alpha); +typedef void (*glClearProc)(GLbitfield mask); + constexpr char kWestonDesktopShell[] = "weston_desktop_shell"; constexpr char kZwpTextInputManagerV1[] = "zwp_text_input_manager_v1"; constexpr char kZwpTextInputManagerV3[] = "zwp_text_input_manager_v3"; @@ -96,6 +107,10 @@ const wp_presentation_feedback_listener tv_nsec; self->frame_rate_ = static_cast(std::round(1000000000000.0 / refresh)); + + if (self->view_properties_.use_window_decoration) { + self->DrawWindowDecoration(); + } }, .discarded = [](void* data, @@ -112,6 +127,10 @@ const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { return; } + if (self->view_properties_.use_window_decoration) { + self->DrawWindowDecoration(); + } + self->last_frame_time_nanos_ = static_cast(time) * 1000000; auto callback = wl_surface_frame(self->native_window_->Surface()); @@ -156,7 +175,9 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); + self->wl_current_surface_ = surface; self->serial_ = serial; + if (self->view_properties_.use_mouse_cursor) { self->cursor_info_.pointer = wl_pointer; self->cursor_info_.serial = serial; @@ -173,7 +194,9 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { .leave = [](void* data, wl_pointer* pointer, uint32_t serial, wl_surface* surface) -> void { auto self = reinterpret_cast(data); + self->wl_current_surface_ = surface; self->serial_ = serial; + if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnPointerLeave(); self->pointer_x_ = -1; @@ -195,6 +218,17 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { uint32_t time, uint32_t button, uint32_t status) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; + + if (self->view_properties_.use_window_decoration && + self->wl_current_surface_ == + self->native_window_decoration_->Surface()) { + if (button == BTN_LEFT && status == WL_POINTER_BUTTON_STATE_PRESSED && + self->xdg_toplevel_) { + xdg_toplevel_move(self->xdg_toplevel_, self->wl_seat_, serial); + } + return; + } + if (self->binding_handler_delegate_) { FlutterPointerMouseButtons flutter_button; switch (button) { @@ -342,6 +376,12 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { FlutterDesktopViewMode::kFullscreen) { self->view_properties_.width = width; self->view_properties_.height = height; + + if (self->view_properties_.use_window_decoration && + self->render_surface_decoration_) { + self->render_surface_decoration_->Resize(width, height); + } + if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnWindowSizeChanged(width, height); } @@ -550,6 +590,10 @@ ELinuxWindowWayland::ELinuxWindowWayland( : cursor_info_({"", 0, nullptr}), display_valid_(false), is_requested_show_virtual_keyboard_(false), + xdg_toplevel_(nullptr), + wl_compositor_(nullptr), + wl_subcompositor_(nullptr), + wl_current_surface_(nullptr), wl_seat_(nullptr), wl_pointer_(nullptr), wl_touch_(nullptr), @@ -729,6 +773,11 @@ ELinuxWindowWayland::~ELinuxWindowWayland() { wl_compositor_ = nullptr; } + if (wl_subcompositor_) { + wl_subcompositor_destroy(wl_subcompositor_); + wl_subcompositor_ = nullptr; + } + if (wl_registry_) { wl_registry_destroy(wl_registry_); wl_registry_ = nullptr; @@ -869,6 +918,19 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { std::make_unique(wl_display_))); render_surface_->SetNativeWindow(native_window_.get()); + if (view_properties_.use_window_decoration) { + native_window_decoration_ = std::make_unique( + wl_compositor_, wl_subcompositor_, native_window_->Surface(), width, + height); + + render_surface_decoration_ = + std::make_unique(std::make_unique( + std::make_unique(wl_display_))); + render_surface_decoration_->SetNativeWindow( + native_window_decoration_.get()); + render_surface_decoration_->Resize(width, height); + } + return true; } @@ -879,6 +941,11 @@ void ELinuxWindowWayland::DestroyRenderSurface() { native_window_ = nullptr; } + if (view_properties_.use_window_decoration) { + render_surface_decoration_ = nullptr; + native_window_decoration_ = nullptr; + } + if (xdg_surface_) { xdg_surface_destroy(xdg_surface_); xdg_surface_ = nullptr; @@ -1002,6 +1069,11 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, return; } + if (!strcmp(interface, wl_subcompositor_interface.name)) { + wl_subcompositor_ = static_cast( + wl_registry_bind(wl_registry, name, &wl_subcompositor_interface, 1)); + } + if (!strcmp(interface, xdg_wm_base_interface.name)) { xdg_wm_base_ = static_cast( wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1)); @@ -1206,4 +1278,18 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { } } +void ELinuxWindowWayland::DrawWindowDecoration() { + render_surface_decoration_->GLContextMakeCurrent(); + + auto glClearColor = reinterpret_cast( + render_surface_decoration_->GlProcResolver("glClearColor")); + glClearColor(51 / 255.0, 51 / 255.0, 51 / 255.0, 1); + + auto glClear = reinterpret_cast( + render_surface_decoration_->GlProcResolver("glClear")); + glClear(GL_COLOR_BUFFER_BIT); + + render_surface_decoration_->GLContextPresent(0); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 70150e5b..53e25b8b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -12,9 +12,11 @@ #include #include +#include "flutter/shell/platform/linux_embedded/surface/surface_decoration.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/elinux_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_wayland.h" +#include "flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" // These header files are automatically generated by the @@ -93,6 +95,8 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void DismissVirtualKeybaord(); + void DrawWindowDecoration(); + static const wl_registry_listener kWlRegistryListener; static const xdg_wm_base_listener kXdgWmBaseListener; static const xdg_surface_listener kXdgSurfaceListener; @@ -117,6 +121,12 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { std::unique_ptr native_window_; std::unique_ptr render_surface_; + // decorations. + wl_surface* wl_current_surface_; + wl_subcompositor* wl_subcompositor_; + std::unique_ptr native_window_decoration_; + std::unique_ptr render_surface_decoration_; + bool display_valid_; uint32_t last_frame_time_; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc new file mode 100644 index 00000000..73c31820 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -0,0 +1,71 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h" + +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +namespace { +constexpr uint kWindowDecorationTitleBarSize = 40; +} // namespace + +NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( + wl_compositor* compositor, wl_subcompositor* subcompositor, + wl_surface* parent_surface, const size_t width, const size_t height) { + surface_ = wl_compositor_create_surface(compositor); + if (!surface_) { + ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; + return; + } + + subsurface_ = + wl_subcompositor_get_subsurface(subcompositor, surface_, parent_surface); + if (!subsurface_) { + ELINUX_LOG(ERROR) << "Failed to get the subsurface."; + return; + } + wl_subsurface_set_desync(subsurface_); + wl_subsurface_set_position(subsurface_, 0, 0); + + window_ = wl_egl_window_create(surface_, 1, 1); + if (!window_) { + ELINUX_LOG(ERROR) << "Failed to create the EGL window."; + return; + } + + width_ = width; + height_ = height; + valid_ = true; +} + +NativeWindowWaylandDecoration::~NativeWindowWaylandDecoration() { + if (window_) { + wl_egl_window_destroy(window_); + window_ = nullptr; + } + + if (surface_) { + wl_surface_destroy(surface_); + surface_ = nullptr; + } +} + +bool NativeWindowWaylandDecoration::Resize(const size_t width, + const size_t height) { + if (!valid_) { + ELINUX_LOG(ERROR) << "Failed to resize the window."; + return false; + } + + wl_subsurface_set_position(subsurface_, 0, -kWindowDecorationTitleBarSize); + wl_egl_window_resize(window_, width, kWindowDecorationTitleBarSize, 0, 0); + + width_ = width; + height_ = height; + return true; +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h new file mode 100644 index 00000000..f78c58d2 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -0,0 +1,35 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_NATIVE_WINDOW_WAYLAND_DECORATION_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_NATIVE_WINDOW_WAYLAND_DECORATION_H_ + +#include +#include + +#include "flutter/shell/platform/linux_embedded/window/native_window.h" + +namespace flutter { + +class NativeWindowWaylandDecoration : public NativeWindow { + public: + NativeWindowWaylandDecoration(wl_compositor* compositor, + wl_subcompositor* subcompositor, + wl_surface* parent_surface, const size_t width, + const size_t height); + ~NativeWindowWaylandDecoration(); + + // |NativeWindow| + bool Resize(const size_t width, const size_t height) override; + + wl_surface* Surface() const { return surface_; } + + private: + wl_surface* surface_ = nullptr; + wl_subsurface* subsurface_ = nullptr; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_NATIVE_WINDOW_WAYLAND_DECORATION_H_ diff --git a/src/templates/app/linux-drm/main.cc b/src/templates/app/linux-drm/main.cc index 3ea7b882..edbe7616 100644 --- a/src/templates/app/linux-drm/main.cc +++ b/src/templates/app/linux-drm/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { flutter::FlutterViewController::ViewMode::kFullscreen; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = false; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc index bd8407f1..acbd179b 100644 --- a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc +++ b/src/templates/app/linux-wayland-weston-desktop-shell/main.cc @@ -61,6 +61,7 @@ int main(int argc, char** argv) { flutter::FlutterViewController::ViewMode::kFullscreen; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = true; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/templates/app/linux-wayland/main.cc b/src/templates/app/linux-wayland/main.cc index 4559c3c9..73e4c941 100644 --- a/src/templates/app/linux-wayland/main.cc +++ b/src/templates/app/linux-wayland/main.cc @@ -21,6 +21,8 @@ int main(int argc, char** argv) { options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); + options.AddWithoutValue("window-decoration", "d", "Enable window decorations", + false); options.AddInt("width", "w", "Flutter app window width", 1280, false); options.AddInt("height", "h", "Flutter app window height", 720, false); if (!options.Parse(argc, argv)) { @@ -33,6 +35,7 @@ int main(int argc, char** argv) { const auto bundle_path = options.GetValue("bundle"); const bool show_cursor = !options.Exist("no-cursor"); const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const bool use_window_decoration = options.Exist("window-decoration"); const auto view_mode = options.Exist("fullscreen") @@ -52,6 +55,7 @@ int main(int argc, char** argv) { view_properties.view_mode = view_mode; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + view_properties.use_window_decoration = use_window_decoration; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/templates/app/linux-x11/main.cc b/src/templates/app/linux-x11/main.cc index 6dfb5fb8..9512dea5 100644 --- a/src/templates/app/linux-x11/main.cc +++ b/src/templates/app/linux-x11/main.cc @@ -48,6 +48,7 @@ int main(int argc, char** argv) { view_properties.view_mode = view_mode; view_properties.use_mouse_cursor = show_cursor; view_properties.use_onscreen_keyboard = false; + view_properties.use_window_decoration = false; // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); From 0c6bf2762e8be92f9f0cfe5a0965a4cbe3cad0bd Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 24 Jun 2021 14:20:18 +0900 Subject: [PATCH 031/178] Rename surface to surface_base (#183) Fixed https://github.com/sony/flutter-embedded-linux/issues/182 --- cmake/build.cmake | 2 +- .../surface/{surface.cc => surface_base.cc} | 17 ++++++++++------- .../surface/{surface.h => surface_base.h} | 11 +++++++---- .../linux_embedded/surface/surface_gl.h | 4 ++-- 4 files changed, 20 insertions(+), 14 deletions(-) rename src/flutter/shell/platform/linux_embedded/surface/{surface.cc => surface_base.cc} (73%) rename src/flutter/shell/platform/linux_embedded/surface/{surface.h => surface_base.h} (86%) diff --git a/cmake/build.cmake b/cmake/build.cmake index 9142d524..73ac1678 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -120,7 +120,7 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/surface/context_egl.cc src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc - src/flutter/shell/platform/linux_embedded/surface/surface.cc + src/flutter/shell/platform/linux_embedded/surface/surface_base.cc src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc ${DISPLAY_BACKEND_SRC} diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc similarity index 73% rename from src/flutter/shell/platform/linux_embedded/surface/surface.cc rename to src/flutter/shell/platform/linux_embedded/surface/surface_base.cc index d67e5f72..f27f4f21 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc @@ -2,17 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "flutter/shell/platform/linux_embedded/surface/surface.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_base.h" #include "flutter/shell/platform/linux_embedded/logger.h" namespace flutter { -bool Surface::IsValid() const { +bool SurfaceBase::IsValid() const { return offscreen_surface_ && context_->IsValid(); }; -bool Surface::SetNativeWindow(NativeWindow* window) { +bool SurfaceBase::SetNativeWindow(NativeWindow* window) { native_window_ = window; onscreen_surface_ = context_->CreateOnscreenSurface(native_window_); @@ -29,7 +29,8 @@ bool Surface::SetNativeWindow(NativeWindow* window) { return true; }; -bool Surface::OnScreenSurfaceResize(const size_t width, const size_t height) { +bool SurfaceBase::OnScreenSurfaceResize(const size_t width, + const size_t height) { if (!native_window_->Resize(width, height)) { ELINUX_LOG(ERROR) << "Failed to resize."; return false; @@ -47,14 +48,16 @@ bool Surface::OnScreenSurfaceResize(const size_t width, const size_t height) { return true; }; -bool Surface::ClearCurrentContext() const { return context_->ClearCurrent(); }; +bool SurfaceBase::ClearCurrentContext() const { + return context_->ClearCurrent(); +}; -void Surface::DestroyOnScreenContext() { +void SurfaceBase::DestroyOnScreenContext() { context_->ClearCurrent(); onscreen_surface_ = nullptr; }; -bool Surface::ResourceContextMakeCurrent() const { +bool SurfaceBase::ResourceContextMakeCurrent() const { if (!offscreen_surface_) { return false; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface.h b/src/flutter/shell/platform/linux_embedded/surface/surface_base.h similarity index 86% rename from src/flutter/shell/platform/linux_embedded/surface/surface.h rename to src/flutter/shell/platform/linux_embedded/surface/surface_base.h index 0612b685..d1c5e2af 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_base.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_BASE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_BASE_H_ #include @@ -13,8 +13,11 @@ namespace flutter { -class Surface { +class SurfaceBase { public: + SurfaceBase() = default; + virtual ~SurfaceBase() = default; + // Shows a surface is valid or not. bool IsValid() const; @@ -45,4 +48,4 @@ class Surface { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_SURFACE_BASE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h index 79e78271..e6b19997 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h @@ -8,12 +8,12 @@ #include #include "flutter/shell/platform/linux_embedded/surface/context_egl.h" -#include "flutter/shell/platform/linux_embedded/surface/surface.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_base.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h" namespace flutter { -class SurfaceGl final : public Surface, public SurfaceGlDelegate { +class SurfaceGl final : public SurfaceBase, public SurfaceGlDelegate { public: SurfaceGl(std::unique_ptr context); ~SurfaceGl() = default; From 75e2d1e429a8bfcf31941ca119016804988a7916 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 25 Jun 2021 09:40:40 +0900 Subject: [PATCH 032/178] Add window decoration buttons for Wayland (#184) Closed #165 --- cmake/build.cmake | 8 +- .../surface/elinux_egl_surface.cc | 3 +- .../linux_embedded/surface/environment_egl.h | 24 +- .../surface/environment_egl_stream.cc | 3 +- .../surface/environment_egl_stream.h | 2 +- .../window/elinux_window_wayland.cc | 141 ++++++----- .../window/elinux_window_wayland.h | 11 +- .../linux_embedded/window/native_window.h | 9 + .../native_window_wayland_decoration.cc | 20 +- .../window/native_window_wayland_decoration.h | 3 + .../linux_embedded/window/renderer/shader.cc | 68 ++++++ .../linux_embedded/window/renderer/shader.h | 41 ++++ .../window/renderer/shader_context.cc | 98 ++++++++ .../window/renderer/shader_context.h | 33 +++ .../window/renderer/shader_program.cc | 102 ++++++++ .../window/renderer/shader_program.h | 37 +++ .../window/renderer/window_decoration.h | 49 ++++ .../renderer/window_decoration_button.cc | 224 ++++++++++++++++++ .../renderer/window_decoration_button.h | 37 +++ .../renderer/window_decoration_titlebar.cc | 81 +++++++ .../renderer/window_decoration_titlebar.h | 30 +++ .../renderer/window_decorations_wayland.cc | 117 +++++++++ .../renderer/window_decorations_wayland.h | 51 ++++ 23 files changed, 1111 insertions(+), 81 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc create mode 100644 src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h diff --git a/cmake/build.cmake b/cmake/build.cmake index 73ac1678..d758212a 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -66,7 +66,13 @@ else() ${_wayland_protocols_src_dir}/presentation-time-protocol.c src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc - src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc) + src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc + src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc + src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc + src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc + src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc + src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc + src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc) endif() # desktop-shell for weston. diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index fc77eeb6..5171cfa8 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -16,7 +16,8 @@ ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, ELinuxEGLSurface::~ELinuxEGLSurface() { if (surface_ != EGL_NO_SURFACE) { if (eglDestroySurface(display_, surface_) != EGL_TRUE) { - ELINUX_LOG(ERROR) << "Failed to destory surface"; + ELINUX_LOG(ERROR) << "Failed to destory surface: " + << get_egl_error_cause(); } surface_ = EGL_NO_SURFACE; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h b/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h index 6f126eb8..83d94472 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/environment_egl.h @@ -14,8 +14,9 @@ namespace flutter { class EnvironmentEgl { public: - EnvironmentEgl(EGLNativeDisplayType platform_display) - : display_(EGL_NO_DISPLAY), valid_(false) { + EnvironmentEgl(EGLNativeDisplayType platform_display, + bool sub_environment = false) + : display_(EGL_NO_DISPLAY), sub_environment_(sub_environment) { display_ = eglGetDisplay(platform_display); if (display_ == EGL_NO_DISPLAY) { ELINUX_LOG(ERROR) << "Failed to get the EGL display: " @@ -23,13 +24,21 @@ class EnvironmentEgl { return; } - valid_ = InitializeEgl(); + // sub_environment flag is used for window decorations such as toolbar and + // buttons. When this flag is active, EGLDisplay doesn't be initialized and + // finalized. + if (!sub_environment_) { + valid_ = InitializeEgl(); + } else { + valid_ = true; + } } - EnvironmentEgl() : display_(EGL_NO_DISPLAY), valid_(false) {} + EnvironmentEgl(bool sub_environment = false) + : display_(EGL_NO_DISPLAY), sub_environment_(sub_environment) {} ~EnvironmentEgl() { - if (display_ != EGL_NO_DISPLAY) { + if (display_ != EGL_NO_DISPLAY && !sub_environment_) { if (eglTerminate(display_) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to terminate the EGL display: " << get_egl_error_cause(); @@ -59,9 +68,10 @@ class EnvironmentEgl { protected: EGLDisplay display_; - bool valid_; + bool valid_ = false; + bool sub_environment_; }; } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ENVIRONMENT_EGL_H_ \ No newline at end of file +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ENVIRONMENT_EGL_H_ diff --git a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc index 8810f372..67062daa 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc @@ -10,7 +10,8 @@ namespace flutter { -EnvironmentEglStream::EnvironmentEglStream() : EnvironmentEgl() { +EnvironmentEglStream::EnvironmentEglStream(bool sub_environment) + : EnvironmentEgl(sub_environment) { if (!SetEglExtensionFunctionPointers()) { ELINUX_LOG(ERROR) << "Failed to set extension function pointers"; return; diff --git a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.h b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.h index e119c3a9..decc5cd7 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.h +++ b/src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.h @@ -14,7 +14,7 @@ namespace flutter { class EnvironmentEglStream : public EnvironmentEgl { public: - EnvironmentEglStream(); + EnvironmentEglStream(bool sub_environment = false); ~EnvironmentEglStream() = default; private: diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 64334734..a8e342d5 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -4,13 +4,6 @@ #include "flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h" -#ifdef USE_GLES3 -#include -#else -#include -#include -#endif - #include #include #include @@ -27,10 +20,6 @@ namespace flutter { namespace { -typedef void (*glClearColorProc)(GLfloat red, GLfloat green, GLfloat blue, - GLfloat alpha); -typedef void (*glClearProc)(GLbitfield mask); - constexpr char kWestonDesktopShell[] = "weston_desktop_shell"; constexpr char kZwpTextInputManagerV1[] = "zwp_text_input_manager_v1"; constexpr char kZwpTextInputManagerV3[] = "zwp_text_input_manager_v3"; @@ -79,6 +68,30 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { }, }; +const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { + .configure = + [](void* data, xdg_toplevel* xdg_toplevel, int32_t width, + int32_t height, wl_array* states) { + if (!width || !height) { + return; + } + + auto self = reinterpret_cast(data); + self->view_properties_.width = width; + self->view_properties_.height = height; + if (self->window_decorations_) { + self->window_decorations_->Resize(width, height); + } + if (self->binding_handler_delegate_) { + self->binding_handler_delegate_->OnWindowSizeChanged(width, height); + } + }, + .close = + [](void* data, xdg_toplevel* xdg_toplevel) { + auto self = reinterpret_cast(data); + self->running_ = false; + }}; + const wp_presentation_listener ELinuxWindowWayland::kWpPresentationListener = { .clock_id = [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { @@ -108,8 +121,8 @@ const wp_presentation_feedback_listener self->frame_rate_ = static_cast(std::round(1000000000000.0 / refresh)); - if (self->view_properties_.use_window_decoration) { - self->DrawWindowDecoration(); + if (self->window_decorations_) { + self->window_decorations_->Draw(); } }, .discarded = @@ -127,8 +140,8 @@ const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { return; } - if (self->view_properties_.use_window_decoration) { - self->DrawWindowDecoration(); + if (self->window_decorations_) { + self->window_decorations_->Draw(); } self->last_frame_time_nanos_ = static_cast(time) * 1000000; @@ -219,14 +232,43 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { auto self = reinterpret_cast(data); self->serial_ = serial; - if (self->view_properties_.use_window_decoration && - self->wl_current_surface_ == - self->native_window_decoration_->Surface()) { - if (button == BTN_LEFT && status == WL_POINTER_BUTTON_STATE_PRESSED && - self->xdg_toplevel_) { + if (button == BTN_LEFT && status == WL_POINTER_BUTTON_STATE_PRESSED) { + if (self->window_decorations_ && + self->window_decorations_->IsMatched( + self->wl_current_surface_, + WindowDecoration::DecorationType::TITLE_BAR)) { xdg_toplevel_move(self->xdg_toplevel_, self->wl_seat_, serial); + return; + } + + if (self->window_decorations_ && + self->window_decorations_->IsMatched( + self->wl_current_surface_, + WindowDecoration::DecorationType::CLOSE_BUTTON)) { + self->running_ = false; + return; + } + + if (self->window_decorations_ && + self->window_decorations_->IsMatched( + self->wl_current_surface_, + WindowDecoration::DecorationType::MAXIMISE_BUTTON)) { + if (self->maximised_) { + xdg_toplevel_unset_maximized(self->xdg_toplevel_); + } else { + xdg_toplevel_set_maximized(self->xdg_toplevel_); + } + self->maximised_ = !self->maximised_; + return; + } + + if (self->window_decorations_ && + self->window_decorations_->IsMatched( + self->wl_current_surface_, + flutter::WindowDecoration::DecorationType::MINIMISE_BUTTON)) { + xdg_toplevel_set_minimized(self->xdg_toplevel_); + return; } - return; } if (self->binding_handler_delegate_) { @@ -377,9 +419,8 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { self->view_properties_.width = width; self->view_properties_.height = height; - if (self->view_properties_.use_window_decoration && - self->render_surface_decoration_) { - self->render_surface_decoration_->Resize(width, height); + if (self->window_decorations_) { + self->window_decorations_->Resize(width, height); } if (self->binding_handler_delegate_) { @@ -589,6 +630,8 @@ ELinuxWindowWayland::ELinuxWindowWayland( FlutterDesktopViewProperties view_properties) : cursor_info_({"", 0, nullptr}), display_valid_(false), + running_(false), + maximised_(false), is_requested_show_virtual_keyboard_(false), xdg_toplevel_(nullptr), wl_compositor_(nullptr), @@ -611,7 +654,8 @@ ELinuxWindowWayland::ELinuxWindowWayland( zwp_text_input_v3_(nullptr), wp_presentation_(nullptr), wp_presentation_clk_id_(UINT32_MAX), - frame_rate_(60000) { + frame_rate_(60000), + window_decorations_(nullptr) { view_properties_ = view_properties; wl_display_ = wl_display_connect(nullptr); @@ -666,10 +710,12 @@ ELinuxWindowWayland::ELinuxWindowWayland( } display_valid_ = true; + running_ = true; } ELinuxWindowWayland::~ELinuxWindowWayland() { display_valid_ = false; + running_ = false; if (weston_desktop_shell_) { weston_desktop_shell_destroy(weston_desktop_shell_); @@ -812,6 +858,10 @@ bool ELinuxWindowWayland::DispatchEvent() { return false; } + if (!running_) { + return false; + } + // Prepare to call wl_display_read_events. while (wl_display_prepare_read(wl_display_) != 0) { // If Wayland compositor terminates, -1 is returned. @@ -907,8 +957,10 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { return false; } xdg_surface_add_listener(xdg_surface_, &kXdgSurfaceListener, this); + xdg_toplevel_ = xdg_surface_get_toplevel(xdg_surface_); xdg_toplevel_set_title(xdg_toplevel_, "Flutter"); + xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this); wl_surface_commit(native_window_->Surface()); auto* callback = wl_surface_frame(native_window_->Surface()); @@ -919,16 +971,9 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { render_surface_->SetNativeWindow(native_window_.get()); if (view_properties_.use_window_decoration) { - native_window_decoration_ = std::make_unique( - wl_compositor_, wl_subcompositor_, native_window_->Surface(), width, - height); - - render_surface_decoration_ = - std::make_unique(std::make_unique( - std::make_unique(wl_display_))); - render_surface_decoration_->SetNativeWindow( - native_window_decoration_.get()); - render_surface_decoration_->Resize(width, height); + window_decorations_ = std::make_unique( + wl_display_, wl_compositor_, wl_subcompositor_, + native_window_->Surface(), width, height); } return true; @@ -936,15 +981,11 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { void ELinuxWindowWayland::DestroyRenderSurface() { // destroy the main surface before destroying the client window on Wayland. - { - render_surface_ = nullptr; - native_window_ = nullptr; - } - - if (view_properties_.use_window_decoration) { - render_surface_decoration_ = nullptr; - native_window_decoration_ = nullptr; + if (window_decorations_) { + window_decorations_ = nullptr; } + render_surface_ = nullptr; + native_window_ = nullptr; if (xdg_surface_) { xdg_surface_destroy(xdg_surface_); @@ -1278,18 +1319,4 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { } } -void ELinuxWindowWayland::DrawWindowDecoration() { - render_surface_decoration_->GLContextMakeCurrent(); - - auto glClearColor = reinterpret_cast( - render_surface_decoration_->GlProcResolver("glClearColor")); - glClearColor(51 / 255.0, 51 / 255.0, 51 / 255.0, 1); - - auto glClear = reinterpret_cast( - render_surface_decoration_->GlProcResolver("glClear")); - glClear(GL_COLOR_BUFFER_BIT); - - render_surface_decoration_->GLContextPresent(0); -} - } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 53e25b8b..655ddc58 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -12,11 +12,10 @@ #include #include -#include "flutter/shell/platform/linux_embedded/surface/surface_decoration.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/elinux_window.h" #include "flutter/shell/platform/linux_embedded/window/native_window_wayland.h" -#include "flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h" #include "flutter/shell/platform/linux_embedded/window_binding_handler.h" // These header files are automatically generated by the @@ -95,11 +94,10 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void DismissVirtualKeybaord(); - void DrawWindowDecoration(); - static const wl_registry_listener kWlRegistryListener; static const xdg_wm_base_listener kXdgWmBaseListener; static const xdg_surface_listener kXdgSurfaceListener; + static const xdg_toplevel_listener kXdgToplevelListener; static const wl_seat_listener kWlSeatListener; static const wl_pointer_listener kWlPointerListener; static const wl_touch_listener kWlTouchListener; @@ -122,12 +120,13 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { std::unique_ptr render_surface_; // decorations. + std::unique_ptr window_decorations_; wl_surface* wl_current_surface_; wl_subcompositor* wl_subcompositor_; - std::unique_ptr native_window_decoration_; - std::unique_ptr render_surface_decoration_; bool display_valid_; + bool running_; + bool maximised_; uint32_t last_frame_time_; // Indicates that exists a keyboard show request from Flutter Engine. diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window.h b/src/flutter/shell/platform/linux_embedded/window/native_window.h index 3ae40dc9..bbe80954 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window.h @@ -37,6 +37,13 @@ class NativeWindow { virtual bool IsNeedRecreateSurfaceAfterResize() const { return false; } + // Sets a window position. Basically, this API is used for window decorations + // such as titlebar. + virtual void SetPosition(const int32_t x, const int32_t y) { + x_ = x; + y_ = y; + }; + virtual bool Resize(const size_t width, const size_t height) = 0; // Swaps frame buffers. This API performs processing only for the DRM-GBM @@ -48,6 +55,8 @@ class NativeWindow { EGLNativeWindowType window_offscreen_; int32_t width_; int32_t height_; + int32_t x_; + int32_t y_; bool valid_ = false; }; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc index 73c31820..063d9143 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -8,10 +8,6 @@ namespace flutter { -namespace { -constexpr uint kWindowDecorationTitleBarSize = 40; -} // namespace - NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* parent_surface, const size_t width, const size_t height) { @@ -60,12 +56,22 @@ bool NativeWindowWaylandDecoration::Resize(const size_t width, return false; } - wl_subsurface_set_position(subsurface_, 0, -kWindowDecorationTitleBarSize); - wl_egl_window_resize(window_, width, kWindowDecorationTitleBarSize, 0, 0); - width_ = width; height_ = height; + wl_egl_window_resize(window_, width, height, 0, 0); return true; } +void NativeWindowWaylandDecoration::SetPosition(const int32_t x, + const int32_t y) { + if (!valid_) { + ELINUX_LOG(ERROR) << "Failed to set the position of the window."; + return; + } + + x_ = x; + y_ = y; + wl_subsurface_set_position(subsurface_, x, y); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h index f78c58d2..4670d8bd 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -23,6 +23,9 @@ class NativeWindowWaylandDecoration : public NativeWindow { // |NativeWindow| bool Resize(const size_t width, const size_t height) override; + // |NativeWindow| + void SetPosition(const int32_t x, const int32_t y) override; + wl_surface* Surface() const { return surface_; } private: diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc new file mode 100644 index 00000000..fed13bd7 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc @@ -0,0 +1,68 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif +#include + +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader.h" + +namespace flutter { + +namespace { + +struct GlProcs { + PFNGLUSEPROGRAMPROC glUseProgram; + bool valid; +}; + +static const GlProcs& GlProcs() { + static struct GlProcs procs = {}; + static bool initialized = false; + if (!initialized) { + procs.glUseProgram = reinterpret_cast( + eglGetProcAddress("glUseProgram")); + procs.valid = procs.glUseProgram; + if (!procs.valid) { + ELINUX_LOG(ERROR) << "Failed to load GlProcs"; + } + initialized = true; + } + return procs; +} + +} // namespace + +void Shader::LoadProgram(std::string vertex_code, std::string fragment_code) { + auto vertex = std::make_unique(vertex_code, GL_VERTEX_SHADER); + auto fragment = + std::make_unique(fragment_code, GL_FRAGMENT_SHADER); + program_ = + std::make_unique(std::move(vertex), std::move(fragment)); +} + +void Shader::Bind() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + gl.glUseProgram(program_->Program()); +} + +void Shader::Unbind() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + gl.glUseProgram(false); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.h b/src/flutter/shell/platform/linux_embedded/window/renderer/shader.h new file mode 100644 index 00000000..0e6b9134 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader.h @@ -0,0 +1,41 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ + +#ifdef USE_GLES3 +#include +#else +#include +#endif + +#include +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader_program.h" + +namespace flutter { + +class Shader { + public: + Shader() = default; + ~Shader() = default; + + void LoadProgram(std::string vertex_code, std::string fragment_code); + void Bind(); + void Unbind(); + GLuint Program() const { return program_->Program(); } + + private: + std::unique_ptr program_; + std::unique_ptr vertex_; + std::unique_ptr fragment_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc new file mode 100644 index 00000000..a3dd5cb8 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc @@ -0,0 +1,98 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif +#include + +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" + +namespace flutter { + +namespace { + +struct GlProcs { + PFNGLCREATESHADERPROC glCreateShader; + PFNGLSHADERSOURCEPROC glShaderSource; + PFNGLCOMPILESHADERPROC glCompileShader; + PFNGLGETSHADERIVPROC glGetShaderiv; + PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; + PFNGLDELETESHADERPROC glDeleteShader; + bool valid; +}; + +static const GlProcs& GlProcs() { + static struct GlProcs procs = {}; + static bool initialized = false; + if (!initialized) { + procs.glCreateShader = reinterpret_cast( + eglGetProcAddress("glCreateShader")); + procs.glShaderSource = reinterpret_cast( + eglGetProcAddress("glShaderSource")); + procs.glCompileShader = reinterpret_cast( + eglGetProcAddress("glCompileShader")); + procs.glGetShaderiv = reinterpret_cast( + eglGetProcAddress("glGetShaderiv")); + procs.glGetShaderInfoLog = reinterpret_cast( + eglGetProcAddress("glGetShaderInfoLog")); + procs.glDeleteShader = reinterpret_cast( + eglGetProcAddress("glDeleteShader")); + procs.valid = procs.glCreateShader && procs.glShaderSource && + procs.glCompileShader && procs.glGetShaderiv && + procs.glGetShaderInfoLog && procs.glDeleteShader; + if (!procs.valid) { + ELINUX_LOG(ERROR) << "Failed to load GlProcs"; + } + initialized = true; + } + return procs; +} + +} // namespace + +ShaderContext::ShaderContext(std::string code, GLenum type) : shader_(0) { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + + shader_ = gl.glCreateShader(type); + if (!shader_) { + ELINUX_LOG(ERROR) << "Failed to create the shader"; + return; + } + + auto* c_code = code.c_str(); + gl.glShaderSource(shader_, 1, &c_code, nullptr); + gl.glCompileShader(shader_); + + GLint success; + gl.glGetShaderiv(shader_, GL_COMPILE_STATUS, &success); + if (!success) { + GLchar buf[1024]; + + gl.glGetShaderInfoLog(shader_, sizeof(buf), nullptr, buf); + ELINUX_LOG(ERROR) << "Couldn't compile the shader: " << buf; + + gl.glDeleteShader(shader_); + shader_ = 0; + } +} + +ShaderContext::~ShaderContext() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + gl.glDeleteShader(shader_); +} + +}; // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h new file mode 100644 index 00000000..2c2bce5f --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h @@ -0,0 +1,33 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ + +#ifdef USE_GLES3 +#include +#else +#include +#endif + +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" + +namespace flutter { + +class ShaderContext { + public: + ShaderContext(std::string code, GLenum type); + ~ShaderContext(); + + GLuint Shader() const { return shader_; } + + private: + GLuint shader_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc new file mode 100644 index 00000000..30d2a0e0 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc @@ -0,0 +1,102 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif +#include + +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader_program.h" + +namespace flutter { + +namespace { + +struct GlProcs { + PFNGLCREATEPROGRAMPROC glCreateProgram; + PFNGLATTACHSHADERPROC glAttachShader; + PFNGLLINKPROGRAMPROC glLinkProgram; + PFNGLGETPROGRAMIVPROC glGetProgramiv; + PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; + PFNGLDELETEPROGRAMPROC glDeleteProgram; + bool valid; +}; + +static const GlProcs& GlProcs() { + static struct GlProcs procs = {}; + static bool initialized = false; + if (!initialized) { + procs.glCreateProgram = reinterpret_cast( + eglGetProcAddress("glCreateProgram")); + procs.glAttachShader = reinterpret_cast( + eglGetProcAddress("glAttachShader")); + procs.glLinkProgram = reinterpret_cast( + eglGetProcAddress("glLinkProgram")); + procs.glGetProgramiv = reinterpret_cast( + eglGetProcAddress("glGetProgramiv")); + procs.glGetProgramInfoLog = reinterpret_cast( + eglGetProcAddress("glGetProgramInfoLog")); + procs.glDeleteProgram = reinterpret_cast( + eglGetProcAddress("glDeleteProgram")); + procs.valid = procs.glCreateProgram && procs.glAttachShader && + procs.glLinkProgram && procs.glGetProgramiv && + procs.glGetProgramInfoLog && procs.glDeleteProgram; + if (!procs.valid) { + ELINUX_LOG(ERROR) << "Failed to load GlProcs"; + } + initialized = true; + } + return procs; +} + +} // namespace + +ShaderProgram::ShaderProgram(std::unique_ptr vertex_shader, + std::unique_ptr fragment_shader) + : vertex_shader_(std::move(vertex_shader)), + fragment_shader_(std::move(fragment_shader)), + program_(0) { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + + program_ = gl.glCreateProgram(); + if (!program_) { + ELINUX_LOG(ERROR) << "Failed to create a shader program"; + return; + } + + gl.glAttachShader(program_, vertex_shader_->Shader()); + gl.glAttachShader(program_, fragment_shader_->Shader()); + gl.glLinkProgram(program_); + + GLint success; + gl.glGetProgramiv(program_, GL_LINK_STATUS, &success); + if (success != GL_TRUE) { + GLchar buf[1024]; + + gl.glGetProgramInfoLog(program_, sizeof(buf), nullptr, buf); + ELINUX_LOG(ERROR) << "Couldn't link the program: " << buf; + + gl.glDeleteProgram(program_); + program_ = 0; + } +} + +ShaderProgram::~ShaderProgram() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + gl.glDeleteProgram(program_); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h new file mode 100644 index 00000000..d26c9cf3 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h @@ -0,0 +1,37 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_PROGRAM_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_PROGRAM_H_ + +#ifdef USE_GLES3 +#include +#else +#include +#endif + +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" + +namespace flutter { + +class ShaderProgram { + public: + ShaderProgram(std::unique_ptr vertex_shader, + std::unique_ptr fragment_shader); + ~ShaderProgram(); + + GLuint Program() const { return program_; } + + private: + GLuint program_; + std::unique_ptr vertex_shader_; + std::unique_ptr fragment_shader_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_PROGRAM_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h new file mode 100644 index 00000000..d722d54c --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h @@ -0,0 +1,49 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_H_ + +#include + +#include + +#include "flutter/shell/platform/linux_embedded/surface/surface_decoration.h" +#include "flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h" + +namespace flutter { + +class WindowDecoration { + public: + enum DecorationType { + CLOSE_BUTTON = 0, + MAXIMISE_BUTTON, + MINIMISE_BUTTON, + TITLE_BAR, + }; + + WindowDecoration() = default; + virtual ~WindowDecoration() = default; + + virtual void Draw() = 0; + + virtual void SetPosition(const int32_t x, const int32_t y) = 0; + + virtual void Resize(const int32_t width, const int32_t height) = 0; + + void DestroyContext() const { render_surface_->DestroyContext(); }; + + wl_surface* Surface() const { return native_window_->Surface(); }; + + DecorationType Type() const { return decoration_type_; }; + + protected: + std::unique_ptr native_window_; + std::unique_ptr render_surface_; + DecorationType decoration_type_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc new file mode 100644 index 00000000..d2f1ca3f --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc @@ -0,0 +1,224 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h" + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif +#include + +namespace flutter { + +namespace { +enum { ATTRIB_VERTEC = 0, ATTRIB_COLOR, NUM_ATTRIBUTES }; + +struct GlProcs { + PFNGLENABLEPROC glEnable; + PFNGLCLEARCOLORPROC glClearColor; + PFNGLCLEARPROC glClear; + PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; + PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; + PFNGLDRAWARRAYSPROC glDrawArrays; + PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; + PFNGLLINEWIDTHPROC glLineWidth; + PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; + PFNGLUSEPROGRAMPROC glUseProgram; + bool valid; +}; + +static const GlProcs& GlProcs() { + static struct GlProcs procs = {}; + static bool initialized = false; + if (!initialized) { + procs.glEnable = + reinterpret_cast(eglGetProcAddress("glEnable")); + procs.glClearColor = reinterpret_cast( + eglGetProcAddress("glClearColor")); + procs.glClear = + reinterpret_cast(eglGetProcAddress("glClear")); + procs.glEnableVertexAttribArray = + reinterpret_cast( + eglGetProcAddress("glEnableVertexAttribArray")); + procs.glLineWidth = + reinterpret_cast(eglGetProcAddress("glLineWidth")); + procs.glVertexAttribPointer = + reinterpret_cast( + eglGetProcAddress("glVertexAttribPointer")); + procs.glDrawArrays = reinterpret_cast( + eglGetProcAddress("glDrawArrays")); + procs.glDisableVertexAttribArray = + reinterpret_cast( + eglGetProcAddress("glDisableVertexAttribArray")); + procs.glBindAttribLocation = reinterpret_cast( + eglGetProcAddress("glBindAttribLocation")); + procs.glUseProgram = reinterpret_cast( + eglGetProcAddress("glUseProgram")); + procs.valid = procs.glEnable && procs.glClearColor && procs.glClear && + procs.glEnableVertexAttribArray && procs.glLineWidth && + procs.glVertexAttribPointer && procs.glDrawArrays && + procs.glDisableVertexAttribArray && + procs.glBindAttribLocation && procs.glUseProgram; + if (!procs.valid) { + ELINUX_LOG(ERROR) << "Failed to load GlProcs"; + } + initialized = true; + } + return procs; +} + +constexpr char kGlVertexPositionVar[] = "Position"; +constexpr char kGlFragmentColorVar[] = "SourceColor"; +constexpr char kGlVertexShader[] = + "attribute vec4 Position; \n" + "attribute vec4 SourceColor; \n" + "varying vec4 DestinationColor; \n" + "void main() { \n" + " gl_Position = Position; \n" + " DestinationColor = SourceColor; \n" + "} \n"; +constexpr char kGlFragmentShader[] = + "varying lowp vec4 DestinationColor; \n" + "void main() { \n" + " gl_FragColor = DestinationColor; \n" + "} \n"; +} // namespace + +WindowDecorationButton::WindowDecorationButton( + DecorationType decoration_type, + std::unique_ptr native_window, + std::unique_ptr render_surface) + : shader_(nullptr) { + decoration_type_ = decoration_type; + native_window_ = std::move(native_window); + render_surface_ = std::move(render_surface); + render_surface_->SetNativeWindow(native_window_.get()); + render_surface_->Resize(native_window_->Width(), native_window_->Height()); +} + +WindowDecorationButton::~WindowDecorationButton() { + render_surface_ = nullptr; + native_window_ = nullptr; + shader_ = nullptr; +} + +void WindowDecorationButton::Draw() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + + render_surface_->GLContextMakeCurrent(); + { + gl.glClearColor(100 / 255.0f, 100 / 255.0f, 100 / 255.0f, 1.0f); + gl.glClear(GL_COLOR_BUFFER_BIT); + { + if (!shader_) { + LoadShader(); + } + shader_->Bind(); + gl.glEnableVertexAttribArray(ATTRIB_VERTEC); + gl.glEnableVertexAttribArray(ATTRIB_COLOR); + gl.glLineWidth(2); + if (decoration_type_ == DecorationType::CLOSE_BUTTON) { + constexpr GLfloat vertices[] = { + // clang-format off + -0.5f, -0.5f, + 0.5f, 0.5f, + 0.5f, -0.5f, + -0.5f, 0.5f, + // clang-format on + }; + constexpr GLfloat colors[] = { + // clang-format off + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + // clang-format on + }; + + gl.glVertexAttribPointer(ATTRIB_VERTEC, 2, GL_FLOAT, GL_FALSE, 0, + vertices); + gl.glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, + colors); + gl.glDrawArrays(GL_LINES, 0, 4); + } else if (decoration_type_ == DecorationType::MAXIMISE_BUTTON) { + constexpr GLfloat vertices[] = { + // clang-format off + -0.5f, -0.5f, + 0.5f, -0.5f, + 0.5f, 0.5f, + -0.5f, 0.5f, + // clang-format on + }; + constexpr GLfloat colors[] = { + // clang-format off + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + // clang-format on + }; + + gl.glVertexAttribPointer(ATTRIB_VERTEC, 2, GL_FLOAT, GL_FALSE, 0, + vertices); + gl.glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, + colors); + gl.glDrawArrays(GL_LINE_LOOP, 0, 4); + } else { + constexpr GLfloat vertices[] = { + // clang-format off + -0.5f, -0.4f, + 0.5f, -0.4f, + // clang-format on + }; + constexpr GLfloat colors[] = { + // clang-format off + 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, + // clang-format on + }; + + gl.glVertexAttribPointer(ATTRIB_VERTEC, 2, GL_FLOAT, GL_FALSE, 0, + vertices); + gl.glVertexAttribPointer(ATTRIB_COLOR, 4, GL_FLOAT, GL_FALSE, 0, + colors); + gl.glDrawArrays(GL_LINES, 0, 2); + } + gl.glDisableVertexAttribArray(ATTRIB_VERTEC); + gl.glDisableVertexAttribArray(ATTRIB_COLOR); + shader_->Unbind(); + } + } + render_surface_->GLContextPresent(0); +} + +void WindowDecorationButton::SetPosition(const int32_t x, const int32_t y) { + native_window_->SetPosition(x, y); +} + +void WindowDecorationButton::Resize(const int32_t width, const int32_t height) { + render_surface_->Resize(width, height); +} + +void WindowDecorationButton::LoadShader() { + if (shader_) { + return; + } + + shader_ = std::make_unique(); + shader_->LoadProgram(kGlVertexShader, kGlFragmentShader); + + const auto& gl = GlProcs(); + gl.glBindAttribLocation(shader_->Program(), ATTRIB_VERTEC, + kGlVertexPositionVar); + gl.glBindAttribLocation(shader_->Program(), ATTRIB_COLOR, + kGlFragmentColorVar); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h new file mode 100644 index 00000000..74765b18 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h @@ -0,0 +1,37 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_BUTTON_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_BUTTON_H_ + +#include "flutter/shell/platform/linux_embedded/window/renderer/shader.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h" + +namespace flutter { + +class WindowDecorationButton : public WindowDecoration { + public: + WindowDecorationButton( + DecorationType decoration_type, + std::unique_ptr native_window, + std::unique_ptr render_surface); + ~WindowDecorationButton(); + + void Draw() override; + + // |WindowDecoration| + void SetPosition(const int32_t x, const int32_t y) override; + + // |WindowDecoration| + void Resize(const int32_t width, const int32_t height) override; + + private: + void LoadShader(); + + std::unique_ptr shader_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_BUTTON_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc new file mode 100644 index 00000000..47b8e69c --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc @@ -0,0 +1,81 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h" + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif +#include + +namespace flutter { + +namespace { +struct GlProcs { + PFNGLCLEARCOLORPROC glClearColor; + PFNGLCLEARPROC glClear; + bool valid; +}; + +static const GlProcs& GlProcs() { + static struct GlProcs procs = {}; + static bool initialized = false; + if (!initialized) { + procs.glClearColor = reinterpret_cast( + eglGetProcAddress("glClearColor")); + procs.glClear = + reinterpret_cast(eglGetProcAddress("glClear")); + procs.valid = procs.glClearColor && procs.glClear; + if (!procs.valid) { + ELINUX_LOG(ERROR) << "Failed to load GlProcs"; + } + initialized = true; + } + return procs; +} + +} // namespace + +WindowDecorationTitlebar::WindowDecorationTitlebar( + std::unique_ptr native_window, + std::unique_ptr render_surface) { + decoration_type_ = DecorationType::TITLE_BAR; + native_window_ = std::move(native_window); + render_surface_ = std::move(render_surface); + render_surface_->SetNativeWindow(native_window_.get()); + render_surface_->Resize(native_window_->Width(), native_window_->Height()); +} + +WindowDecorationTitlebar::~WindowDecorationTitlebar() { + render_surface_ = nullptr; + native_window_ = nullptr; +} + +void WindowDecorationTitlebar::Draw() { + const auto& gl = GlProcs(); + if (!gl.valid) { + return; + } + + render_surface_->GLContextMakeCurrent(); + { + gl.glClearColor(51 / 255.0f, 51 / 255.0f, 51 / 255.0f, 1.0f); + gl.glClear(GL_COLOR_BUFFER_BIT); + } + render_surface_->GLContextPresent(0); +} + +void WindowDecorationTitlebar::SetPosition(const int32_t x, const int32_t y) { + native_window_->SetPosition(x, y); +} + +void WindowDecorationTitlebar::Resize(const int32_t width, + const int32_t height) { + render_surface_->Resize(width, height); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h new file mode 100644 index 00000000..9cb5fce5 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h @@ -0,0 +1,30 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_TITLEBAR_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_TITLEBAR_H_ + +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h" + +namespace flutter { + +class WindowDecorationTitlebar : public WindowDecoration { + public: + WindowDecorationTitlebar( + std::unique_ptr native_window, + std::unique_ptr render_surface); + ~WindowDecorationTitlebar(); + + void Draw() override; + + // |WindowDecoration| + void SetPosition(const int32_t x, const int32_t y) override; + + // |WindowDecoration| + void Resize(const int32_t width, const int32_t height) override; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_TITLEBAR_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc new file mode 100644 index 00000000..cd932d33 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -0,0 +1,117 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h" + +#include "flutter/shell/platform/linux_embedded/surface/environment_egl.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" + +namespace flutter { + +namespace { +constexpr uint kTitleBarHeight = 30; + +constexpr uint kButtonWidth = 15; +constexpr uint kButtonHeight = 15; +constexpr uint kButtonMargin = 10; +} // namespace + +WindowDecorationsWayland::WindowDecorationsWayland( + wl_display* display, wl_compositor* compositor, + wl_subcompositor* subcompositor, wl_surface* root_surface, int32_t width, + int32_t height) { + constexpr bool sub_egl_display = true; + + // title-bar. + titlebar_ = std::make_unique( + std::make_unique( + compositor, subcompositor, root_surface, width, kTitleBarHeight), + std::make_unique(std::make_unique( + std::make_unique(display, sub_egl_display)))); + titlebar_->SetPosition(0, -kTitleBarHeight); + + // close button. + auto type = WindowDecorationButton::DecorationType::CLOSE_BUTTON; + buttons_.push_back(std::make_unique( + type, + std::make_unique( + compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + std::make_unique(std::make_unique( + std::make_unique(display, sub_egl_display))))); + buttons_[type]->SetPosition( + width - kButtonWidth - kButtonMargin, + -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + + // maximise button. + type = WindowDecorationButton::DecorationType::MAXIMISE_BUTTON; + buttons_.push_back(std::make_unique( + type, + std::make_unique( + compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + std::make_unique(std::make_unique( + std::make_unique(display, sub_egl_display))))); + buttons_[type]->SetPosition( + width - kButtonWidth * 2 - kButtonMargin * 2, + -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + + // minimise button. + type = WindowDecorationButton::DecorationType::MINIMISE_BUTTON; + buttons_.push_back(std::make_unique( + type, + std::make_unique( + compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + std::make_unique(std::make_unique( + std::make_unique(display, sub_egl_display))))); + buttons_[type]->SetPosition( + width - kButtonWidth * 3 - kButtonMargin * 3, + -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); +} + +WindowDecorationsWayland::~WindowDecorationsWayland() { + DestroyContext(); + titlebar_ = nullptr; + for (auto& b : buttons_) { + buttons_.pop_back(); + } +} + +void WindowDecorationsWayland::Draw() { + titlebar_->Draw(); + for (auto& b : buttons_) { + b->Draw(); + } +} + +void WindowDecorationsWayland::Resize(const int32_t width, + const int32_t height) { + titlebar_->SetPosition(0, -kTitleBarHeight); + titlebar_->Resize(width, kTitleBarHeight); + + for (auto i = 0; i < buttons_.size(); i++) { + buttons_[i]->SetPosition( + width - kButtonWidth * (i + 1) - kButtonMargin * (i + 1), + -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + buttons_[i]->Resize(kButtonWidth, -kButtonHeight); + } +} + +bool WindowDecorationsWayland::IsMatched( + wl_surface* surface, + WindowDecoration::DecorationType decoration_type) const { + switch (decoration_type) { + case WindowDecoration::DecorationType::TITLE_BAR: + return titlebar_->Surface() == surface; + default: + return buttons_[decoration_type]->Surface() == surface; + } +} + +void WindowDecorationsWayland::DestroyContext() { + titlebar_->DestroyContext(); + for (auto& b : buttons_) { + b->DestroyContext(); + } +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h new file mode 100644 index 00000000..85121289 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -0,0 +1,51 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATIONS_WAYLAND_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATIONS_WAYLAND_H_ + +#ifdef USE_GLES3 +#include +#else +#include +#endif + +#include + +#include +#include + +#include "flutter/shell/platform/linux_embedded/logger.h" +#include "flutter/shell/platform/linux_embedded/surface/surface_decoration.h" +#include "flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h" + +namespace flutter { + +class WindowDecorationsWayland { + public: + WindowDecorationsWayland(wl_display* display, wl_compositor* compositor, + wl_subcompositor* subcompositor, + wl_surface* root_surface, int32_t width, + int32_t height); + ~WindowDecorationsWayland(); + + void Draw(); + + void Resize(const int32_t width, const int32_t height); + + bool IsMatched(wl_surface* surface, + WindowDecoration::DecorationType decoration_type) const; + + private: + void DestroyContext(); + + std::unique_ptr titlebar_; + std::vector> buttons_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATIONS_WAYLAND_H_ From 91b2af2c81a315a5f8a5b6c04c1a518d81721392 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 25 Jun 2021 10:06:25 +0900 Subject: [PATCH 033/178] Update common cpp library to the latest version (06252021) (#185) Merged from https://github.com/flutter/engine/commit/c2bd0a25c7e2bd1914246b82ed898282dad32ee0 --- .../common/client_wrapper/include/flutter/event_channel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h index 1c1a056d..fe0e1414 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h @@ -165,7 +165,7 @@ class EventChannel { BinaryMessenger* messenger_; const std::string name_; const MethodCodec* codec_; - bool is_listening_; + bool is_listening_ = false; }; } // namespace flutter From 63172c7b603546bb6275c98bdc7bb4e15b8bd710 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 2 Jul 2021 15:02:26 +0900 Subject: [PATCH 034/178] Add video player plugin using GStreamer (#187) Closed #174 --- .../flutter-video-player-plugin/README.md | 42 ++ .../cmake/user_build.cmake | 28 + .../cmake/user_config.cmake | 7 + .../command_options.h | 367 +++++++++++ .../flutter/generated_plugin_registrant.cc | 14 + .../flutter/generated_plugin_registrant.h | 13 + .../flutter/generated_plugins.cmake | 23 + .../video_player/elinux/CMakeLists.txt | 49 ++ .../video_player/elinux/gst_video_player.cc | 396 ++++++++++++ .../video_player/elinux/gst_video_player.h | 72 +++ .../video_player/video_player_plugin.h | 23 + .../elinux/messages/create_message.h | 90 +++ .../elinux/messages/looping_message.h | 63 ++ .../video_player/elinux/messages/messages.h | 16 + .../elinux/messages/mix_with_others_message.h | 52 ++ .../elinux/messages/playback_speed_message.h | 62 ++ .../elinux/messages/position_message.h | 65 ++ .../elinux/messages/texture_message.h | 49 ++ .../elinux/messages/volume_message.h | 62 ++ .../elinux/video_player_plugin.cc | 590 ++++++++++++++++++ .../elinux/video_player_stream_handler.h | 32 + .../elinux/video_player_stream_handler_impl.h | 58 ++ .../flutter_window.cc | 79 +++ .../flutter_window.h | 34 + examples/flutter-video-player-plugin/main.cc | 69 ++ 25 files changed, 2355 insertions(+) create mode 100644 examples/flutter-video-player-plugin/README.md create mode 100644 examples/flutter-video-player-plugin/cmake/user_build.cmake create mode 100644 examples/flutter-video-player-plugin/cmake/user_config.cmake create mode 100644 examples/flutter-video-player-plugin/command_options.h create mode 100644 examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.cc create mode 100644 examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.h create mode 100644 examples/flutter-video-player-plugin/flutter/generated_plugins.cmake create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/CMakeLists.txt create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/include/video_player/video_player_plugin.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/create_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/looping_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/messages.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/mix_with_others_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/playback_speed_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/position_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/texture_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/volume_message.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_plugin.cc create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler.h create mode 100644 examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler_impl.h create mode 100644 examples/flutter-video-player-plugin/flutter_window.cc create mode 100644 examples/flutter-video-player-plugin/flutter_window.h create mode 100644 examples/flutter-video-player-plugin/main.cc diff --git a/examples/flutter-video-player-plugin/README.md b/examples/flutter-video-player-plugin/README.md new file mode 100644 index 00000000..f1f0c93b --- /dev/null +++ b/examples/flutter-video-player-plugin/README.md @@ -0,0 +1,42 @@ +# Overview +Flutter video player example using video player plugin for Embedded Linux. The interface of the plugin is compatible with [the Flutter official video player plugin](https://github.com/flutter/plugins/tree/master/packages/video_player/video_player). Also, this plugin is temporarily putting here and there are still some bugs. It will be moved to another new repo soon. + +The procedure described here is a provisional step until you build a flutter app for Embedded Linux using this embedder with another tool. + +![image](https://user-images.githubusercontent.com/62131389/124210378-43f06400-db26-11eb-8723-40dad0eb67b0.png) + +## Quick start + +### Install libraries +This plugin uses GStreamer internally. + +```Shell +$ sudo apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-0 \ + gstreamer1.0-plugins-base gstreamer1.0-plugins-good \ + gstreamer1.0-plugins-bad gstreamer1.0-plugins-ugly gstreamer1.0-libav +``` + +### Building the embedder + +```Shell +$ mkdir build +$ cd build +$ cmake -DUSER_PROJECT_PATH=examples/flutter-video-player-plugin .. +$ cmake --build . +``` + +### Building Flutter app with debug mode + +```Shell +$ git clone https://github.com/flutter/plugins.git +$ cd plugins/packages/video_player/video_player +$ flutter build bundle --asset-dir=./bundle/data/flutter_assets +$ cp /bin/cache/artifacts/engine/linux-*/icudtl.dat ./bundle/data +``` + +### Running Flutter app + +```Shell +$ cd +$ LD_LIBRARY_PATH=./plugins/video_player/ ./flutter-client -b ./bundle/ +``` diff --git a/examples/flutter-video-player-plugin/cmake/user_build.cmake b/examples/flutter-video-player-plugin/cmake/user_build.cmake new file mode 100644 index 00000000..7acfd70f --- /dev/null +++ b/examples/flutter-video-player-plugin/cmake/user_build.cmake @@ -0,0 +1,28 @@ +cmake_minimum_required(VERSION 3.10) + +# user binary name. +set(TARGET flutter-client) + +# source files for user apps. +set(USER_APP_SRCS + examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.cc + examples/flutter-video-player-plugin/flutter_window.cc + examples/flutter-video-player-plugin/main.cc +) + +# header files for user apps. +set(USER_APP_INCLUDE_DIRS + ## Public APIs for developers (Don't edit!). + src/client_wrapper/include + src/flutter/shell/platform/common/client_wrapper + src/flutter/shell/platform/common/client_wrapper/include + src/flutter/shell/platform/common/client_wrapper/include/flutter + src/flutter/shell/platform/common/public + src/flutter/shell/platform/linux_embedded/public + src/public/include + ## header file include path for user apps. + examples/flutter-video-player-plugin +) + +# link libraries for user apps. +set(USER_APP_LIBRARIES) diff --git a/examples/flutter-video-player-plugin/cmake/user_config.cmake b/examples/flutter-video-player-plugin/cmake/user_config.cmake new file mode 100644 index 00000000..9432b4fa --- /dev/null +++ b/examples/flutter-video-player-plugin/cmake/user_config.cmake @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.10) + +# Flutter embedder configurations. +# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options +set(BACKEND_TYPE WAYLAND) +set(DESKTOP_SHELL OFF) +set(USE_GLES3 OFF) diff --git a/examples/flutter-video-player-plugin/command_options.h b/examples/flutter-video-player-plugin/command_options.h new file mode 100644 index 00000000..2cb5a66c --- /dev/null +++ b/examples/flutter-video-player-plugin/command_options.h @@ -0,0 +1,367 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMMAND_OPTIONS_ +#define COMMAND_OPTIONS_ + +#include +#include +#include +#include +#include +#include +#include + +// todo: Supports other types besides int, string. + +namespace commandline { + +namespace { +constexpr char kOptionStyleNormal[] = "--"; +constexpr char kOptionStyleShort[] = "-"; +constexpr char kOptionValueForHelpMessage[] = "="; +} // namespace + +class Exception : public std::exception { + public: + Exception(const std::string& msg) : msg_(msg) {} + ~Exception() throw() {} + + const char* what() const throw() { return msg_.c_str(); } + + private: + std::string msg_; +}; + +class CommandOptions { + public: + CommandOptions() = default; + ~CommandOptions() = default; + + void AddWithoutValue(const std::string& name, const std::string& short_name, + const std::string& description, bool required) { + Add(name, short_name, description, "", + ReaderString(), required, false); + } + + void AddInt(const std::string& name, const std::string& short_name, + const std::string& description, const int& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderInt(), required, true); + } + + void AddString(const std::string& name, const std::string& short_name, + const std::string& description, + const std::string& default_value, bool required) { + Add(name, short_name, description, default_value, + ReaderString(), required, true); + } + + template + void Add(const std::string& name, const std::string& short_name, + const std::string& description, const T default_value, + F reader = F(), bool required = true, bool required_value = true) { + if (options_.find(name) != options_.end()) { + std::cerr << "Already registered option: " << name << std::endl; + return; + } + + if (lut_short_options_.find(short_name) != lut_short_options_.end()) { + std::cerr << short_name << "is already registered" << std::endl; + return; + } + lut_short_options_[short_name] = name; + + options_[name] = std::make_unique>( + name, short_name, description, default_value, reader, required, + required_value); + + // register to show help message. + registration_order_options_.push_back(options_[name].get()); + } + + bool Exist(const std::string& name) { + auto itr = options_.find(name); + return itr != options_.end() && itr->second->HasValue(); + } + + template + const T& GetValue(const std::string& name) { + auto itr = options_.find(name); + if (itr == options_.end()) { + throw Exception("Not found: " + name); + } + + auto* option_value = dynamic_cast*>(itr->second.get()); + if (!option_value) { + throw Exception("Type mismatch: " + name); + } + return option_value->GetValue(); + } + + bool Parse(int argc, const char* const* argv) { + if (argc < 1) { + errors_.push_back("No options"); + return false; + } + + command_name_ = argv[0]; + for (auto i = 1; i < argc; i++) { + const std::string arg(argv[i]); + + // normal options: e.g. --bundle=/data/sample/bundle --fullscreen + if (arg.length() > 2 && + arg.substr(0, 2).compare(kOptionStyleNormal) == 0) { + const size_t option_value_len = arg.find("=") != std::string::npos + ? (arg.length() - arg.find("=")) + : 0; + const bool has_value = option_value_len != 0; + std::string option_name = + arg.substr(2, arg.length() - 2 - option_value_len); + + if (options_.find(option_name) == options_.end()) { + errors_.push_back("Not found option: " + option_name); + continue; + } + + if (!has_value && options_[option_name]->IsRequiredValue()) { + errors_.push_back(option_name + " requres an option value"); + continue; + } + + if (has_value && !options_[option_name]->IsRequiredValue()) { + errors_.push_back(option_name + " doesn't requres an option value"); + continue; + } + + if (has_value) { + SetOptionValue(option_name, arg.substr(arg.find("=") + 1)); + } else { + SetOption(option_name); + } + } + // short options: e.g. -f /foo/file.txt -h 640 -abc + else if (arg.length() > 1 && + arg.substr(0, 1).compare(kOptionStyleShort) == 0) { + for (int j = 1; j < arg.length(); j++) { + const std::string option_name{argv[i][j]}; + + if (lut_short_options_.find(option_name) == + lut_short_options_.end()) { + errors_.push_back("Not found short option: " + option_name); + break; + } + + if (j == arg.length() - 1 && + options_[lut_short_options_[option_name]]->IsRequiredValue()) { + if (i == argc - 1) { + errors_.push_back("Invalid format option: " + option_name); + break; + } + SetOptionValue(lut_short_options_[option_name], argv[++i]); + } else { + SetOption(lut_short_options_[option_name]); + } + } + } else { + errors_.push_back("Invalid format option: " + arg); + } + } + + for (auto i = 0; i < registration_order_options_.size(); i++) { + if (registration_order_options_[i]->IsRequired() && + !registration_order_options_[i]->HasValue()) { + errors_.push_back( + std::string(registration_order_options_[i]->GetName()) + + " option is mandatory."); + } + } + + return errors_.size() == 0; + } + + std::string GetError() { return errors_.size() > 0 ? errors_[0] : ""; } + + std::vector& GetErrors() { return errors_; } + + std::string ShowHelp() { + std::ostringstream ostream; + + ostream << "Usage: " << command_name_ << " "; + for (auto i = 0; i < registration_order_options_.size(); i++) { + if (registration_order_options_[i]->IsRequired()) { + ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; + } + } + ostream << std::endl; + + ostream << "Global options:" << std::endl; + size_t max_name_len = 0; + for (auto i = 0; i < registration_order_options_.size(); i++) { + max_name_len = std::max( + max_name_len, registration_order_options_[i]->GetName().length()); + } + + for (auto i = 0; i < registration_order_options_.size(); i++) { + if (!registration_order_options_[i]->GetShortName().empty()) { + ostream << kOptionStyleShort + << registration_order_options_[i]->GetShortName() << ", "; + } else { + ostream << std::string(4, ' '); + } + + size_t index_adjust = 0; + constexpr int kSpacerNum = 5; + auto need_value = registration_order_options_[i]->IsRequiredValue(); + ostream << kOptionStyleNormal + << registration_order_options_[i]->GetName(); + if (need_value) { + ostream << kOptionValueForHelpMessage; + index_adjust += std::string(kOptionValueForHelpMessage).length(); + } + ostream << std::string( + max_name_len + kSpacerNum - index_adjust - + registration_order_options_[i]->GetName().length(), + ' '); + ostream << registration_order_options_[i]->GetDescription() << std::endl; + } + + return ostream.str(); + } + + private: + struct ReaderInt { + int operator()(const std::string& value) { return std::stoi(value); } + }; + + struct ReaderString { + std::string operator()(const std::string& value) { return value; } + }; + + class Option { + public: + Option(const std::string& name, const std::string& short_name, + const std::string& description, bool required, bool required_value) + : name_(name), + short_name_(short_name), + description_(description), + is_required_(required), + is_required_value_(required_value), + value_set_(false){}; + virtual ~Option() = default; + + const std::string& GetName() const { return name_; }; + + const std::string& GetShortName() const { return short_name_; }; + + const std::string& GetDescription() const { return description_; }; + + const std::string GetHelpShortMessage() const { + std::string message = kOptionStyleNormal + name_; + if (is_required_value_) { + message += kOptionValueForHelpMessage; + } + return message; + } + + bool IsRequired() const { return is_required_; }; + + bool IsRequiredValue() const { return is_required_value_; }; + + void Set() { value_set_ = true; }; + + virtual bool SetValue(const std::string& value) = 0; + + virtual bool HasValue() const = 0; + + protected: + bool is_required_; + bool is_required_value_; + std::string name_; + std::string short_name_; + std::string description_; + bool value_set_; + }; + + template + class OptionValue : public Option { + public: + OptionValue(const std::string& name, const std::string& short_name, + const std::string& description, const T& default_value, + bool required, bool required_value) + : Option(name, short_name, description, required, required_value), + default_value_(default_value), + value_(default_value){}; + virtual ~OptionValue() = default; + + bool SetValue(const std::string& value) { + value_ = Read(value); + value_set_ = true; + return true; + } + + bool HasValue() const { return value_set_; } + + const T& GetValue() const { return value_; } + + protected: + virtual T Read(const std::string& s) = 0; + + T default_value_; + T value_; + }; + + template + class OptionValueReader : public OptionValue { + public: + OptionValueReader(const std::string& name, const std::string& short_name, + const std::string& description, const T default_value, + F reader, bool required, bool required_value) + : OptionValue(name, short_name, description, default_value, required, + required_value), + reader_(reader) {} + ~OptionValueReader() = default; + + private: + T Read(const std::string& value) { return reader_(value); } + + F reader_; + }; + + bool SetOption(const std::string& name) { + auto itr = options_.find(name); + if (itr == options_.end()) { + errors_.push_back("Unknown option: " + name); + return false; + } + + itr->second->Set(); + return true; + } + + bool SetOptionValue(const std::string& name, const std::string& value) { + auto itr = options_.find(name); + if (itr == options_.end()) { + errors_.push_back("Unknown option: " + name); + return false; + } + + if (!itr->second->SetValue(value)) { + errors_.push_back("Invalid option value: " + name + " = " + value); + return false; + } + return true; + } + + std::string command_name_; + std::unordered_map> options_; + std::unordered_map lut_short_options_; + std::vector registration_order_options_; + std::vector errors_; +}; + +} // namespace commandline + +#endif // COMMAND_OPTIONS_ diff --git a/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.cc b/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.cc new file mode 100644 index 00000000..3d6f1746 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.cc @@ -0,0 +1,14 @@ +// +// Generated file. Do not edit. +// + +// clang-format off + +#include "generated_plugin_registrant.h" + +#include + +void RegisterPlugins(flutter::PluginRegistry* registry) { + VideoPlayerPluginRegisterWithRegistrar( + registry->GetRegistrarForPlugin("VideoPlayerPlugin")); +} diff --git a/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.h b/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.h new file mode 100644 index 00000000..a31c23cd --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/generated_plugin_registrant.h @@ -0,0 +1,13 @@ +// +// Generated file. Do not edit. +// + +#ifndef GENERATED_PLUGIN_REGISTRANT_ +#define GENERATED_PLUGIN_REGISTRANT_ + +#include + +// Registers Flutter plugins. +void RegisterPlugins(flutter::PluginRegistry* registry); + +#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-video-player-plugin/flutter/generated_plugins.cmake b/examples/flutter-video-player-plugin/flutter/generated_plugins.cmake new file mode 100644 index 00000000..0c60dc83 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/generated_plugins.cmake @@ -0,0 +1,23 @@ +# +# Generated file, do not edit. +# + +list(APPEND FLUTTER_PLUGIN_LIST + video_player +) + +set(PLUGIN_BUNDLED_LIBRARIES) + +foreach(plugin ${FLUTTER_PLUGIN_LIST}) + add_subdirectory( + ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) + + target_link_libraries(${TARGET} + PRIVATE + ${plugin}_plugin + ) + + list(APPEND PLUGIN_BUNDLED_LIBRARIES + ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so + ) +endforeach(plugin) diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/CMakeLists.txt b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/CMakeLists.txt new file mode 100644 index 00000000..75ffbd0f --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/CMakeLists.txt @@ -0,0 +1,49 @@ +cmake_minimum_required(VERSION 3.10) + +set(PROJECT_NAME "video_player") +set(PLUGIN_NAME "${PROJECT_NAME}_plugin") +project(${PROJECT_NAME} LANGUAGES CXX) + +find_package(PkgConfig) +pkg_check_modules(GLIB REQUIRED glib-2.0) +pkg_check_modules(GSTREAMER REQUIRED + gstreamer-1.0 + gstreamer-app-1.0 + gstreamer-video-1.0 + gstreamer-audio-1.0 +) + +add_library(${PLUGIN_NAME} + SHARED + "${PLUGIN_NAME}.cc" + "gst_video_player.cc" +) + +target_compile_definitions(${PLUGIN_NAME} + PRIVATE + FLUTTER_PLUGIN_IMPL +) + +target_include_directories(${PLUGIN_NAME} + INTERFACE + ${CMAKE_CURRENT_SOURCE_DIR}/include +) + +target_include_directories(${PLUGIN_NAME} + PRIVATE + ${CMAKE_SOURCE_DIR}/src/flutter/shell/platform/common/client_wrapper/include + ${CMAKE_SOURCE_DIR}/src/flutter/shell/platform/common/public +) + +target_include_directories(${PLUGIN_NAME} + PRIVATE + ${GLIB_INCLUDE_DIRS} + ${GSTREAMER_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +target_link_libraries(${PLUGIN_NAME} + PRIVATE + ${GLIB_LIBRARIES} + ${GSTREAMER_LIBRARIES} +) diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc new file mode 100644 index 00000000..6960d241 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc @@ -0,0 +1,396 @@ +// Copyright 2021 Sony Group Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "gst_video_player.h" + +#include +#include +#include + +#include + +GstVideoPlayer::GstVideoPlayer( + const std::string& uri, std::unique_ptr handler) + : stream_handler_(std::move(handler)) { + gst_.pipeline = nullptr; + gst_.playbin = nullptr; + gst_.video_convert = nullptr; + gst_.video_sink = nullptr; + gst_.output = nullptr; + gst_.bus = nullptr; + gst_.buffer = nullptr; + + uri_ = ParseUri(uri); + if (!CreatePipeline()) { + std::cerr << "Failed to create a pipeline" << std::endl; + DestroyPipeline(); + return; + } + + // Prerolls before getting information from the pipeline. + Preroll(); + + // Sets internal video size and buffier. + GetVideoSize(width_, height_); + pixels_.reset(new uint32_t[width_ * height_]); + + stream_handler_->OnNotifyInitialized(); +} + +GstVideoPlayer::~GstVideoPlayer() { + Stop(); + DestroyPipeline(); +} + +// static +void GstVideoPlayer::GstLibraryLoad() { gst_init(NULL, NULL); } + +// static +void GstVideoPlayer::GstLibraryUnload() { gst_deinit(); } + +bool GstVideoPlayer::Play() { + if (gst_element_set_state(gst_.pipeline, GST_STATE_PLAYING) == + GST_STATE_CHANGE_FAILURE) { + std::cerr << "Failed to change the state to PLAYING" << std::endl; + return false; + } + return true; +} + +bool GstVideoPlayer::Pause() { + if (gst_element_set_state(gst_.pipeline, GST_STATE_PAUSED) == + GST_STATE_CHANGE_FAILURE) { + std::cerr << "Failed to change the state to PAUSED" << std::endl; + return false; + } + return true; +} + +bool GstVideoPlayer::Stop() { + if (gst_element_set_state(gst_.pipeline, GST_STATE_READY) == + GST_STATE_CHANGE_FAILURE) { + std::cerr << "Failed to change the state to READY" << std::endl; + return false; + } + return true; +} + +bool GstVideoPlayer::SetVolume(double volume) { + if (!gst_.playbin) { + return false; + } + + volume_ = volume; + g_object_set(gst_.playbin, "volume", volume, NULL); + return true; +} + +bool GstVideoPlayer::SetPlaybackRate(double rate) { + if (!gst_.playbin) { + return false; + } + + if (rate <= 0) { + std::cerr << "Rate " << rate << " is not supported" << std::endl; + return false; + } + + if (!gst_element_seek(gst_.pipeline, rate, GST_FORMAT_TIME, + GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, + GetCurrentPosition() * GST_MSECOND, GST_SEEK_TYPE_SET, + GST_CLOCK_TIME_NONE)) { + std::cerr << "Failed to set playback rate to " << rate + << " (gst_element_seek failed)" << std::endl; + return false; + } + + playback_rate_ = rate; + mute_ = (rate < 0.5 || rate > 2); + g_object_set(gst_.playbin, "mute", mute_, NULL); + + return true; +} + +bool GstVideoPlayer::SetSeek(int64_t position) { + auto nanosecond = position * 1000 * 1000; + if (!gst_element_seek( + gst_.pipeline, playback_rate_, GST_FORMAT_TIME, + (GstSeekFlags)(GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT), + GST_SEEK_TYPE_SET, nanosecond, GST_SEEK_TYPE_SET, + GST_CLOCK_TIME_NONE)) { + std::cerr << "Failed to seek " << nanosecond << std::endl; + return false; + } + return true; +} + +int64_t GstVideoPlayer::GetDuration() { + GstFormat fmt = GST_FORMAT_TIME; + int64_t duration_msec; + if (!gst_element_query_duration(gst_.pipeline, fmt, &duration_msec)) { + std::cerr << "Failed to get duration" << std::endl; + return -1; + } + duration_msec /= GST_MSECOND; + return duration_msec; +} + +int64_t GstVideoPlayer::GetCurrentPosition() { + gint64 position = 0; + if (!gst_element_query_position(gst_.pipeline, GST_FORMAT_TIME, &position)) { + std::cerr << "Failed to get current position" << std::endl; + } + return position / GST_MSECOND; +} + +const uint8_t* GstVideoPlayer::GetFrameBuffer() { + std::shared_lock lock(mutex_buffer_); + if (!gst_.buffer) { + return nullptr; + } + + const uint32_t pixel_bytes = width_ * height_ * 4; + const gsize buf_size = gst_buffer_get_size(gst_.buffer); + gst_buffer_extract(gst_.buffer, 0, pixels_.get(), pixel_bytes); + return reinterpret_cast(pixels_.get()); +} + +// Creats a video pipeline using playbin. +// $ playbin uri= video-sink="videoconvert ! video/x-raw,format=RGBA ! +// fakesink" +bool GstVideoPlayer::CreatePipeline() { + gst_.pipeline = gst_pipeline_new("pipeline"); + if (!gst_.pipeline) { + std::cerr << "Failed to create a pipeline" << std::endl; + return false; + } + gst_.playbin = gst_element_factory_make("playbin", "playbin"); + if (!gst_.playbin) { + std::cerr << "Failed to create a source" << std::endl; + return false; + } + gst_.video_convert = gst_element_factory_make("videoconvert", "videoconvert"); + if (!gst_.video_convert) { + std::cerr << "Failed to create a videoconvert" << std::endl; + return false; + } + gst_.video_sink = gst_element_factory_make("fakesink", "videosink"); + if (!gst_.video_sink) { + std::cerr << "Failed to create a videosink" << std::endl; + return false; + } + gst_.output = gst_bin_new("output"); + if (!gst_.output) { + std::cerr << "Failed to create an output" << std::endl; + return false; + } + gst_.bus = gst_pipeline_get_bus(GST_PIPELINE(gst_.pipeline)); + if (!gst_.bus) { + std::cerr << "Failed to create a bus" << std::endl; + return false; + } + gst_bus_set_sync_handler(gst_.bus, (GstBusSyncHandler)HandleGstMessage, this, + NULL); + + // Sets properties to fakesink to get the callback of a decoded frame. + g_object_set(G_OBJECT(gst_.video_sink), "sync", TRUE, "qos", FALSE, NULL); + g_object_set(G_OBJECT(gst_.video_sink), "signal-handoffs", TRUE, NULL); + g_signal_connect(G_OBJECT(gst_.video_sink), "handoff", + G_CALLBACK(HandoffHandler), this); + gst_bin_add_many(GST_BIN(gst_.output), gst_.video_convert, gst_.video_sink, + NULL); + + // Adds caps to the converter to convert the color format to RGBA. + auto* caps = gst_caps_from_string("video/x-raw,format=RGBA"); + auto link_ok = + gst_element_link_filtered(gst_.video_convert, gst_.video_sink, caps); + gst_caps_unref(caps); + if (!link_ok) { + std::cerr << "Failed to link elements" << std::endl; + return false; + } + + auto* sinkpad = gst_element_get_static_pad(gst_.video_convert, "sink"); + auto* ghost_sinkpad = gst_ghost_pad_new("sink", sinkpad); + gst_pad_set_active(ghost_sinkpad, TRUE); + gst_element_add_pad(gst_.output, ghost_sinkpad); + + // Sets properties to playbin. + g_object_set(gst_.playbin, "uri", uri_.c_str(), NULL); + g_object_set(gst_.playbin, "video-sink", gst_.output, NULL); + gst_bin_add_many(GST_BIN(gst_.pipeline), gst_.playbin, NULL); + + return true; +} + +void GstVideoPlayer::Preroll() { + if (!gst_.playbin) { + return; + } + + auto result = gst_element_set_state(gst_.pipeline, GST_STATE_PAUSED); + if (result == GST_STATE_CHANGE_FAILURE) { + std::cerr << "Failed to change the state to PAUSED" << std::endl; + return; + } + + // Waits until the state becomes GST_STATE_PAUSED. + if (result == GST_STATE_CHANGE_ASYNC) { + GstState state; + result = + gst_element_get_state(gst_.pipeline, &state, NULL, GST_CLOCK_TIME_NONE); + if (result == GST_STATE_CHANGE_FAILURE) { + std::cerr << "Failed to get the current state" << std::endl; + } + } +} + +void GstVideoPlayer::DestroyPipeline() { + if (gst_.video_sink) { + g_object_set(G_OBJECT(gst_.video_sink), "signal-handoffs", FALSE, NULL); + } + + if (gst_.pipeline) { + gst_element_set_state(gst_.pipeline, GST_STATE_NULL); + } + + if (gst_.buffer) { + gst_buffer_unref(gst_.buffer); + gst_.buffer = nullptr; + } + + if (gst_.bus) { + gst_object_unref(gst_.bus); + gst_.bus = nullptr; + } + + if (gst_.pipeline) { + gst_object_unref(gst_.pipeline); + gst_.pipeline = nullptr; + } + + if (gst_.playbin) { + gst_.playbin = nullptr; + } + + if (gst_.output) { + gst_.output = nullptr; + } + + if (gst_.video_sink) { + gst_.video_sink = nullptr; + } + + if (gst_.video_convert) { + gst_.video_convert = nullptr; + } +} + +std::string GstVideoPlayer::ParseUri(const std::string& uri) { + if (gst_uri_is_valid(uri.c_str())) { + return uri; + } + + const auto* filename_uri = gst_filename_to_uri(uri.c_str(), NULL); + if (!filename_uri) { + std::cerr << "Faild to open " << uri.c_str() << std::endl; + return uri; + } + std::string result_uri(filename_uri); + delete filename_uri; + + return result_uri; +} + +void GstVideoPlayer::GetVideoSize(int32_t& width, int32_t& height) { + if (!gst_.pipeline || !gst_.video_sink) { + std::cerr + << "Failed to get video size. The pileline hasn't initialized yet."; + return; + } + + auto* sink_pad = gst_element_get_static_pad(gst_.video_sink, "sink"); + if (!sink_pad) { + std::cerr << "Failed to get a pad"; + return; + } + + auto* caps = gst_pad_get_current_caps(sink_pad); + auto* structure = gst_caps_get_structure(caps, 0); + if (!structure) { + std::cerr << "Failed to get a structure"; + return; + } + + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); +} + +// static +void GstVideoPlayer::HandoffHandler(GstElement* fakesink, GstBuffer* buf, + GstPad* new_pad, gpointer user_data) { + auto* self = reinterpret_cast(user_data); + auto* caps = gst_pad_get_current_caps(new_pad); + auto* structure = gst_caps_get_structure(caps, 0); + + int width; + int height; + gst_structure_get_int(structure, "width", &width); + gst_structure_get_int(structure, "height", &height); + if (width != self->width_ || height != self->height_) { + self->width_ = width; + self->height_ = height; + self->pixels_.reset(new uint32_t[width * height]); + std::cout << "Pixel buffer size: width = " << width + << ", height = " << height << std::endl; + } + + std::lock_guard lock(self->mutex_buffer_); + if (self->gst_.buffer) { + gst_buffer_unref(self->gst_.buffer); + self->gst_.buffer = nullptr; + } + self->gst_.buffer = gst_buffer_ref(buf); + self->stream_handler_->OnNotifyFrameDecoded(); +} + +// static +gboolean GstVideoPlayer::HandleGstMessage(GstBus* bus, GstMessage* message, + gpointer user_data) { + switch (GST_MESSAGE_TYPE(message)) { + case GST_MESSAGE_EOS: { + auto* self = reinterpret_cast(user_data); + self->stream_handler_->OnNotifyCompleted(); + if (self->auto_repeat_) { + self->SetSeek(0); + } + break; + } + case GST_MESSAGE_WARNING: { + gchar* debug; + GError* error; + gst_message_parse_warning(message, &error, &debug); + g_printerr("WARNING from element %s: %s\n", GST_OBJECT_NAME(message->src), + error->message); + g_printerr("Warning details: %s\n", debug); + g_free(debug); + g_error_free(error); + break; + } + case GST_MESSAGE_ERROR: { + gchar* debug; + GError* error; + gst_message_parse_error(message, &error, &debug); + g_printerr("ERROR from element %s: %s\n", GST_OBJECT_NAME(message->src), + error->message); + g_printerr("Error details: %s\n", debug); + g_free(debug); + g_error_free(error); + break; + } + default: + break; + } + return TRUE; +} diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.h new file mode 100644 index 00000000..eb589077 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.h @@ -0,0 +1,72 @@ +// Copyright 2021 Sony Group Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_GST_VIDEO_PLAYER_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_GST_VIDEO_PLAYER_H_ + +#include + +#include +#include +#include + +#include "video_player_stream_handler.h" + +class GstVideoPlayer { + public: + GstVideoPlayer(const std::string& uri, + std::unique_ptr handler); + ~GstVideoPlayer(); + + static void GstLibraryLoad(); + static void GstLibraryUnload(); + + bool Play(); + bool Pause(); + bool Stop(); + bool SetVolume(double volume); + bool SetPlaybackRate(double rate); + void SetAutoRepeat(bool auto_repeat) { auto_repeat_ = auto_repeat; }; + bool SetSeek(int64_t position); + int64_t GetDuration(); + int64_t GetCurrentPosition(); + const uint8_t* GetFrameBuffer(); + int32_t GetWidth() const { return width_; }; + int32_t GetHeight() const { return height_; }; + + private: + struct GstVideoElements { + GstElement* pipeline; + GstElement* playbin; + GstElement* video_convert; + GstElement* video_sink; + GstElement* output; + GstBus* bus; + GstBuffer* buffer; + }; + + static void HandoffHandler(GstElement* fakesink, GstBuffer* buf, + GstPad* new_pad, gpointer user_data); + static gboolean HandleGstMessage(GstBus* bus, GstMessage* message, + gpointer user_data); + std::string ParseUri(const std::string& uri); + bool CreatePipeline(); + void DestroyPipeline(); + void Preroll(); + void GetVideoSize(int32_t& width, int32_t& height); + + GstVideoElements gst_; + std::string uri_; + std::unique_ptr pixels_; + int32_t width_; + int32_t height_; + double volume_ = 1.0; + double playback_rate_ = 1.0; + bool mute_ = false; + bool auto_repeat_ = false; + std::shared_mutex mutex_buffer_; + std::unique_ptr stream_handler_; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_GST_VIDEO_PLAYER_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/include/video_player/video_player_plugin.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/include/video_player/video_player_plugin.h new file mode 100644 index 00000000..ee0ae0a3 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/include/video_player/video_player_plugin.h @@ -0,0 +1,23 @@ +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_INCLUDE_VIDEO_PLAYER_VIDEO_PLAYER_PLUGIN_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_INCLUDE_VIDEO_PLAYER_VIDEO_PLAYER_PLUGIN_H_ + +#include + +#ifdef FLUTTER_PLUGIN_IMPL +#define FLUTTER_PLUGIN_EXPORT __attribute__((visibility("default"))) +#else +#define FLUTTER_PLUGIN_EXPORT +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + +FLUTTER_PLUGIN_EXPORT void VideoPlayerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar); + +#if defined(__cplusplus) +} // extern "C" +#endif + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_INCLUDE_VIDEO_PLAYER_VIDEO_PLAYER_PLUGIN_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/create_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/create_message.h new file mode 100644 index 00000000..fc0fd0fe --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/create_message.h @@ -0,0 +1,90 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_CREATE_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_CREATE_MESSAGE_H_ + +#include +#include + +class CreateMessage { + public: + CreateMessage() = default; + ~CreateMessage() = default; + + // Prevent copying. + CreateMessage(CreateMessage const&) = default; + CreateMessage& operator=(CreateMessage const&) = default; + + void SetAsset(const std::string& asset) { asset_ = asset; } + + std::string GetAsset() const { return asset_; } + + void SetUri(const std::string& uri) { uri_ = uri; } + + std::string GetUri() const { return uri_; } + + void SetPackageName(const std::string& packageName) { + package_name_ = packageName; + } + + std::string GetPackageName() const { return package_name_; } + + void SetFormatHint(const std::string& formatHint) { + format_hint_ = formatHint; + } + + std::string GetFormatHint() const { return format_hint_; } + + flutter::EncodableValue ToMap() { + // todo: Add httpHeaders. + flutter::EncodableMap map = { + {flutter::EncodableValue("asset"), flutter::EncodableValue(asset_)}, + {flutter::EncodableValue("uri"), flutter::EncodableValue(uri_)}, + {flutter::EncodableValue("packageName"), + flutter::EncodableValue(package_name_)}, + {flutter::EncodableValue("formatHint"), + flutter::EncodableValue(format_hint_)}}; + return flutter::EncodableValue(map); + } + + static CreateMessage FromMap(const flutter::EncodableValue& value) { + CreateMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& asset = map[flutter::EncodableValue("asset")]; + if (std::holds_alternative(asset)) { + message.SetAsset(std::get(asset)); + } + + flutter::EncodableValue& uri = map[flutter::EncodableValue("uri")]; + if (std::holds_alternative(uri)) { + message.SetUri(std::get(uri)); + } + + flutter::EncodableValue& packageName = + map[flutter::EncodableValue("packageName")]; + if (std::holds_alternative(packageName)) { + message.SetPackageName(std::get(uri)); + } + + flutter::EncodableValue& formatHint = + map[flutter::EncodableValue("formatHint")]; + if (std::holds_alternative(formatHint)) { + message.SetFormatHint(std::get(formatHint)); + } + } + + return message; + } + + private: + std::string asset_; + std::string uri_; + std::string package_name_; + std::string format_hint_; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_CREATE_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/looping_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/looping_message.h new file mode 100644 index 00000000..2219f37b --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/looping_message.h @@ -0,0 +1,63 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_LOOPING_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_LOOPING_MESSAGE_H_ + +#include +#include + +class LoopingMessage { + public: + LoopingMessage() = default; + ~LoopingMessage() = default; + + // Prevent copying. + LoopingMessage(LoopingMessage const&) = default; + LoopingMessage& operator=(LoopingMessage const&) = default; + + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } + + int64_t GetTextureId() const { return texture_id_; } + + void SetIsLooping(bool is_looping) { is_looping_ = is_looping; } + + bool GetIsLooping() const { return is_looping_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap map = {{flutter::EncodableValue("textureId"), + flutter::EncodableValue(texture_id_)}, + {flutter::EncodableValue("isLooping"), + flutter::EncodableValue(is_looping_)}}; + return flutter::EncodableValue(map); + } + + static LoopingMessage FromMap(const flutter::EncodableValue& value) { + LoopingMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& texture_id = + map[flutter::EncodableValue("textureId")]; + if (std::holds_alternative(texture_id) || + std::holds_alternative(texture_id)) { + message.SetTextureId(texture_id.LongValue()); + } + + flutter::EncodableValue& is_looping = + map[flutter::EncodableValue("isLooping")]; + if (std::holds_alternative(is_looping)) { + message.SetIsLooping(std::get(is_looping)); + } + } + + return message; + } + + private: + int64_t texture_id_ = 0; + bool is_looping_ = false; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_LOOPING_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/messages.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/messages.h new file mode 100644 index 00000000..4f642e0f --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/messages.h @@ -0,0 +1,16 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MESSAGES_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MESSAGES_H_ + +#include "create_message.h" +#include "looping_message.h" +#include "mix_with_others_message.h" +#include "playback_speed_message.h" +#include "position_message.h" +#include "texture_message.h" +#include "volume_message.h" + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MESSAGES_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/mix_with_others_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/mix_with_others_message.h new file mode 100644 index 00000000..78798a5e --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/mix_with_others_message.h @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MIX_WITH_OTHERS_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MIX_WITH_OTHERS_MESSAGE_H_ + +#include +#include + +class MixWithOthersMessage { + public: + MixWithOthersMessage() = default; + ~MixWithOthersMessage() = default; + + // Prevent copying. + MixWithOthersMessage(MixWithOthersMessage const&) = default; + MixWithOthersMessage& operator=(MixWithOthersMessage const&) = default; + + void SetMixWithOthers(bool mixWithOthers) { + mix_with_others_ = mixWithOthers; + } + + bool GetMixWithOthers() const { return mix_with_others_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap map = {{flutter::EncodableValue("mixWithOthers"), + flutter::EncodableValue(mix_with_others_)}}; + + return flutter::EncodableValue(map); + } + + static MixWithOthersMessage FromMap(const flutter::EncodableValue& value) { + MixWithOthersMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& mixWithOthers = + map[flutter::EncodableValue("mixWithOthers")]; + if (std::holds_alternative(mixWithOthers)) { + message.SetMixWithOthers(std::get(mixWithOthers)); + } + } + + return message; + } + + private: + bool mix_with_others_ = false; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_MIX_WITH_OTHERS_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/playback_speed_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/playback_speed_message.h new file mode 100644 index 00000000..147da225 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/playback_speed_message.h @@ -0,0 +1,62 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_PLAYBACK_SPEED_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_PLAYBACK_SPEED_MESSAGE_H_ + +#include +#include + +class PlaybackSpeedMessage { + public: + PlaybackSpeedMessage() = default; + ~PlaybackSpeedMessage() = default; + + // Prevent copying. + PlaybackSpeedMessage(PlaybackSpeedMessage const&) = default; + PlaybackSpeedMessage& operator=(PlaybackSpeedMessage const&) = default; + + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } + + int64_t GetTextureId() const { return texture_id_; } + + void SetSpeed(double speed) { speed_ = speed; } + + double GetSpeed() const { return speed_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap map = { + {flutter::EncodableValue("textureId"), + flutter::EncodableValue(texture_id_)}, + {flutter::EncodableValue("speed"), flutter::EncodableValue(speed_)}}; + return flutter::EncodableValue(map); + } + + static PlaybackSpeedMessage FromMap(const flutter::EncodableValue& value) { + PlaybackSpeedMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& texture_id = + map[flutter::EncodableValue("textureId")]; + if (std::holds_alternative(texture_id) || + std::holds_alternative(texture_id)) { + message.SetTextureId(texture_id.LongValue()); + } + + flutter::EncodableValue& speed = map[flutter::EncodableValue("speed")]; + if (std::holds_alternative(speed)) { + message.SetSpeed(std::get(speed)); + } + } + + return message; + } + + private: + int64_t texture_id_ = 0; + double speed_ = 1.0; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_PLAYBACK_SPEED_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/position_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/position_message.h new file mode 100644 index 00000000..b1ce2f5b --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/position_message.h @@ -0,0 +1,65 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_POSITION_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_POSITION_MESSAGE_H_ + +#include +#include + +class PositionMessage { + public: + PositionMessage() = default; + ~PositionMessage() = default; + + // Prevent copying. + PositionMessage(PositionMessage const&) = default; + PositionMessage& operator=(PositionMessage const&) = default; + + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } + + int64_t GetTextureId() const { return texture_id_; } + + void SetPosition(int64_t position) { position_ = position; } + + int64_t GetPosition() const { return position_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap toMapResult = {{flutter::EncodableValue("textureId"), + flutter::EncodableValue(texture_id_)}, + {flutter::EncodableValue("position"), + flutter::EncodableValue(position_)}}; + + return flutter::EncodableValue(toMapResult); + } + + static PositionMessage FromMap(const flutter::EncodableValue& value) { + PositionMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& texture_id = + map[flutter::EncodableValue("textureId")]; + if (std::holds_alternative(texture_id) || + std::holds_alternative(texture_id)) { + message.SetTextureId(texture_id.LongValue()); + } + + flutter::EncodableValue& position = + map[flutter::EncodableValue("position")]; + if (std::holds_alternative(position) || + std::holds_alternative(position)) { + message.SetPosition(position.LongValue()); + } + } + + return message; + } + + private: + int64_t texture_id_ = 0; + int64_t position_ = 0; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_POSITION_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/texture_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/texture_message.h new file mode 100644 index 00000000..8b730184 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/texture_message.h @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_ + +#include +#include + +class TextureMessage { + public: + TextureMessage() = default; + ~TextureMessage() = default; + + // Prevent copying. + TextureMessage(TextureMessage const&) = default; + TextureMessage& operator=(TextureMessage const&) = default; + + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } + + int64_t GetTextureId() const { return texture_id_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap map = {{flutter::EncodableValue("textureId"), + flutter::EncodableValue(texture_id_)}}; + return flutter::EncodableValue(map); + } + + static TextureMessage FromMap(const flutter::EncodableValue& value) { + TextureMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& texture_id = + map[flutter::EncodableValue("textureId")]; + if (std::holds_alternative(texture_id) || + std::holds_alternative(texture_id)) { + message.SetTextureId(texture_id.LongValue()); + } + } + return message; + } + + private: + int64_t texture_id_ = 0; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_TEXTURE_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/volume_message.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/volume_message.h new file mode 100644 index 00000000..dd8d1574 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/messages/volume_message.h @@ -0,0 +1,62 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_VOLUME_MESSAGE_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_VOLUME_MESSAGE_H_ + +#include +#include + +class VolumeMessage { + public: + VolumeMessage() = default; + ~VolumeMessage() = default; + + // Prevent copying. + VolumeMessage(VolumeMessage const&) = default; + VolumeMessage& operator=(VolumeMessage const&) = default; + + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } + + int64_t GetTextureId() const { return texture_id_; } + + void SetVolume(double volume) { volume_ = volume; } + + double GetVolume() const { return volume_; } + + flutter::EncodableValue ToMap() { + flutter::EncodableMap map = { + {flutter::EncodableValue("textureId"), + flutter::EncodableValue(texture_id_)}, + {flutter::EncodableValue("volume"), flutter::EncodableValue(volume_)}}; + return flutter::EncodableValue(map); + } + + static VolumeMessage FromMap(const flutter::EncodableValue& value) { + VolumeMessage message; + if (std::holds_alternative(value)) { + auto map = std::get(value); + + flutter::EncodableValue& texture_id = + map[flutter::EncodableValue("textureId")]; + if (std::holds_alternative(texture_id) || + std::holds_alternative(texture_id)) { + message.SetTextureId(texture_id.LongValue()); + } + + flutter::EncodableValue& volume = map[flutter::EncodableValue("volume")]; + if (std::holds_alternative(volume)) { + message.SetVolume(std::get(volume)); + } + } + + return message; + } + + private: + int64_t texture_id_ = 0; + double volume_ = 0; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_MESSAGES_VOLUME_MESSAGE_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_plugin.cc b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_plugin.cc new file mode 100644 index 00000000..ff99793e --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_plugin.cc @@ -0,0 +1,590 @@ +// Copyright 2021 Sony Group Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "include/video_player/video_player_plugin.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "gst_video_player.h" +#include "messages/messages.h" +#include "video_player_stream_handler_impl.h" + +namespace { +constexpr char kVideoPlayerApiChannelInitializeName[] = + "dev.flutter.pigeon.VideoPlayerApi.initialize"; +constexpr char kVideoPlayerApiChannelSetMixWithOthersName[] = + "dev.flutter.pigeon.VideoPlayerApi.setMixWithOthers"; +constexpr char kVideoPlayerApiChannelCreateName[] = + "dev.flutter.pigeon.VideoPlayerApi.create"; +constexpr char kVideoPlayerApiChannelDisposeName[] = + "dev.flutter.pigeon.VideoPlayerApi.dispose"; +constexpr char kVideoPlayerApiChannelSetLoopingName[] = + "dev.flutter.pigeon.VideoPlayerApi.setLooping"; +constexpr char kVideoPlayerApiChannelSetVolumeName[] = + "dev.flutter.pigeon.VideoPlayerApi.setVolume"; +constexpr char kVideoPlayerApiChannelPauseName[] = + "dev.flutter.pigeon.VideoPlayerApi.pause"; +constexpr char kVideoPlayerApiChannelPlayName[] = + "dev.flutter.pigeon.VideoPlayerApi.play"; +constexpr char kVideoPlayerApiChannelPositionName[] = + "dev.flutter.pigeon.VideoPlayerApi.position"; +constexpr char kVideoPlayerApiChannelSetPlaybackSpeedName[] = + "dev.flutter.pigeon.VideoPlayerApi.setPlaybackSpeed"; +constexpr char kVideoPlayerApiChannelSeekToName[] = + "dev.flutter.pigeon.VideoPlayerApi.seekTo"; + +constexpr char kVideoPlayerVideoEventsChannelName[] = + "flutter.io/videoPlayer/videoEvents"; + +constexpr char kEncodableMapkeyResult[] = "result"; +constexpr char kEncodableMapkeyError[] = "error"; + +class VideoPlayerPlugin : public flutter::Plugin { + public: + static void RegisterWithRegistrar(flutter::PluginRegistrar* registrar); + + VideoPlayerPlugin(flutter::PluginRegistrar* plugin_registrar, + flutter::TextureRegistrar* texture_registrar) + : plugin_registrar_(plugin_registrar), + texture_registrar_(texture_registrar) { + // Needs to call 'gst_init' that initializing the GStreamer library before + // using it. + GstVideoPlayer::GstLibraryLoad(); + } + virtual ~VideoPlayerPlugin() { + for (auto itr = players_.begin(); itr != players_.end(); itr++) { + auto texture_id = itr->first; + auto* player = itr->second.get(); + player->event_sink = nullptr; + if (player->event_channel) { + player->event_channel->SetStreamHandler(nullptr); + } + player->player = nullptr; + player->buffer = nullptr; + player->texture = nullptr; + texture_registrar_->UnregisterTexture(texture_id); + } + players_.clear(); + + GstVideoPlayer::GstLibraryUnload(); + } + + private: + struct FlutterVideoPlayer { + int64_t texture_id; + std::unique_ptr player; + std::unique_ptr texture; + std::unique_ptr buffer; + std::unique_ptr> + event_channel; + std::unique_ptr> event_sink; + }; + + void HandleInitializeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleCreateMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleDisposeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandlePauseMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandlePlayMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleSetLoopingMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleSetVolumeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleSetMixWithOthersMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleSetPlaybackSpeedMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandleSeekToMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + void HandlePositionMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply); + + void SendInitializedEventMessage(int64_t texture_id); + void SendPlayCompletedEventMessage(int64_t texture_id); + + flutter::EncodableValue WrapError(const std::string& message, + const std::string& code = std::string(), + const std::string& details = std::string()); + + flutter::PluginRegistrar* plugin_registrar_; + flutter::TextureRegistrar* texture_registrar_; + std::unordered_map> players_; +}; + +// static +void VideoPlayerPlugin::RegisterWithRegistrar( + flutter::PluginRegistrar* registrar) { + auto plugin = std::make_unique( + registrar, registrar->texture_registrar()); + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelInitializeName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleInitializeMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelCreateName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleCreateMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelDisposeName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleDisposeMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelPauseName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandlePauseMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelPlayName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandlePlayMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelSetLoopingName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleSetLoopingMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelSetVolumeName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleSetVolumeMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelSetMixWithOthersName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleSetMixWithOthersMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelSetPlaybackSpeedName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleSetPlaybackSpeedMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelSeekToName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandleSeekToMethodCall(message, reply); + }); + } + + { + auto channel = + std::make_unique>( + registrar->messenger(), kVideoPlayerApiChannelPositionName, + &flutter::StandardMessageCodec::GetInstance()); + channel->SetMessageHandler( + [plugin_pointer = plugin.get()](const auto& message, auto reply) { + plugin_pointer->HandlePositionMethodCall(message, reply); + }); + } + + registrar->AddPlugin(std::move(plugin)); +} + +void VideoPlayerPlugin::HandleInitializeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + flutter::EncodableMap result; + + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleCreateMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto meta = CreateMessage::FromMap(message); + std::string uri; + if (!meta.GetAsset().empty()) { + // todo: gets propery path of the Flutter project. + std::string flutter_project_path = "./bundle/data/"; + uri = flutter_project_path + "flutter_assets/" + meta.GetAsset(); + } else { + uri = meta.GetUri(); + } + + auto instance = std::make_unique(); + instance->buffer = std::make_unique(); + instance->texture = + std::make_unique(flutter::PixelBufferTexture( + [instance = instance.get()]( + size_t width, size_t height) -> const FlutterDesktopPixelBuffer* { + instance->buffer->width = instance->player->GetWidth(); + instance->buffer->height = instance->player->GetHeight(); + instance->buffer->buffer = instance->player->GetFrameBuffer(); + return instance->buffer.get(); + })); + const auto texture_id = + texture_registrar_->RegisterTexture(instance->texture.get()); + instance->texture_id = texture_id; + { + auto event_channel = + std::make_unique>( + plugin_registrar_->messenger(), + kVideoPlayerVideoEventsChannelName + std::to_string(texture_id), + &flutter::StandardMethodCodec::GetInstance()); + auto event_channel_handler = std::make_unique< + flutter::StreamHandlerFunctions>( + [instance = instance.get(), host = this]( + const flutter::EncodableValue* arguments, + std::unique_ptr>&& + events) + -> std::unique_ptr< + flutter::StreamHandlerError> { + instance->event_sink = std::move(events); + host->SendInitializedEventMessage(instance->texture_id); + return nullptr; + }, + [instance = instance.get()](const flutter::EncodableValue* arguments) + -> std::unique_ptr< + flutter::StreamHandlerError> { + instance->event_sink = nullptr; + return nullptr; + }); + event_channel->SetStreamHandler(std::move(event_channel_handler)); + instance->event_channel = std::move(event_channel); + } + { + auto player_handler = std::make_unique( + // OnNotifyInitialized + [texture_id, host = this]() { + host->SendInitializedEventMessage(texture_id); + }, + // OnNotifyFrameDecoded + [texture_id, host = this]() { + host->texture_registrar_->MarkTextureFrameAvailable(texture_id); + }, + // OnNotifyCompleted + [texture_id, host = this]() { + host->SendPlayCompletedEventMessage(texture_id); + }); + instance->player = + std::make_unique(uri, std::move(player_handler)); + players_[texture_id] = std::move(instance); + } + + flutter::EncodableMap value; + TextureMessage result; + result.SetTextureId(texture_id); + value.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + result.ToMap()); + reply(flutter::EncodableValue(value)); +} + +void VideoPlayerPlugin::HandleDisposeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = TextureMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + auto* player = players_[texture_id].get(); + player->event_sink = nullptr; + player->event_channel->SetStreamHandler(nullptr); + player->player = nullptr; + player->buffer = nullptr; + player->texture = nullptr; + players_.erase(texture_id); + texture_registrar_->UnregisterTexture(texture_id); + + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandlePauseMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = TextureMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->Pause(); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandlePlayMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = TextureMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->Play(); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleSetLoopingMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = LoopingMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->SetAutoRepeat(parameter.GetIsLooping()); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleSetVolumeMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = VolumeMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->SetVolume(parameter.GetVolume()); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleSetMixWithOthersMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + // todo: implements here. + + flutter::EncodableMap result; + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandlePositionMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = TextureMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + PositionMessage send_message; + send_message.SetTextureId(texture_id); + send_message.SetPosition( + players_[texture_id]->player->GetCurrentPosition()); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + send_message.ToMap()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleSetPlaybackSpeedMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = PlaybackSpeedMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->SetPlaybackRate(parameter.GetSpeed()); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::HandleSeekToMethodCall( + const flutter::EncodableValue& message, + flutter::MessageReply reply) { + auto parameter = PositionMessage::FromMap(message); + const auto texture_id = parameter.GetTextureId(); + flutter::EncodableMap result; + + if (players_.find(texture_id) != players_.end()) { + players_[texture_id]->player->SetSeek(parameter.GetPosition()); + result.emplace(flutter::EncodableValue(kEncodableMapkeyResult), + flutter::EncodableValue()); + } else { + auto error_message = "Couldn't find the player with texture id: " + + std::to_string(texture_id); + result.emplace(flutter::EncodableValue(kEncodableMapkeyError), + flutter::EncodableValue(WrapError(error_message))); + } + reply(flutter::EncodableValue(result)); +} + +void VideoPlayerPlugin::SendInitializedEventMessage(int64_t texture_id) { + if (players_.find(texture_id) == players_.end() || + !players_[texture_id]->event_sink) { + return; + } + + auto duration = players_[texture_id]->player->GetDuration(); + auto width = players_[texture_id]->player->GetWidth(); + auto height = players_[texture_id]->player->GetHeight(); + flutter::EncodableMap encodables = { + {flutter::EncodableValue("event"), + flutter::EncodableValue("initialized")}, + {flutter::EncodableValue("duration"), flutter::EncodableValue(duration)}, + {flutter::EncodableValue("width"), flutter::EncodableValue(width)}, + {flutter::EncodableValue("height"), flutter::EncodableValue(height)}}; + flutter::EncodableValue event(encodables); + players_[texture_id]->event_sink->Success(event); +} + +void VideoPlayerPlugin::SendPlayCompletedEventMessage(int64_t texture_id) { + if (players_.find(texture_id) == players_.end() || + !players_[texture_id]->event_sink) { + return; + } + + flutter::EncodableMap encodables = { + {flutter::EncodableValue("event"), flutter::EncodableValue("completed")}}; + flutter::EncodableValue event(encodables); + players_[texture_id]->event_sink->Success(event); +} + +flutter::EncodableValue VideoPlayerPlugin::WrapError( + const std::string& message, const std::string& code, + const std::string& details) { + flutter::EncodableMap map = { + {flutter::EncodableValue("message"), flutter::EncodableValue(message)}, + {flutter::EncodableValue("code"), flutter::EncodableValue(code)}, + {flutter::EncodableValue("details"), flutter::EncodableValue(details)}}; + return flutter::EncodableValue(map); +} + +} // namespace + +void VideoPlayerPluginRegisterWithRegistrar( + FlutterDesktopPluginRegistrarRef registrar) { + VideoPlayerPlugin::RegisterWithRegistrar( + flutter::PluginRegistrarManager::GetInstance() + ->GetRegistrar(registrar)); +} diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler.h new file mode 100644 index 00000000..cf63c4aa --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler.h @@ -0,0 +1,32 @@ +// Copyright 2021 Sony Group Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_H_ + +class VideoPlayerStreamHandler { + public: + VideoPlayerStreamHandler() = default; + virtual ~VideoPlayerStreamHandler() = default; + + // Prevent copying. + VideoPlayerStreamHandler(VideoPlayerStreamHandler const&) = delete; + VideoPlayerStreamHandler& operator=(VideoPlayerStreamHandler const&) = delete; + + // Notifies the completion of initializing the video player. + void OnNotifyInitialized() { OnNotifyInitializedInternal(); } + + // Notifies the completion of decoding a video frame. + void OnNotifyFrameDecoded() { OnNotifyFrameDecodedInternal(); } + + // Notifies the completion of playing a video. + void OnNotifyCompleted() { OnNotifyCompletedInternal(); } + + protected: + virtual void OnNotifyInitializedInternal() = 0; + virtual void OnNotifyFrameDecodedInternal() = 0; + virtual void OnNotifyCompletedInternal() = 0; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_H_ diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler_impl.h b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler_impl.h new file mode 100644 index 00000000..7b955b0f --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/video_player_stream_handler_impl.h @@ -0,0 +1,58 @@ +// Copyright 2021 Sony Group Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_IMPL_H_ +#define PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_IMPL_H_ + +#include + +#include "video_player_stream_handler.h" + +class VideoPlayerStreamHandlerImpl : public VideoPlayerStreamHandler { + public: + using OnNotifyInitialized = std::function; + using OnNotifyFrameDecoded = std::function; + using OnNotifyCompleted = std::function; + + VideoPlayerStreamHandlerImpl(OnNotifyInitialized on_notify_initialized, + OnNotifyFrameDecoded on_notify_frame_decoded, + OnNotifyCompleted on_notify_completed) + : on_notify_initialized_(on_notify_initialized), + on_notify_frame_decoded_(on_notify_frame_decoded), + on_notify_completed_(on_notify_completed) {} + virtual ~VideoPlayerStreamHandlerImpl() = default; + + // Prevent copying. + VideoPlayerStreamHandlerImpl(VideoPlayerStreamHandlerImpl const&) = delete; + VideoPlayerStreamHandlerImpl& operator=(VideoPlayerStreamHandlerImpl const&) = + delete; + + protected: + // |VideoPlayerStreamHandler| + void OnNotifyInitializedInternal() { + if (on_notify_initialized_) { + on_notify_initialized_(); + } + } + + // |VideoPlayerStreamHandler| + void OnNotifyFrameDecodedInternal() { + if (on_notify_frame_decoded_) { + on_notify_frame_decoded_(); + } + } + + // |VideoPlayerStreamHandler| + void OnNotifyCompletedInternal() { + if (on_notify_completed_) { + on_notify_completed_(); + } + } + + OnNotifyInitialized on_notify_initialized_; + OnNotifyFrameDecoded on_notify_frame_decoded_; + OnNotifyCompleted on_notify_completed_; +}; + +#endif // PACKAGES_VIDEO_PLAYER_VIDEO_PLAYER_ELINUX_VIDEO_PLAYER_STREAM_HANDLER_IMPL_H_ diff --git a/examples/flutter-video-player-plugin/flutter_window.cc b/examples/flutter-video-player-plugin/flutter_window.cc new file mode 100644 index 00000000..0c5b6397 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter_window.cc @@ -0,0 +1,79 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter_window.h" + +#include +#include +#include +#include + +#include "flutter/generated_plugin_registrant.h" + +FlutterWindow::FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project) + : view_properties_(view_properties), project_(project) {} + +bool FlutterWindow::OnCreate() { + flutter_view_controller_ = std::make_unique( + view_properties_, project_); + + // Ensure that basic setup of the controller was successful. + if (!flutter_view_controller_->engine() || + !flutter_view_controller_->view()) { + return false; + } + + // Register Flutter plugins. + RegisterPlugins(flutter_view_controller_->engine()); + + return true; +} + +void FlutterWindow::OnDestroy() { + if (flutter_view_controller_) { + flutter_view_controller_ = nullptr; + } +} + +void FlutterWindow::Run() { + // Main loop. + auto next_flutter_event_time = + std::chrono::steady_clock::time_point::clock::now(); + while (flutter_view_controller_->view()->DispatchEvent()) { + // Wait until the next event. + { + auto wait_duration = + std::max(std::chrono::nanoseconds(0), + next_flutter_event_time - + std::chrono::steady_clock::time_point::clock::now()); + std::this_thread::sleep_for( + std::chrono::duration_cast(wait_duration)); + } + + // Processes any pending events in the Flutter engine, and returns the + // number of nanoseconds until the next scheduled event (or max, if none). + auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); + { + auto next_event_time = std::chrono::steady_clock::time_point::max(); + if (wait_duration != std::chrono::nanoseconds::max()) { + next_event_time = + std::min(next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + wait_duration); + } else { + // Wait for the next frame if no events. + auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); + next_event_time = std::min( + next_event_time, + std::chrono::steady_clock::time_point::clock::now() + + std::chrono::milliseconds( + static_cast(std::trunc(1000000.0 / frame_rate)))); + } + next_flutter_event_time = + std::max(next_flutter_event_time, next_event_time); + } + } +} diff --git a/examples/flutter-video-player-plugin/flutter_window.h b/examples/flutter-video-player-plugin/flutter_window.h new file mode 100644 index 00000000..20b9cb88 --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter_window.h @@ -0,0 +1,34 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_WINDOW_ +#define FLUTTER_WINDOW_ + +#include +#include + +#include + +class FlutterWindow { + public: + explicit FlutterWindow( + const flutter::FlutterViewController::ViewProperties view_properties, + const flutter::DartProject project); + ~FlutterWindow() = default; + + // Prevent copying. + FlutterWindow(FlutterWindow const&) = delete; + FlutterWindow& operator=(FlutterWindow const&) = delete; + + bool OnCreate(); + void OnDestroy(); + void Run(); + + private: + flutter::FlutterViewController::ViewProperties view_properties_; + flutter::DartProject project_; + std::unique_ptr flutter_view_controller_; +}; + +#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc new file mode 100644 index 00000000..73e4c941 --- /dev/null +++ b/examples/flutter-video-player-plugin/main.cc @@ -0,0 +1,69 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include +#include + +#include +#include +#include + +#include "command_options.h" +#include "flutter_window.h" + +int main(int argc, char** argv) { + commandline::CommandOptions options; + options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", + false); + options.AddWithoutValue("window-decoration", "d", "Enable window decorations", + false); + options.AddInt("width", "w", "Flutter app window width", 1280, false); + options.AddInt("height", "h", "Flutter app window height", 720, false); + if (!options.Parse(argc, argv)) { + std::cerr << options.GetError() << std::endl; + std::cout << options.ShowHelp(); + return 0; + } + + // The project to run. + const auto bundle_path = options.GetValue("bundle"); + const bool show_cursor = !options.Exist("no-cursor"); + const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); + const bool use_window_decoration = options.Exist("window-decoration"); + + const auto view_mode = + options.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + const auto width = options.GetValue("width"); + const auto height = options.GetValue("height"); + + const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); + flutter::DartProject project(fl_path); + auto command_line_arguments = std::vector(); + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); + + flutter::FlutterViewController::ViewProperties view_properties = {}; + view_properties.width = width; + view_properties.height = height; + view_properties.view_mode = view_mode; + view_properties.use_mouse_cursor = show_cursor; + view_properties.use_onscreen_keyboard = use_onscreen_keyboard; + view_properties.use_window_decoration = use_window_decoration; + + // The Flutter instance hosted by this window. + FlutterWindow window(view_properties, project); + if (!window.OnCreate()) { + std::cerr << "Failed to create a Flutter window." << std::endl; + return 0; + } + window.Run(); + window.OnDestroy(); + return 0; +} From 804dfdd8d28f29b72950acf8842d75534e4bfef9 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 2 Jul 2021 15:13:21 +0900 Subject: [PATCH 035/178] fix the timing of calling wp_presentation_feedback_add_listener (#188) --- .../window/elinux_window_wayland.cc | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index a8e342d5..be750254 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -124,6 +124,11 @@ const wp_presentation_feedback_listener if (self->window_decorations_) { self->window_decorations_->Draw(); } + + wp_presentation_feedback_add_listener( + ::wp_presentation_feedback(self->wp_presentation_, + self->native_window_->Surface()), + &kWpPresentationFeedbackListener, data); }, .discarded = [](void* data, @@ -873,25 +878,10 @@ bool ELinuxWindowWayland::DispatchEvent() { wl_display_flush(wl_display_); // Handle Vsync. - { - if (wp_presentation_clk_id_ != UINT32_MAX) { - // This path is used if the presentation-time protocol is supported by the - // compositor. - wp_presentation_feedback_add_listener( - ::wp_presentation_feedback(wp_presentation_, - native_window_->Surface()), - &kWpPresentationFeedbackListener, this); - auto result = wl_display_dispatch_pending(wl_display_); - if (result == -1) { - return false; - } - } - - if (binding_handler_delegate_) { - const uint64_t vsync_interval_time_nanos = 1000000000000 / frame_rate_; - binding_handler_delegate_->OnVsync(last_frame_time_nanos_, - vsync_interval_time_nanos); - } + if (binding_handler_delegate_) { + const uint64_t vsync_interval_time_nanos = 1000000000000 / frame_rate_; + binding_handler_delegate_->OnVsync(last_frame_time_nanos_, + vsync_interval_time_nanos); } // Handle Wayland events. @@ -963,8 +953,14 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this); wl_surface_commit(native_window_->Surface()); - auto* callback = wl_surface_frame(native_window_->Surface()); - wl_callback_add_listener(callback, &kWlSurfaceFrameListener, this); + { + auto* callback = wl_surface_frame(native_window_->Surface()); + wl_callback_add_listener(callback, &kWlSurfaceFrameListener, this); + + wp_presentation_feedback_add_listener( + ::wp_presentation_feedback(wp_presentation_, native_window_->Surface()), + &kWpPresentationFeedbackListener, this); + } render_surface_ = std::make_unique(std::make_unique( std::make_unique(wl_display_))); From 9c58d5ef49f474c182e380a0ddb38f52b95294b1 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 6 Jul 2021 09:27:56 +0900 Subject: [PATCH 036/178] reregister RapidJSON library (#190) --- cmake/build.cmake | 4 +- src/third_party/rapidjson/CHANGELOG.md | 158 +++++++++++++++++ .../{ => include/rapidjson}/allocators.h | 0 .../rapidjson}/cursorstreamwrapper.h | 0 .../{ => include/rapidjson}/document.h | 0 .../{ => include/rapidjson}/encodedstream.h | 0 .../{ => include/rapidjson}/encodings.h | 0 .../{ => include/rapidjson}/error/en.h | 0 .../{ => include/rapidjson}/error/error.h | 0 .../{ => include/rapidjson}/filereadstream.h | 0 .../{ => include/rapidjson}/filewritestream.h | 0 .../rapidjson/{ => include/rapidjson}/fwd.h | 0 .../rapidjson}/internal/biginteger.h | 0 .../{ => include/rapidjson}/internal/diyfp.h | 0 .../{ => include/rapidjson}/internal/dtoa.h | 0 .../rapidjson}/internal/ieee754.h | 0 .../{ => include/rapidjson}/internal/itoa.h | 0 .../{ => include/rapidjson}/internal/meta.h | 0 .../{ => include/rapidjson}/internal/pow10.h | 0 .../{ => include/rapidjson}/internal/regex.h | 0 .../{ => include/rapidjson}/internal/stack.h | 0 .../rapidjson}/internal/strfunc.h | 0 .../{ => include/rapidjson}/internal/strtod.h | 0 .../{ => include/rapidjson}/internal/swap.h | 0 .../{ => include/rapidjson}/istreamwrapper.h | 0 .../{ => include/rapidjson}/memorybuffer.h | 0 .../{ => include/rapidjson}/memorystream.h | 0 .../rapidjson}/msinttypes/inttypes.h | 0 .../rapidjson}/msinttypes/stdint.h | 0 .../{ => include/rapidjson}/ostreamwrapper.h | 0 .../{ => include/rapidjson}/pointer.h | 0 .../{ => include/rapidjson}/prettywriter.h | 0 .../{ => include/rapidjson}/rapidjson.h | 0 .../{ => include/rapidjson}/reader.h | 0 .../{ => include/rapidjson}/schema.h | 0 .../{ => include/rapidjson}/stream.h | 0 .../{ => include/rapidjson}/stringbuffer.h | 0 .../{ => include/rapidjson}/writer.h | 0 src/third_party/rapidjson/license.txt | 57 +++++++ src/third_party/rapidjson/readme.md | 160 ++++++++++++++++++ src/third_party/rapidjson/readme.zh-cn.md | 152 +++++++++++++++++ 41 files changed, 529 insertions(+), 2 deletions(-) create mode 100644 src/third_party/rapidjson/CHANGELOG.md rename src/third_party/rapidjson/{ => include/rapidjson}/allocators.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/cursorstreamwrapper.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/document.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/encodedstream.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/encodings.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/error/en.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/error/error.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/filereadstream.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/filewritestream.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/fwd.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/biginteger.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/diyfp.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/dtoa.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/ieee754.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/itoa.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/meta.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/pow10.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/regex.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/stack.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/strfunc.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/strtod.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/internal/swap.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/istreamwrapper.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/memorybuffer.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/memorystream.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/msinttypes/inttypes.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/msinttypes/stdint.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/ostreamwrapper.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/pointer.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/prettywriter.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/rapidjson.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/reader.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/schema.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/stream.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/stringbuffer.h (100%) rename src/third_party/rapidjson/{ => include/rapidjson}/writer.h (100%) create mode 100644 src/third_party/rapidjson/license.txt create mode 100644 src/third_party/rapidjson/readme.md create mode 100644 src/third_party/rapidjson/readme.zh-cn.md diff --git a/cmake/build.cmake b/cmake/build.cmake index d758212a..e27bf4bb 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -146,13 +146,13 @@ add_executable(${TARGET} src/flutter/shell/platform/common/incoming_message_dispatcher.cc ) -set(THIRD_PARTY_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party) +set(RAPIDJSON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/rapidjson/include/) target_include_directories(${TARGET} PRIVATE src ## third-party libraries. + ${RAPIDJSON_INCLUDE_DIRS} ${XKBCOMMON_INCLUDE_DIRS} - ${THIRD_PARTY_INCLUDE_DIR} ${WAYLAND_CLIENT_INCLUDE_DIRS} ${WAYLAND_CURSOR_INCLUDE_DIRS} ${WAYLAND_EGL_INCLUDE_DIRS} diff --git a/src/third_party/rapidjson/CHANGELOG.md b/src/third_party/rapidjson/CHANGELOG.md new file mode 100644 index 00000000..1c580bd1 --- /dev/null +++ b/src/third_party/rapidjson/CHANGELOG.md @@ -0,0 +1,158 @@ +# Change Log +All notable changes to this project will be documented in this file. +This project adheres to [Semantic Versioning](http://semver.org/). + +## [Unreleased] + +## 1.1.0 - 2016-08-25 + +### Added +* Add GenericDocument ctor overload to specify JSON type (#369) +* Add FAQ (#372, #373, #374, #376) +* Add forward declaration header `fwd.h` +* Add @PlatformIO Library Registry manifest file (#400) +* Implement assignment operator for BigInteger (#404) +* Add comments support (#443) +* Adding coapp definition (#460) +* documenttest.cpp: EXPECT_THROW when checking empty allocator (470) +* GenericDocument: add implicit conversion to ParseResult (#480) +* Use with C++ linkage on Windows ARM (#485) +* Detect little endian for Microsoft ARM targets +* Check Nan/Inf when writing a double (#510) +* Add JSON Schema Implementation (#522) +* Add iostream wrapper (#530) +* Add Jsonx example for converting JSON into JSONx (a XML format) (#531) +* Add optional unresolvedTokenIndex parameter to Pointer::Get() (#532) +* Add encoding validation option for Writer/PrettyWriter (#534) +* Add Writer::SetMaxDecimalPlaces() (#536) +* Support {0, } and {0, m} in Regex (#539) +* Add Value::Get/SetFloat(), Value::IsLossLessFloat/Double() (#540) +* Add stream position check to reader unit tests (#541) +* Add Templated accessors and range-based for (#542) +* Add (Pretty)Writer::RawValue() (#543) +* Add Document::Parse(std::string), Document::Parse(const char*, size_t length) and related APIs. (#553) +* Add move constructor for GenericSchemaDocument (#554) +* Add VS2010 and VS2015 to AppVeyor CI (#555) +* Add parse-by-parts example (#556, #562) +* Support parse number as string (#564, #589) +* Add kFormatSingleLineArray for PrettyWriter (#577) +* Added optional support for trailing commas (#584) +* Added filterkey and filterkeydom examples (#615) +* Added npm docs (#639) +* Allow options for writing and parsing NaN/Infinity (#641) +* Add std::string overload to PrettyWriter::Key() when RAPIDJSON_HAS_STDSTRING is defined (#698) + +### Fixed +* Fix gcc/clang/vc warnings (#350, #394, #397, #444, #447, #473, #515, #582, #589, #595, #667) +* Fix documentation (#482, #511, #550, #557, #614, #635, #660) +* Fix emscripten alignment issue (#535) +* Fix missing allocator to uses of AddMember in document (#365) +* CMake will no longer complain that the minimum CMake version is not specified (#501) +* Make it usable with old VC8 (VS2005) (#383) +* Prohibit C++11 move from Document to Value (#391) +* Try to fix incorrect 64-bit alignment (#419) +* Check return of fwrite to avoid warn_unused_result build failures (#421) +* Fix UB in GenericDocument::ParseStream (#426) +* Keep Document value unchanged on parse error (#439) +* Add missing return statement (#450) +* Fix Document::Parse(const Ch*) for transcoding (#478) +* encodings.h: fix typo in preprocessor condition (#495) +* Custom Microsoft headers are necessary only for Visual Studio 2012 and lower (#559) +* Fix memory leak for invalid regex (26e69ffde95ba4773ab06db6457b78f308716f4b) +* Fix a bug in schema minimum/maximum keywords for 64-bit integer (e7149d665941068ccf8c565e77495521331cf390) +* Fix a crash bug in regex (#605) +* Fix schema "required" keyword cannot handle duplicated keys (#609) +* Fix cmake CMP0054 warning (#612) +* Added missing include guards in istreamwrapper.h and ostreamwrapper.h (#634) +* Fix undefined behaviour (#646) +* Fix buffer overrun using PutN (#673) +* Fix rapidjson::value::Get() may returns wrong data (#681) +* Add Flush() for all value types (#689) +* Handle malloc() fail in PoolAllocator (#691) +* Fix builds on x32 platform. #703 + +### Changed +* Clarify problematic JSON license (#392) +* Move Travis to container based infrastructure (#504, #558) +* Make whitespace array more compact (#513) +* Optimize Writer::WriteString() with SIMD (#544) +* x86-64 48-bit pointer optimization for GenericValue (#546) +* Define RAPIDJSON_HAS_CXX11_RVALUE_REFS directly in clang (#617) +* Make GenericSchemaDocument constructor explicit (#674) +* Optimize FindMember when use std::string (#690) + +## [1.0.2] - 2015-05-14 + +### Added +* Add Value::XXXMember(...) overloads for std::string (#335) + +### Fixed +* Include rapidjson.h for all internal/error headers. +* Parsing some numbers incorrectly in full-precision mode (`kFullPrecisionParseFlag`) (#342) +* Fix some numbers parsed incorrectly (#336) +* Fix alignment of 64bit platforms (#328) +* Fix MemoryPoolAllocator::Clear() to clear user-buffer (0691502573f1afd3341073dd24b12c3db20fbde4) + +### Changed +* CMakeLists for include as a thirdparty in projects (#334, #337) +* Change Document::ParseStream() to use stack allocator for Reader (ffbe38614732af8e0b3abdc8b50071f386a4a685) + +## [1.0.1] - 2015-04-25 + +### Added +* Changelog following [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog) suggestions. + +### Fixed +* Parsing of some numbers (e.g. "1e-00011111111111") causing assertion (#314). +* Visual C++ 32-bit compilation error in `diyfp.h` (#317). + +## [1.0.0] - 2015-04-22 + +### Added +* 100% [Coverall](https://coveralls.io/r/Tencent/rapidjson?branch=master) coverage. +* Version macros (#311) + +### Fixed +* A bug in trimming long number sequence (4824f12efbf01af72b8cb6fc96fae7b097b73015). +* Double quote in unicode escape (#288). +* Negative zero roundtrip (double only) (#289). +* Standardize behavior of `memcpy()` and `malloc()` (0c5c1538dcfc7f160e5a4aa208ddf092c787be5a, #305, 0e8bbe5e3ef375e7f052f556878be0bd79e9062d). + +### Removed +* Remove an invalid `Document::ParseInsitu()` API (e7f1c6dd08b522cfcf9aed58a333bd9a0c0ccbeb). + +## 1.0-beta - 2015-04-8 + +### Added +* RFC 7159 (#101) +* Optional Iterative Parser (#76) +* Deep-copy values (#20) +* Error code and message (#27) +* ASCII Encoding (#70) +* `kParseStopWhenDoneFlag` (#83) +* `kParseFullPrecisionFlag` (881c91d696f06b7f302af6d04ec14dd08db66ceb) +* Add `Key()` to handler concept (#134) +* C++11 compatibility and support (#128) +* Optimized number-to-string and vice versa conversions (#137, #80) +* Short-String Optimization (#131) +* Local stream optimization by traits (#32) +* Travis & Appveyor Continuous Integration, with Valgrind verification (#24, #242) +* Redo all documentation (English, Simplified Chinese) + +### Changed +* Copyright ownership transferred to THL A29 Limited (a Tencent company). +* Migrating from Premake to CMAKE (#192) +* Resolve all warning reports + +### Removed +* Remove other JSON libraries for performance comparison (#180) + +## 0.11 - 2012-11-16 + +## 0.1 - 2011-11-18 + +[Unreleased]: https://github.com/Tencent/rapidjson/compare/v1.1.0...HEAD +[1.1.0]: https://github.com/Tencent/rapidjson/compare/v1.0.2...v1.1.0 +[1.0.2]: https://github.com/Tencent/rapidjson/compare/v1.0.1...v1.0.2 +[1.0.1]: https://github.com/Tencent/rapidjson/compare/v1.0.0...v1.0.1 +[1.0.0]: https://github.com/Tencent/rapidjson/compare/v1.0-beta...v1.0.0 diff --git a/src/third_party/rapidjson/allocators.h b/src/third_party/rapidjson/include/rapidjson/allocators.h similarity index 100% rename from src/third_party/rapidjson/allocators.h rename to src/third_party/rapidjson/include/rapidjson/allocators.h diff --git a/src/third_party/rapidjson/cursorstreamwrapper.h b/src/third_party/rapidjson/include/rapidjson/cursorstreamwrapper.h similarity index 100% rename from src/third_party/rapidjson/cursorstreamwrapper.h rename to src/third_party/rapidjson/include/rapidjson/cursorstreamwrapper.h diff --git a/src/third_party/rapidjson/document.h b/src/third_party/rapidjson/include/rapidjson/document.h similarity index 100% rename from src/third_party/rapidjson/document.h rename to src/third_party/rapidjson/include/rapidjson/document.h diff --git a/src/third_party/rapidjson/encodedstream.h b/src/third_party/rapidjson/include/rapidjson/encodedstream.h similarity index 100% rename from src/third_party/rapidjson/encodedstream.h rename to src/third_party/rapidjson/include/rapidjson/encodedstream.h diff --git a/src/third_party/rapidjson/encodings.h b/src/third_party/rapidjson/include/rapidjson/encodings.h similarity index 100% rename from src/third_party/rapidjson/encodings.h rename to src/third_party/rapidjson/include/rapidjson/encodings.h diff --git a/src/third_party/rapidjson/error/en.h b/src/third_party/rapidjson/include/rapidjson/error/en.h similarity index 100% rename from src/third_party/rapidjson/error/en.h rename to src/third_party/rapidjson/include/rapidjson/error/en.h diff --git a/src/third_party/rapidjson/error/error.h b/src/third_party/rapidjson/include/rapidjson/error/error.h similarity index 100% rename from src/third_party/rapidjson/error/error.h rename to src/third_party/rapidjson/include/rapidjson/error/error.h diff --git a/src/third_party/rapidjson/filereadstream.h b/src/third_party/rapidjson/include/rapidjson/filereadstream.h similarity index 100% rename from src/third_party/rapidjson/filereadstream.h rename to src/third_party/rapidjson/include/rapidjson/filereadstream.h diff --git a/src/third_party/rapidjson/filewritestream.h b/src/third_party/rapidjson/include/rapidjson/filewritestream.h similarity index 100% rename from src/third_party/rapidjson/filewritestream.h rename to src/third_party/rapidjson/include/rapidjson/filewritestream.h diff --git a/src/third_party/rapidjson/fwd.h b/src/third_party/rapidjson/include/rapidjson/fwd.h similarity index 100% rename from src/third_party/rapidjson/fwd.h rename to src/third_party/rapidjson/include/rapidjson/fwd.h diff --git a/src/third_party/rapidjson/internal/biginteger.h b/src/third_party/rapidjson/include/rapidjson/internal/biginteger.h similarity index 100% rename from src/third_party/rapidjson/internal/biginteger.h rename to src/third_party/rapidjson/include/rapidjson/internal/biginteger.h diff --git a/src/third_party/rapidjson/internal/diyfp.h b/src/third_party/rapidjson/include/rapidjson/internal/diyfp.h similarity index 100% rename from src/third_party/rapidjson/internal/diyfp.h rename to src/third_party/rapidjson/include/rapidjson/internal/diyfp.h diff --git a/src/third_party/rapidjson/internal/dtoa.h b/src/third_party/rapidjson/include/rapidjson/internal/dtoa.h similarity index 100% rename from src/third_party/rapidjson/internal/dtoa.h rename to src/third_party/rapidjson/include/rapidjson/internal/dtoa.h diff --git a/src/third_party/rapidjson/internal/ieee754.h b/src/third_party/rapidjson/include/rapidjson/internal/ieee754.h similarity index 100% rename from src/third_party/rapidjson/internal/ieee754.h rename to src/third_party/rapidjson/include/rapidjson/internal/ieee754.h diff --git a/src/third_party/rapidjson/internal/itoa.h b/src/third_party/rapidjson/include/rapidjson/internal/itoa.h similarity index 100% rename from src/third_party/rapidjson/internal/itoa.h rename to src/third_party/rapidjson/include/rapidjson/internal/itoa.h diff --git a/src/third_party/rapidjson/internal/meta.h b/src/third_party/rapidjson/include/rapidjson/internal/meta.h similarity index 100% rename from src/third_party/rapidjson/internal/meta.h rename to src/third_party/rapidjson/include/rapidjson/internal/meta.h diff --git a/src/third_party/rapidjson/internal/pow10.h b/src/third_party/rapidjson/include/rapidjson/internal/pow10.h similarity index 100% rename from src/third_party/rapidjson/internal/pow10.h rename to src/third_party/rapidjson/include/rapidjson/internal/pow10.h diff --git a/src/third_party/rapidjson/internal/regex.h b/src/third_party/rapidjson/include/rapidjson/internal/regex.h similarity index 100% rename from src/third_party/rapidjson/internal/regex.h rename to src/third_party/rapidjson/include/rapidjson/internal/regex.h diff --git a/src/third_party/rapidjson/internal/stack.h b/src/third_party/rapidjson/include/rapidjson/internal/stack.h similarity index 100% rename from src/third_party/rapidjson/internal/stack.h rename to src/third_party/rapidjson/include/rapidjson/internal/stack.h diff --git a/src/third_party/rapidjson/internal/strfunc.h b/src/third_party/rapidjson/include/rapidjson/internal/strfunc.h similarity index 100% rename from src/third_party/rapidjson/internal/strfunc.h rename to src/third_party/rapidjson/include/rapidjson/internal/strfunc.h diff --git a/src/third_party/rapidjson/internal/strtod.h b/src/third_party/rapidjson/include/rapidjson/internal/strtod.h similarity index 100% rename from src/third_party/rapidjson/internal/strtod.h rename to src/third_party/rapidjson/include/rapidjson/internal/strtod.h diff --git a/src/third_party/rapidjson/internal/swap.h b/src/third_party/rapidjson/include/rapidjson/internal/swap.h similarity index 100% rename from src/third_party/rapidjson/internal/swap.h rename to src/third_party/rapidjson/include/rapidjson/internal/swap.h diff --git a/src/third_party/rapidjson/istreamwrapper.h b/src/third_party/rapidjson/include/rapidjson/istreamwrapper.h similarity index 100% rename from src/third_party/rapidjson/istreamwrapper.h rename to src/third_party/rapidjson/include/rapidjson/istreamwrapper.h diff --git a/src/third_party/rapidjson/memorybuffer.h b/src/third_party/rapidjson/include/rapidjson/memorybuffer.h similarity index 100% rename from src/third_party/rapidjson/memorybuffer.h rename to src/third_party/rapidjson/include/rapidjson/memorybuffer.h diff --git a/src/third_party/rapidjson/memorystream.h b/src/third_party/rapidjson/include/rapidjson/memorystream.h similarity index 100% rename from src/third_party/rapidjson/memorystream.h rename to src/third_party/rapidjson/include/rapidjson/memorystream.h diff --git a/src/third_party/rapidjson/msinttypes/inttypes.h b/src/third_party/rapidjson/include/rapidjson/msinttypes/inttypes.h similarity index 100% rename from src/third_party/rapidjson/msinttypes/inttypes.h rename to src/third_party/rapidjson/include/rapidjson/msinttypes/inttypes.h diff --git a/src/third_party/rapidjson/msinttypes/stdint.h b/src/third_party/rapidjson/include/rapidjson/msinttypes/stdint.h similarity index 100% rename from src/third_party/rapidjson/msinttypes/stdint.h rename to src/third_party/rapidjson/include/rapidjson/msinttypes/stdint.h diff --git a/src/third_party/rapidjson/ostreamwrapper.h b/src/third_party/rapidjson/include/rapidjson/ostreamwrapper.h similarity index 100% rename from src/third_party/rapidjson/ostreamwrapper.h rename to src/third_party/rapidjson/include/rapidjson/ostreamwrapper.h diff --git a/src/third_party/rapidjson/pointer.h b/src/third_party/rapidjson/include/rapidjson/pointer.h similarity index 100% rename from src/third_party/rapidjson/pointer.h rename to src/third_party/rapidjson/include/rapidjson/pointer.h diff --git a/src/third_party/rapidjson/prettywriter.h b/src/third_party/rapidjson/include/rapidjson/prettywriter.h similarity index 100% rename from src/third_party/rapidjson/prettywriter.h rename to src/third_party/rapidjson/include/rapidjson/prettywriter.h diff --git a/src/third_party/rapidjson/rapidjson.h b/src/third_party/rapidjson/include/rapidjson/rapidjson.h similarity index 100% rename from src/third_party/rapidjson/rapidjson.h rename to src/third_party/rapidjson/include/rapidjson/rapidjson.h diff --git a/src/third_party/rapidjson/reader.h b/src/third_party/rapidjson/include/rapidjson/reader.h similarity index 100% rename from src/third_party/rapidjson/reader.h rename to src/third_party/rapidjson/include/rapidjson/reader.h diff --git a/src/third_party/rapidjson/schema.h b/src/third_party/rapidjson/include/rapidjson/schema.h similarity index 100% rename from src/third_party/rapidjson/schema.h rename to src/third_party/rapidjson/include/rapidjson/schema.h diff --git a/src/third_party/rapidjson/stream.h b/src/third_party/rapidjson/include/rapidjson/stream.h similarity index 100% rename from src/third_party/rapidjson/stream.h rename to src/third_party/rapidjson/include/rapidjson/stream.h diff --git a/src/third_party/rapidjson/stringbuffer.h b/src/third_party/rapidjson/include/rapidjson/stringbuffer.h similarity index 100% rename from src/third_party/rapidjson/stringbuffer.h rename to src/third_party/rapidjson/include/rapidjson/stringbuffer.h diff --git a/src/third_party/rapidjson/writer.h b/src/third_party/rapidjson/include/rapidjson/writer.h similarity index 100% rename from src/third_party/rapidjson/writer.h rename to src/third_party/rapidjson/include/rapidjson/writer.h diff --git a/src/third_party/rapidjson/license.txt b/src/third_party/rapidjson/license.txt new file mode 100644 index 00000000..7ccc161c --- /dev/null +++ b/src/third_party/rapidjson/license.txt @@ -0,0 +1,57 @@ +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +If you have downloaded a copy of the RapidJSON binary from Tencent, please note that the RapidJSON binary is licensed under the MIT License. +If you have downloaded a copy of the RapidJSON source code from Tencent, please note that RapidJSON source code is licensed under the MIT License, except for the third-party components listed below which are subject to different license terms. Your integration of RapidJSON into your own projects may require compliance with the MIT License, as well as the other licenses applicable to the third-party components included within RapidJSON. To avoid the problematic JSON license in your own projects, it's sufficient to exclude the bin/jsonchecker/ directory, as it's the only code under the JSON license. +A copy of the MIT License is included in this file. + +Other dependencies and licenses: + +Open Source Software Licensed Under the BSD License: +-------------------------------------------------------------------- + +The msinttypes r29 +Copyright (c) 2006-2013 Alexander Chemeris +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +* Neither the name of copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Open Source Software Licensed Under the JSON License: +-------------------------------------------------------------------- + +json.org +Copyright (c) 2002 JSON.org +All Rights Reserved. + +JSON_checker +Copyright (c) 2002 JSON.org +All Rights Reserved. + + +Terms of the JSON License: +--------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +The Software shall be used for Good, not Evil. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +Terms of the MIT License: +-------------------------------------------------------------------- + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/src/third_party/rapidjson/readme.md b/src/third_party/rapidjson/readme.md new file mode 100644 index 00000000..78c9540d --- /dev/null +++ b/src/third_party/rapidjson/readme.md @@ -0,0 +1,160 @@ +![RapidJSON logo](doc/logo/rapidjson.png) + +![Release version](https://img.shields.io/badge/release-v1.1.0-blue.svg) + +## A fast JSON parser/generator for C++ with both SAX/DOM style API + +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +* [RapidJSON GitHub](https://github.com/Tencent/rapidjson/) +* RapidJSON Documentation + * [English](http://rapidjson.org/) + * [简体中文](http://rapidjson.org/zh-cn/) + * [GitBook](https://www.gitbook.com/book/miloyip/rapidjson/) with downloadable PDF/EPUB/MOBI, without API reference. + +## Build status + +| [Linux][lin-link] | [Windows][win-link] | [Coveralls][cov-link] | +| :---------------: | :-----------------: | :-------------------: | +| ![lin-badge] | ![win-badge] | ![cov-badge] | + +[lin-badge]: https://travis-ci.org/Tencent/rapidjson.svg?branch=master "Travis build status" +[lin-link]: https://travis-ci.org/Tencent/rapidjson "Travis build status" +[win-badge]: https://ci.appveyor.com/api/projects/status/l6qulgqahcayidrf/branch/master?svg=true "AppVeyor build status" +[win-link]: https://ci.appveyor.com/project/miloyip/rapidjson-0fdqj/branch/master "AppVeyor build status" +[cov-badge]: https://coveralls.io/repos/Tencent/rapidjson/badge.svg?branch=master "Coveralls coverage" +[cov-link]: https://coveralls.io/r/Tencent/rapidjson?branch=master "Coveralls coverage" + +## Introduction + +RapidJSON is a JSON parser and generator for C++. It was inspired by [RapidXml](http://rapidxml.sourceforge.net/). + +* RapidJSON is **small** but **complete**. It supports both SAX and DOM style API. The SAX parser is only a half thousand lines of code. + +* RapidJSON is **fast**. Its performance can be comparable to `strlen()`. It also optionally supports SSE2/SSE4.2 for acceleration. + +* RapidJSON is **self-contained** and **header-only**. It does not depend on external libraries such as BOOST. It even does not depend on STL. + +* RapidJSON is **memory-friendly**. Each JSON value occupies exactly 16 bytes for most 32/64-bit machines (excluding text string). By default it uses a fast memory allocator, and the parser allocates memory compactly during parsing. + +* RapidJSON is **Unicode-friendly**. It supports UTF-8, UTF-16, UTF-32 (LE & BE), and their detection, validation and transcoding internally. For example, you can read a UTF-8 file and let RapidJSON transcode the JSON strings into UTF-16 in the DOM. It also supports surrogates and "\u0000" (null character). + +More features can be read [here](doc/features.md). + +JSON(JavaScript Object Notation) is a light-weight data exchange format. RapidJSON should be in full compliance with RFC7159/ECMA-404, with optional support of relaxed syntax. More information about JSON can be obtained at +* [Introducing JSON](http://json.org/) +* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159) +* [Standard ECMA-404: The JSON Data Interchange Format](https://www.ecma-international.org/publications/standards/Ecma-404.htm) + +## Highlights in v1.1 (2016-8-25) + +* Added [JSON Pointer](doc/pointer.md) +* Added [JSON Schema](doc/schema.md) +* Added [relaxed JSON syntax](doc/dom.md) (comment, trailing comma, NaN/Infinity) +* Iterating array/object with [C++11 Range-based for loop](doc/tutorial.md) +* Reduce memory overhead of each `Value` from 24 bytes to 16 bytes in x86-64 architecture. + +For other changes please refer to [change log](CHANGELOG.md). + +## Compatibility + +RapidJSON is cross-platform. Some platform/compiler combinations which have been tested are shown as follows. +* Visual C++ 2008/2010/2013 on Windows (32/64-bit) +* GNU C++ 3.8.x on Cygwin +* Clang 3.4 on Mac OS X (32/64-bit) and iOS +* Clang 3.4 on Android NDK + +Users can build and run the unit tests on their platform/compiler. + +## Installation + +RapidJSON is a header-only C++ library. Just copy the `include/rapidjson` folder to system or project's include path. + +RapidJSON uses following software as its dependencies: +* [CMake](https://cmake.org/) as a general build tool +* (optional) [Doxygen](http://www.doxygen.org) to build documentation +* (optional) [googletest](https://github.com/google/googletest) for unit and performance testing + +To generate user documentation and run tests please proceed with the steps below: + +1. Execute `git submodule update --init` to get the files of thirdparty submodules (google test). +2. Create directory called `build` in rapidjson source directory. +3. Change to `build` directory and run `cmake ..` command to configure your build. Windows users can do the same with cmake-gui application. +4. On Windows, build the solution found in the build directory. On Linux, run `make` from the build directory. + +On successful build you will find compiled test and example binaries in `bin` +directory. The generated documentation will be available in `doc/html` +directory of the build tree. To run tests after finished build please run `make +test` or `ctest` from your build tree. You can get detailed output using `ctest +-V` command. + +It is possible to install library system-wide by running `make install` command +from the build tree with administrative privileges. This will install all files +according to system preferences. Once RapidJSON is installed, it is possible +to use it from other CMake projects by adding `find_package(RapidJSON)` line to +your CMakeLists.txt. + +## Usage at a glance + +This simple example parses a JSON string into a document (DOM), make a simple modification of the DOM, and finally stringify the DOM to a JSON string. + +~~~~~~~~~~cpp +// rapidjson/example/simpledom/simpledom.cpp` +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include + +using namespace rapidjson; + +int main() { + // 1. Parse a JSON string into DOM. + const char* json = "{\"project\":\"rapidjson\",\"stars\":10}"; + Document d; + d.Parse(json); + + // 2. Modify it by DOM. + Value& s = d["stars"]; + s.SetInt(s.GetInt() + 1); + + // 3. Stringify the DOM + StringBuffer buffer; + Writer writer(buffer); + d.Accept(writer); + + // Output {"project":"rapidjson","stars":11} + std::cout << buffer.GetString() << std::endl; + return 0; +} +~~~~~~~~~~ + +Note that this example did not handle potential errors. + +The following diagram shows the process. + +![simpledom](doc/diagram/simpledom.png) + +More [examples](https://github.com/Tencent/rapidjson/tree/master/example) are available: + +* DOM API + * [tutorial](https://github.com/Tencent/rapidjson/blob/master/example/tutorial/tutorial.cpp): Basic usage of DOM API. + +* SAX API + * [simplereader](https://github.com/Tencent/rapidjson/blob/master/example/simplereader/simplereader.cpp): Dumps all SAX events while parsing a JSON by `Reader`. + * [condense](https://github.com/Tencent/rapidjson/blob/master/example/condense/condense.cpp): A command line tool to rewrite a JSON, with all whitespaces removed. + * [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp): A command line tool to rewrite a JSON with indents and newlines by `PrettyWriter`. + * [capitalize](https://github.com/Tencent/rapidjson/blob/master/example/capitalize/capitalize.cpp): A command line tool to capitalize strings in JSON. + * [messagereader](https://github.com/Tencent/rapidjson/blob/master/example/messagereader/messagereader.cpp): Parse a JSON message with SAX API. + * [serialize](https://github.com/Tencent/rapidjson/blob/master/example/serialize/serialize.cpp): Serialize a C++ object into JSON with SAX API. + * [jsonx](https://github.com/Tencent/rapidjson/blob/master/example/jsonx/jsonx.cpp): Implements a `JsonxWriter` which stringify SAX events into [JSONx](https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html) (a kind of XML) format. The example is a command line tool which converts input JSON into JSONx format. + +* Schema + * [schemavalidator](https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp) : A command line tool to validate a JSON with a JSON schema. + +* Advanced + * [prettyauto](https://github.com/Tencent/rapidjson/blob/master/example/prettyauto/prettyauto.cpp): A modified version of [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp) to automatically handle JSON with any UTF encodings. + * [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): Implements an `AsyncDocumentParser` which can parse JSON in parts, using C++11 thread. + * [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): A command line tool to remove all values with user-specified key. + * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkeydom/filterkeydom.cpp): Same tool as above, but it demonstrates how to use a generator to populate a `Document`. diff --git a/src/third_party/rapidjson/readme.zh-cn.md b/src/third_party/rapidjson/readme.zh-cn.md new file mode 100644 index 00000000..ccf16699 --- /dev/null +++ b/src/third_party/rapidjson/readme.zh-cn.md @@ -0,0 +1,152 @@ +![RapidJSON logo](doc/logo/rapidjson.png) + +![Release version](https://img.shields.io/badge/release-v1.1.0-blue.svg) + +## 高效的 C++ JSON 解析/生成器,提供 SAX 及 DOM 风格 API + +Tencent is pleased to support the open source community by making RapidJSON available. + +Copyright (C) 2015 THL A29 Limited, a Tencent company, and Milo Yip. All rights reserved. + +* [RapidJSON GitHub](https://github.com/Tencent/rapidjson/) +* RapidJSON 文档 + * [English](http://rapidjson.org/) + * [简体中文](http://rapidjson.org/zh-cn/) + * [GitBook](https://www.gitbook.com/book/miloyip/rapidjson/details/zh-cn) 可下载 PDF/EPUB/MOBI,但不含 API 参考手册。 + +## Build 状态 + +| [Linux][lin-link] | [Windows][win-link] | [Coveralls][cov-link] | +| :---------------: | :-----------------: | :-------------------: | +| ![lin-badge] | ![win-badge] | ![cov-badge] | + +[lin-badge]: https://travis-ci.org/Tencent/rapidjson.svg?branch=master "Travis build status" +[lin-link]: https://travis-ci.org/Tencent/rapidjson "Travis build status" +[win-badge]: https://ci.appveyor.com/api/projects/status/l6qulgqahcayidrf/branch/master?svg=true "AppVeyor build status" +[win-link]: https://ci.appveyor.com/project/miloyip/rapidjson-0fdqj/branch/master "AppVeyor build status" +[cov-badge]: https://coveralls.io/repos/Tencent/rapidjson/badge.svg?branch=master "Coveralls coverage" +[cov-link]: https://coveralls.io/r/Tencent/rapidjson?branch=master "Coveralls coverage" + +## 简介 + +RapidJSON 是一个 C++ 的 JSON 解析器及生成器。它的灵感来自 [RapidXml](http://rapidxml.sourceforge.net/)。 + +* RapidJSON 小而全。它同时支持 SAX 和 DOM 风格的 API。SAX 解析器只有约 500 行代码。 + +* RapidJSON 快。它的性能可与 `strlen()` 相比。可支持 SSE2/SSE4.2 加速。 + +* RapidJSON 独立。它不依赖于 BOOST 等外部库。它甚至不依赖于 STL。 + +* RapidJSON 对内存友好。在大部分 32/64 位机器上,每个 JSON 值只占 16 字节(除字符串外)。它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。 + +* RapidJSON 对 Unicode 友好。它支持 UTF-8、UTF-16、UTF-32 (大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON 可以在分析一个 UTF-8 文件至 DOM 时,把当中的 JSON 字符串转码至 UTF-16。它也支持代理对(surrogate pair)及 `"\u0000"`(空字符)。 + +在 [这里](doc/features.zh-cn.md) 可读取更多特点。 + +JSON(JavaScript Object Notation)是一个轻量的数据交换格式。RapidJSON 应该完全遵从 RFC7159/ECMA-404,并支持可选的放宽语法。 关于 JSON 的更多信息可参考: +* [Introducing JSON](http://json.org/) +* [RFC7159: The JavaScript Object Notation (JSON) Data Interchange Format](https://tools.ietf.org/html/rfc7159) +* [Standard ECMA-404: The JSON Data Interchange Format](https://www.ecma-international.org/publications/standards/Ecma-404.htm) + +## v1.1 中的亮点 (2016-8-25) + +* 加入 [JSON Pointer](doc/pointer.zh-cn.md) 功能,可更简单地访问及更改 DOM。 +* 加入 [JSON Schema](doc/schema.zh-cn.md) 功能,可在解析或生成 JSON 时进行校验。 +* 加入 [放宽的 JSON 语法](doc/dom.zh-cn.md) (注释、尾随逗号、NaN/Infinity) +* 使用 [C++11 范围 for 循环](doc/tutorial.zh-cn.md) 去遍历 array 和 object。 +* 在 x86-64 架构下,缩减每个 `Value` 的内存开销从 24 字节至 16 字节。 + +其他改动请参考 [change log](CHANGELOG.md). + +## 兼容性 + +RapidJSON 是跨平台的。以下是一些曾测试的平台/编译器组合: +* Visual C++ 2008/2010/2013 在 Windows (32/64-bit) +* GNU C++ 3.8.x 在 Cygwin +* Clang 3.4 在 Mac OS X (32/64-bit) 及 iOS +* Clang 3.4 在 Android NDK + +用户也可以在他们的平台上生成及执行单元测试。 + +## 安装 + +RapidJSON 是只有头文件的 C++ 库。只需把 `include/rapidjson` 目录复制至系统或项目的 include 目录中。 + +RapidJSON 依赖于以下软件: +* [CMake](https://cmake.org/) 作为通用生成工具 +* (optional) [Doxygen](http://www.doxygen.org) 用于生成文档 +* (optional) [googletest](https://github.com/google/googletest) 用于单元及性能测试 + +生成测试及例子的步骤: + +1. 执行 `git submodule update --init` 去获取 thirdparty submodules (google test)。 +2. 在 rapidjson 目录下,建立一个 `build` 目录。 +3. 在 `build` 目录下执行 `cmake ..` 命令以设置生成。Windows 用户可使用 cmake-gui 应用程序。 +4. 在 Windows 下,编译生成在 build 目录中的 solution。在 Linux 下,于 build 目录运行 `make`。 + +成功生成后,你会在 `bin` 的目录下找到编译后的测试及例子可执行文件。而生成的文档将位于 build 下的 `doc/html` 目录。要执行测试,请在 build 下执行 `make test` 或 `ctest`。使用 `ctest -V` 命令可获取详细的输出。 + +我们也可以把程序库安装至全系统中,只要在具管理权限下从 build 目录执行 `make install` 命令。这样会按系统的偏好设置安装所有文件。当安装 RapidJSON 后,其他的 CMake 项目需要使用它时,可以通过在 `CMakeLists.txt` 加入一句 `find_package(RapidJSON)`。 + +## 用法一览 + +此简单例子解析一个 JSON 字符串至一个 document (DOM),对 DOM 作出简单修改,最终把 DOM 转换(stringify)至 JSON 字符串。 + +~~~~~~~~~~cpp +// rapidjson/example/simpledom/simpledom.cpp` +#include "rapidjson/document.h" +#include "rapidjson/writer.h" +#include "rapidjson/stringbuffer.h" +#include + +using namespace rapidjson; + +int main() { + // 1. 把 JSON 解析至 DOM。 + const char* json = "{\"project\":\"rapidjson\",\"stars\":10}"; + Document d; + d.Parse(json); + + // 2. 利用 DOM 作出修改。 + Value& s = d["stars"]; + s.SetInt(s.GetInt() + 1); + + // 3. 把 DOM 转换(stringify)成 JSON。 + StringBuffer buffer; + Writer writer(buffer); + d.Accept(writer); + + // Output {"project":"rapidjson","stars":11} + std::cout << buffer.GetString() << std::endl; + return 0; +} +~~~~~~~~~~ + +注意此例子并没有处理潜在错误。 + +下图展示执行过程。 + +![simpledom](doc/diagram/simpledom.png) + +还有许多 [例子](https://github.com/Tencent/rapidjson/tree/master/example) 可供参考: + +* DOM API + * [tutorial](https://github.com/Tencent/rapidjson/blob/master/example/tutorial/tutorial.cpp): DOM API 的基本使用方法。 + +* SAX API + * [simplereader](https://github.com/Tencent/rapidjson/blob/master/example/simplereader/simplereader.cpp): 使用 `Reader` 解析 JSON 时,打印所有 SAX 事件。 + * [condense](https://github.com/Tencent/rapidjson/blob/master/example/condense/condense.cpp): 移除 JSON 中所有空白符的命令行工具。 + * [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp): 为 JSON 加入缩进与换行的命令行工具,当中使用了 `PrettyWriter`。 + * [capitalize](https://github.com/Tencent/rapidjson/blob/master/example/capitalize/capitalize.cpp): 把 JSON 中所有字符串改为大写的命令行工具。 + * [messagereader](https://github.com/Tencent/rapidjson/blob/master/example/messagereader/messagereader.cpp): 使用 SAX API 去解析一个 JSON 报文。 + * [serialize](https://github.com/Tencent/rapidjson/blob/master/example/serialize/serialize.cpp): 使用 SAX API 去序列化 C++ 对象,生成 JSON。 + * [jsonx](https://github.com/Tencent/rapidjson/blob/master/example/jsonx/jsonx.cpp): 实现了一个 `JsonxWriter`,它能把 SAX 事件写成 [JSONx](https://www-01.ibm.com/support/knowledgecenter/SS9H2Y_7.1.0/com.ibm.dp.doc/json_jsonx.html)(一种 XML)格式。这个例子是把 JSON 输入转换成 JSONx 格式的命令行工具。 + +* Schema API + * [schemavalidator](https://github.com/Tencent/rapidjson/blob/master/example/schemavalidator/schemavalidator.cpp): 使用 JSON Schema 去校验 JSON 的命令行工具。 + +* 进阶 + * [prettyauto](https://github.com/Tencent/rapidjson/blob/master/example/prettyauto/prettyauto.cpp): [pretty](https://github.com/Tencent/rapidjson/blob/master/example/pretty/pretty.cpp) 的修改版本,可自动处理任何 UTF 编码的 JSON。 + * [parsebyparts](https://github.com/Tencent/rapidjson/blob/master/example/parsebyparts/parsebyparts.cpp): 这例子中的 `AsyncDocumentParser` 类使用 C++ 线程来逐段解析 JSON。 + * [filterkey](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): 移取使用者指定的键值的命令行工具。 + * [filterkeydom](https://github.com/Tencent/rapidjson/blob/master/example/filterkey/filterkey.cpp): 如上的工具,但展示如何使用生成器(generator)去填充一个 `Document`。 \ No newline at end of file From 811c831b5ef253d18862463b06c785795a777cfb Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 7 Jul 2021 16:32:31 +0900 Subject: [PATCH 037/178] Update examples readme: add video player plugin (#191) --- examples/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/README.md b/examples/README.md index 9f7c23f8..3df5d096 100644 --- a/examples/README.md +++ b/examples/README.md @@ -3,10 +3,13 @@ ## Description These are an example of how to use embedded Linux embedding for Flutter. -## Examples +## Each backend examples - [flutter-wayland-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-wayland-client): Wayland client app -- [flutter-weston-desktop-shell](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-weston-desktop-shell): Works on Weston desktop-shell - [flutter-drm-gbm-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-gbm-backend): Fullscreen app on DRM backend with GBM - [flutter-drm-eglstream-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-eglstream-backend): Fullscreen app on DRM backend with EGLStream - [flutter-x11-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-x11-client): X11 client app -- [flutter-external-texture-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-external-texture-plugin): Wayland client app using external texture plugin +- [flutter-weston-desktop-shell](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-weston-desktop-shell): Works on Weston desktop-shell + +## Examples using Flutter Plugins +- [flutter-video-player-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-video-player-plugin): Flutter video player plugin +- [flutter-external-texture-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-external-texture-plugin): Flutter external texture plugin From ecb4d768f92d5b04eef410113a2b2370211298fe Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 8 Jul 2021 09:59:20 +0900 Subject: [PATCH 038/178] Move and rename wayland/protocol directory (#192) --- cmake/build.cmake | 12 ++++++------ .../linux_embedded/window/elinux_window_wayland.h | 10 +++++----- .../weston-desktop-shell-client-protocol.h | 0 .../protocols}/weston-desktop-shell-protocol.c | 0 4 files changed, 11 insertions(+), 11 deletions(-) rename src/{wayland/protocol => third_party/wayland/protocols}/weston-desktop-shell-client-protocol.h (100%) rename src/{wayland/protocol => third_party/wayland/protocols}/weston-desktop-shell-protocol.c (100%) diff --git a/cmake/build.cmake b/cmake/build.cmake index e27bf4bb..d5abfa7f 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -36,7 +36,7 @@ elseif(${BACKEND_TYPE} STREQUAL "X11") else() include(cmake/generate_wayland_protocols.cmake) set(_wayland_protocols_xml_dir $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/share/wayland-protocols) - set(_wayland_protocols_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/src/wayland/protocol) + set(_wayland_protocols_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/wayland/protocols) generate_wayland_client_protocol( PROTOCOL_FILE ${_wayland_protocols_xml_dir}/stable/xdg-shell/xdg-shell.xml @@ -56,7 +56,7 @@ else() generate_wayland_client_protocol( PROTOCOL_FILE ${_wayland_protocols_xml_dir}/stable/presentation-time/presentation-time.xml CODE_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.c - HEADER_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.h) + HEADER_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.h) add_definitions(-DDISPLAY_BACKEND_TYPE_WAYLAND) set(DISPLAY_BACKEND_SRC @@ -81,9 +81,8 @@ if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) endif() # weston private protocols. -set(WAYLAND_PROTOCOL_SRC "") if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) - set(WAYLAND_PROTOCOL_SRC ${WAYLAND_PROTOCOL_SRC} src/wayland/protocol/weston-desktop-shell-protocol.c) + set(DISPLAY_BACKEND_SRC ${DISPLAY_BACKEND_SRC} src/third_party/wayland/protocols/weston-desktop-shell-protocol.c) endif() # OpenGL ES version. @@ -130,7 +129,6 @@ add_executable(${TARGET} src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc ${DISPLAY_BACKEND_SRC} - ${WAYLAND_PROTOCOL_SRC} ## The following file were copied from: ## https://github.com/flutter/engine/blob/master/shell/platform/glfw/ src/flutter/shell/platform/linux_embedded/system_utils.cc @@ -146,11 +144,13 @@ add_executable(${TARGET} src/flutter/shell/platform/common/incoming_message_dispatcher.cc ) -set(RAPIDJSON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/rapidjson/include/) +set(THIRD_PARTY_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party) +set(RAPIDJSON_INCLUDE_DIRS ${THIRD_PARTY_DIRS}/rapidjson/include/) target_include_directories(${TARGET} PRIVATE src ## third-party libraries. + ${THIRD_PARTY_DIRS} ${RAPIDJSON_INCLUDE_DIRS} ${XKBCOMMON_INCLUDE_DIRS} ${WAYLAND_CLIENT_INCLUDE_DIRS} diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 655ddc58..169f0872 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -21,11 +21,11 @@ // These header files are automatically generated by the // wayland-scanner. extern "C" { -#include "wayland/protocol/presentation-time-protocol.h" -#include "wayland/protocol/text-input-unstable-v1-client-protocol.h" -#include "wayland/protocol/text-input-unstable-v3-client-protocol.h" -#include "wayland/protocol/weston-desktop-shell-client-protocol.h" -#include "wayland/protocol/xdg-shell-client-protocol.h" +#include "wayland/protocols/presentation-time-protocol.h" +#include "wayland/protocols/text-input-unstable-v1-client-protocol.h" +#include "wayland/protocols/text-input-unstable-v3-client-protocol.h" +#include "wayland/protocols/weston-desktop-shell-client-protocol.h" +#include "wayland/protocols/xdg-shell-client-protocol.h" } namespace flutter { diff --git a/src/wayland/protocol/weston-desktop-shell-client-protocol.h b/src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h similarity index 100% rename from src/wayland/protocol/weston-desktop-shell-client-protocol.h rename to src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h diff --git a/src/wayland/protocol/weston-desktop-shell-protocol.c b/src/third_party/wayland/protocols/weston-desktop-shell-protocol.c similarity index 100% rename from src/wayland/protocol/weston-desktop-shell-protocol.c rename to src/third_party/wayland/protocols/weston-desktop-shell-protocol.c From 8d0ae705d725dd1a5883660d51a7947699290a5b Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 8 Jul 2021 14:10:21 +0900 Subject: [PATCH 039/178] Change download path in CI/CD workflow (#193) --- .github/workflows/build-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 0a8fce7d..65b57baf 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -30,8 +30,8 @@ jobs: # unzip linux-x64-embedder # mv libflutter_engine.so ${{github.workspace}}/build run: | - curl -L https://github.com/sony/flutter-embedded-linux/releases/download/939fb62b30/linux-x64-release.zip > linux-x64-release.zip - unzip linux-x64-release.zip + curl -L https://github.com/sony/flutter-embedded-linux/releases/latest/download/elinux-x64-release.zip > elinux-x64-release.zip + unzip elinux-x64-release.zip mv libflutter_engine.so ${{github.workspace}}/build - name: Configure CMake for wayland client From 70a68fa4c7955b1790c7ddb94f8b730682314bb6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 9 Jul 2021 17:54:13 +0900 Subject: [PATCH 040/178] Create shared library for flutter sdk (#194) Changes: - Add CMake option to create libflutter_elinux_{wayland|drm|x11}.so for a Flutter SDK tool - Fix compiler warning message of command_options.h - Refactor CMake files --- .github/workflows/build-test.yml | 10 + CMakeLists.txt | 12 +- cmake/build.cmake | 213 +++++++++++------- .../cmake/user_build.cmake | 1 - .../command_options.h | 14 +- .../cmake/user_build.cmake | 1 - .../flutter-drm-gbm-backend/command_options.h | 14 +- .../cmake/user_build.cmake | 1 - .../command_options.h | 14 +- .../cmake/user_build.cmake | 1 - .../command_options.h | 14 +- .../cmake/user_build.cmake | 1 - .../flutter-wayland-client/command_options.h | 14 +- .../cmake/user_build.cmake | 1 - .../flutter-x11-client/cmake/user_build.cmake | 1 - examples/flutter-x11-client/command_options.h | 14 +- .../app/{common => runner}/command_options.h | 14 +- .../flutter/generated_plugin_registrant.cc | 0 .../flutter/generated_plugin_registrant.h | 0 .../flutter/generated_plugins.cmake | 0 .../app/{common => runner}/flutter_window.cc | 0 .../app/{common => runner}/flutter_window.h | 0 .../app/{linux-drm => runner_drm}/main.cc | 0 .../main.cc | 0 .../{linux-wayland => runner_wayland}/main.cc | 0 .../app/{linux-x11 => runner_x11}/main.cc | 0 26 files changed, 197 insertions(+), 143 deletions(-) rename src/templates/app/{common => runner}/command_options.h (97%) rename src/templates/app/{common => runner}/flutter/generated_plugin_registrant.cc (100%) rename src/templates/app/{common => runner}/flutter/generated_plugin_registrant.h (100%) rename src/templates/app/{common => runner}/flutter/generated_plugins.cmake (100%) rename src/templates/app/{common => runner}/flutter_window.cc (100%) rename src/templates/app/{common => runner}/flutter_window.h (100%) rename src/templates/app/{linux-drm => runner_drm}/main.cc (100%) rename src/templates/app/{linux-wayland-weston-desktop-shell => runner_wayland-weston-desktop-shell}/main.cc (100%) rename src/templates/app/{linux-wayland => runner_wayland}/main.cc (100%) rename src/templates/app/{linux-x11 => runner_x11}/main.cc (100%) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 65b57baf..b4a834fe 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -74,3 +74,13 @@ jobs: working-directory: ${{github.workspace}}/build shell: bash run: cmake --build . --config $BUILD_TYPE + + - name: Configure CMake to build libflutter_elinux.so + shell: bash + working-directory: ${{github.workspace}}/build + run: cmake $GITHUB_WORKSPACE -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DBUILD_ELINUX_SO=ON -DBACKEND_TYPE=WAYLAND .. + + - name: Build libflutter_elinux.so + working-directory: ${{github.workspace}}/build + shell: bash + run: cmake --build . --config $BUILD_TYPE diff --git a/CMakeLists.txt b/CMakeLists.txt index e08a73ee..82bb1c5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,11 +13,17 @@ project("flutter_elinux" LANGUAGES CXX C) option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) +option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) # Load the user project. -set(USER_PROJECT_PATH "examples/flutter-wayland-client" CACHE STRING "") -message("User project: ${USER_PROJECT_PATH}") -include(${USER_PROJECT_PATH}/cmake/user_config.cmake) +if(NOT BUILD_ELINUX_SO) + set(USER_PROJECT_PATH "examples/flutter-wayland-client" CACHE STRING "") + message("User project: ${USER_PROJECT_PATH}") + include(${USER_PROJECT_PATH}/cmake/user_config.cmake) +else() + string(TOLOWER ${BACKEND_TYPE} TARGET_SUFFIX) + set(TARGET "flutter_elinux_${TARGET_SUFFIX}") +endif() # System level dependent library. include(cmake/package.cmake) diff --git a/cmake/build.cmake b/cmake/build.cmake index d5abfa7f..4fd83fec 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -19,60 +19,60 @@ set(DISPLAY_BACKEND_SRC "") if(${BACKEND_TYPE} STREQUAL "DRM-GBM") add_definitions(-DDISPLAY_BACKEND_TYPE_DRM_GBM) set(DISPLAY_BACKEND_SRC - src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc - src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc) + "src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc") elseif(${BACKEND_TYPE} STREQUAL "DRM-EGLSTREAM") add_definitions(-DDISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) set(DISPLAY_BACKEND_SRC - src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc - src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc - src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc - src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc) + "src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc" + "src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc") elseif(${BACKEND_TYPE} STREQUAL "X11") add_definitions(-DDISPLAY_BACKEND_TYPE_X11) set(DISPLAY_BACKEND_SRC - src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc - src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc) + "src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc") else() include(cmake/generate_wayland_protocols.cmake) - set(_wayland_protocols_xml_dir $ENV{PKG_CONFIG_SYSROOT_DIR}/usr/share/wayland-protocols) - set(_wayland_protocols_src_dir ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/wayland/protocols) + set(_wayland_protocols_xml_dir "$ENV{PKG_CONFIG_SYSROOT_DIR}/usr/share/wayland-protocols") + set(_wayland_protocols_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/wayland/protocols") generate_wayland_client_protocol( - PROTOCOL_FILE ${_wayland_protocols_xml_dir}/stable/xdg-shell/xdg-shell.xml - CODE_FILE ${_wayland_protocols_src_dir}/xdg-shell-protocol.c - HEADER_FILE ${_wayland_protocols_src_dir}/xdg-shell-client-protocol.h) + PROTOCOL_FILE "${_wayland_protocols_xml_dir}/stable/xdg-shell/xdg-shell.xml" + CODE_FILE "${_wayland_protocols_src_dir}/xdg-shell-protocol.c" + HEADER_FILE "${_wayland_protocols_src_dir}/xdg-shell-client-protocol.h") generate_wayland_client_protocol( - PROTOCOL_FILE ${_wayland_protocols_xml_dir}/unstable/text-input/text-input-unstable-v1.xml - CODE_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c - HEADER_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v1-client-protocol.h) + PROTOCOL_FILE "${_wayland_protocols_xml_dir}/unstable/text-input/text-input-unstable-v1.xml" + CODE_FILE "${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c" + HEADER_FILE "${_wayland_protocols_src_dir}/text-input-unstable-v1-client-protocol.h") generate_wayland_client_protocol( - PROTOCOL_FILE ${_wayland_protocols_xml_dir}/unstable/text-input/text-input-unstable-v3.xml - CODE_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c - HEADER_FILE ${_wayland_protocols_src_dir}/text-input-unstable-v3-client-protocol.h) + PROTOCOL_FILE "${_wayland_protocols_xml_dir}/unstable/text-input/text-input-unstable-v3.xml" + CODE_FILE "${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c" + HEADER_FILE "${_wayland_protocols_src_dir}/text-input-unstable-v3-client-protocol.h") generate_wayland_client_protocol( - PROTOCOL_FILE ${_wayland_protocols_xml_dir}/stable/presentation-time/presentation-time.xml - CODE_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.c - HEADER_FILE ${_wayland_protocols_src_dir}/presentation-time-protocol.h) + PROTOCOL_FILE "${_wayland_protocols_xml_dir}/stable/presentation-time/presentation-time.xml" + CODE_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.c" + HEADER_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.h") add_definitions(-DDISPLAY_BACKEND_TYPE_WAYLAND) set(DISPLAY_BACKEND_SRC - ${_wayland_protocols_src_dir}/xdg-shell-protocol.c - ${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c - ${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c - ${_wayland_protocols_src_dir}/presentation-time-protocol.c - src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc - src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc - src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc - src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc - src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc - src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc - src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc - src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc - src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc) + "${_wayland_protocols_src_dir}/xdg-shell-protocol.c" + "${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c" + "${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c" + "${_wayland_protocols_src_dir}/presentation-time-protocol.c" + "src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc" + "src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc") endif() # desktop-shell for weston. @@ -82,7 +82,10 @@ endif() # weston private protocols. if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) - set(DISPLAY_BACKEND_SRC ${DISPLAY_BACKEND_SRC} src/third_party/wayland/protocols/weston-desktop-shell-protocol.c) + set(DISPLAY_BACKEND_SRC + ${DISPLAY_BACKEND_SRC} + "src/third_party/wayland/protocols/weston-desktop-shell-protocol.c" + ) endif() # OpenGL ES version. @@ -97,58 +100,93 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug) ) endif() -# cmake script for developers. -include(${USER_PROJECT_PATH}/cmake/user_build.cmake) - -add_executable(${TARGET} - ${USER_APP_SRCS} - src/client_wrapper/flutter_engine.cc - src/client_wrapper/flutter_view_controller.cc - src/flutter/shell/platform/linux_embedded/flutter_elinux.cc - src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc - src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc - src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc - src/flutter/shell/platform/linux_embedded/task_runner.cc - src/flutter/shell/platform/linux_embedded/system_utils.cc - src/flutter/shell/platform/linux_embedded/logger.cc - src/flutter/shell/platform/linux_embedded/external_texture_gl.cc - src/flutter/shell/platform/linux_embedded/vsync_waiter.cc - src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc - src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc - src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc - src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc - src/flutter/shell/platform/linux_embedded/surface/context_egl.cc - src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc - src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc - src/flutter/shell/platform/linux_embedded/surface/surface_base.cc - src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc - src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc - ${DISPLAY_BACKEND_SRC} +set(CPP_WRAPPER_SOURCES_CORE + "src/flutter/shell/platform/common/client_wrapper/engine_method_result.cc" + "src/flutter/shell/platform/common/client_wrapper/standard_codec.cc" +) +set(CPP_WRAPPER_SOURCES_PLUGIN + "src/flutter/shell/platform/common/client_wrapper/plugin_registrar.cc" +) +set(CPP_WRAPPER_SOURCES_APP + "src/client_wrapper/flutter_engine.cc" + "src/client_wrapper/flutter_view_controller.cc" +) + +set(ELINUX_COMMON_SRC + "src/flutter/shell/platform/linux_embedded/flutter_elinux.cc" + "src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc" + "src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc" + "src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc" + "src/flutter/shell/platform/linux_embedded/task_runner.cc" + "src/flutter/shell/platform/linux_embedded/system_utils.cc" + "src/flutter/shell/platform/linux_embedded/logger.cc" + "src/flutter/shell/platform/linux_embedded/external_texture_gl.cc" + "src/flutter/shell/platform/linux_embedded/vsync_waiter.cc" + "src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc" + "src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc" + "src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc" + "src/flutter/shell/platform/linux_embedded/surface/context_egl.cc" + "src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc" + "src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc" + "src/flutter/shell/platform/linux_embedded/surface/surface_base.cc" + "src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc" + "src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc" + "${DISPLAY_BACKEND_SRC}" ## The following file were copied from: ## https://github.com/flutter/engine/blob/master/shell/platform/glfw/ - src/flutter/shell/platform/linux_embedded/system_utils.cc + "src/flutter/shell/platform/linux_embedded/system_utils.cc" ## Following files were imported from: ## https://github.com/flutter/engine/tree/master/shell/platform/common - src/flutter/shell/platform/common/client_wrapper/engine_method_result.cc - src/flutter/shell/platform/common/client_wrapper/standard_codec.cc - src/flutter/shell/platform/common/client_wrapper/plugin_registrar.cc - src/flutter/shell/platform/common/text_input_model.cc - src/flutter/shell/platform/common/json_message_codec.cc - src/flutter/shell/platform/common/json_method_codec.cc - src/flutter/shell/platform/common/engine_switches.cc - src/flutter/shell/platform/common/incoming_message_dispatcher.cc + "src/flutter/shell/platform/common/text_input_model.cc" + "src/flutter/shell/platform/common/json_message_codec.cc" + "src/flutter/shell/platform/common/json_method_codec.cc" + "src/flutter/shell/platform/common/engine_switches.cc" + "src/flutter/shell/platform/common/incoming_message_dispatcher.cc" ) -set(THIRD_PARTY_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/src/third_party) -set(RAPIDJSON_INCLUDE_DIRS ${THIRD_PARTY_DIRS}/rapidjson/include/) +if(NOT BUILD_ELINUX_SO) + # cmake script for developers. + include(${USER_PROJECT_PATH}/cmake/user_build.cmake) + + add_executable(${TARGET} + ${ELINUX_COMMON_SRC} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} + ${USER_APP_SRCS} + ) +else() + add_library(${TARGET} + SHARED + ${ELINUX_COMMON_SRC} + ) + + target_include_directories(${TARGET} + PUBLIC + "src/flutter/shell/platform/linux_embedded/public" + ) + + target_include_directories(${TARGET} + PRIVATE + "src/client_wrapper/include" + "src/flutter/shell/platform/common/client_wrapper" + "src/flutter/shell/platform/common/client_wrapper/include" + "src/flutter/shell/platform/common/client_wrapper/include/flutter" + "src/flutter/shell/platform/common/public" + ) +endif() + +set(THIRD_PARTY_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/src/third_party") +set(RAPIDJSON_INCLUDE_DIRS "${THIRD_PARTY_DIRS}/rapidjson/include/") target_include_directories(${TARGET} PRIVATE - src + "src" ## third-party libraries. ${THIRD_PARTY_DIRS} ${RAPIDJSON_INCLUDE_DIRS} @@ -169,8 +207,6 @@ target_include_directories(${TARGET} ${USER_APP_INCLUDE_DIRS} ) -set(CMAKE_SKIP_RPATH true) -set(FLUTTER_EMBEDDER_LIB ${CMAKE_CURRENT_SOURCE_DIR}/build/libflutter_engine.so) target_link_libraries(${TARGET} PRIVATE ${XKBCOMMON_LIBRARIES} @@ -197,10 +233,19 @@ target_link_libraries(${TARGET} ) endif() +set(FLUTTER_EMBEDDER_LIB "${CMAKE_CURRENT_SOURCE_DIR}/build/libflutter_engine.so") +set(CMAKE_SKIP_RPATH true) +target_link_libraries(${TARGET} + PRIVATE + ${FLUTTER_EMBEDDER_LIB} +) + target_compile_options(${TARGET} PUBLIC ${EGL_CFLAGS} ) -# Generated plugin build rules -include(${USER_PROJECT_PATH}/flutter/generated_plugins.cmake) +if(NOT BUILD_ELINUX_SO) + # Generated plugin build rules + include(${USER_PROJECT_PATH}/flutter/generated_plugins.cmake) +endif() diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake index f8ad2082..ecf37e32 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-drm-eglstream-backend ) diff --git a/examples/flutter-drm-eglstream-backend/command_options.h b/examples/flutter-drm-eglstream-backend/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-drm-eglstream-backend/command_options.h +++ b/examples/flutter-drm-eglstream-backend/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake index 445581e1..59c0f368 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_build.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-drm-gbm-backend ) diff --git a/examples/flutter-drm-gbm-backend/command_options.h b/examples/flutter-drm-gbm-backend/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-drm-gbm-backend/command_options.h +++ b/examples/flutter-drm-gbm-backend/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/examples/flutter-external-texture-plugin/cmake/user_build.cmake b/examples/flutter-external-texture-plugin/cmake/user_build.cmake index 092926f2..fc29a3bb 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_build.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-external-texture-plugin ) diff --git a/examples/flutter-external-texture-plugin/command_options.h b/examples/flutter-external-texture-plugin/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-external-texture-plugin/command_options.h +++ b/examples/flutter-external-texture-plugin/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/examples/flutter-video-player-plugin/cmake/user_build.cmake b/examples/flutter-video-player-plugin/cmake/user_build.cmake index 7acfd70f..6014e1db 100644 --- a/examples/flutter-video-player-plugin/cmake/user_build.cmake +++ b/examples/flutter-video-player-plugin/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-video-player-plugin ) diff --git a/examples/flutter-video-player-plugin/command_options.h b/examples/flutter-video-player-plugin/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-video-player-plugin/command_options.h +++ b/examples/flutter-video-player-plugin/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/examples/flutter-wayland-client/cmake/user_build.cmake b/examples/flutter-wayland-client/cmake/user_build.cmake index 213a3444..8bcd69ae 100644 --- a/examples/flutter-wayland-client/cmake/user_build.cmake +++ b/examples/flutter-wayland-client/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-wayland-client ) diff --git a/examples/flutter-wayland-client/command_options.h b/examples/flutter-wayland-client/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-wayland-client/command_options.h +++ b/examples/flutter-wayland-client/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake index a8af88a3..fce0a17b 100644 --- a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake +++ b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-weston-desktop-shell ) diff --git a/examples/flutter-x11-client/cmake/user_build.cmake b/examples/flutter-x11-client/cmake/user_build.cmake index a2a7c54a..8b7f3d70 100644 --- a/examples/flutter-x11-client/cmake/user_build.cmake +++ b/examples/flutter-x11-client/cmake/user_build.cmake @@ -19,7 +19,6 @@ set(USER_APP_INCLUDE_DIRS src/flutter/shell/platform/common/client_wrapper/include/flutter src/flutter/shell/platform/common/public src/flutter/shell/platform/linux_embedded/public - src/public/include ## header file include path for user apps. examples/flutter-x11-client ) diff --git a/examples/flutter-x11-client/command_options.h b/examples/flutter-x11-client/command_options.h index 2cb5a66c..977cdc83 100644 --- a/examples/flutter-x11-client/command_options.h +++ b/examples/flutter-x11-client/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/src/templates/app/common/command_options.h b/src/templates/app/runner/command_options.h similarity index 97% rename from src/templates/app/common/command_options.h rename to src/templates/app/runner/command_options.h index 2cb5a66c..977cdc83 100644 --- a/src/templates/app/common/command_options.h +++ b/src/templates/app/runner/command_options.h @@ -145,7 +145,7 @@ class CommandOptions { // short options: e.g. -f /foo/file.txt -h 640 -abc else if (arg.length() > 1 && arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (int j = 1; j < arg.length(); j++) { + for (size_t j = 1; j < arg.length(); j++) { const std::string option_name{argv[i][j]}; if (lut_short_options_.find(option_name) == @@ -170,7 +170,7 @@ class CommandOptions { } } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired() && !registration_order_options_[i]->HasValue()) { errors_.push_back( @@ -190,7 +190,7 @@ class CommandOptions { std::ostringstream ostream; ostream << "Usage: " << command_name_ << " "; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (registration_order_options_[i]->IsRequired()) { ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; } @@ -199,12 +199,12 @@ class CommandOptions { ostream << "Global options:" << std::endl; size_t max_name_len = 0; - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { max_name_len = std::max( max_name_len, registration_order_options_[i]->GetName().length()); } - for (auto i = 0; i < registration_order_options_.size(); i++) { + for (size_t i = 0; i < registration_order_options_.size(); i++) { if (!registration_order_options_[i]->GetShortName().empty()) { ostream << kOptionStyleShort << registration_order_options_[i]->GetShortName() << ", "; @@ -277,11 +277,11 @@ class CommandOptions { virtual bool HasValue() const = 0; protected: - bool is_required_; - bool is_required_value_; std::string name_; std::string short_name_; std::string description_; + bool is_required_; + bool is_required_value_; bool value_set_; }; diff --git a/src/templates/app/common/flutter/generated_plugin_registrant.cc b/src/templates/app/runner/flutter/generated_plugin_registrant.cc similarity index 100% rename from src/templates/app/common/flutter/generated_plugin_registrant.cc rename to src/templates/app/runner/flutter/generated_plugin_registrant.cc diff --git a/src/templates/app/common/flutter/generated_plugin_registrant.h b/src/templates/app/runner/flutter/generated_plugin_registrant.h similarity index 100% rename from src/templates/app/common/flutter/generated_plugin_registrant.h rename to src/templates/app/runner/flutter/generated_plugin_registrant.h diff --git a/src/templates/app/common/flutter/generated_plugins.cmake b/src/templates/app/runner/flutter/generated_plugins.cmake similarity index 100% rename from src/templates/app/common/flutter/generated_plugins.cmake rename to src/templates/app/runner/flutter/generated_plugins.cmake diff --git a/src/templates/app/common/flutter_window.cc b/src/templates/app/runner/flutter_window.cc similarity index 100% rename from src/templates/app/common/flutter_window.cc rename to src/templates/app/runner/flutter_window.cc diff --git a/src/templates/app/common/flutter_window.h b/src/templates/app/runner/flutter_window.h similarity index 100% rename from src/templates/app/common/flutter_window.h rename to src/templates/app/runner/flutter_window.h diff --git a/src/templates/app/linux-drm/main.cc b/src/templates/app/runner_drm/main.cc similarity index 100% rename from src/templates/app/linux-drm/main.cc rename to src/templates/app/runner_drm/main.cc diff --git a/src/templates/app/linux-wayland-weston-desktop-shell/main.cc b/src/templates/app/runner_wayland-weston-desktop-shell/main.cc similarity index 100% rename from src/templates/app/linux-wayland-weston-desktop-shell/main.cc rename to src/templates/app/runner_wayland-weston-desktop-shell/main.cc diff --git a/src/templates/app/linux-wayland/main.cc b/src/templates/app/runner_wayland/main.cc similarity index 100% rename from src/templates/app/linux-wayland/main.cc rename to src/templates/app/runner_wayland/main.cc diff --git a/src/templates/app/linux-x11/main.cc b/src/templates/app/runner_x11/main.cc similarity index 100% rename from src/templates/app/linux-x11/main.cc rename to src/templates/app/runner_x11/main.cc From 5c9f6593f552ae48ea92642f81269205835cb8d6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 12 Jul 2021 07:49:55 +0900 Subject: [PATCH 041/178] Change filename of elinux .so (#195) --- CMakeLists.txt | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 82bb1c5d..e65b210d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,13 +15,22 @@ option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) -# Load the user project. if(NOT BUILD_ELINUX_SO) + # Load the user project. set(USER_PROJECT_PATH "examples/flutter-wayland-client" CACHE STRING "") message("User project: ${USER_PROJECT_PATH}") include(${USER_PROJECT_PATH}/cmake/user_config.cmake) else() - string(TOLOWER ${BACKEND_TYPE} TARGET_SUFFIX) + # Set the filename of elinux .so file + if(${BACKEND_TYPE} STREQUAL "DRM-GBM") + set(TARGET_SUFFIX "gbm") + elseif(${BACKEND_TYPE} STREQUAL "DRM-EGLSTREAM") + set(TARGET_SUFFIX "eglstream") + elseif(${BACKEND_TYPE} STREQUAL "X11") + set(TARGET_SUFFIX "x11") + else() + set(TARGET_SUFFIX "wayland") + endif() set(TARGET "flutter_elinux_${TARGET_SUFFIX}") endif() From 9aefe4a832030193009ef71b866e1f5e6f996eec Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 12 Jul 2021 10:29:58 +0900 Subject: [PATCH 042/178] Fix link error in elinux .so (#196) --- cmake/build.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/build.cmake b/cmake/build.cmake index 4fd83fec..d098956a 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -165,6 +165,8 @@ else() add_library(${TARGET} SHARED ${ELINUX_COMMON_SRC} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} ) target_include_directories(${TARGET} From 0fc3a26100a897ceb87c3dc21a29583cf25a6901 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 12 Jul 2021 16:38:55 +0900 Subject: [PATCH 043/178] Add compiler option to ignore log messages (#197) --- src/flutter/shell/platform/linux_embedded/logger.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/logger.h b/src/flutter/shell/platform/linux_embedded/logger.h index 5eb1d7d7..d87d6df7 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.h +++ b/src/flutter/shell/platform/linux_embedded/logger.h @@ -20,11 +20,15 @@ constexpr int ELINUX_LOG_ERROR = 4; constexpr int ELINUX_LOG_FATAL = 5; constexpr int ELINUX_LOG_NUM = 6; +#if defined(NDEBUG) +#define ELINUX_LOG(level) Logger(-1, "", 0).stream() +#else #define __LOG_FILE_NAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) #define ELINUX_LOG(level) \ Logger(ELINUX_LOG_##level, __LOG_FILE_NAME__, __LINE__).stream() +#endif class Logger { public: From 692c8190e2fb2da4336b3bed8bf986995a2d6153 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 13 Jul 2021 11:16:36 +0900 Subject: [PATCH 044/178] Add ENABLE_ELINUX_EMBEDDER_LOG compiler option (#198) I added `ENABLE_ELINUX_EMBEDDER_LOG` compiler option. --- CMakeLists.txt | 1 + cmake/build.cmake | 7 +++++++ src/flutter/shell/platform/linux_embedded/logger.h | 8 +++++++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e65b210d..7de87113 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the displ option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) +option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) if(NOT BUILD_ELINUX_SO) # Load the user project. diff --git a/cmake/build.cmake b/cmake/build.cmake index d098956a..6aeedf0b 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -100,6 +100,13 @@ if(NOT CMAKE_BUILD_TYPE MATCHES Debug) ) endif() +# Enable logger of eLinux embedder. +if(ENABLE_ELINUX_EMBEDDER_LOG) + add_definitions( + -DENABLE_ELINUX_EMBEDDER_LOG + ) +endif() + set(CPP_WRAPPER_SOURCES_CORE "src/flutter/shell/platform/common/client_wrapper/engine_method_result.cc" "src/flutter/shell/platform/common/client_wrapper/standard_codec.cc" diff --git a/src/flutter/shell/platform/linux_embedded/logger.h b/src/flutter/shell/platform/linux_embedded/logger.h index d87d6df7..e3666aba 100644 --- a/src/flutter/shell/platform/linux_embedded/logger.h +++ b/src/flutter/shell/platform/linux_embedded/logger.h @@ -20,8 +20,11 @@ constexpr int ELINUX_LOG_ERROR = 4; constexpr int ELINUX_LOG_FATAL = 5; constexpr int ELINUX_LOG_NUM = 6; +#if defined(ENABLE_ELINUX_EMBEDDER_LOG) #if defined(NDEBUG) -#define ELINUX_LOG(level) Logger(-1, "", 0).stream() +// We don't use __FILE__ macro with release build. +#define ELINUX_LOG(level) \ + Logger(ELINUX_LOG_##level, __FUNCTION__, __LINE__).stream() #else #define __LOG_FILE_NAME__ \ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) @@ -29,6 +32,9 @@ constexpr int ELINUX_LOG_NUM = 6; #define ELINUX_LOG(level) \ Logger(ELINUX_LOG_##level, __LOG_FILE_NAME__, __LINE__).stream() #endif +#else +#define ELINUX_LOG(level) Logger(-1, "", 0).stream() +#endif class Logger { public: From baba21f0a1826b7466d2edb4395cc012b3392a96 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 13 Jul 2021 11:31:44 +0900 Subject: [PATCH 045/178] Add FLUTTER_RELEASE compiler option (#199) I added FLUTTER_RELEASE cmake option to separate it from CMAKE_BUILD_TYPE. --- CMakeLists.txt | 1 + cmake/build.cmake | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7de87113..63d8f1c7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) +option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) if(NOT BUILD_ELINUX_SO) # Load the user project. diff --git a/cmake/build.cmake b/cmake/build.cmake index 6aeedf0b..d2c80169 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -94,7 +94,7 @@ if(USE_GLES3) endif() # Flutter embedder runtime mode. -if(NOT CMAKE_BUILD_TYPE MATCHES Debug) +if(FLUTTER_RELEASE) add_definitions( -DFLUTTER_RELEASE # release mode ) From 44788054b702f09dbce16627a6c5b0fe6facc1d6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 15 Jul 2021 14:56:35 +0900 Subject: [PATCH 046/178] Update app templates for elinux tools (#200) --- src/templates/app/CMakeLists.txt.tmpl | 104 +++++++++++++++++ src/templates/app/flutter/CMakeLists.txt | 108 ++++++++++++++++++ src/templates/app/runner/CMakeLists.txt | 13 +++ .../flutter/generated_plugin_registrant.cc | 10 -- .../flutter/generated_plugin_registrant.h | 13 --- .../runner/flutter/generated_plugins.cmake | 22 ---- 6 files changed, 225 insertions(+), 45 deletions(-) create mode 100644 src/templates/app/CMakeLists.txt.tmpl create mode 100644 src/templates/app/flutter/CMakeLists.txt create mode 100644 src/templates/app/runner/CMakeLists.txt delete mode 100644 src/templates/app/runner/flutter/generated_plugin_registrant.cc delete mode 100644 src/templates/app/runner/flutter/generated_plugin_registrant.h delete mode 100644 src/templates/app/runner/flutter/generated_plugins.cmake diff --git a/src/templates/app/CMakeLists.txt.tmpl b/src/templates/app/CMakeLists.txt.tmpl new file mode 100644 index 00000000..c031dcba --- /dev/null +++ b/src/templates/app/CMakeLists.txt.tmpl @@ -0,0 +1,104 @@ +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +set(BINARY_NAME "{{projectName}}") + +cmake_policy(SET CMP0063 NEW) + +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") + +# Root filesystem for cross-building. +if(FLUTTER_TARGET_PLATFORM_SYSROOT) + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endif() + +# Configure build options. +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + set(CMAKE_BUILD_TYPE "Debug" CACHE + STRING "Flutter build mode" FORCE) + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "Debug" "Profile" "Release") +endif() + +# Configure build option to target backend. +if (NOT FLUTTER_TARGET_BACKEND_TYPE) + set(FLUTTER_TARGET_BACKEND_TYPE "wayland" CACHE + STRING "Flutter target backend type" FORCE) + set_property(CACHE FLUTTER_TARGET_BACKEND_TYPE PROPERTY STRINGS + "wayland" "gbm" "eglstream" "x11") +endif() + +# Compilation settings that should be applied to most targets. +function(APPLY_STANDARD_SETTINGS TARGET) + target_compile_features(${TARGET} PUBLIC cxx_std_17) + target_compile_options(${TARGET} PRIVATE -Wall -Werror) + target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") + target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") +endfunction() + +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") + +# Flutter library and tool build rules. +add_subdirectory(${FLUTTER_MANAGED_DIR}) + +# Application build +add_subdirectory("runner") + +# Generated plugin build rules, which manage building the plugins and adding +# them to the application. +include(flutter/generated_plugins.cmake) + +# === Installation === +# By default, "installing" just makes a relocatable bundle in the build +# directory. +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) +endif() + +# Start with a clean build bundle directory every time. +install(CODE " + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") + " COMPONENT Runtime) + +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") + +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" + COMPONENT Runtime) + +install(FILES "${FLUTTER_LIBRARY}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +install(FILES "${FLUTTER_EMBEDDER_LIBRARY}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) + +if(PLUGIN_BUNDLED_LIBRARIES) + install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() + +# Fully re-copy the assets directory on each build to avoid having stale files +# from a previous install. +set(FLUTTER_ASSET_DIR_NAME "flutter_assets") +install(CODE " + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") + " COMPONENT Runtime) +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) + +# Install the AOT library on non-Debug builds only. +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" + COMPONENT Runtime) +endif() diff --git a/src/templates/app/flutter/CMakeLists.txt b/src/templates/app/flutter/CMakeLists.txt new file mode 100644 index 00000000..376be867 --- /dev/null +++ b/src/templates/app/flutter/CMakeLists.txt @@ -0,0 +1,108 @@ +cmake_minimum_required(VERSION 3.10) + +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") + +# Configuration provided via flutter tool. +include(${EPHEMERAL_DIR}/generated_config.cmake) + +set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") + +# Serves the same purpose as list(TRANSFORM ... PREPEND ...), +# which isn't available in 3.10. +function(list_prepend LIST_NAME PREFIX) + set(NEW_LIST "") + foreach(element ${${LIST_NAME}}) + list(APPEND NEW_LIST "${PREFIX}${element}") + endforeach(element) + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) +endfunction() + +# === Flutter Library === +# System-level dependencies. +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_engine.so") +if(FLUTTER_TARGET_BACKEND_TYPE MATCHES "gbm") + set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_gbm.so") +elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "eglstream") + set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_eglstream.so") +elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "x11") + set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_x11.so") +else() + set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_wayland.so") +endif() + +# Published to parent scope for install step. +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_EMBEDDER_LIBRARY ${FLUTTER_EMBEDDER_LIBRARY} PARENT_SCOPE) +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/elinux/" PARENT_SCOPE) +set(AOT_LIBRARY "${EPHEMERAL_DIR}/libapp.so" PARENT_SCOPE) + +list(APPEND FLUTTER_LIBRARY_HEADERS + "flutter_export.h" + "flutter_plugin_registrar.h" + "flutter_messenger.h" + "flutter_texture_registrar.h" + "flutter_elinux.h" + "flutter_platform_views.h" +) +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/") +add_library(flutter INTERFACE) +target_include_directories(flutter INTERFACE + "${EPHEMERAL_DIR}" +) +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") +target_link_libraries(flutter INTERFACE "${FLUTTER_EMBEDDER_LIBRARY}") +add_dependencies(flutter flutter_assemble) + +# === Wrapper === +list(APPEND CPP_WRAPPER_SOURCES_CORE + "core_implementations.cc" + "standard_codec.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_PLUGIN + "plugin_registrar.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") +list(APPEND CPP_WRAPPER_SOURCES_APP + "flutter_engine.cc" + "flutter_view_controller.cc" +) +list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") + +# Wrapper sources needed for a plugin. +add_library(flutter_wrapper_plugin STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} +) +apply_standard_settings(flutter_wrapper_plugin) +set_target_properties(flutter_wrapper_plugin PROPERTIES + POSITION_INDEPENDENT_CODE ON) +set_target_properties(flutter_wrapper_plugin PROPERTIES + CXX_VISIBILITY_PRESET hidden) +target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) +target_include_directories(flutter_wrapper_plugin PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_plugin flutter_assemble) + +# Wrapper sources needed for the runner. +add_library(flutter_wrapper_app STATIC + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_APP} +) +apply_standard_settings(flutter_wrapper_app) +target_link_libraries(flutter_wrapper_app PUBLIC flutter) +target_include_directories(flutter_wrapper_app PUBLIC + "${WRAPPER_ROOT}/include" +) +add_dependencies(flutter_wrapper_app flutter_assemble) + +add_custom_target(flutter_assemble DEPENDS + "${FLUTTER_LIBRARY}" + "${FLUTTER_EMBEDDER_LIBRARY}" + ${FLUTTER_LIBRARY_HEADERS} + ${CPP_WRAPPER_SOURCES_CORE} + ${CPP_WRAPPER_SOURCES_PLUGIN} + ${CPP_WRAPPER_SOURCES_APP} +) diff --git a/src/templates/app/runner/CMakeLists.txt b/src/templates/app/runner/CMakeLists.txt new file mode 100644 index 00000000..de800cf9 --- /dev/null +++ b/src/templates/app/runner/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 3.10) +project(runner LANGUAGES CXX) + +add_executable(${BINARY_NAME} + "flutter_window.cc" + "main.cc" + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" +) +apply_standard_settings(${BINARY_NAME}) +target_link_libraries(${BINARY_NAME} PRIVATE flutter) +target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) +target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") +add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/src/templates/app/runner/flutter/generated_plugin_registrant.cc b/src/templates/app/runner/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 7e6e6c2d..00000000 --- a/src/templates/app/runner/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) { -} diff --git a/src/templates/app/runner/flutter/generated_plugin_registrant.h b/src/templates/app/runner/flutter/generated_plugin_registrant.h deleted file mode 100644 index a31c23cd..00000000 --- a/src/templates/app/runner/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated file. Do not edit. -// - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/src/templates/app/runner/flutter/generated_plugins.cmake b/src/templates/app/runner/flutter/generated_plugins.cmake deleted file mode 100644 index fcbf0d6e..00000000 --- a/src/templates/app/runner/flutter/generated_plugins.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory( - ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) - - target_link_libraries(${TARGET} - PRIVATE - ${plugin}_plugin - ) - - list(APPEND PLUGIN_BUNDLED_LIBRARIES - ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so - ) -endforeach(plugin) From 0c1914b16f089ccd9cfb8ead5c16f3b6044d0c3f Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 16 Jul 2021 12:18:50 +0900 Subject: [PATCH 047/178] Refactoring: integrate multi main.cc files (#201) * Refactoring: integrate multi main.cc files * Remove unused include --- cmake/build.cmake | 4 + .../flutter_embedder_options.h | 103 ++++++++++++++++++ .../flutter-drm-eglstream-backend/main.cc | 27 ++--- .../flutter_embedder_options.h | 103 ++++++++++++++++++ examples/flutter-drm-gbm-backend/main.cc | 27 ++--- .../flutter_embedder_options.h | 103 ++++++++++++++++++ .../flutter-external-texture-plugin/main.cc | 45 ++------ .../flutter_embedder_options.h | 103 ++++++++++++++++++ examples/flutter-video-player-plugin/main.cc | 45 ++------ .../flutter_embedder_options.h | 103 ++++++++++++++++++ examples/flutter-wayland-client/main.cc | 45 ++------ .../flutter_embedder_options.h | 103 ++++++++++++++++++ examples/flutter-x11-client/main.cc | 38 ++----- src/templates/app/runner/CMakeLists.txt | 10 ++ .../app/runner/flutter_embedder_options.h | 103 ++++++++++++++++++ .../app/{runner_drm => runner}/main.cc | 27 ++--- src/templates/app/runner_wayland/main.cc | 69 ------------ src/templates/app/runner_x11/main.cc | 62 ----------- 18 files changed, 812 insertions(+), 308 deletions(-) create mode 100644 examples/flutter-drm-eglstream-backend/flutter_embedder_options.h create mode 100644 examples/flutter-drm-gbm-backend/flutter_embedder_options.h create mode 100644 examples/flutter-external-texture-plugin/flutter_embedder_options.h create mode 100644 examples/flutter-video-player-plugin/flutter_embedder_options.h create mode 100644 examples/flutter-wayland-client/flutter_embedder_options.h create mode 100644 examples/flutter-x11-client/flutter_embedder_options.h create mode 100644 src/templates/app/runner/flutter_embedder_options.h rename src/templates/app/{runner_drm => runner}/main.cc (58%) delete mode 100644 src/templates/app/runner_wayland/main.cc delete mode 100644 src/templates/app/runner_x11/main.cc diff --git a/cmake/build.cmake b/cmake/build.cmake index d2c80169..a8c52a0b 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -18,11 +18,13 @@ endif() set(DISPLAY_BACKEND_SRC "") if(${BACKEND_TYPE} STREQUAL "DRM-GBM") add_definitions(-DDISPLAY_BACKEND_TYPE_DRM_GBM) + add_definitions(-DFLUTTER_TARGET_BACKEND_GBM) set(DISPLAY_BACKEND_SRC "src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc") elseif(${BACKEND_TYPE} STREQUAL "DRM-EGLSTREAM") add_definitions(-DDISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) + add_definitions(-DFLUTTER_TARGET_BACKEND_EGLSTREAM) set(DISPLAY_BACKEND_SRC "src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc" "src/flutter/shell/platform/linux_embedded/surface/environment_egl_stream.cc" @@ -30,6 +32,7 @@ elseif(${BACKEND_TYPE} STREQUAL "DRM-EGLSTREAM") "src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc") elseif(${BACKEND_TYPE} STREQUAL "X11") add_definitions(-DDISPLAY_BACKEND_TYPE_X11) + add_definitions(-DFLUTTER_TARGET_BACKEND_X11) set(DISPLAY_BACKEND_SRC "src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc") @@ -58,6 +61,7 @@ else() CODE_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.c" HEADER_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.h") + add_definitions(-DFLUTTER_TARGET_BACKEND_WAYLAND) add_definitions(-DDISPLAY_BACKEND_TYPE_WAYLAND) set(DISPLAY_BACKEND_SRC "${_wayland_protocols_src_dir}/xdg-shell-protocol.c" diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index edbe7616..9c9c91d3 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -9,35 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const bool show_cursor = !options.Exist("no-cursor"); - const auto bundle_path = options.GetValue("bundle"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.view_mode = - flutter::FlutterViewController::ViewMode::kFullscreen; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = false; - view_properties.use_window_decoration = false; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -47,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index edbe7616..9c9c91d3 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -9,35 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const bool show_cursor = !options.Exist("no-cursor"); - const auto bundle_path = options.GetValue("bundle"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.view_mode = - flutter::FlutterViewController::ViewMode::kFullscreen; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = false; - view_properties.use_window_decoration = false; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -47,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 73e4c941..9c9c91d3 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -9,53 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", - false); - options.AddWithoutValue("window-decoration", "d", "Enable window decorations", - false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const bool show_cursor = !options.Exist("no-cursor"); - const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); - const bool use_window_decoration = options.Exist("window-decoration"); - - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = use_onscreen_keyboard; - view_properties.use_window_decoration = use_window_decoration; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -65,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index 73e4c941..9c9c91d3 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -9,53 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", - false); - options.AddWithoutValue("window-decoration", "d", "Enable window decorations", - false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const bool show_cursor = !options.Exist("no-cursor"); - const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); - const bool use_window_decoration = options.Exist("window-decoration"); - - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = use_onscreen_keyboard; - view_properties.use_window_decoration = use_window_decoration; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -65,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 73e4c941..9c9c91d3 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -9,53 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", - false); - options.AddWithoutValue("window-decoration", "d", "Enable window decorations", - false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const bool show_cursor = !options.Exist("no-cursor"); - const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); - const bool use_window_decoration = options.Exist("window-decoration"); - - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = use_onscreen_keyboard; - view_properties.use_window_decoration = use_window_decoration; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -65,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 9512dea5..9c9c91d3 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -9,46 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const bool show_cursor = !options.Exist("no-cursor"); - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - const auto bundle_path = options.GetValue("bundle"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = false; - view_properties.use_window_decoration = false; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -58,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/src/templates/app/runner/CMakeLists.txt b/src/templates/app/runner/CMakeLists.txt index de800cf9..8bb17790 100644 --- a/src/templates/app/runner/CMakeLists.txt +++ b/src/templates/app/runner/CMakeLists.txt @@ -1,6 +1,16 @@ cmake_minimum_required(VERSION 3.10) project(runner LANGUAGES CXX) +if(FLUTTER_TARGET_BACKEND_TYPE MATCHES "gbm") + add_definitions(-DFLUTTER_TARGET_BACKEND_GBM) +elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "eglstream") + add_definitions(-DFLUTTER_TARGET_BACKEND_EGLSTREAM) +elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "x11") + add_definitions(-DFLUTTER_TARGET_BACKEND_X11) +else() + add_definitions(-DFLUTTER_TARGET_BACKEND_WAYLAND) +endif() + add_executable(${BINARY_NAME} "flutter_window.cc" "main.cc" diff --git a/src/templates/app/runner/flutter_embedder_options.h b/src/templates/app/runner/flutter_embedder_options.h new file mode 100644 index 00000000..51e378fc --- /dev/null +++ b/src/templates/app/runner/flutter_embedder_options.h @@ -0,0 +1,103 @@ +// Copyright 2021 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_EMBEDDER_OPTIONS_ +#define FLUTTER_EMBEDDER_OPTIONS_ + +#include + +#include + +#include "command_options.h" + +class FlutterEmbedderOptions { + public: + FlutterEmbedderOptions() { + options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", + true); + options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", + false); +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + // no more options. +#elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddWithoutValue("onscreen-keyboard", "k", + "Enable on-screen keyboard", false); + options_.AddWithoutValue("window-decoration", "d", + "Enable window decorations", false); + options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", + false); + options_.AddInt("width", "w", "Flutter app window width", 1280, false); + options_.AddInt("height", "h", "Flutter app window height", 720, false); +#endif + } + ~FlutterEmbedderOptions() = default; + + bool Parse(int argc, char** argv) { + if (!options_.Parse(argc, argv)) { + std::cerr << options_.GetError() << std::endl; + std::cout << options_.ShowHelp(); + return false; + } + + bundle_path_ = options_.GetValue("bundle"); + use_mouse_cursor_ = !options_.Exist("no-cursor"); + +#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ + defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; +#elif defined(FLUTTER_TARGET_BACKEND_X11) + use_onscreen_keyboard_ = false; + use_window_decoration_ = false; + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#else // FLUTTER_TARGET_BACKEND_WAYLAND + use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); + use_window_decoration_ = options_.Exist("window-decoration"); + window_view_mode_ = + options_.Exist("fullscreen") + ? flutter::FlutterViewController::ViewMode::kFullscreen + : flutter::FlutterViewController::ViewMode::kNormal; + window_width_ = options_.GetValue("width"); + window_height_ = options_.GetValue("height"); +#endif + + return true; + } + + std::string BundlePath() const { return bundle_path_; } + bool IsUseMouseCursor() const { return use_mouse_cursor_; } + bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } + bool IsUseWindowDecoraation() const { return use_window_decoration_; } + flutter::FlutterViewController::ViewMode WindowViewMode() const { + return window_view_mode_; + } + int WindowWidth() const { return window_width_; } + int WindowHeight() const { return window_height_; } + + private: + commandline::CommandOptions options_; + + std::string bundle_path_; + bool use_mouse_cursor_ = true; + bool use_onscreen_keyboard_ = false; + bool use_window_decoration_ = false; + flutter::FlutterViewController::ViewMode window_view_mode_ = + flutter::FlutterViewController::ViewMode::kNormal; + int window_width_ = 1280; + int window_height_ = 720; +}; + +#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/src/templates/app/runner_drm/main.cc b/src/templates/app/runner/main.cc similarity index 58% rename from src/templates/app/runner_drm/main.cc rename to src/templates/app/runner/main.cc index edbe7616..9c9c91d3 100644 --- a/src/templates/app/runner_drm/main.cc +++ b/src/templates/app/runner/main.cc @@ -9,35 +9,29 @@ #include #include -#include "command_options.h" +#include "flutter_embedder_options.h" #include "flutter_window.h" int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + FlutterEmbedderOptions options; if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); return 0; } - // The project to run. - const bool show_cursor = !options.Exist("no-cursor"); - const auto bundle_path = options.GetValue("bundle"); - + // Creates the Flutter project. + const auto bundle_path = options.BundlePath(); const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); flutter::DartProject project(fl_path); auto command_line_arguments = std::vector(); project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.view_mode = - flutter::FlutterViewController::ViewMode::kFullscreen; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = false; - view_properties.use_window_decoration = false; + view_properties.width = options.WindowWidth(); + view_properties.height = options.WindowHeight(); + view_properties.view_mode = options.WindowViewMode(); + view_properties.use_mouse_cursor = options.IsUseMouseCursor(); + view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); + view_properties.use_window_decoration = options.IsUseWindowDecoraation(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); @@ -47,5 +41,6 @@ int main(int argc, char** argv) { } window.Run(); window.OnDestroy(); + return 0; } diff --git a/src/templates/app/runner_wayland/main.cc b/src/templates/app/runner_wayland/main.cc deleted file mode 100644 index 73e4c941..00000000 --- a/src/templates/app/runner_wayland/main.cc +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include -#include -#include - -#include "command_options.h" -#include "flutter_window.h" - -int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", - false); - options.AddWithoutValue("window-decoration", "d", "Enable window decorations", - false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); - if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); - return 0; - } - - // The project to run. - const auto bundle_path = options.GetValue("bundle"); - const bool show_cursor = !options.Exist("no-cursor"); - const bool use_onscreen_keyboard = options.Exist("onscreen-keyboard"); - const bool use_window_decoration = options.Exist("window-decoration"); - - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = use_onscreen_keyboard; - view_properties.use_window_decoration = use_window_decoration; - - // The Flutter instance hosted by this window. - FlutterWindow window(view_properties, project); - if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; - return 0; - } - window.Run(); - window.OnDestroy(); - return 0; -} diff --git a/src/templates/app/runner_x11/main.cc b/src/templates/app/runner_x11/main.cc deleted file mode 100644 index 9512dea5..00000000 --- a/src/templates/app/runner_x11/main.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include -#include -#include - -#include "command_options.h" -#include "flutter_window.h" - -int main(int argc, char** argv) { - commandline::CommandOptions options; - options.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); - options.AddInt("width", "w", "Flutter app window width", 1280, false); - options.AddInt("height", "h", "Flutter app window height", 720, false); - if (!options.Parse(argc, argv)) { - std::cerr << options.GetError() << std::endl; - std::cout << options.ShowHelp(); - return 0; - } - - // The project to run. - const bool show_cursor = !options.Exist("no-cursor"); - const auto view_mode = - options.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - const auto width = options.GetValue("width"); - const auto height = options.GetValue("height"); - const auto bundle_path = options.GetValue("bundle"); - - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = view_mode; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = false; - view_properties.use_window_decoration = false; - - // The Flutter instance hosted by this window. - FlutterWindow window(view_properties, project); - if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; - return 0; - } - window.Run(); - window.OnDestroy(); - return 0; -} From 5b92e7ef4f38896980a45709ecde8825c59775f0 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 16 Jul 2021 16:12:24 +0900 Subject: [PATCH 048/178] Add companion repos (#202) I added the link of the companion repos to README. --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 7f9d5aee..4e1e544c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Embedded Linux embedding for Flutter +# Embedded Linux (eLinux) embedding for Flutter [![build-test](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml/badge.svg)](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml) This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. @@ -25,6 +25,14 @@ We would be grateful if you could give us feedback on bugs and new feature reque - API compatibility with Flutter desktop for Windows and GLFW - APIs such as MethodChannel and EventChannel are completely the same with them +## Companion repos +| Repo | Purpose | +| ------------- | ------------- | +| [flutter-elinux](https://github.com/sony/flutter-elinux) | Flutter tools for eLinux | +| [flutter-elinux-plugins](https://github.com/sony/flutter-elinux-plugins) | Flutter plugins for eLinux | +| [flutter-embedded-linux](https://github.com/sony/flutter-embedded-linux) | eLinux embedding for Flutter | +| [meta-flutter](https://github.com/sony/meta-flutter) | Yocto recipes of eLinux embedding for Flutter | + ## Documentation Documentation for this software is summarised on the [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). From b978c7d827b5d4ea226e4aa7239897e485bf695c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 16 Jul 2021 16:25:21 +0900 Subject: [PATCH 049/178] Delete app templates (#203) I deleted the app templates to migrate it to flutter-elinux repo. --- src/templates/app/CMakeLists.txt.tmpl | 104 ----- src/templates/app/flutter/CMakeLists.txt | 108 ------ src/templates/app/runner/CMakeLists.txt | 23 -- src/templates/app/runner/command_options.h | 367 ------------------ .../app/runner/flutter_embedder_options.h | 103 ----- src/templates/app/runner/flutter_window.cc | 79 ---- src/templates/app/runner/flutter_window.h | 34 -- src/templates/app/runner/main.cc | 46 --- .../main.cc | 75 ---- 9 files changed, 939 deletions(-) delete mode 100644 src/templates/app/CMakeLists.txt.tmpl delete mode 100644 src/templates/app/flutter/CMakeLists.txt delete mode 100644 src/templates/app/runner/CMakeLists.txt delete mode 100644 src/templates/app/runner/command_options.h delete mode 100644 src/templates/app/runner/flutter_embedder_options.h delete mode 100644 src/templates/app/runner/flutter_window.cc delete mode 100644 src/templates/app/runner/flutter_window.h delete mode 100644 src/templates/app/runner/main.cc delete mode 100644 src/templates/app/runner_wayland-weston-desktop-shell/main.cc diff --git a/src/templates/app/CMakeLists.txt.tmpl b/src/templates/app/CMakeLists.txt.tmpl deleted file mode 100644 index c031dcba..00000000 --- a/src/templates/app/CMakeLists.txt.tmpl +++ /dev/null @@ -1,104 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -set(BINARY_NAME "{{projectName}}") - -cmake_policy(SET CMP0063 NEW) - -set(CMAKE_INSTALL_RPATH "$ORIGIN/lib") - -# Root filesystem for cross-building. -if(FLUTTER_TARGET_PLATFORM_SYSROOT) - set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT}) - set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) - set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) - set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) -endif() - -# Configure build options. -if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - set(CMAKE_BUILD_TYPE "Debug" CACHE - STRING "Flutter build mode" FORCE) - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "Debug" "Profile" "Release") -endif() - -# Configure build option to target backend. -if (NOT FLUTTER_TARGET_BACKEND_TYPE) - set(FLUTTER_TARGET_BACKEND_TYPE "wayland" CACHE - STRING "Flutter target backend type" FORCE) - set_property(CACHE FLUTTER_TARGET_BACKEND_TYPE PROPERTY STRINGS - "wayland" "gbm" "eglstream" "x11") -endif() - -# Compilation settings that should be applied to most targets. -function(APPLY_STANDARD_SETTINGS TARGET) - target_compile_features(${TARGET} PUBLIC cxx_std_17) - target_compile_options(${TARGET} PRIVATE -Wall -Werror) - target_compile_options(${TARGET} PRIVATE "$<$>:-O3>") - target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>") -endfunction() - -set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter") - -# Flutter library and tool build rules. -add_subdirectory(${FLUTTER_MANAGED_DIR}) - -# Application build -add_subdirectory("runner") - -# Generated plugin build rules, which manage building the plugins and adding -# them to the application. -include(flutter/generated_plugins.cmake) - -# === Installation === -# By default, "installing" just makes a relocatable bundle in the build -# directory. -set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle") -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE) -endif() - -# Start with a clean build bundle directory every time. -install(CODE " - file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\") - " COMPONENT Runtime) - -set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data") -set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib") - -install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" - COMPONENT Runtime) - -install(FILES "${FLUTTER_LIBRARY}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -install(FILES "${FLUTTER_EMBEDDER_LIBRARY}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) - -if(PLUGIN_BUNDLED_LIBRARIES) - install(FILES "${PLUGIN_BUNDLED_LIBRARIES}" - DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() - -# Fully re-copy the assets directory on each build to avoid having stale files -# from a previous install. -set(FLUTTER_ASSET_DIR_NAME "flutter_assets") -install(CODE " - file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\") - " COMPONENT Runtime) -install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}" - DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime) - -# Install the AOT library on non-Debug builds only. -if(NOT CMAKE_BUILD_TYPE MATCHES "Debug") - install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}" - COMPONENT Runtime) -endif() diff --git a/src/templates/app/flutter/CMakeLists.txt b/src/templates/app/flutter/CMakeLists.txt deleted file mode 100644 index 376be867..00000000 --- a/src/templates/app/flutter/CMakeLists.txt +++ /dev/null @@ -1,108 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral") - -# Configuration provided via flutter tool. -include(${EPHEMERAL_DIR}/generated_config.cmake) - -set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper") - -# Serves the same purpose as list(TRANSFORM ... PREPEND ...), -# which isn't available in 3.10. -function(list_prepend LIST_NAME PREFIX) - set(NEW_LIST "") - foreach(element ${${LIST_NAME}}) - list(APPEND NEW_LIST "${PREFIX}${element}") - endforeach(element) - set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE) -endfunction() - -# === Flutter Library === -# System-level dependencies. -set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_engine.so") -if(FLUTTER_TARGET_BACKEND_TYPE MATCHES "gbm") - set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_gbm.so") -elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "eglstream") - set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_eglstream.so") -elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "x11") - set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_x11.so") -else() - set(FLUTTER_EMBEDDER_LIBRARY "${EPHEMERAL_DIR}/libflutter_elinux_wayland.so") -endif() - -# Published to parent scope for install step. -set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_EMBEDDER_LIBRARY ${FLUTTER_EMBEDDER_LIBRARY} PARENT_SCOPE) -set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE) -set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/elinux/" PARENT_SCOPE) -set(AOT_LIBRARY "${EPHEMERAL_DIR}/libapp.so" PARENT_SCOPE) - -list(APPEND FLUTTER_LIBRARY_HEADERS - "flutter_export.h" - "flutter_plugin_registrar.h" - "flutter_messenger.h" - "flutter_texture_registrar.h" - "flutter_elinux.h" - "flutter_platform_views.h" -) -list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/") -add_library(flutter INTERFACE) -target_include_directories(flutter INTERFACE - "${EPHEMERAL_DIR}" -) -target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}") -target_link_libraries(flutter INTERFACE "${FLUTTER_EMBEDDER_LIBRARY}") -add_dependencies(flutter flutter_assemble) - -# === Wrapper === -list(APPEND CPP_WRAPPER_SOURCES_CORE - "core_implementations.cc" - "standard_codec.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_PLUGIN - "plugin_registrar.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/") -list(APPEND CPP_WRAPPER_SOURCES_APP - "flutter_engine.cc" - "flutter_view_controller.cc" -) -list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/") - -# Wrapper sources needed for a plugin. -add_library(flutter_wrapper_plugin STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} -) -apply_standard_settings(flutter_wrapper_plugin) -set_target_properties(flutter_wrapper_plugin PROPERTIES - POSITION_INDEPENDENT_CODE ON) -set_target_properties(flutter_wrapper_plugin PROPERTIES - CXX_VISIBILITY_PRESET hidden) -target_link_libraries(flutter_wrapper_plugin PUBLIC flutter) -target_include_directories(flutter_wrapper_plugin PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_plugin flutter_assemble) - -# Wrapper sources needed for the runner. -add_library(flutter_wrapper_app STATIC - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_APP} -) -apply_standard_settings(flutter_wrapper_app) -target_link_libraries(flutter_wrapper_app PUBLIC flutter) -target_include_directories(flutter_wrapper_app PUBLIC - "${WRAPPER_ROOT}/include" -) -add_dependencies(flutter_wrapper_app flutter_assemble) - -add_custom_target(flutter_assemble DEPENDS - "${FLUTTER_LIBRARY}" - "${FLUTTER_EMBEDDER_LIBRARY}" - ${FLUTTER_LIBRARY_HEADERS} - ${CPP_WRAPPER_SOURCES_CORE} - ${CPP_WRAPPER_SOURCES_PLUGIN} - ${CPP_WRAPPER_SOURCES_APP} -) diff --git a/src/templates/app/runner/CMakeLists.txt b/src/templates/app/runner/CMakeLists.txt deleted file mode 100644 index 8bb17790..00000000 --- a/src/templates/app/runner/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.10) -project(runner LANGUAGES CXX) - -if(FLUTTER_TARGET_BACKEND_TYPE MATCHES "gbm") - add_definitions(-DFLUTTER_TARGET_BACKEND_GBM) -elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "eglstream") - add_definitions(-DFLUTTER_TARGET_BACKEND_EGLSTREAM) -elseif(FLUTTER_TARGET_BACKEND_TYPE MATCHES "x11") - add_definitions(-DFLUTTER_TARGET_BACKEND_X11) -else() - add_definitions(-DFLUTTER_TARGET_BACKEND_WAYLAND) -endif() - -add_executable(${BINARY_NAME} - "flutter_window.cc" - "main.cc" - "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc" -) -apply_standard_settings(${BINARY_NAME}) -target_link_libraries(${BINARY_NAME} PRIVATE flutter) -target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app) -target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") -add_dependencies(${BINARY_NAME} flutter_assemble) diff --git a/src/templates/app/runner/command_options.h b/src/templates/app/runner/command_options.h deleted file mode 100644 index 977cdc83..00000000 --- a/src/templates/app/runner/command_options.h +++ /dev/null @@ -1,367 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef COMMAND_OPTIONS_ -#define COMMAND_OPTIONS_ - -#include -#include -#include -#include -#include -#include -#include - -// todo: Supports other types besides int, string. - -namespace commandline { - -namespace { -constexpr char kOptionStyleNormal[] = "--"; -constexpr char kOptionStyleShort[] = "-"; -constexpr char kOptionValueForHelpMessage[] = "="; -} // namespace - -class Exception : public std::exception { - public: - Exception(const std::string& msg) : msg_(msg) {} - ~Exception() throw() {} - - const char* what() const throw() { return msg_.c_str(); } - - private: - std::string msg_; -}; - -class CommandOptions { - public: - CommandOptions() = default; - ~CommandOptions() = default; - - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { - Add(name, short_name, description, "", - ReaderString(), required, false); - } - - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, - bool required) { - Add(name, short_name, description, default_value, - ReaderInt(), required, true); - } - - void AddString(const std::string& name, const std::string& short_name, - const std::string& description, - const std::string& default_value, bool required) { - Add(name, short_name, description, default_value, - ReaderString(), required, true); - } - - template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { - if (options_.find(name) != options_.end()) { - std::cerr << "Already registered option: " << name << std::endl; - return; - } - - if (lut_short_options_.find(short_name) != lut_short_options_.end()) { - std::cerr << short_name << "is already registered" << std::endl; - return; - } - lut_short_options_[short_name] = name; - - options_[name] = std::make_unique>( - name, short_name, description, default_value, reader, required, - required_value); - - // register to show help message. - registration_order_options_.push_back(options_[name].get()); - } - - bool Exist(const std::string& name) { - auto itr = options_.find(name); - return itr != options_.end() && itr->second->HasValue(); - } - - template - const T& GetValue(const std::string& name) { - auto itr = options_.find(name); - if (itr == options_.end()) { - throw Exception("Not found: " + name); - } - - auto* option_value = dynamic_cast*>(itr->second.get()); - if (!option_value) { - throw Exception("Type mismatch: " + name); - } - return option_value->GetValue(); - } - - bool Parse(int argc, const char* const* argv) { - if (argc < 1) { - errors_.push_back("No options"); - return false; - } - - command_name_ = argv[0]; - for (auto i = 1; i < argc; i++) { - const std::string arg(argv[i]); - - // normal options: e.g. --bundle=/data/sample/bundle --fullscreen - if (arg.length() > 2 && - arg.substr(0, 2).compare(kOptionStyleNormal) == 0) { - const size_t option_value_len = arg.find("=") != std::string::npos - ? (arg.length() - arg.find("=")) - : 0; - const bool has_value = option_value_len != 0; - std::string option_name = - arg.substr(2, arg.length() - 2 - option_value_len); - - if (options_.find(option_name) == options_.end()) { - errors_.push_back("Not found option: " + option_name); - continue; - } - - if (!has_value && options_[option_name]->IsRequiredValue()) { - errors_.push_back(option_name + " requres an option value"); - continue; - } - - if (has_value && !options_[option_name]->IsRequiredValue()) { - errors_.push_back(option_name + " doesn't requres an option value"); - continue; - } - - if (has_value) { - SetOptionValue(option_name, arg.substr(arg.find("=") + 1)); - } else { - SetOption(option_name); - } - } - // short options: e.g. -f /foo/file.txt -h 640 -abc - else if (arg.length() > 1 && - arg.substr(0, 1).compare(kOptionStyleShort) == 0) { - for (size_t j = 1; j < arg.length(); j++) { - const std::string option_name{argv[i][j]}; - - if (lut_short_options_.find(option_name) == - lut_short_options_.end()) { - errors_.push_back("Not found short option: " + option_name); - break; - } - - if (j == arg.length() - 1 && - options_[lut_short_options_[option_name]]->IsRequiredValue()) { - if (i == argc - 1) { - errors_.push_back("Invalid format option: " + option_name); - break; - } - SetOptionValue(lut_short_options_[option_name], argv[++i]); - } else { - SetOption(lut_short_options_[option_name]); - } - } - } else { - errors_.push_back("Invalid format option: " + arg); - } - } - - for (size_t i = 0; i < registration_order_options_.size(); i++) { - if (registration_order_options_[i]->IsRequired() && - !registration_order_options_[i]->HasValue()) { - errors_.push_back( - std::string(registration_order_options_[i]->GetName()) + - " option is mandatory."); - } - } - - return errors_.size() == 0; - } - - std::string GetError() { return errors_.size() > 0 ? errors_[0] : ""; } - - std::vector& GetErrors() { return errors_; } - - std::string ShowHelp() { - std::ostringstream ostream; - - ostream << "Usage: " << command_name_ << " "; - for (size_t i = 0; i < registration_order_options_.size(); i++) { - if (registration_order_options_[i]->IsRequired()) { - ostream << registration_order_options_[i]->GetHelpShortMessage() << " "; - } - } - ostream << std::endl; - - ostream << "Global options:" << std::endl; - size_t max_name_len = 0; - for (size_t i = 0; i < registration_order_options_.size(); i++) { - max_name_len = std::max( - max_name_len, registration_order_options_[i]->GetName().length()); - } - - for (size_t i = 0; i < registration_order_options_.size(); i++) { - if (!registration_order_options_[i]->GetShortName().empty()) { - ostream << kOptionStyleShort - << registration_order_options_[i]->GetShortName() << ", "; - } else { - ostream << std::string(4, ' '); - } - - size_t index_adjust = 0; - constexpr int kSpacerNum = 5; - auto need_value = registration_order_options_[i]->IsRequiredValue(); - ostream << kOptionStyleNormal - << registration_order_options_[i]->GetName(); - if (need_value) { - ostream << kOptionValueForHelpMessage; - index_adjust += std::string(kOptionValueForHelpMessage).length(); - } - ostream << std::string( - max_name_len + kSpacerNum - index_adjust - - registration_order_options_[i]->GetName().length(), - ' '); - ostream << registration_order_options_[i]->GetDescription() << std::endl; - } - - return ostream.str(); - } - - private: - struct ReaderInt { - int operator()(const std::string& value) { return std::stoi(value); } - }; - - struct ReaderString { - std::string operator()(const std::string& value) { return value; } - }; - - class Option { - public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) - : name_(name), - short_name_(short_name), - description_(description), - is_required_(required), - is_required_value_(required_value), - value_set_(false){}; - virtual ~Option() = default; - - const std::string& GetName() const { return name_; }; - - const std::string& GetShortName() const { return short_name_; }; - - const std::string& GetDescription() const { return description_; }; - - const std::string GetHelpShortMessage() const { - std::string message = kOptionStyleNormal + name_; - if (is_required_value_) { - message += kOptionValueForHelpMessage; - } - return message; - } - - bool IsRequired() const { return is_required_; }; - - bool IsRequiredValue() const { return is_required_value_; }; - - void Set() { value_set_ = true; }; - - virtual bool SetValue(const std::string& value) = 0; - - virtual bool HasValue() const = 0; - - protected: - std::string name_; - std::string short_name_; - std::string description_; - bool is_required_; - bool is_required_value_; - bool value_set_; - }; - - template - class OptionValue : public Option { - public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) - : Option(name, short_name, description, required, required_value), - default_value_(default_value), - value_(default_value){}; - virtual ~OptionValue() = default; - - bool SetValue(const std::string& value) { - value_ = Read(value); - value_set_ = true; - return true; - } - - bool HasValue() const { return value_set_; } - - const T& GetValue() const { return value_; } - - protected: - virtual T Read(const std::string& s) = 0; - - T default_value_; - T value_; - }; - - template - class OptionValueReader : public OptionValue { - public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, - required_value), - reader_(reader) {} - ~OptionValueReader() = default; - - private: - T Read(const std::string& value) { return reader_(value); } - - F reader_; - }; - - bool SetOption(const std::string& name) { - auto itr = options_.find(name); - if (itr == options_.end()) { - errors_.push_back("Unknown option: " + name); - return false; - } - - itr->second->Set(); - return true; - } - - bool SetOptionValue(const std::string& name, const std::string& value) { - auto itr = options_.find(name); - if (itr == options_.end()) { - errors_.push_back("Unknown option: " + name); - return false; - } - - if (!itr->second->SetValue(value)) { - errors_.push_back("Invalid option value: " + name + " = " + value); - return false; - } - return true; - } - - std::string command_name_; - std::unordered_map> options_; - std::unordered_map lut_short_options_; - std::vector registration_order_options_; - std::vector errors_; -}; - -} // namespace commandline - -#endif // COMMAND_OPTIONS_ diff --git a/src/templates/app/runner/flutter_embedder_options.h b/src/templates/app/runner/flutter_embedder_options.h deleted file mode 100644 index 51e378fc..00000000 --- a/src/templates/app/runner/flutter_embedder_options.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_EMBEDDER_OPTIONS_ -#define FLUTTER_EMBEDDER_OPTIONS_ - -#include - -#include - -#include "command_options.h" - -class FlutterEmbedderOptions { - public: - FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); - options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", - false); -#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ - defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) - // no more options. -#elif defined(FLUTTER_TARGET_BACKEND_X11) - options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); -#else // FLUTTER_TARGET_BACKEND_WAYLAND - options_.AddWithoutValue("onscreen-keyboard", "k", - "Enable on-screen keyboard", false); - options_.AddWithoutValue("window-decoration", "d", - "Enable window decorations", false); - options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", - false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); -#endif - } - ~FlutterEmbedderOptions() = default; - - bool Parse(int argc, char** argv) { - if (!options_.Parse(argc, argv)) { - std::cerr << options_.GetError() << std::endl; - std::cout << options_.ShowHelp(); - return false; - } - - bundle_path_ = options_.GetValue("bundle"); - use_mouse_cursor_ = !options_.Exist("no-cursor"); - -#if defined(FLUTTER_TARGET_BACKEND_GBM) || \ - defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) - use_onscreen_keyboard_ = false; - use_window_decoration_ = false; - window_view_mode_ = flutter::FlutterViewController::ViewMode::kFullscreen; -#elif defined(FLUTTER_TARGET_BACKEND_X11) - use_onscreen_keyboard_ = false; - use_window_decoration_ = false; - window_view_mode_ = - options_.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - window_width_ = options_.GetValue("width"); - window_height_ = options_.GetValue("height"); -#else // FLUTTER_TARGET_BACKEND_WAYLAND - use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); - use_window_decoration_ = options_.Exist("window-decoration"); - window_view_mode_ = - options_.Exist("fullscreen") - ? flutter::FlutterViewController::ViewMode::kFullscreen - : flutter::FlutterViewController::ViewMode::kNormal; - window_width_ = options_.GetValue("width"); - window_height_ = options_.GetValue("height"); -#endif - - return true; - } - - std::string BundlePath() const { return bundle_path_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } - flutter::FlutterViewController::ViewMode WindowViewMode() const { - return window_view_mode_; - } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } - - private: - commandline::CommandOptions options_; - - std::string bundle_path_; - bool use_mouse_cursor_ = true; - bool use_onscreen_keyboard_ = false; - bool use_window_decoration_ = false; - flutter::FlutterViewController::ViewMode window_view_mode_ = - flutter::FlutterViewController::ViewMode::kNormal; - int window_width_ = 1280; - int window_height_ = 720; -}; - -#endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/src/templates/app/runner/flutter_window.cc b/src/templates/app/runner/flutter_window.cc deleted file mode 100644 index 0c5b6397..00000000 --- a/src/templates/app/runner/flutter_window.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter_window.h" - -#include -#include -#include -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow( - const flutter::FlutterViewController::ViewProperties view_properties, - const flutter::DartProject project) - : view_properties_(view_properties), project_(project) {} - -bool FlutterWindow::OnCreate() { - flutter_view_controller_ = std::make_unique( - view_properties_, project_); - - // Ensure that basic setup of the controller was successful. - if (!flutter_view_controller_->engine() || - !flutter_view_controller_->view()) { - return false; - } - - // Register Flutter plugins. - RegisterPlugins(flutter_view_controller_->engine()); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_view_controller_) { - flutter_view_controller_ = nullptr; - } -} - -void FlutterWindow::Run() { - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_view_controller_->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait for the next frame if no events. - auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); - next_event_time = std::min( - next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds( - static_cast(std::trunc(1000000.0 / frame_rate)))); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } -} diff --git a/src/templates/app/runner/flutter_window.h b/src/templates/app/runner/flutter_window.h deleted file mode 100644 index 20b9cb88..00000000 --- a/src/templates/app/runner/flutter_window.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_WINDOW_ -#define FLUTTER_WINDOW_ - -#include -#include - -#include - -class FlutterWindow { - public: - explicit FlutterWindow( - const flutter::FlutterViewController::ViewProperties view_properties, - const flutter::DartProject project); - ~FlutterWindow() = default; - - // Prevent copying. - FlutterWindow(FlutterWindow const&) = delete; - FlutterWindow& operator=(FlutterWindow const&) = delete; - - bool OnCreate(); - void OnDestroy(); - void Run(); - - private: - flutter::FlutterViewController::ViewProperties view_properties_; - flutter::DartProject project_; - std::unique_ptr flutter_view_controller_; -}; - -#endif // FLUTTER_WINDOW_ diff --git a/src/templates/app/runner/main.cc b/src/templates/app/runner/main.cc deleted file mode 100644 index 9c9c91d3..00000000 --- a/src/templates/app/runner/main.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include - -#include -#include -#include - -#include "flutter_embedder_options.h" -#include "flutter_window.h" - -int main(int argc, char** argv) { - FlutterEmbedderOptions options; - if (!options.Parse(argc, argv)) { - return 0; - } - - // Creates the Flutter project. - const auto bundle_path = options.BundlePath(); - const std::wstring fl_path(bundle_path.begin(), bundle_path.end()); - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = options.WindowWidth(); - view_properties.height = options.WindowHeight(); - view_properties.view_mode = options.WindowViewMode(); - view_properties.use_mouse_cursor = options.IsUseMouseCursor(); - view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); - view_properties.use_window_decoration = options.IsUseWindowDecoraation(); - - // The Flutter instance hosted by this window. - FlutterWindow window(view_properties, project); - if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; - return 0; - } - window.Run(); - window.OnDestroy(); - - return 0; -} diff --git a/src/templates/app/runner_wayland-weston-desktop-shell/main.cc b/src/templates/app/runner_wayland-weston-desktop-shell/main.cc deleted file mode 100644 index acbd179b..00000000 --- a/src/templates/app/runner_wayland-weston-desktop-shell/main.cc +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include -#include - -#include -#include -#include - -#include "flutter_window.h" - -int main(int argc, char** argv) { - // Works as a weston desktop shell. - bool show_cursor; - auto config_file = weston_config_get_name_from_env(); - auto config = weston_config_parse(config_file); - auto s = weston_config_get_section(config, "flutter_linux_wayland", nullptr, - nullptr); - char* path = nullptr; - if (s) { - weston_config_section_get_bool(s, "show-cursor", &show_cursor, true); - weston_config_section_get_string( - s, "flutter-project-path", &path, - "../../sample-app/sample/build/linux/x64/release/bundle"); - } - - std::wstring fl_path; - if (path != nullptr) { - // convert char* to wstring. - std::string str(path); - std::wstring ws_temp(str.begin(), str.end()); - if (!ws_temp.empty()) { - fl_path = ws_temp; - } - - free(path); - } - - // libweston-6 does not export weston_config_destroy(). - // So run free() instead. - if (config) { - free(config); - } - // weston_config_destroy(config); - - // The project to run. - constexpr int width = 640; - constexpr int height = 480; - - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = - flutter::FlutterViewController::ViewMode::kFullscreen; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = true; - view_properties.use_window_decoration = false; - - // The Flutter instance hosted by this window. - FlutterWindow window(view_properties, project); - if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; - return 0; - } - window.Run(); - window.OnDestroy(); - return 0; -} From 18e5b316fd9f7f847a62df550b6de37e661f6074 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 26 Jul 2021 08:42:52 +0900 Subject: [PATCH 050/178] Update common-cpp-library (07262021) (#204) Merged from https://github.com/flutter/engine/commit/39f9a27ef57262102cba5bbadde958686a238e38 --- .../shell/platform/common/client_wrapper/standard_codec.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index e37e4a18..d7dd89d5 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -318,6 +318,9 @@ StandardMessageCodec::~StandardMessageCodec() = default; std::unique_ptr StandardMessageCodec::DecodeMessageInternal( const uint8_t* binary_message, size_t message_size) const { + if (!binary_message) { + return std::make_unique(); + } ByteBufferStreamReader stream(binary_message, message_size); return std::make_unique(serializer_->ReadValue(&stream)); } From 8b23f93500d5ea7ddbf2d07a4d8c27473de534c9 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 30 Jul 2021 09:20:55 +0900 Subject: [PATCH 051/178] Update video player example (#205) * fix compiler warning * update README --- examples/flutter-video-player-plugin/README.md | 4 ++-- .../flutter/plugins/video_player/elinux/gst_video_player.cc | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/flutter-video-player-plugin/README.md b/examples/flutter-video-player-plugin/README.md index f1f0c93b..4e643a99 100644 --- a/examples/flutter-video-player-plugin/README.md +++ b/examples/flutter-video-player-plugin/README.md @@ -1,7 +1,7 @@ # Overview -Flutter video player example using video player plugin for Embedded Linux. The interface of the plugin is compatible with [the Flutter official video player plugin](https://github.com/flutter/plugins/tree/master/packages/video_player/video_player). Also, this plugin is temporarily putting here and there are still some bugs. It will be moved to another new repo soon. +Flutter video player example using video player plugin for Embedded Linux. The interface of the plugin is compatible with [the Flutter official video player plugin](https://github.com/flutter/plugins/tree/master/packages/video_player/video_player). -The procedure described here is a provisional step until you build a flutter app for Embedded Linux using this embedder with another tool. +Note that this is just example for eLinux embedder, so please use [sony/flutter-elinux-plugins/packages/video_player](https://github.com/sony/flutter-elinux-plugins/tree/main/packages/video_player) ![image](https://user-images.githubusercontent.com/62131389/124210378-43f06400-db26-11eb-8723-40dad0eb67b0.png) diff --git a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc index 6960d241..40a3fc2f 100644 --- a/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc +++ b/examples/flutter-video-player-plugin/flutter/plugins/video_player/elinux/gst_video_player.cc @@ -151,7 +151,6 @@ const uint8_t* GstVideoPlayer::GetFrameBuffer() { } const uint32_t pixel_bytes = width_ * height_ * 4; - const gsize buf_size = gst_buffer_get_size(gst_.buffer); gst_buffer_extract(gst_.buffer, 0, pixels_.get(), pixel_bytes); return reinterpret_cast(pixels_.get()); } From 03ba3b104dd2c32106585b01cff31a6cbfbb66d0 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 30 Jul 2021 09:47:03 +0900 Subject: [PATCH 052/178] Merge: delete duplicate error message (#206) Merged from https://github.com/sony/flutter-elinux/pull/33 --- examples/flutter-drm-eglstream-backend/main.cc | 1 - examples/flutter-drm-gbm-backend/main.cc | 1 - examples/flutter-external-texture-plugin/main.cc | 1 - examples/flutter-video-player-plugin/main.cc | 1 - examples/flutter-wayland-client/main.cc | 1 - examples/flutter-weston-desktop-shell/main.cc | 1 - examples/flutter-x11-client/main.cc | 1 - 7 files changed, 7 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc index acbd179b..301c0088 100644 --- a/examples/flutter-weston-desktop-shell/main.cc +++ b/examples/flutter-weston-desktop-shell/main.cc @@ -66,7 +66,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 9c9c91d3..92a6513c 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -36,7 +36,6 @@ int main(int argc, char** argv) { // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); if (!window.OnCreate()) { - std::cerr << "Failed to create a Flutter window." << std::endl; return 0; } window.Run(); From 141b74c2f83f76f84c7c0610ffece4bddd599ead Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 2 Aug 2021 09:58:20 +0900 Subject: [PATCH 053/178] Add mouse scroll support for X11 (#207) Add mouse scroll and back/forward buttons support for X11. --- .../window/elinux_window_x11.cc | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index c5ba48d3..868dccfc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -13,6 +13,14 @@ namespace flutter { +namespace { +// Only Button1 - Button5 are defined in X11/X.h +constexpr int kButton6 = 6; +constexpr int kButton7 = 7; +constexpr int kButton8 = 8; +constexpr int kButton9 = 9; +} // namespace + ELinuxWindowX11::ELinuxWindowX11(FlutterDesktopViewProperties view_properties) { view_properties_ = view_properties; @@ -173,9 +181,21 @@ void ELinuxWindowX11::HandlePointerButtonEvent(uint32_t button, flutter_button = kFlutterPointerButtonMouseSecondary; break; case Button4: + case Button5: + case kButton6: + case kButton7: { + const bool vertical_scroll = (button == Button4 || button == Button5); + const double delta = button == Button5 ? 1 : -1; + constexpr int32_t kScrollOffsetMultiplier = 20; + binding_handler_delegate_->OnScroll(x, y, vertical_scroll ? 0 : delta, + vertical_scroll ? delta : 0, + kScrollOffsetMultiplier); + return; + } + case kButton8: flutter_button = kFlutterPointerButtonMouseBack; break; - case Button5: + case kButton9: flutter_button = kFlutterPointerButtonMouseForward; break; default: From f96b802de7cd98d0c7887fdfb2d49604db88f8bf Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 6 Aug 2021 15:57:35 +0900 Subject: [PATCH 054/178] Update README: add software stack image of elinux embedder (#208) * Added the image of elinux's software stack * Added the link to flutter-elinux --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4e1e544c..88524a65 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. +![image](https://user-images.githubusercontent.com/62131389/128468439-1d7250b2-0462-43d2-878d-5c48e70f5ef3.png) + +Note that this project is the source code of the embedder, so flutter app developers should use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. + ## Objective & Goal Our objective is to use Flutter in embedded systems. We're developing this embedder to use Flutter in embedded products. Ultimately we would like to propose and contribute this software to the mainline of [Flutter Engine](https://github.com/flutter/engine), which means we would like to add an embedded systems version into the Flutter repo for all embedded developers. Please note that this is just our ideal, not the official opinion of the Flutter community. From 45fcf29eb6675f5f5e4f182ee2e815477926c4ad Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 6 Aug 2021 16:41:43 +0900 Subject: [PATCH 055/178] Refactoring: remove duplicate include (#209) --- .../shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc index 92a3f0de..c71377af 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc @@ -5,7 +5,6 @@ #include "flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.h" #include -#include #include From 53e2978b339bc0a2345a06fc96eb34d05d2cbadd Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 16 Aug 2021 09:38:05 +0900 Subject: [PATCH 056/178] Merge the latest version from engine repo (#210) See: https://github.com/flutter/engine/commit/2fa5f698a3a33ff1a82da5b002a4d93f50db1b04 --- .../platform/common/client_wrapper/standard_codec.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index d7dd89d5..f16a0f97 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -295,8 +295,8 @@ const StandardMessageCodec& StandardMessageCodec::GetInstance( if (!serializer) { serializer = &StandardCodecSerializer::GetInstance(); } - auto* sInstances = new std::map>; + static auto* sInstances = new std::map>; auto it = sInstances->find(serializer); if (it == sInstances->end()) { // Uses new due to private constructor (to prevent API clients from @@ -342,8 +342,8 @@ const StandardMethodCodec& StandardMethodCodec::GetInstance( if (!serializer) { serializer = &StandardCodecSerializer::GetInstance(); } - auto* sInstances = new std::map>; + static auto* sInstances = new std::map>; auto it = sInstances->find(serializer); if (it == sInstances->end()) { // Uses new due to private constructor (to prevent API clients from From b6187cdc60a74a31808cfd8c6e5be4986a65cf15 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 18 Aug 2021 13:41:51 +0900 Subject: [PATCH 057/178] [Wayland] Delete weston desktop shell (#212) See: https://github.com/sony/flutter-embedded-linux/issues/189 --- CMakeLists.txt | 1 - cmake/build.cmake | 14 +- cmake/package.cmake | 7 - examples/README.md | 1 - examples/config/weston.ini | 23 -- .../cmake/user_config.cmake | 1 - .../cmake/user_config.cmake | 1 - .../cmake/user_config.cmake | 1 - .../cmake/user_config.cmake | 1 - .../cmake/user_config.cmake | 1 - .../flutter-weston-desktop-shell/README.md | 12 - .../cmake/user_build.cmake | 27 -- .../cmake/user_config.cmake | 7 - .../flutter/generated_plugin_registrant.cc | 10 - .../flutter/generated_plugin_registrant.h | 13 - .../flutter/generated_plugins.cmake | 22 -- .../flutter_window.cc | 79 ---- .../flutter_window.h | 34 -- examples/flutter-weston-desktop-shell/main.cc | 74 ---- .../cmake/user_config.cmake | 1 - .../window/elinux_window_wayland.cc | 21 -- .../window/elinux_window_wayland.h | 3 - .../weston-desktop-shell-client-protocol.h | 357 ------------------ .../protocols/weston-desktop-shell-protocol.c | 67 ---- 24 files changed, 1 insertion(+), 777 deletions(-) delete mode 100644 examples/config/weston.ini delete mode 100644 examples/flutter-weston-desktop-shell/README.md delete mode 100644 examples/flutter-weston-desktop-shell/cmake/user_build.cmake delete mode 100644 examples/flutter-weston-desktop-shell/cmake/user_config.cmake delete mode 100644 examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc delete mode 100644 examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h delete mode 100644 examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake delete mode 100644 examples/flutter-weston-desktop-shell/flutter_window.cc delete mode 100644 examples/flutter-weston-desktop-shell/flutter_window.h delete mode 100644 examples/flutter-weston-desktop-shell/main.cc delete mode 100644 src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h delete mode 100644 src/third_party/wayland/protocols/weston-desktop-shell-protocol.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 63d8f1c7..9fe0192a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,6 @@ project("flutter_elinux" LANGUAGES CXX C) # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) -option(DESKTOP_SHELL "Work as weston desktop-shell" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) diff --git a/cmake/build.cmake b/cmake/build.cmake index a8c52a0b..d57dcc32 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -40,6 +40,7 @@ else() include(cmake/generate_wayland_protocols.cmake) set(_wayland_protocols_xml_dir "$ENV{PKG_CONFIG_SYSROOT_DIR}/usr/share/wayland-protocols") set(_wayland_protocols_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/wayland/protocols") + file(MAKE_DIRECTORY "${_wayland_protocols_src_dir}") generate_wayland_client_protocol( PROTOCOL_FILE "${_wayland_protocols_xml_dir}/stable/xdg-shell/xdg-shell.xml" @@ -79,19 +80,6 @@ else() "src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc") endif() -# desktop-shell for weston. -if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) - add_definitions(-DDESKTOP_SHELL) -endif() - -# weston private protocols. -if((${BACKEND_TYPE} STREQUAL "WAYLAND") AND DESKTOP_SHELL) - set(DISPLAY_BACKEND_SRC - ${DISPLAY_BACKEND_SRC} - "src/third_party/wayland/protocols/weston-desktop-shell-protocol.c" - ) -endif() - # OpenGL ES version. if(USE_GLES3) add_definitions(-DUSE_GLES3) diff --git a/cmake/package.cmake b/cmake/package.cmake index 055e7739..390d8113 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -28,13 +28,6 @@ else() pkg_check_modules(WAYLAND_CLIENT REQUIRED wayland-client>=1.16.0) pkg_check_modules(WAYLAND_CURSOR REQUIRED wayland-cursor>=1.16.0) pkg_check_modules(WAYLAND_EGL REQUIRED wayland-egl>=1.16.0) - - if(DESKTOP_SHELL) - pkg_check_modules(WESTON REQUIRED weston>=8.0.0) - string(REPLACE "." ";" WESTON_VERSION_LIST ${WESTON_VERSION}) - list(GET WESTON_VERSION_LIST 0 WESTON_VERSION_MAJOR) - pkg_check_modules(LIBWESTON REQUIRED libweston-${WESTON_VERSION_MAJOR}) - endif() endif() # requires for supporting external texture plugin. diff --git a/examples/README.md b/examples/README.md index 3df5d096..ef2e517e 100644 --- a/examples/README.md +++ b/examples/README.md @@ -8,7 +8,6 @@ These are an example of how to use embedded Linux embedding for Flutter. - [flutter-drm-gbm-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-gbm-backend): Fullscreen app on DRM backend with GBM - [flutter-drm-eglstream-backend](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-drm-eglstream-backend): Fullscreen app on DRM backend with EGLStream - [flutter-x11-client](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-x11-client): X11 client app -- [flutter-weston-desktop-shell](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-weston-desktop-shell): Works on Weston desktop-shell ## Examples using Flutter Plugins - [flutter-video-player-plugin](https://github.com/sony/flutter-embedded-linux/tree/master/examples/flutter-video-player-plugin): Flutter video player plugin diff --git a/examples/config/weston.ini b/examples/config/weston.ini deleted file mode 100644 index 746d9ffd..00000000 --- a/examples/config/weston.ini +++ /dev/null @@ -1,23 +0,0 @@ -[core] -# Disable idle timeout -idle-time=0 - -# Flutter Engine only support this format -gbm-format=argb8888 - -[shell] -# Disable the panel at the top -panel-position=none - -# Anmation type when an app starts -animation=zoom - -# The binary path of weston-desktop-shell -client=/usr/sbin/flutter-desktop-shell - -[flutter_linux_wayland] -# Show mouse cursor -show-cursor=true - -# Flutter dart project path -flutter-project-path=../flutter-projects/sample/bundle diff --git a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake index 7a2a5a59..4d2cb636 100644 --- a/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-eglstream-backend/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-EGLSTREAM) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake index 4bcb9b48..a3a5931e 100644 --- a/examples/flutter-drm-gbm-backend/cmake/user_config.cmake +++ b/examples/flutter-drm-gbm-backend/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE DRM-GBM) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-external-texture-plugin/cmake/user_config.cmake b/examples/flutter-external-texture-plugin/cmake/user_config.cmake index 9432b4fa..5f72786b 100644 --- a/examples/flutter-external-texture-plugin/cmake/user_config.cmake +++ b/examples/flutter-external-texture-plugin/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-video-player-plugin/cmake/user_config.cmake b/examples/flutter-video-player-plugin/cmake/user_config.cmake index 9432b4fa..5f72786b 100644 --- a/examples/flutter-video-player-plugin/cmake/user_config.cmake +++ b/examples/flutter-video-player-plugin/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-wayland-client/cmake/user_config.cmake b/examples/flutter-wayland-client/cmake/user_config.cmake index 9432b4fa..5f72786b 100644 --- a/examples/flutter-wayland-client/cmake/user_config.cmake +++ b/examples/flutter-wayland-client/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE WAYLAND) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/examples/flutter-weston-desktop-shell/README.md b/examples/flutter-weston-desktop-shell/README.md deleted file mode 100644 index b87f0918..00000000 --- a/examples/flutter-weston-desktop-shell/README.md +++ /dev/null @@ -1,12 +0,0 @@ -# Overview - -This is the example of Wayland backend + weston desktop-shell. - -## Building - -```Shell -$ mkdir build -$ cd build -$ cmake -DUSER_PROJECT_PATH=examples/flutter-weston-desktop-shell .. -$ cmake --build . -``` diff --git a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake b/examples/flutter-weston-desktop-shell/cmake/user_build.cmake deleted file mode 100644 index fce0a17b..00000000 --- a/examples/flutter-weston-desktop-shell/cmake/user_build.cmake +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# user binary name. -set(TARGET flutter-desktop-shell) - -# source files for user apps. -set(USER_APP_SRCS - examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc - examples/flutter-weston-desktop-shell/flutter_window.cc - examples/flutter-weston-desktop-shell/main.cc -) - -# header files for user apps. -set(USER_APP_INCLUDE_DIRS - ## Public APIs for developers (Don't edit!). - src/client_wrapper/include - src/flutter/shell/platform/common/client_wrapper - src/flutter/shell/platform/common/client_wrapper/include - src/flutter/shell/platform/common/client_wrapper/include/flutter - src/flutter/shell/platform/common/public - src/flutter/shell/platform/linux_embedded/public - ## header file include path for user apps. - examples/flutter-weston-desktop-shell -) - -# link libraries for user apps. -set(USER_APP_LIBRARIES) diff --git a/examples/flutter-weston-desktop-shell/cmake/user_config.cmake b/examples/flutter-weston-desktop-shell/cmake/user_config.cmake deleted file mode 100644 index aa81327d..00000000 --- a/examples/flutter-weston-desktop-shell/cmake/user_config.cmake +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required(VERSION 3.10) - -# Flutter embedder configurations. -# See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options -set(BACKEND_TYPE WAYLAND) -set(DESKTOP_SHELL ON) -set(USE_GLES3 OFF) diff --git a/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc b/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc deleted file mode 100644 index 7e6e6c2d..00000000 --- a/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.cc +++ /dev/null @@ -1,10 +0,0 @@ -// -// Generated file. Do not edit. -// - -// clang-format off - -#include "generated_plugin_registrant.h" - -void RegisterPlugins(flutter::PluginRegistry* registry) { -} diff --git a/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h b/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h deleted file mode 100644 index a31c23cd..00000000 --- a/examples/flutter-weston-desktop-shell/flutter/generated_plugin_registrant.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// Generated file. Do not edit. -// - -#ifndef GENERATED_PLUGIN_REGISTRANT_ -#define GENERATED_PLUGIN_REGISTRANT_ - -#include - -// Registers Flutter plugins. -void RegisterPlugins(flutter::PluginRegistry* registry); - -#endif // GENERATED_PLUGIN_REGISTRANT_ diff --git a/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake b/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake deleted file mode 100644 index fcbf0d6e..00000000 --- a/examples/flutter-weston-desktop-shell/flutter/generated_plugins.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -# Generated file, do not edit. -# - -list(APPEND FLUTTER_PLUGIN_LIST -) - -set(PLUGIN_BUNDLED_LIBRARIES) - -foreach(plugin ${FLUTTER_PLUGIN_LIST}) - add_subdirectory( - ${USER_PROJECT_PATH}/flutter/plugins/${plugin}/elinux plugins/${plugin}) - - target_link_libraries(${TARGET} - PRIVATE - ${plugin}_plugin - ) - - list(APPEND PLUGIN_BUNDLED_LIBRARIES - ${PROJECT_BINARY_DIR}/plugins/${plugin}/lib${plugin}_plugin.so - ) -endforeach(plugin) diff --git a/examples/flutter-weston-desktop-shell/flutter_window.cc b/examples/flutter-weston-desktop-shell/flutter_window.cc deleted file mode 100644 index 0c5b6397..00000000 --- a/examples/flutter-weston-desktop-shell/flutter_window.cc +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter_window.h" - -#include -#include -#include -#include - -#include "flutter/generated_plugin_registrant.h" - -FlutterWindow::FlutterWindow( - const flutter::FlutterViewController::ViewProperties view_properties, - const flutter::DartProject project) - : view_properties_(view_properties), project_(project) {} - -bool FlutterWindow::OnCreate() { - flutter_view_controller_ = std::make_unique( - view_properties_, project_); - - // Ensure that basic setup of the controller was successful. - if (!flutter_view_controller_->engine() || - !flutter_view_controller_->view()) { - return false; - } - - // Register Flutter plugins. - RegisterPlugins(flutter_view_controller_->engine()); - - return true; -} - -void FlutterWindow::OnDestroy() { - if (flutter_view_controller_) { - flutter_view_controller_ = nullptr; - } -} - -void FlutterWindow::Run() { - // Main loop. - auto next_flutter_event_time = - std::chrono::steady_clock::time_point::clock::now(); - while (flutter_view_controller_->view()->DispatchEvent()) { - // Wait until the next event. - { - auto wait_duration = - std::max(std::chrono::nanoseconds(0), - next_flutter_event_time - - std::chrono::steady_clock::time_point::clock::now()); - std::this_thread::sleep_for( - std::chrono::duration_cast(wait_duration)); - } - - // Processes any pending events in the Flutter engine, and returns the - // number of nanoseconds until the next scheduled event (or max, if none). - auto wait_duration = flutter_view_controller_->engine()->ProcessMessages(); - { - auto next_event_time = std::chrono::steady_clock::time_point::max(); - if (wait_duration != std::chrono::nanoseconds::max()) { - next_event_time = - std::min(next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - wait_duration); - } else { - // Wait for the next frame if no events. - auto frame_rate = flutter_view_controller_->view()->GetFrameRate(); - next_event_time = std::min( - next_event_time, - std::chrono::steady_clock::time_point::clock::now() + - std::chrono::milliseconds( - static_cast(std::trunc(1000000.0 / frame_rate)))); - } - next_flutter_event_time = - std::max(next_flutter_event_time, next_event_time); - } - } -} diff --git a/examples/flutter-weston-desktop-shell/flutter_window.h b/examples/flutter-weston-desktop-shell/flutter_window.h deleted file mode 100644 index 20b9cb88..00000000 --- a/examples/flutter-weston-desktop-shell/flutter_window.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_WINDOW_ -#define FLUTTER_WINDOW_ - -#include -#include - -#include - -class FlutterWindow { - public: - explicit FlutterWindow( - const flutter::FlutterViewController::ViewProperties view_properties, - const flutter::DartProject project); - ~FlutterWindow() = default; - - // Prevent copying. - FlutterWindow(FlutterWindow const&) = delete; - FlutterWindow& operator=(FlutterWindow const&) = delete; - - bool OnCreate(); - void OnDestroy(); - void Run(); - - private: - flutter::FlutterViewController::ViewProperties view_properties_; - flutter::DartProject project_; - std::unique_ptr flutter_view_controller_; -}; - -#endif // FLUTTER_WINDOW_ diff --git a/examples/flutter-weston-desktop-shell/main.cc b/examples/flutter-weston-desktop-shell/main.cc deleted file mode 100644 index 301c0088..00000000 --- a/examples/flutter-weston-desktop-shell/main.cc +++ /dev/null @@ -1,74 +0,0 @@ -// Copyright 2021 Sony Corporation. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include -#include -#include - -#include -#include -#include - -#include "flutter_window.h" - -int main(int argc, char** argv) { - // Works as a weston desktop shell. - bool show_cursor; - auto config_file = weston_config_get_name_from_env(); - auto config = weston_config_parse(config_file); - auto s = weston_config_get_section(config, "flutter_linux_wayland", nullptr, - nullptr); - char* path = nullptr; - if (s) { - weston_config_section_get_bool(s, "show-cursor", &show_cursor, true); - weston_config_section_get_string( - s, "flutter-project-path", &path, - "../../sample-app/sample/build/linux/x64/release/bundle"); - } - - std::wstring fl_path; - if (path != nullptr) { - // convert char* to wstring. - std::string str(path); - std::wstring ws_temp(str.begin(), str.end()); - if (!ws_temp.empty()) { - fl_path = ws_temp; - } - - free(path); - } - - // libweston-6 does not export weston_config_destroy(). - // So run free() instead. - if (config) { - free(config); - } - // weston_config_destroy(config); - - // The project to run. - constexpr int width = 640; - constexpr int height = 480; - - flutter::DartProject project(fl_path); - auto command_line_arguments = std::vector(); - project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); - - flutter::FlutterViewController::ViewProperties view_properties = {}; - view_properties.width = width; - view_properties.height = height; - view_properties.view_mode = - flutter::FlutterViewController::ViewMode::kFullscreen; - view_properties.use_mouse_cursor = show_cursor; - view_properties.use_onscreen_keyboard = true; - view_properties.use_window_decoration = false; - - // The Flutter instance hosted by this window. - FlutterWindow window(view_properties, project); - if (!window.OnCreate()) { - return 0; - } - window.Run(); - window.OnDestroy(); - return 0; -} diff --git a/examples/flutter-x11-client/cmake/user_config.cmake b/examples/flutter-x11-client/cmake/user_config.cmake index 417f2103..aa0196fc 100644 --- a/examples/flutter-x11-client/cmake/user_config.cmake +++ b/examples/flutter-x11-client/cmake/user_config.cmake @@ -3,5 +3,4 @@ cmake_minimum_required(VERSION 3.10) # Flutter embedder configurations. # See: https://github.com/sony/flutter-embedded-linux/wiki/Building-Embedded-Linux-embedding-for-Flutter#user-configuration-parameters-cmake-options set(BACKEND_TYPE X11) -set(DESKTOP_SHELL OFF) set(USE_GLES3 OFF) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index be750254..4d235a7e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -20,7 +20,6 @@ namespace flutter { namespace { -constexpr char kWestonDesktopShell[] = "weston_desktop_shell"; constexpr char kZwpTextInputManagerV1[] = "zwp_text_input_manager_v1"; constexpr char kZwpTextInputManagerV3[] = "zwp_text_input_manager_v3"; @@ -710,10 +709,6 @@ ELinuxWindowWayland::ELinuxWindowWayland( } } - if (weston_desktop_shell_) { - weston_desktop_shell_desktop_ready(weston_desktop_shell_); - } - display_valid_ = true; running_ = true; } @@ -722,11 +717,6 @@ ELinuxWindowWayland::~ELinuxWindowWayland() { display_valid_ = false; running_ = false; - if (weston_desktop_shell_) { - weston_desktop_shell_destroy(weston_desktop_shell_); - weston_desktop_shell_ = nullptr; - } - if (wl_cursor_theme_) { wl_cursor_theme_destroy(wl_cursor_theme_); wl_cursor_theme_ = nullptr; @@ -1125,17 +1115,6 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, return; } -#ifdef DESKTOP_SHELL - if (!strcmp(interface, kWestonDesktopShell)) { - weston_desktop_shell_ = - static_cast(wl_registry_bind( - wl_registry, name, &weston_desktop_shell_interface, 1)); - return; - } -#else - weston_desktop_shell_ = nullptr; -#endif - if (!strcmp(interface, wl_output_interface.name)) { wl_output_ = static_cast( wl_registry_bind(wl_registry, name, &wl_output_interface, 1)); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 169f0872..0acb0e58 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -24,7 +24,6 @@ extern "C" { #include "wayland/protocols/presentation-time-protocol.h" #include "wayland/protocols/text-input-unstable-v1-client-protocol.h" #include "wayland/protocols/text-input-unstable-v3-client-protocol.h" -#include "wayland/protocols/weston-desktop-shell-client-protocol.h" #include "wayland/protocols/xdg-shell-client-protocol.h" } @@ -170,8 +169,6 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_data_source* wl_data_source_; uint32_t wl_data_device_manager_version_; uint32_t serial_; - - weston_desktop_shell* weston_desktop_shell_; }; } // namespace flutter diff --git a/src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h b/src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h deleted file mode 100644 index edffdd0e..00000000 --- a/src/third_party/wayland/protocols/weston-desktop-shell-client-protocol.h +++ /dev/null @@ -1,357 +0,0 @@ -/* Generated by wayland-scanner 1.18.0 */ - -#ifndef WESTON_DESKTOP_CLIENT_PROTOCOL_H -#define WESTON_DESKTOP_CLIENT_PROTOCOL_H - -#include -#include -#include "wayland-client.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @page page_weston_desktop The weston_desktop protocol - * @section page_ifaces_weston_desktop Interfaces - * - @subpage page_iface_weston_desktop_shell - create desktop widgets and helpers - * - @subpage page_iface_weston_screensaver - interface for implementing screensavers - */ -struct weston_desktop_shell; -struct weston_screensaver; -struct wl_output; -struct wl_surface; - -/** - * @page page_iface_weston_desktop_shell weston_desktop_shell - * @section page_iface_weston_desktop_shell_desc Description - * - * Traditional user interfaces can rely on this interface to define the - * foundations of typical desktops. Currently it's possible to set up - * background, panels and locking surfaces. - * @section page_iface_weston_desktop_shell_api API - * See @ref iface_weston_desktop_shell. - */ -/** - * @defgroup iface_weston_desktop_shell The weston_desktop_shell interface - * - * Traditional user interfaces can rely on this interface to define the - * foundations of typical desktops. Currently it's possible to set up - * background, panels and locking surfaces. - */ -extern const struct wl_interface weston_desktop_shell_interface; -/** - * @page page_iface_weston_screensaver weston_screensaver - * @section page_iface_weston_screensaver_desc Description - * - * Only one client can bind this interface at a time. - * @section page_iface_weston_screensaver_api API - * See @ref iface_weston_screensaver. - */ -/** - * @defgroup iface_weston_screensaver The weston_screensaver interface - * - * Only one client can bind this interface at a time. - */ -extern const struct wl_interface weston_screensaver_interface; - -#ifndef WESTON_DESKTOP_SHELL_CURSOR_ENUM -#define WESTON_DESKTOP_SHELL_CURSOR_ENUM -enum weston_desktop_shell_cursor { - WESTON_DESKTOP_SHELL_CURSOR_NONE = 0, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_TOP = 1, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM = 2, - WESTON_DESKTOP_SHELL_CURSOR_ARROW = 3, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_LEFT = 4, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_TOP_LEFT = 5, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM_LEFT = 6, - WESTON_DESKTOP_SHELL_CURSOR_MOVE = 7, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_RIGHT = 8, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_TOP_RIGHT = 9, - WESTON_DESKTOP_SHELL_CURSOR_RESIZE_BOTTOM_RIGHT = 10, - WESTON_DESKTOP_SHELL_CURSOR_BUSY = 11, -}; -#endif /* WESTON_DESKTOP_SHELL_CURSOR_ENUM */ - -#ifndef WESTON_DESKTOP_SHELL_PANEL_POSITION_ENUM -#define WESTON_DESKTOP_SHELL_PANEL_POSITION_ENUM -enum weston_desktop_shell_panel_position { - WESTON_DESKTOP_SHELL_PANEL_POSITION_TOP = 0, - WESTON_DESKTOP_SHELL_PANEL_POSITION_BOTTOM = 1, - WESTON_DESKTOP_SHELL_PANEL_POSITION_LEFT = 2, - WESTON_DESKTOP_SHELL_PANEL_POSITION_RIGHT = 3, -}; -#endif /* WESTON_DESKTOP_SHELL_PANEL_POSITION_ENUM */ - -#ifndef WESTON_DESKTOP_SHELL_ERROR_ENUM -#define WESTON_DESKTOP_SHELL_ERROR_ENUM -enum weston_desktop_shell_error { - /** - * an invalid argument was provided in a request - */ - WESTON_DESKTOP_SHELL_ERROR_INVALID_ARGUMENT = 0, -}; -#endif /* WESTON_DESKTOP_SHELL_ERROR_ENUM */ - -/** - * @ingroup iface_weston_desktop_shell - * @struct weston_desktop_shell_listener - */ -struct weston_desktop_shell_listener { - /** - */ - void (*configure)(void *data, - struct weston_desktop_shell *weston_desktop_shell, - uint32_t edges, - struct wl_surface *surface, - int32_t width, - int32_t height); - /** - * tell the client to create, set the lock surface - * - * Tell the client we want it to create and set the lock surface, - * which is a GUI asking the user to unlock the screen. The lock - * surface is announced with 'set_lock_surface'. Whether or not the - * client actually implements locking, it MUST send 'unlock' - * request to let the normal desktop resume. - */ - void (*prepare_lock_surface)(void *data, - struct weston_desktop_shell *weston_desktop_shell); - /** - * tell client what cursor to show during a grab - * - * This event will be sent immediately before a fake enter event - * on the grab surface. - */ - void (*grab_cursor)(void *data, - struct weston_desktop_shell *weston_desktop_shell, - uint32_t cursor); -}; - -/** - * @ingroup iface_weston_desktop_shell - */ -static inline int -weston_desktop_shell_add_listener(struct weston_desktop_shell *weston_desktop_shell, - const struct weston_desktop_shell_listener *listener, void *data) -{ - return wl_proxy_add_listener((struct wl_proxy *) weston_desktop_shell, - (void (**)(void)) listener, data); -} - -#define WESTON_DESKTOP_SHELL_SET_BACKGROUND 0 -#define WESTON_DESKTOP_SHELL_SET_PANEL 1 -#define WESTON_DESKTOP_SHELL_SET_LOCK_SURFACE 2 -#define WESTON_DESKTOP_SHELL_UNLOCK 3 -#define WESTON_DESKTOP_SHELL_SET_GRAB_SURFACE 4 -#define WESTON_DESKTOP_SHELL_DESKTOP_READY 5 -#define WESTON_DESKTOP_SHELL_SET_PANEL_POSITION 6 - -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_CONFIGURE_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_PREPARE_LOCK_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_GRAB_CURSOR_SINCE_VERSION 1 - -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_SET_BACKGROUND_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_SET_PANEL_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_SET_LOCK_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_UNLOCK_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_SET_GRAB_SURFACE_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_DESKTOP_READY_SINCE_VERSION 1 -/** - * @ingroup iface_weston_desktop_shell - */ -#define WESTON_DESKTOP_SHELL_SET_PANEL_POSITION_SINCE_VERSION 1 - -/** @ingroup iface_weston_desktop_shell */ -static inline void -weston_desktop_shell_set_user_data(struct weston_desktop_shell *weston_desktop_shell, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) weston_desktop_shell, user_data); -} - -/** @ingroup iface_weston_desktop_shell */ -static inline void * -weston_desktop_shell_get_user_data(struct weston_desktop_shell *weston_desktop_shell) -{ - return wl_proxy_get_user_data((struct wl_proxy *) weston_desktop_shell); -} - -static inline uint32_t -weston_desktop_shell_get_version(struct weston_desktop_shell *weston_desktop_shell) -{ - return wl_proxy_get_version((struct wl_proxy *) weston_desktop_shell); -} - -/** @ingroup iface_weston_desktop_shell */ -static inline void -weston_desktop_shell_destroy(struct weston_desktop_shell *weston_desktop_shell) -{ - wl_proxy_destroy((struct wl_proxy *) weston_desktop_shell); -} - -/** - * @ingroup iface_weston_desktop_shell - */ -static inline void -weston_desktop_shell_set_background(struct weston_desktop_shell *weston_desktop_shell, struct wl_output *output, struct wl_surface *surface) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_SET_BACKGROUND, output, surface); -} - -/** - * @ingroup iface_weston_desktop_shell - */ -static inline void -weston_desktop_shell_set_panel(struct weston_desktop_shell *weston_desktop_shell, struct wl_output *output, struct wl_surface *surface) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_SET_PANEL, output, surface); -} - -/** - * @ingroup iface_weston_desktop_shell - */ -static inline void -weston_desktop_shell_set_lock_surface(struct weston_desktop_shell *weston_desktop_shell, struct wl_surface *surface) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_SET_LOCK_SURFACE, surface); -} - -/** - * @ingroup iface_weston_desktop_shell - */ -static inline void -weston_desktop_shell_unlock(struct weston_desktop_shell *weston_desktop_shell) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_UNLOCK); -} - -/** - * @ingroup iface_weston_desktop_shell - * - * The surface set by this request will receive a fake - * pointer.enter event during grabs at position 0, 0 and is - * expected to set an appropriate cursor image as described by - * the grab_cursor event sent just before the enter event. - */ -static inline void -weston_desktop_shell_set_grab_surface(struct weston_desktop_shell *weston_desktop_shell, struct wl_surface *surface) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_SET_GRAB_SURFACE, surface); -} - -/** - * @ingroup iface_weston_desktop_shell - * - * Tell the server, that enough desktop elements have been drawn - * to make the desktop look ready for use. During start-up, the - * server can wait for this request with a black screen before - * starting to fade in the desktop, for instance. If the client - * parts of a desktop take a long time to initialize, we avoid - * showing temporary garbage. - */ -static inline void -weston_desktop_shell_desktop_ready(struct weston_desktop_shell *weston_desktop_shell) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_DESKTOP_READY); -} - -/** - * @ingroup iface_weston_desktop_shell - * - * Tell the shell which side of the screen the panel is - * located. This is so that new windows do not overlap the panel - * and maximized windows maximize properly. - */ -static inline void -weston_desktop_shell_set_panel_position(struct weston_desktop_shell *weston_desktop_shell, uint32_t position) -{ - wl_proxy_marshal((struct wl_proxy *) weston_desktop_shell, - WESTON_DESKTOP_SHELL_SET_PANEL_POSITION, position); -} - -#define WESTON_SCREENSAVER_SET_SURFACE 0 - - -/** - * @ingroup iface_weston_screensaver - */ -#define WESTON_SCREENSAVER_SET_SURFACE_SINCE_VERSION 1 - -/** @ingroup iface_weston_screensaver */ -static inline void -weston_screensaver_set_user_data(struct weston_screensaver *weston_screensaver, void *user_data) -{ - wl_proxy_set_user_data((struct wl_proxy *) weston_screensaver, user_data); -} - -/** @ingroup iface_weston_screensaver */ -static inline void * -weston_screensaver_get_user_data(struct weston_screensaver *weston_screensaver) -{ - return wl_proxy_get_user_data((struct wl_proxy *) weston_screensaver); -} - -static inline uint32_t -weston_screensaver_get_version(struct weston_screensaver *weston_screensaver) -{ - return wl_proxy_get_version((struct wl_proxy *) weston_screensaver); -} - -/** @ingroup iface_weston_screensaver */ -static inline void -weston_screensaver_destroy(struct weston_screensaver *weston_screensaver) -{ - wl_proxy_destroy((struct wl_proxy *) weston_screensaver); -} - -/** - * @ingroup iface_weston_screensaver - * - * A screensaver surface is normally hidden, and only visible after an - * idle timeout. - */ -static inline void -weston_screensaver_set_surface(struct weston_screensaver *weston_screensaver, struct wl_surface *surface, struct wl_output *output) -{ - wl_proxy_marshal((struct wl_proxy *) weston_screensaver, - WESTON_SCREENSAVER_SET_SURFACE, surface, output); -} - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/third_party/wayland/protocols/weston-desktop-shell-protocol.c b/src/third_party/wayland/protocols/weston-desktop-shell-protocol.c deleted file mode 100644 index 7bda93da..00000000 --- a/src/third_party/wayland/protocols/weston-desktop-shell-protocol.c +++ /dev/null @@ -1,67 +0,0 @@ -/* Generated by wayland-scanner 1.18.0 */ - -#include -#include -#include "wayland-util.h" - -#ifndef __has_attribute -# define __has_attribute(x) 0 /* Compatibility with non-clang compilers. */ -#endif - -#if (__has_attribute(visibility) || defined(__GNUC__) && __GNUC__ >= 4) -#define WL_PRIVATE __attribute__ ((visibility("hidden"))) -#else -#define WL_PRIVATE -#endif - -extern const struct wl_interface wl_output_interface; -extern const struct wl_interface wl_surface_interface; - -static const struct wl_interface *weston_desktop_types[] = { - NULL, - &wl_output_interface, - &wl_surface_interface, - &wl_output_interface, - &wl_surface_interface, - &wl_surface_interface, - &wl_surface_interface, - NULL, - &wl_surface_interface, - NULL, - NULL, - &wl_surface_interface, - &wl_output_interface, -}; - -static const struct wl_message weston_desktop_shell_requests[] = { - { "set_background", "oo", weston_desktop_types + 1 }, - { "set_panel", "oo", weston_desktop_types + 3 }, - { "set_lock_surface", "o", weston_desktop_types + 5 }, - { "unlock", "", weston_desktop_types + 0 }, - { "set_grab_surface", "o", weston_desktop_types + 6 }, - { "desktop_ready", "", weston_desktop_types + 0 }, - { "set_panel_position", "u", weston_desktop_types + 0 }, -}; - -static const struct wl_message weston_desktop_shell_events[] = { - { "configure", "uoii", weston_desktop_types + 7 }, - { "prepare_lock_surface", "", weston_desktop_types + 0 }, - { "grab_cursor", "u", weston_desktop_types + 0 }, -}; - -WL_PRIVATE const struct wl_interface weston_desktop_shell_interface = { - "weston_desktop_shell", 1, - 7, weston_desktop_shell_requests, - 3, weston_desktop_shell_events, -}; - -static const struct wl_message weston_screensaver_requests[] = { - { "set_surface", "oo", weston_desktop_types + 11 }, -}; - -WL_PRIVATE const struct wl_interface weston_screensaver_interface = { - "weston_screensaver", 1, - 1, weston_screensaver_requests, - 0, NULL, -}; - From 24d773c5ff8c8e2c482e8ef8cd6c2ddb8a9186fa Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 20 Aug 2021 12:49:35 +0900 Subject: [PATCH 058/178] Fix wayland wp presentation null access (#213) I got the segmentation fault on RPI4 (Ubuntu 21) when I launch the flutter app. wp_presentation_ var could be null accessed and should be avoided. --- .../linux_embedded/window/elinux_window_wayland.cc | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 4d235a7e..6004b031 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -947,9 +947,12 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { auto* callback = wl_surface_frame(native_window_->Surface()); wl_callback_add_listener(callback, &kWlSurfaceFrameListener, this); - wp_presentation_feedback_add_listener( - ::wp_presentation_feedback(wp_presentation_, native_window_->Surface()), - &kWpPresentationFeedbackListener, this); + if (wp_presentation_) { + wp_presentation_feedback_add_listener( + ::wp_presentation_feedback(wp_presentation_, + native_window_->Surface()), + &kWpPresentationFeedbackListener, this); + } } render_surface_ = std::make_unique(std::make_unique( From 2fba792414852aa668f139f49c8c4d29c2a0faf2 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 31 Aug 2021 10:53:32 +0900 Subject: [PATCH 059/178] Fix conflict class name (#215) - rename shader_* to elinux_shader_* --- cmake/build.cmake | 6 ++--- .../renderer/{shader.cc => elinux_shader.cc} | 18 ++++++++------- .../renderer/{shader.h => elinux_shader.h} | 22 +++++++++---------- ...er_context.cc => elinux_shader_context.cc} | 7 +++--- ...ader_context.h => elinux_shader_context.h} | 12 +++++----- ...er_program.cc => elinux_shader_program.cc} | 9 ++++---- ...ader_program.h => elinux_shader_program.h} | 14 ++++++------ .../renderer/window_decoration_button.cc | 2 +- .../renderer/window_decoration_button.h | 4 ++-- 9 files changed, 49 insertions(+), 45 deletions(-) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader.cc => elinux_shader.cc} (70%) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader.h => elinux_shader.h} (62%) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader_context.cc => elinux_shader_context.cc} (94%) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader_context.h => elinux_shader_context.h} (62%) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader_program.cc => elinux_shader_program.cc} (92%) rename src/flutter/shell/platform/linux_embedded/window/renderer/{shader_program.h => elinux_shader_program.h} (69%) diff --git a/cmake/build.cmake b/cmake/build.cmake index d57dcc32..a14bdc0d 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -72,9 +72,9 @@ else() "src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc" - "src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc" - "src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc" - "src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.cc" + "src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.cc" "src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc" "src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc" "src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc") diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.cc similarity index 70% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.cc index fed13bd7..86f3b57d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.cc @@ -13,7 +13,7 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.h" namespace flutter { @@ -41,15 +41,17 @@ static const GlProcs& GlProcs() { } // namespace -void Shader::LoadProgram(std::string vertex_code, std::string fragment_code) { - auto vertex = std::make_unique(vertex_code, GL_VERTEX_SHADER); +void ELinuxShader::LoadProgram(std::string vertex_code, + std::string fragment_code) { + auto vertex = + std::make_unique(vertex_code, GL_VERTEX_SHADER); auto fragment = - std::make_unique(fragment_code, GL_FRAGMENT_SHADER); - program_ = - std::make_unique(std::move(vertex), std::move(fragment)); + std::make_unique(fragment_code, GL_FRAGMENT_SHADER); + program_ = std::make_unique(std::move(vertex), + std::move(fragment)); } -void Shader::Bind() { +void ELinuxShader::Bind() { const auto& gl = GlProcs(); if (!gl.valid) { return; @@ -57,7 +59,7 @@ void Shader::Bind() { gl.glUseProgram(program_->Program()); } -void Shader::Unbind() { +void ELinuxShader::Unbind() { const auto& gl = GlProcs(); if (!gl.valid) { return; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.h b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.h similarity index 62% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader.h rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.h index 0e6b9134..ecb64b4a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_H_ #ifdef USE_GLES3 #include @@ -15,15 +15,15 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader_program.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.h" namespace flutter { -class Shader { +class ELinuxShader { public: - Shader() = default; - ~Shader() = default; + ELinuxShader() = default; + ~ELinuxShader() = default; void LoadProgram(std::string vertex_code, std::string fragment_code); void Bind(); @@ -31,11 +31,11 @@ class Shader { GLuint Program() const { return program_->Program(); } private: - std::unique_ptr program_; - std::unique_ptr vertex_; - std::unique_ptr fragment_; + std::unique_ptr program_; + std::unique_ptr vertex_; + std::unique_ptr fragment_; }; } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.cc similarity index 94% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.cc index a3dd5cb8..c097b284 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.cc @@ -13,7 +13,7 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h" namespace flutter { @@ -58,7 +58,8 @@ static const GlProcs& GlProcs() { } // namespace -ShaderContext::ShaderContext(std::string code, GLenum type) : shader_(0) { +ELinuxShaderContext::ELinuxShaderContext(std::string code, GLenum type) + : shader_(0) { const auto& gl = GlProcs(); if (!gl.valid) { return; @@ -87,7 +88,7 @@ ShaderContext::ShaderContext(std::string code, GLenum type) : shader_(0) { } } -ShaderContext::~ShaderContext() { +ELinuxShaderContext::~ELinuxShaderContext() { const auto& gl = GlProcs(); if (!gl.valid) { return; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h similarity index 62% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h index 2c2bce5f..463ead2a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_context.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_CONTEXT_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_CONTEXT_H_ #ifdef USE_GLES3 #include @@ -17,10 +17,10 @@ namespace flutter { -class ShaderContext { +class ELinuxShaderContext { public: - ShaderContext(std::string code, GLenum type); - ~ShaderContext(); + ELinuxShaderContext(std::string code, GLenum type); + ~ELinuxShaderContext(); GLuint Shader() const { return shader_; } @@ -30,4 +30,4 @@ class ShaderContext { } // namespace flutter -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_SHADER_CONTEXT_H_ +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_ELINUX_SHADER_CONTEXT_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.cc similarity index 92% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.cc index 30d2a0e0..07eb9a45 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.cc @@ -13,7 +13,7 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader_program.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.h" namespace flutter { @@ -58,8 +58,9 @@ static const GlProcs& GlProcs() { } // namespace -ShaderProgram::ShaderProgram(std::unique_ptr vertex_shader, - std::unique_ptr fragment_shader) +ELinuxShaderProgram::ELinuxShaderProgram( + std::unique_ptr vertex_shader, + std::unique_ptr fragment_shader) : vertex_shader_(std::move(vertex_shader)), fragment_shader_(std::move(fragment_shader)), program_(0) { @@ -91,7 +92,7 @@ ShaderProgram::ShaderProgram(std::unique_ptr vertex_shader, } } -ShaderProgram::~ShaderProgram() { +ELinuxShaderProgram::~ELinuxShaderProgram() { const auto& gl = GlProcs(); if (!gl.valid) { return; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.h similarity index 69% rename from src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h rename to src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.h index d26c9cf3..6c93cea6 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/shader_program.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_program.h @@ -14,22 +14,22 @@ #include #include "flutter/shell/platform/linux_embedded/logger.h" -#include "flutter/shell/platform/linux_embedded/window/renderer/shader_context.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader_context.h" namespace flutter { -class ShaderProgram { +class ELinuxShaderProgram { public: - ShaderProgram(std::unique_ptr vertex_shader, - std::unique_ptr fragment_shader); - ~ShaderProgram(); + ELinuxShaderProgram(std::unique_ptr vertex_shader, + std::unique_ptr fragment_shader); + ~ELinuxShaderProgram(); GLuint Program() const { return program_; } private: GLuint program_; - std::unique_ptr vertex_shader_; - std::unique_ptr fragment_shader_; + std::unique_ptr vertex_shader_; + std::unique_ptr fragment_shader_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc index d2f1ca3f..60f071a7 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc @@ -211,7 +211,7 @@ void WindowDecorationButton::LoadShader() { return; } - shader_ = std::make_unique(); + shader_ = std::make_unique(); shader_->LoadProgram(kGlVertexShader, kGlFragmentShader); const auto& gl = GlProcs(); diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h index 74765b18..89e8fc95 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h @@ -5,7 +5,7 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_BUTTON_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_RENDERER_WINDOW_DECORATION_BUTTON_H_ -#include "flutter/shell/platform/linux_embedded/window/renderer/shader.h" +#include "flutter/shell/platform/linux_embedded/window/renderer/elinux_shader.h" #include "flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h" namespace flutter { @@ -29,7 +29,7 @@ class WindowDecorationButton : public WindowDecoration { private: void LoadShader(); - std::unique_ptr shader_; + std::unique_ptr shader_; }; } // namespace flutter From b8afd78ef0badd06ce890e3027101aafd99d6896 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 6 Sep 2021 16:02:05 +0900 Subject: [PATCH 060/178] Update README (#217) - Change the link path of the image - Fix some sentences --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 88524a65..2244d108 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,12 @@ # Embedded Linux (eLinux) embedding for Flutter +![image](https://github.com/sony/flutter-elinux/blob/main/doc/images/overview.png) + [![build-test](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml/badge.svg)](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml) This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. -![image](https://user-images.githubusercontent.com/62131389/128468439-1d7250b2-0462-43d2-878d-5c48e70f5ef3.png) - -Note that this project is the source code of the embedder, so flutter app developers should use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. +### flutter-elinux +Note that this project is the source code of the embedder. If you develop your flutter app for eLinux, use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. ## Objective & Goal Our objective is to use Flutter in embedded systems. We're developing this embedder to use Flutter in embedded products. Ultimately we would like to propose and contribute this software to the mainline of [Flutter Engine](https://github.com/flutter/engine), which means we would like to add an embedded systems version into the Flutter repo for all embedded developers. Please note that this is just our ideal, not the official opinion of the Flutter community. @@ -14,8 +15,8 @@ We would be grateful if you could give us feedback on bugs and new feature reque ## Features - Flutter embedder optimized for Embedded Systems - - Minimal dependent libraries - Lightweight than Flutter desktop for Linux (Not using X11 and GTK) + - Minimal dependent libraries - The main target of this embedder is Arm64 devices. We haven't confirmed in Arm 32bit (ARMv7, armhf) devices - Display backend support - [Wayland](https://wayland.freedesktop.org/) @@ -34,11 +35,10 @@ We would be grateful if you could give us feedback on bugs and new feature reque | ------------- | ------------- | | [flutter-elinux](https://github.com/sony/flutter-elinux) | Flutter tools for eLinux | | [flutter-elinux-plugins](https://github.com/sony/flutter-elinux-plugins) | Flutter plugins for eLinux | -| [flutter-embedded-linux](https://github.com/sony/flutter-embedded-linux) | eLinux embedding for Flutter | | [meta-flutter](https://github.com/sony/meta-flutter) | Yocto recipes of eLinux embedding for Flutter | ## Documentation -Documentation for this software is summarised on the [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). +Documentation for this software can be found at [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). ## Supported platforms This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. From 5dab228be1aba1eab0dd866e427738c4e690ea62 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 8 Sep 2021 11:28:18 +0900 Subject: [PATCH 061/178] Fix wrong touch input (#219) Fixed the touch-input bug in #127, which caused by the wrong time unit. --- .../platform/linux_embedded/flutter_elinux_view.cc | 12 +++++++----- .../platform/linux_embedded/flutter_elinux_view.h | 1 - .../linux_embedded/window_binding_handler_delegate.h | 10 ++++++++++ 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 869439ac..e7929acd 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -10,6 +10,10 @@ namespace flutter { +namespace { +constexpr int kMicrosecondsPerMillisecond = 1000; +} // namespace + FlutterELinuxView::FlutterELinuxView( std::unique_ptr window_binding) { // Take the binding handler, and give it a pointer back to self. @@ -106,12 +110,11 @@ void FlutterELinuxView::OnTouchDown(uint32_t time, int32_t id, double x, point->event_mask = TouchEvent::kDown; point->x = x; point->y = y; - touch_event_.time = time; FlutterPointerEvent event = { .struct_size = sizeof(event), .phase = FlutterPointerPhase::kDown, - .timestamp = time, + .timestamp = time * kMicrosecondsPerMillisecond, .x = x, .y = y, .device = id, @@ -134,7 +137,7 @@ void FlutterELinuxView::OnTouchUp(uint32_t time, int32_t id) { FlutterPointerEvent event = { .struct_size = sizeof(event), .phase = FlutterPointerPhase::kUp, - .timestamp = time, + .timestamp = time * kMicrosecondsPerMillisecond, .x = point->x, .y = point->y, .device = id, @@ -156,12 +159,11 @@ void FlutterELinuxView::OnTouchMotion(uint32_t time, int32_t id, double x, point->event_mask = TouchEvent::kMotion; point->x = x; point->y = y; - touch_event_.time = time; FlutterPointerEvent event = { .struct_size = sizeof(event), .phase = FlutterPointerPhase::kMove, - .timestamp = time, + .timestamp = time * kMicrosecondsPerMillisecond, .x = x, .y = y, .device = id, diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index b3eb1645..68bd9396 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -166,7 +166,6 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { }; struct touch_event { - uint32_t time; touch_point points[10]; }; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index a01a6cd8..1984a53b 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -35,14 +35,24 @@ class WindowBindingHandlerDelegate { // Notifies delegate that backing window touch pointer has been pressed. // Typically called by currently configured WindowBindingHandler + // @param[in] time Monotonically increasing timestamp in milliseconds. + // @param[in] id The unique id of this touch point. + // @param[in] x The Surface local x coordinate. + // @param[in] y The Surface local y coordinate. virtual void OnTouchDown(uint32_t time, int32_t id, double x, double y) = 0; // Notifies delegate that backing window touch pointer has been released. // Typically called by currently configured WindowBindingHandler + // @param[in] time Monotonically increasing timestamp in milliseconds. + // @param[in] id The unique id of this touch point. virtual void OnTouchUp(uint32_t time, int32_t id) = 0; // Notifies delegate that backing window touch pointer has moved. // Typically called by currently configured WindowBindingHandler + // @param[in] time Monotonically increasing timestamp in milliseconds. + // @param[in] id The unique id of this touch point. + // @param[in] x The Surface local x coordinate. + // @param[in] y The Surface local y coordinate. virtual void OnTouchMotion(uint32_t time, int32_t id, double x, double y) = 0; // Notifies delegate that backing window touch pointer has been canceled. From 2ad0ccf06d6ea9a0498d232a6a46ba9195fb4db3 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 15 Sep 2021 15:14:48 +0900 Subject: [PATCH 062/178] Fix synchronized frame on Wayland (#221) Currently, the embedder always waits for the next Vsync when flutter calls eglSwapBuffers. - Fixed https://github.com/sony/flutter-embedded-linux/issues/220 --- .../linux_embedded/surface/elinux_egl_surface.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 5171cfa8..f25af190 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -31,6 +31,15 @@ bool ELinuxEGLSurface::MakeCurrent() const { << get_egl_error_cause(); return false; } + +#if defined(DISPLAY_BACKEND_TYPE_WAYLAND) + // Non-blocking when swappipping buffers on Wayland. + if (eglSwapInterval(display_, 0) != EGL_TRUE) { + ELINUX_LOG(ERROR) << "Failed to eglSwapInterval(Free): " + << get_egl_error_cause(); + } +#endif + return true; } From 490b904806a8884763883f552c8ba5fc35c68cfc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 16 Sep 2021 09:31:15 +0900 Subject: [PATCH 063/178] Merge the latest embedder header from flutter/engine (#222) Merged from https://github.com/flutter/engine/commit/0112d4b422de28dba00505df4c1f84846a6b75ec#diff-06f2c0a6c7bb5df337492f6d661883b12f847d1677220bd7dd7add48a78784c5 --- src/flutter/shell/platform/embedder/embedder.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index c630c61b..0a63b558 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -693,6 +693,14 @@ typedef enum { /// released. /// * All events throughout a key press sequence shall have the same `physical` /// and `logical`. Having different `character`s is allowed. +/// +/// A `FlutterKeyEvent` with `physical` 0 and `logical` 0 is an empty event. +/// This is the only case either `physical` or `logical` can be 0. An empty +/// event must be sent if a key message should be converted to no +/// `FlutterKeyEvent`s, for example, when a key down message is received for a +/// key that has already been pressed according to the record. This is to ensure +/// some `FlutterKeyEvent` arrives at the framework before raw key message. +/// See https://github.com/flutter/flutter/issues/87230. typedef struct { /// The size of this struct. Must be sizeof(FlutterKeyEvent). size_t struct_size; @@ -706,11 +714,17 @@ typedef struct { /// /// For the full definition and list of pre-defined physical keys, see /// `PhysicalKeyboardKey` from the framework. + /// + /// The only case that `physical` might be 0 is when this is an empty event. + /// See `FlutterKeyEvent` for introduction. uint64_t physical; /// The key ID for the logical key of this event. /// /// For the full definition and a list of pre-defined logical keys, see /// `LogicalKeyboardKey` from the framework. + /// + /// The only case that `logical` might be 0 is when this is an empty event. + /// See `FlutterKeyEvent` for introduction. uint64_t logical; /// Null-terminated character input from the event. Can be null. Ignored for /// up events. From a37181845ee20d68cb682a6ec2869a2106a60445 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 16 Sep 2021 09:50:15 +0900 Subject: [PATCH 064/178] Merge the latest common cpp source files from flutter/engine (#223) Merged from https://github.com/flutter/engine/commit/cc3529093ae0caa15857de385613794365120080#diff-b751ee972d196d9d78adb28211809428af5875890719ed63f76980b57430fca8 --- .../common/client_wrapper/include/flutter/encodable_value.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h index 870cfc80..dec1bdfc 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h @@ -110,8 +110,8 @@ using EncodableValueVariant = std::variant, EncodableList, EncodableMap, - std::vector, - CustomEncodableValue>; + CustomEncodableValue, + std::vector>; } // namespace internal // An object that can contain any value or collection type supported by @@ -156,10 +156,10 @@ using EncodableValueVariant = std::variant -> Uint8List // std::vector -> Int32List // std::vector -> Int64List +// std::vector -> Float32List // std::vector -> Float64List // EncodableList -> List // EncodableMap -> Map -// std::vector -> Float32List class EncodableValue : public internal::EncodableValueVariant { public: // Rely on std::variant for most of the constructors/operators. From f65dac55d4cee662d1e01570130c213c69c5f3df Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 16 Sep 2021 15:59:10 +0900 Subject: [PATCH 065/178] [wayland] Fix crashes with `xdg_surface buffer does not match the configured state` (#224) ## Issue 1. Run a flutter app with the window decorations on Weston 8.0 2. Press the maximize button ``` [15:42:27.378] libwayland: error in client communication (pid 20431) xdg_wm_base@11: error 4: xdg_surface buffer does not match the configured state ``` I'm not sure, but this issue doesn't happen on Gnome Wayland. --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 6004b031..78d0caf2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -63,6 +63,10 @@ const xdg_wm_base_listener ELinuxWindowWayland::kXdgWmBaseListener = { const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { .configure = [](void* data, xdg_surface* xdg_surface, uint32_t serial) { + auto self = reinterpret_cast(data); + xdg_surface_set_window_geometry(xdg_surface, 0, 0, + self->view_properties_.width, + self->view_properties_.height); xdg_surface_ack_configure(xdg_surface, serial); }, }; From eaae5cf5d4bc974f7f497ae9fb39b24575acd52c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 21 Sep 2021 17:12:29 +0900 Subject: [PATCH 066/178] [wayland] Fix operations of the max button in the window decorations (#225) - Add restore original window size support (unset maximize-window) - Fix the window decorations will be hidden after pressing the max-button --- .../window/elinux_window_wayland.cc | 63 ++++++++++++++++--- .../window/elinux_window_wayland.h | 3 + .../renderer/window_decorations_wayland.cc | 2 + .../renderer/window_decorations_wayland.h | 2 + 4 files changed, 63 insertions(+), 7 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 78d0caf2..98751f61 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -64,7 +64,15 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { .configure = [](void* data, xdg_surface* xdg_surface, uint32_t serial) { auto self = reinterpret_cast(data); - xdg_surface_set_window_geometry(xdg_surface, 0, 0, + constexpr int32_t x = 0; + int32_t y = 0; + if (self->view_properties_.use_window_decoration) { + // TODO: Moves the window to the bottom to show the window + // decorations, but the bottom area of the window will be hidden + // because of this shifting. + y = -self->window_decorations_->Height(); + } + xdg_surface_set_window_geometry(xdg_surface, x, y, self->view_properties_.width, self->view_properties_.height); xdg_surface_ack_configure(xdg_surface, serial); @@ -75,18 +83,51 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { .configure = [](void* data, xdg_toplevel* xdg_toplevel, int32_t width, int32_t height, wl_array* states) { - if (!width || !height) { - return; + auto is_maximized = false; + auto is_resizing = false; + uint32_t* state = static_cast(states->data); + for (auto i = 0; i < states->size; i++) { + switch (*state) { + case XDG_TOPLEVEL_STATE_MAXIMIZED: + is_maximized = true; + break; + case XDG_TOPLEVEL_STATE_RESIZING: + is_resizing = true; + break; + case XDG_TOPLEVEL_STATE_ACTIVATED: + case XDG_TOPLEVEL_STATE_FULLSCREEN: + default: + break; + } + state++; } auto self = reinterpret_cast(data); - self->view_properties_.width = width; - self->view_properties_.height = height; + int32_t next_width = 0; + int32_t next_height = 0; + if (is_maximized || is_resizing) { + next_width = width; + next_height = height; + } else if (self->restore_window_required_) { + self->restore_window_required_ = false; + next_width = self->restore_window_width_; + next_height = self->restore_window_height_; + } + + if (!next_width || !next_height || + (self->view_properties_.width == next_width && + self->view_properties_.height == next_height)) { + return; + } + + self->view_properties_.width = next_width; + self->view_properties_.height = next_height; if (self->window_decorations_) { - self->window_decorations_->Resize(width, height); + self->window_decorations_->Resize(next_width, next_height); } if (self->binding_handler_delegate_) { - self->binding_handler_delegate_->OnWindowSizeChanged(width, height); + self->binding_handler_delegate_->OnWindowSizeChanged(next_width, + next_height); } }, .close = @@ -263,7 +304,15 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { WindowDecoration::DecorationType::MAXIMISE_BUTTON)) { if (self->maximised_) { xdg_toplevel_unset_maximized(self->xdg_toplevel_); + + // Requests to return to the original window size before maximizing. + self->restore_window_required_ = true; } else { + // Stores original window size. + self->restore_window_width_ = self->view_properties_.width; + self->restore_window_height_ = self->view_properties_.height; + self->restore_window_required_ = false; + xdg_toplevel_set_maximized(self->xdg_toplevel_); } self->maximised_ = !self->maximised_; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 0acb0e58..1eb19012 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -122,6 +122,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { std::unique_ptr window_decorations_; wl_surface* wl_current_surface_; wl_subcompositor* wl_subcompositor_; + bool restore_window_required_ = false; + int32_t restore_window_width_; + int32_t restore_window_height_; bool display_valid_; bool running_; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index cd932d33..1c8cdb7d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -114,4 +114,6 @@ void WindowDecorationsWayland::DestroyContext() { } } +int32_t WindowDecorationsWayland::Height() const { return kTitleBarHeight; } + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 85121289..4b71350b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -39,6 +39,8 @@ class WindowDecorationsWayland { bool IsMatched(wl_surface* surface, WindowDecoration::DecorationType decoration_type) const; + int32_t Height() const; + private: void DestroyContext(); From 61301fb9f3e598eb9f08bcd591b40e9eb030438d Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 25 Oct 2021 15:25:48 +0900 Subject: [PATCH 067/178] Merge the latest cpp shared common source file from flutter/engine repo (#232) Merged from https://github.com/flutter/engine/pull/29270 --- src/flutter/shell/platform/common/json_message_codec.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/common/json_message_codec.cc b/src/flutter/shell/platform/common/json_message_codec.cc index b91e57e4..ae362f73 100644 --- a/src/flutter/shell/platform/common/json_message_codec.cc +++ b/src/flutter/shell/platform/common/json_message_codec.cc @@ -37,9 +37,7 @@ std::unique_ptr JsonMessageCodec::DecodeMessageInternal( auto json_message = std::make_unique(); rapidjson::ParseResult result = json_message->Parse(raw_message, message_size); - bool parsing_successful = - result == rapidjson::ParseErrorCode::kParseErrorNone; - if (!parsing_successful) { + if (result.IsError()) { std::cerr << "Unable to parse JSON message:" << std::endl << rapidjson::GetParseError_En(result.Code()) << std::endl; return nullptr; From be0a03f403cd78cf8299797818e56c4a1b362259 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 28 Oct 2021 11:07:00 +0900 Subject: [PATCH 068/178] Add verifying code format (#233) - Reformat source code files by clang-format - Add code format check in GitHub actions --- .github/workflows/build-test.yml | 6 + src/client_wrapper/flutter_view_controller.cc | 3 +- .../platform/linux_embedded/flutter_elinux.cc | 18 +- .../linux_embedded/flutter_elinux_engine.cc | 18 +- .../linux_embedded/flutter_elinux_engine.h | 6 +- .../flutter_elinux_texture_registrar.h | 4 +- .../linux_embedded/flutter_elinux_view.cc | 40 ++- .../linux_embedded/flutter_elinux_view.h | 22 +- .../plugins/key_event_plugin.cc | 16 +- .../linux_embedded/plugins/key_event_plugin.h | 10 +- .../plugins/lifecycle_plugin.cc | 4 +- .../plugins/mouse_cursor_plugin.cc | 4 +- .../plugins/navigation_plugin.cc | 4 +- .../linux_embedded/plugins/platform_plugin.cc | 4 +- .../plugins/platform_views_plugin.cc | 3 +- .../plugins/text_input_plugin.cc | 4 +- .../public/flutter_platform_views.h | 7 +- .../linux_embedded/surface/context_egl.cc | 4 +- .../surface/elinux_egl_surface.cc | 7 +- .../surface/surface_decoration.cc | 8 +- .../linux_embedded/surface/surface_gl.cc | 4 +- .../platform/linux_embedded/task_runner.cc | 4 +- .../platform/linux_embedded/task_runner.h | 3 +- .../linux_embedded/window/elinux_window_drm.h | 12 +- .../window/elinux_window_wayland.cc | 260 +++++++++++++----- .../window/elinux_window_wayland.h | 6 +- .../window/elinux_window_x11.cc | 15 +- .../linux_embedded/window/elinux_window_x11.h | 4 +- .../linux_embedded/window/native_window_drm.h | 3 +- .../window/native_window_drm_eglstream.cc | 10 +- .../window/native_window_drm_eglstream.h | 7 +- .../window/native_window_drm_gbm.cc | 3 +- .../window/native_window_drm_gbm.h | 3 +- .../window/native_window_wayland.h | 3 +- .../native_window_wayland_decoration.cc | 7 +- .../window/native_window_wayland_decoration.h | 3 +- .../window/native_window_x11.cc | 6 +- .../linux_embedded/window/native_window_x11.h | 4 +- .../renderer/window_decorations_wayland.cc | 11 +- .../renderer/window_decorations_wayland.h | 6 +- .../window_binding_handler_delegate.h | 17 +- 41 files changed, 414 insertions(+), 169 deletions(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index b4a834fe..ddd680ed 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -16,8 +16,14 @@ jobs: - name: Install libraries run: | sudo apt update + sudo apt install clang-format sudo apt install libgles2-mesa-dev libegl1-mesa-dev libxkbcommon-dev libwayland-dev libdrm-dev libgbm-dev libinput-dev libudev-dev libsystemd-dev wayland-protocols libx11-dev + - name: Verify formatting + run: | + find src/flutter/shell/platform/linux_embedded/ -iname *.h -o -iname *.cc | xargs clang-format --dry-run --Werror + find src/client_wrapper -iname *.h -o -iname *.cc | xargs clang-format --dry-run --Werror + - name: Create Build Environment run: cmake -E make_directory ${{github.workspace}}/build diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index afd61d08..e7b52622 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -10,7 +10,8 @@ namespace flutter { FlutterViewController::FlutterViewController( - const ViewProperties& view_properties, const DartProject& project) { + const ViewProperties& view_properties, + const DartProject& project) { engine_ = std::make_unique(project); FlutterDesktopViewProperties c_view_properties = {}; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index e8633d10..1279155b 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -160,7 +160,8 @@ void FlutterDesktopEngineReloadSystemFonts(FlutterDesktopEngineRef engine) { } FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar( - FlutterDesktopEngineRef engine, const char* plugin_name) { + FlutterDesktopEngineRef engine, + const char* plugin_name) { // Currently, one registrar acts as the registrar for all plugins, so the // name is ignored. It is part of the API to reduce churn in the future when // aligning more closely with the Flutter registrar system. @@ -208,7 +209,8 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, } bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, - const char* channel, const uint8_t* message, + const char* channel, + const uint8_t* message, const size_t message_size) { return FlutterDesktopMessengerSendWithReply(messenger, channel, message, message_size, nullptr, nullptr); @@ -216,7 +218,8 @@ bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, void FlutterDesktopMessengerSendResponse( FlutterDesktopMessengerRef messenger, - const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, + const FlutterDesktopMessageResponseHandle* handle, + const uint8_t* data, size_t data_length) { messenger->engine->SendPlatformMessageResponse(handle, data, data_length); } @@ -242,19 +245,22 @@ int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( } bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( - FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id) { + FlutterDesktopTextureRegistrarRef texture_registrar, + int64_t texture_id) { return TextureRegistrarFromHandle(texture_registrar) ->UnregisterTexture(texture_id); } bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( - FlutterDesktopTextureRegistrarRef texture_registrar, int64_t texture_id) { + FlutterDesktopTextureRegistrarRef texture_registrar, + int64_t texture_id) { return TextureRegistrarFromHandle(texture_registrar) ->MarkTextureFrameAvailable(texture_id); } void FlutterDesktopRegisterPlatformViewFactory( - FlutterDesktopPluginRegistrarRef registrar, const char* view_type, + FlutterDesktopPluginRegistrarRef registrar, + const char* view_type, std::unique_ptr view_factory) { registrar->engine->view()->RegisterPlatformViewFactory( view_type, std::move(view_factory)); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 13c69c39..033cc3d5 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -139,7 +139,9 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) vsync_waiter_ = std::make_unique(); } -FlutterELinuxEngine::~FlutterELinuxEngine() { Stop(); } +FlutterELinuxEngine::~FlutterELinuxEngine() { + Stop(); +} bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { if (!project_->HasValidPaths()) { @@ -263,7 +265,9 @@ bool FlutterELinuxEngine::Stop() { return false; } -void FlutterELinuxEngine::SetView(FlutterELinuxView* view) { view_ = view; } +void FlutterELinuxEngine::SetView(FlutterELinuxView* view) { + view_ = view; +} // Returns the currently configured Plugin Registrar. FlutterDesktopPluginRegistrarRef FlutterELinuxEngine::GetRegistrar() { @@ -289,8 +293,11 @@ void FlutterELinuxEngine::SendPointerEvent(const FlutterPointerEvent& event) { } bool FlutterELinuxEngine::SendPlatformMessage( - const char* channel, const uint8_t* message, const size_t message_size, - const FlutterDesktopBinaryReply reply, void* user_data) { + const char* channel, + const uint8_t* message, + const size_t message_size, + const FlutterDesktopBinaryReply reply, + void* user_data) { FlutterPlatformMessageResponseHandle* response_handle = nullptr; if (reply != nullptr && user_data != nullptr) { FlutterEngineResult result = @@ -320,7 +327,8 @@ bool FlutterELinuxEngine::SendPlatformMessage( } void FlutterELinuxEngine::SendPlatformMessageResponse( - const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, + const FlutterDesktopMessageResponseHandle* handle, + const uint8_t* data, size_t data_length) { embedder_api_.SendPlatformMessageResponse(engine_, handle, data, data_length); } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 9824e5cc..11a378b6 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -84,14 +84,16 @@ class FlutterELinuxEngine { // Sends the given message to the engine, calling |reply| with |user_data| // when a reponse is received from the engine if they are non-null. - bool SendPlatformMessage(const char* channel, const uint8_t* message, + bool SendPlatformMessage(const char* channel, + const uint8_t* message, const size_t message_size, const FlutterDesktopBinaryReply reply, void* user_data); // Sends the given data as the response to an earlier platform message. void SendPlatformMessageResponse( - const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, + const FlutterDesktopMessageResponseHandle* handle, + const uint8_t* data, size_t data_length); // Callback passed to Flutter engine for notifying window of platform diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h index 511f2cb5..0b46a1fa 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h @@ -36,7 +36,9 @@ class FlutterELinuxTextureRegistrar { // Attempts to populate the given |texture| by copying the // contents of the texture identified by |texture_id|. // Returns true on success. - bool PopulateTexture(int64_t texture_id, size_t width, size_t height, + bool PopulateTexture(int64_t texture_id, + size_t width, + size_t height, FlutterOpenGLTexture* texture); private: diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index e7929acd..9a85b6a9 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -82,7 +82,9 @@ void FlutterELinuxView::OnPointerMove(double x, double y) { } void FlutterELinuxView::OnPointerDown( - double x, double y, FlutterPointerMouseButtons flutter_button) { + double x, + double y, + FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; SetMouseButtons(mouse_buttons); @@ -90,7 +92,8 @@ void FlutterELinuxView::OnPointerDown( } } -void FlutterELinuxView::OnPointerUp(double x, double y, +void FlutterELinuxView::OnPointerUp(double x, + double y, FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; @@ -99,9 +102,13 @@ void FlutterELinuxView::OnPointerUp(double x, double y, } } -void FlutterELinuxView::OnPointerLeave() { SendPointerLeave(); } +void FlutterELinuxView::OnPointerLeave() { + SendPointerLeave(); +} -void FlutterELinuxView::OnTouchDown(uint32_t time, int32_t id, double x, +void FlutterELinuxView::OnTouchDown(uint32_t time, + int32_t id, + double x, double y) { auto* point = GgeTouchPoint(id); if (!point) { @@ -150,7 +157,9 @@ void FlutterELinuxView::OnTouchUp(uint32_t time, int32_t id) { engine_->SendPointerEvent(event); } -void FlutterELinuxView::OnTouchMotion(uint32_t time, int32_t id, double x, +void FlutterELinuxView::OnTouchMotion(uint32_t time, + int32_t id, + double x, double y) { auto* point = GgeTouchPoint(id); if (!point) { @@ -194,7 +203,8 @@ void FlutterELinuxView::OnKey(uint32_t key, bool pressed) { void FlutterELinuxView::OnKeyModifiers(uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { + uint32_t mods_locked, + uint32_t group) { keyboard_handler_->OnModifiers(mods_depressed, mods_latched, mods_locked, group); } @@ -210,8 +220,11 @@ void FlutterELinuxView::OnVirtualSpecialKey(uint32_t keycode) { textinput_handler_->OnKeyPressed(keycode, code_point); } -void FlutterELinuxView::OnScroll(double x, double y, double delta_x, - double delta_y, int scroll_offset_multiplier) { +void FlutterELinuxView::OnScroll(double x, + double y, + double delta_x, + double delta_y, + int scroll_offset_multiplier) { SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); } @@ -240,7 +253,8 @@ FlutterELinuxView::touch_point* FlutterELinuxView::GgeTouchPoint(int32_t id) { } // Sends new size information to FlutterEngine. -void FlutterELinuxView::SendWindowMetrics(size_t width, size_t height, +void FlutterELinuxView::SendWindowMetrics(size_t width, + size_t height, double dpiScale) const { FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); @@ -304,7 +318,9 @@ void FlutterELinuxView::SendPointerLeave() { SendPointerEventWithData(event); } -void FlutterELinuxView::SendScroll(double x, double y, double delta_x, +void FlutterELinuxView::SendScroll(double x, + double y, + double delta_x, double delta_y, int scroll_offset_multiplier) { FlutterPointerEvent event = {}; @@ -395,7 +411,9 @@ ELinuxRenderSurfaceTarget* FlutterELinuxView::GetRenderSurfaceTarget() const { return binding_handler_->GetRenderSurfaceTarget(); } -FlutterELinuxEngine* FlutterELinuxView::GetEngine() { return engine_.get(); } +FlutterELinuxEngine* FlutterELinuxView::GetEngine() { + return engine_.get(); +} int32_t FlutterELinuxView::GetFrameRate() { return binding_handler_->GetFrameRate(); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index 68bd9396..b8e057d0 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -85,11 +85,13 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void OnPointerMove(double x, double y) override; // |WindowBindingHandlerDelegate| - void OnPointerDown(double x, double y, + void OnPointerDown(double x, + double y, FlutterPointerMouseButtons button) override; // |WindowBindingHandlerDelegate| - void OnPointerUp(double x, double y, + void OnPointerUp(double x, + double y, FlutterPointerMouseButtons button) override; // |WindowBindingHandlerDelegate| @@ -111,8 +113,10 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void OnKeyMap(uint32_t format, int fd, uint32_t size) override; // |WindowBindingHandlerDelegate| - void OnKeyModifiers(uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) override; + void OnKeyModifiers(uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) override; // |WindowBindingHandlerDelegate| void OnKey(uint32_t key, bool pressed) override; @@ -124,7 +128,10 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void OnVirtualSpecialKey(uint32_t keycode) override; // |WindowBindingHandlerDelegate| - void OnScroll(double x, double y, double delta_x, double delta_y, + void OnScroll(double x, + double y, + double delta_x, + double delta_y, int scroll_offset_multiplier) override; // |WindowBindingHandlerDelegate| @@ -193,7 +200,10 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void SendPointerLeave(); // Reports scroll wheel events to Flutter engine. - void SendScroll(double x, double y, double delta_x, double delta_y, + void SendScroll(double x, + double y, + double delta_x, + double delta_y, int scroll_offset_multiplier); // Sets |event_data|'s phase to either kMove or kHover depending on the diff --git a/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc index 60b52697..dff808e2 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.cc @@ -41,7 +41,9 @@ constexpr char kXkboptionsKey[] = "XKBOPTIONS"; KeyeventPlugin::KeyeventPlugin(BinaryMessenger* messenger) : channel_(std::make_unique>( - messenger, kChannelName, &flutter::JsonMessageCodec::GetInstance())), + messenger, + kChannelName, + &flutter::JsonMessageCodec::GetInstance())), xkb_context_(xkb_context_new(XKB_CONTEXT_NO_FLAGS)) { #if defined(DISPLAY_BACKEND_TYPE_WAYLAND) xkb_keymap_ = nullptr; @@ -105,16 +107,20 @@ void KeyeventPlugin::OnKey(uint32_t keycode, bool pressed) { SendKeyEvent(keyscancode, unicode, mods, pressed); } -void KeyeventPlugin::OnModifiers(uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) { +void KeyeventPlugin::OnModifiers(uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) { xkb_state_update_mask(xkb_state_, mods_depressed, mods_latched, mods_locked, 0, 0, group); xkb_mods_mask_ = xkb_state_serialize_mods(xkb_state_, XKB_STATE_MODS_EFFECTIVE); } -void KeyeventPlugin::SendKeyEvent(uint32_t keycode, uint32_t unicode, - uint32_t modifiers, bool pressed) { +void KeyeventPlugin::SendKeyEvent(uint32_t keycode, + uint32_t unicode, + uint32_t modifiers, + bool pressed) { rapidjson::Document event(rapidjson::kObjectType); auto& allocator = event.GetAllocator(); event.AddMember(kKeyCodeKey, keycode, allocator); diff --git a/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h index 6de36a45..d7e4fe47 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/key_event_plugin.h @@ -25,15 +25,19 @@ class KeyeventPlugin { void OnKey(uint32_t keycode, bool pressed); - void OnModifiers(uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group); + void OnModifiers(uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group); uint32_t GetCodePoint(uint32_t keycode); bool IsTextInputSuppressed(uint32_t code_point); private: - void SendKeyEvent(uint32_t keycode, uint32_t unicode, uint32_t modifiers, + void SendKeyEvent(uint32_t keycode, + uint32_t unicode, + uint32_t modifiers, bool pressed); void OnModifiers(uint32_t keycode, bool pressed); xkb_keymap* CreateKeymap(xkb_context* context); diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc index 6ea582f2..59a9fc0f 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc @@ -19,7 +19,9 @@ constexpr char kDetached[] = "AppLifecycleState.detached"; LifecyclePlugin::LifecyclePlugin(BinaryMessenger* messenger) : channel_(std::make_unique>( - messenger, kChannelName, &StandardMessageCodec::GetInstance())) {} + messenger, + kChannelName, + &StandardMessageCodec::GetInstance())) {} void LifecyclePlugin::OnInactive() const { ELINUX_LOG(DEBUG) << "App lifecycle changed to inactive state."; diff --git a/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc index 957f71b5..af695d45 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/mouse_cursor_plugin.cc @@ -31,7 +31,9 @@ constexpr char kKindKey[] = "kind"; MouseCursorPlugin::MouseCursorPlugin(BinaryMessenger* messenger, WindowBindingHandler* delegate) : channel_(std::make_unique>( - messenger, kChannelName, &StandardMethodCodec::GetInstance())), + messenger, + kChannelName, + &StandardMethodCodec::GetInstance())), delegate_(delegate) { channel_->SetMethodCallHandler( [this](const MethodCall& call, diff --git a/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc index 35c07e02..e23b09c4 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc @@ -19,7 +19,9 @@ constexpr char kPopRouteMethod[] = "popRoute"; NavigationPlugin::NavigationPlugin(BinaryMessenger* messenger) : channel_(std::make_unique>( - messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())) {} + messenger, + kChannelName, + &flutter::JsonMethodCodec::GetInstance())) {} void NavigationPlugin::SetInitialRoute(std::string route) const { ELINUX_LOG(DEBUG) << "SetInitialRoute = " << route; diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc index 2d6de395..7670c157 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc @@ -37,7 +37,9 @@ constexpr char kUnknownClipboardFormatError[] = PlatformPlugin::PlatformPlugin(BinaryMessenger* messenger, WindowBindingHandler* delegate) : channel_(std::make_unique>( - messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())), + messenger, + kChannelName, + &flutter::JsonMethodCodec::GetInstance())), delegate_(delegate) { channel_->SetMethodCallHandler( [this]( diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc index 2a618882..85c553e8 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -32,7 +32,8 @@ constexpr char kParamsKey[] = "params"; PlatformViewsPlugin::PlatformViewsPlugin(BinaryMessenger* messenger) : channel_( std::make_unique>( - messenger, kChannelName, + messenger, + kChannelName, &flutter::StandardMethodCodec::GetInstance())), current_view_id_(-1) { channel_->SetMethodCallHandler( diff --git a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc index 5c89f72a..3cc932c9 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc @@ -98,7 +98,9 @@ void TextInputPlugin::OnKeyPressed(uint32_t keycode, uint32_t code_point) { TextInputPlugin::TextInputPlugin(BinaryMessenger* messenger, WindowBindingHandler* delegate) : channel_(std::make_unique>( - messenger, kChannelName, &flutter::JsonMethodCodec::GetInstance())), + messenger, + kChannelName, + &flutter::JsonMethodCodec::GetInstance())), delegate_(delegate), active_model_(nullptr) { channel_->SetMethodCallHandler( diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h index 8efbf2f9..5ecb2f30 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h @@ -53,7 +53,9 @@ class FlutterDesktopPlatformViewFactory { flutter::PluginRegistrar* GetPluginRegistrar() const { return registrar_; } virtual FlutterDesktopPlatformView* Create( - int view_id, double width, double height, + int view_id, + double width, + double height, const std::vector& params) = 0; virtual void Dispose() = 0; @@ -67,7 +69,8 @@ extern "C" { #endif void FlutterDesktopRegisterPlatformViewFactory( - FlutterDesktopPluginRegistrarRef registrar, const char* view_type, + FlutterDesktopPluginRegistrarRef registrar, + const char* view_type, std::unique_ptr view_factory); #if defined(__cplusplus) diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index 85c4a31e..978af656 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -105,7 +105,9 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( resource_context_); } -bool ContextEgl::IsValid() const { return valid_; } +bool ContextEgl::IsValid() const { + return valid_; +} bool ContextEgl::ClearCurrent() const { if (eglGetCurrentContext() != context_) { diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index f25af190..b47567f9 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -9,7 +9,8 @@ namespace flutter { -ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, +ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, + EGLDisplay display, EGLContext context) : surface_(surface), display_(display), context_(context){}; @@ -23,7 +24,9 @@ ELinuxEGLSurface::~ELinuxEGLSurface() { } } -bool ELinuxEGLSurface::IsValid() const { return surface_ != EGL_NO_SURFACE; } +bool ELinuxEGLSurface::IsValid() const { + return surface_ != EGL_NO_SURFACE; +} bool ELinuxEGLSurface::MakeCurrent() const { if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) { diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc index b4c7bb4e..dc7e932c 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc @@ -12,7 +12,9 @@ SurfaceDecoration::SurfaceDecoration(std::unique_ptr context) { context_ = std::move(context); } -bool SurfaceDecoration::IsValid() const { return context_->IsValid(); }; +bool SurfaceDecoration::IsValid() const { + return context_->IsValid(); +}; bool SurfaceDecoration::SetNativeWindow(NativeWindow* window) { native_window_ = window; @@ -60,7 +62,9 @@ bool SurfaceDecoration::GLContextPresent(uint32_t fbo_id) const { return surface_->SwapBuffers(); } -uint32_t SurfaceDecoration::GLContextFBO() const { return 0; } +uint32_t SurfaceDecoration::GLContextFBO() const { + return 0; +} void* SurfaceDecoration::GlProcResolver(const char* name) const { return context_->GlProcResolver(name); diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc index 314c5025..7467dd84 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc @@ -26,7 +26,9 @@ bool SurfaceGl::GLContextPresent(uint32_t fbo_id) const { return true; } -uint32_t SurfaceGl::GLContextFBO() const { return 0; } +uint32_t SurfaceGl::GLContextFBO() const { + return 0; +} void* SurfaceGl::GlProcResolver(const char* name) const { return context_->GlProcResolver(name); diff --git a/src/flutter/shell/platform/linux_embedded/task_runner.cc b/src/flutter/shell/platform/linux_embedded/task_runner.cc index fd28fe96..8a5b617a 100644 --- a/src/flutter/shell/platform/linux_embedded/task_runner.cc +++ b/src/flutter/shell/platform/linux_embedded/task_runner.cc @@ -5,8 +5,8 @@ #include "flutter/shell/platform/linux_embedded/task_runner.h" #include -#include #include +#include namespace flutter { @@ -22,7 +22,7 @@ bool TaskRunner::RunsTasksOnCurrentThread() const { } void TaskRunner::PostFlutterTask(FlutterTask flutter_task, - uint64_t flutter_target_time_nanos) { + uint64_t flutter_target_time_nanos) { Task task; task.fire_time = TimePointFromFlutterTime(flutter_target_time_nanos); task.variant = flutter_task; diff --git a/src/flutter/shell/platform/linux_embedded/task_runner.h b/src/flutter/shell/platform/linux_embedded/task_runner.h index 723a75ac..9b88d3d8 100644 --- a/src/flutter/shell/platform/linux_embedded/task_runner.h +++ b/src/flutter/shell/platform/linux_embedded/task_runner.h @@ -26,7 +26,8 @@ class TaskRunner { using TaskExpiredCallback = std::function; using TaskClosure = std::function; - TaskRunner(std::thread::id main_thread_id, CurrentTimeProc get_current_time, + TaskRunner(std::thread::id main_thread_id, + CurrentTimeProc get_current_time, const TaskExpiredCallback& on_task_expired); ~TaskRunner() = default; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 3c120999..724b5fc2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -194,8 +194,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { protected: static constexpr libinput_interface kLibinputInterface = { - .open_restricted = [](const char* path, int flags, - void* user_data) -> int { + .open_restricted = + [](const char* path, int flags, void* user_data) -> int { auto ret = open(path, flags | O_CLOEXEC); if (ret == -1) { ELINUX_LOG(ERROR) @@ -275,7 +275,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return true; } - static int OnUdevDrmEvent(sd_event_source* source, int fd, uint32_t revents, + static int OnUdevDrmEvent(sd_event_source* source, + int fd, + uint32_t revents, void* data) { auto self = reinterpret_cast(data); auto device = udev_monitor_receive_device(self->udev_monitor_); @@ -326,7 +328,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return std::strcmp(value, kPropertyOn) == 0; } - static int OnLibinputEvent(sd_event_source* source, int fd, uint32_t revents, + static int OnLibinputEvent(sd_event_source* source, + int fd, + uint32_t revents, void* data) { auto self = reinterpret_cast(data); auto ret = libinput_dispatch(self->libinput_); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 98751f61..c196131d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -43,8 +43,11 @@ constexpr char kClipboardMimeTypeText[] = "text/plain"; const wl_registry_listener ELinuxWindowWayland::kWlRegistryListener = { .global = - [](void* data, wl_registry* wl_registry, uint32_t name, - const char* interface, uint32_t version) { + [](void* data, + wl_registry* wl_registry, + uint32_t name, + const char* interface, + uint32_t version) { auto self = reinterpret_cast(data); self->WlRegistryHandler(wl_registry, name, interface, version); }, @@ -56,7 +59,8 @@ const wl_registry_listener ELinuxWindowWayland::kWlRegistryListener = { }; const xdg_wm_base_listener ELinuxWindowWayland::kXdgWmBaseListener = { - .ping = [](void* data, xdg_wm_base* xdg_wm_base, + .ping = [](void* data, + xdg_wm_base* xdg_wm_base, uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); }, }; @@ -81,8 +85,11 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { .configure = - [](void* data, xdg_toplevel* xdg_toplevel, int32_t width, - int32_t height, wl_array* states) { + [](void* data, + xdg_toplevel* xdg_toplevel, + int32_t width, + int32_t height, + wl_array* states) { auto is_maximized = false; auto is_resizing = false; uint32_t* state = static_cast(states->data); @@ -154,8 +161,12 @@ const wp_presentation_feedback_listener .presented = [](void* data, struct wp_presentation_feedback* wp_presentation_feedback, - uint32_t tv_sec_hi, uint32_t tv_sec_lo, uint32_t tv_nsec, - uint32_t refresh, uint32_t seq_hi, uint32_t seq_lo, + uint32_t tv_sec_hi, + uint32_t tv_sec_lo, + uint32_t tv_nsec, + uint32_t refresh, + uint32_t seq_hi, + uint32_t seq_lo, uint32_t flags) { auto self = reinterpret_cast(data); self->last_frame_time_nanos_ = @@ -233,8 +244,11 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { }; const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { - .enter = [](void* data, wl_pointer* wl_pointer, uint32_t serial, - wl_surface* surface, wl_fixed_t surface_x, + .enter = [](void* data, + wl_pointer* wl_pointer, + uint32_t serial, + wl_surface* surface, + wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); self->wl_current_surface_ = surface; @@ -253,7 +267,9 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->pointer_y_ = y; } }, - .leave = [](void* data, wl_pointer* pointer, uint32_t serial, + .leave = [](void* data, + wl_pointer* pointer, + uint32_t serial, wl_surface* surface) -> void { auto self = reinterpret_cast(data); self->wl_current_surface_ = surface; @@ -265,8 +281,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->pointer_y_ = -1; } }, - .motion = [](void* data, wl_pointer* pointer, uint32_t time, - wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + .motion = [](void* data, + wl_pointer* pointer, + uint32_t time, + wl_fixed_t surface_x, + wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); @@ -276,8 +295,12 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->pointer_y_ = y; } }, - .button = [](void* data, wl_pointer* pointer, uint32_t serial, - uint32_t time, uint32_t button, uint32_t status) -> void { + .button = [](void* data, + wl_pointer* pointer, + uint32_t serial, + uint32_t time, + uint32_t button, + uint32_t status) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; @@ -360,7 +383,10 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { } } }, - .axis = [](void* data, wl_pointer* wl_pointer, uint32_t time, uint32_t axis, + .axis = [](void* data, + wl_pointer* wl_pointer, + uint32_t time, + uint32_t axis, wl_fixed_t value) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { @@ -376,8 +402,13 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { }; const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { - .down = [](void* data, wl_touch* wl_touch, uint32_t serial, uint32_t time, - wl_surface* surface, int32_t id, wl_fixed_t surface_x, + .down = [](void* data, + wl_touch* wl_touch, + uint32_t serial, + uint32_t time, + wl_surface* surface, + int32_t id, + wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; @@ -387,7 +418,10 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { self->binding_handler_delegate_->OnTouchDown(time, id, x, y); } }, - .up = [](void* data, wl_touch* wl_touch, uint32_t serial, uint32_t time, + .up = [](void* data, + wl_touch* wl_touch, + uint32_t serial, + uint32_t time, int32_t id) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; @@ -395,8 +429,12 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { self->binding_handler_delegate_->OnTouchUp(time, id); } }, - .motion = [](void* data, wl_touch* wl_touch, uint32_t time, int32_t id, - wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + .motion = [](void* data, + wl_touch* wl_touch, + uint32_t time, + int32_t id, + wl_fixed_t surface_x, + wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); @@ -414,7 +452,10 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { }; const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { - .keymap = [](void* data, wl_keyboard* wl_keyboard, uint32_t format, int fd, + .keymap = [](void* data, + wl_keyboard* wl_keyboard, + uint32_t format, + int fd, uint32_t size) -> void { auto self = reinterpret_cast(data); assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); @@ -422,18 +463,27 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { self->binding_handler_delegate_->OnKeyMap(format, fd, size); } }, - .enter = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, - wl_surface* surface, wl_array* keys) -> void { + .enter = [](void* data, + wl_keyboard* wl_keyboard, + uint32_t serial, + wl_surface* surface, + wl_array* keys) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; }, - .leave = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, + .leave = [](void* data, + wl_keyboard* wl_keyboard, + uint32_t serial, wl_surface* surface) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; }, - .key = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, - uint32_t time, uint32_t key, uint32_t state) -> void { + .key = [](void* data, + wl_keyboard* wl_keyboard, + uint32_t serial, + uint32_t time, + uint32_t key, + uint32_t state) -> void { auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { @@ -441,26 +491,40 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { key, state == WL_KEYBOARD_KEY_STATE_PRESSED); } }, - .modifiers = [](void* data, wl_keyboard* wl_keyboard, uint32_t serial, - uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) -> void { + .modifiers = [](void* data, + wl_keyboard* wl_keyboard, + uint32_t serial, + uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnKeyModifiers( mods_depressed, mods_latched, mods_locked, group); } }, - .repeat_info = [](void* data, wl_keyboard* wl_keyboard, int rate, - int delay) -> void {}, + .repeat_info = [](void* data, wl_keyboard* wl_keyboard, int rate, int delay) + -> void {}, }; const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { - .geometry = [](void* data, wl_output* wl_output, int32_t x, int32_t y, - int32_t physical_width, int32_t physical_height, - int32_t subpixel, const char* make, const char* model, + .geometry = [](void* data, + wl_output* wl_output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char* make, + const char* model, int32_t output_transform) -> void {}, - .mode = [](void* data, wl_output* wl_output, uint32_t flags, int32_t width, - int32_t height, int32_t refresh) -> void { + .mode = [](void* data, + wl_output* wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh) -> void { auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { ELINUX_LOG(INFO) << "Display output info: width = " << width @@ -496,7 +560,8 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = { - .enter = [](void* data, zwp_text_input_v1* zwp_text_input_v1, + .enter = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, wl_surface* surface) -> void { auto self = reinterpret_cast(data); // If there is no input data, the backspace key cannot be used, @@ -512,13 +577,16 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = zwp_text_input_v1_hide_input_panel(self->zwp_text_input_v1_); } }, - .modifiers_map = [](void* data, zwp_text_input_v1* zwp_text_input_v1, + .modifiers_map = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, wl_array* map) -> void {}, .input_panel_state = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t state) -> void {}, - .preedit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t serial, const char* text, + .preedit_string = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t serial, + const char* text, const char* commit) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { @@ -532,13 +600,18 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = " ", 1, 1); } }, - .preedit_styling = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t index, uint32_t length, + .preedit_styling = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t index, + uint32_t length, uint32_t style) -> void {}, - .preedit_cursor = [](void* data, zwp_text_input_v1* zwp_text_input_v1, + .preedit_cursor = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, int32_t index) -> void {}, - .commit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t serial, const char* text) -> void { + .commit_string = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t serial, + const char* text) -> void { // commit_string is notified only when the space key is pressed. auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { @@ -551,11 +624,14 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = " ", 1, 1); } }, - .cursor_position = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - int32_t index, int32_t anchor) -> void {}, + .cursor_position = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + int32_t index, + int32_t anchor) -> void {}, .delete_surrounding_text = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - int32_t index, uint32_t length) -> void { + int32_t index, + uint32_t length) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnVirtualSpecialKey(KEY_BACKSPACE); @@ -567,9 +643,13 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = " ", 1, 1); } }, - .keysym = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t serial, uint32_t time, uint32_t sym, - uint32_t state, uint32_t modifiers) -> void { + .keysym = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t serial, + uint32_t time, + uint32_t sym, + uint32_t state, + uint32_t modifiers) -> void { auto self = reinterpret_cast(data); if ((state == WL_KEYBOARD_KEY_STATE_PRESSED) && (self->binding_handler_delegate_)) { @@ -597,15 +677,20 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = } } }, - .language = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t serial, const char* language) -> void {}, - .text_direction = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t serial, uint32_t direction) -> void {}, + .language = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t serial, + const char* language) -> void {}, + .text_direction = [](void* data, + zwp_text_input_v1* zwp_text_input_v1, + uint32_t serial, + uint32_t direction) -> void {}, }; const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = { - .enter = [](void* data, zwp_text_input_v3* zwp_text_input_v3, + .enter = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, wl_surface* surface) -> void { // To appear the on-screen keyboard when the user returns to a Flutter // app which needs to show the on-screen keyboard. @@ -614,36 +699,51 @@ const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = self->ShowVirtualKeyboard(); } }, - .leave = [](void* data, zwp_text_input_v3* zwp_text_input_v3, + .leave = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, wl_surface* surface) -> void {}, - .preedit_string = [](void* data, zwp_text_input_v3* zwp_text_input_v3, - const char* text, int32_t cursor_begin, + .preedit_string = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, + const char* text, + int32_t cursor_begin, int32_t cursor_end) -> void {}, - .commit_string = [](void* data, zwp_text_input_v3* zwp_text_input_v3, + .commit_string = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, const char* text) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); } }, - .delete_surrounding_text = - [](void* data, zwp_text_input_v3* zwp_text_input_v3, - uint32_t before_length, uint32_t after_length) -> void {}, - .done = [](void* data, zwp_text_input_v3* zwp_text_input_v3, + .delete_surrounding_text = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, + uint32_t before_length, + uint32_t after_length) -> void {}, + .done = [](void* data, + zwp_text_input_v3* zwp_text_input_v3, uint32_t serial) -> void {}, }; const wl_data_device_listener ELinuxWindowWayland::kWlDataDeviceListener = { - .data_offer = [](void* data, wl_data_device* wl_data_device, + .data_offer = [](void* data, + wl_data_device* wl_data_device, wl_data_offer* offer) -> void {}, - .enter = [](void* data, wl_data_device* wl_data_device, uint32_t serial, - wl_surface* surface, wl_fixed_t x, wl_fixed_t y, + .enter = [](void* data, + wl_data_device* wl_data_device, + uint32_t serial, + wl_surface* surface, + wl_fixed_t x, + wl_fixed_t y, wl_data_offer* offer) -> void {}, .leave = [](void* data, wl_data_device* wl_data_device) -> void {}, - .motion = [](void* data, wl_data_device* wl_data_device, uint32_t time, - wl_fixed_t x, wl_fixed_t y) -> void {}, + .motion = [](void* data, + wl_data_device* wl_data_device, + uint32_t time, + wl_fixed_t x, + wl_fixed_t y) -> void {}, .drop = [](void* data, wl_data_device* wl_data_device) -> void {}, - .selection = [](void* data, wl_data_device* wl_data_device, + .selection = [](void* data, + wl_data_device* wl_data_device, wl_data_offer* offer) -> void { auto self = reinterpret_cast(data); if (self->wl_data_offer_) { @@ -654,10 +754,13 @@ const wl_data_device_listener ELinuxWindowWayland::kWlDataDeviceListener = { }; const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { - .target = [](void* data, wl_data_source* wl_data_source, + .target = [](void* data, + wl_data_source* wl_data_source, const char* mime_type) -> void {}, - .send = [](void* data, wl_data_source* wl_data_source, - const char* mime_type, int32_t fd) -> void { + .send = [](void* data, + wl_data_source* wl_data_source, + const char* mime_type, + int32_t fd) -> void { if (strcmp(mime_type, kClipboardMimeTypeText)) { ELINUX_LOG(ERROR) << "Not expected mime_type: " << mime_type; return; @@ -679,7 +782,8 @@ const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { .dnd_drop_performed = [](void* data, wl_data_source* wl_data_source) -> void {}, .dnd_finished = [](void* data, wl_data_source* wl_data_source) -> void {}, - .action = [](void* data, wl_data_source* wl_data_source, + .action = [](void* data, + wl_data_source* wl_data_source, uint32_t dnd_action) -> void {}, }; @@ -892,13 +996,17 @@ ELinuxRenderSurfaceTarget* ELinuxWindowWayland::GetRenderSurfaceTarget() const { return render_surface_.get(); } -double ELinuxWindowWayland::GetDpiScale() { return current_scale_; } +double ELinuxWindowWayland::GetDpiScale() { + return current_scale_; +} PhysicalWindowBounds ELinuxWindowWayland::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } -int32_t ELinuxWindowWayland::GetFrameRate() { return frame_rate_; } +int32_t ELinuxWindowWayland::GetFrameRate() { + return frame_rate_; +} bool ELinuxWindowWayland::DispatchEvent() { if (!IsValid()) { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 1eb19012..5a73232e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -80,8 +80,10 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_pointer* pointer; }; - void WlRegistryHandler(wl_registry* wl_registry, uint32_t name, - const char* interface, uint32_t version); + void WlRegistryHandler(wl_registry* wl_registry, + uint32_t name, + const char* interface, + uint32_t version); void WlUnRegistryHandler(wl_registry* wl_registry, uint32_t name); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 868dccfc..3d475888 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -143,13 +143,17 @@ ELinuxRenderSurfaceTarget* ELinuxWindowX11::GetRenderSurfaceTarget() const { return render_surface_.get(); } -double ELinuxWindowX11::GetDpiScale() { return current_scale_; } +double ELinuxWindowX11::GetDpiScale() { + return current_scale_; +} PhysicalWindowBounds ELinuxWindowX11::GetPhysicalWindowBounds() { return {GetCurrentWidth(), GetCurrentHeight()}; } -int32_t ELinuxWindowX11::GetFrameRate() { return 60000; } +int32_t ELinuxWindowX11::GetFrameRate() { + return 60000; +} void ELinuxWindowX11::UpdateFlutterCursor(const std::string& cursor_name) { // TODO: implement here @@ -159,14 +163,17 @@ void ELinuxWindowX11::UpdateVirtualKeyboardStatus(const bool show) { // currently not supported. } -std::string ELinuxWindowX11::GetClipboardData() { return clipboard_data_; } +std::string ELinuxWindowX11::GetClipboardData() { + return clipboard_data_; +} void ELinuxWindowX11::SetClipboardData(const std::string& data) { clipboard_data_ = data; } void ELinuxWindowX11::HandlePointerButtonEvent(uint32_t button, - bool button_pressed, int16_t x, + bool button_pressed, + int16_t x, int16_t y) { if (binding_handler_delegate_) { FlutterPointerMouseButtons flutter_button; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 2a972fb5..7eb73262 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -60,7 +60,9 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { private: // Handles the events of the mouse button. - void HandlePointerButtonEvent(uint32_t button, bool button_pressed, int16_t x, + void HandlePointerButtonEvent(uint32_t button, + bool button_pressed, + int16_t x, int16_t y); // A pointer to a FlutterWindowsView that can be used to update engine diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index e2c96270..4ec29050 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -25,7 +25,8 @@ class NativeWindowDrm : public NativeWindow { virtual bool ShowCursor(double x, double y) = 0; - virtual bool UpdateCursor(const std::string& cursor_name, double x, + virtual bool UpdateCursor(const std::string& cursor_name, + double x, double y) = 0; virtual bool DismissCursor() = 0; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc index b5449ae5..b762321a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc @@ -70,7 +70,8 @@ bool NativeWindowDrmEglstream::ShowCursor(double x, double y) { } bool NativeWindowDrmEglstream::UpdateCursor(const std::string& cursor_name, - double x, double y) { + double x, + double y) { if (cursor_name.compare(cursor_name_) == 0) { return true; } @@ -162,7 +163,8 @@ uint32_t NativeWindowDrmEglstream::FindPrimaryPlaneId( return -1; } -uint64_t NativeWindowDrmEglstream::GetPropertyValue(uint32_t id, uint32_t type, +uint64_t NativeWindowDrmEglstream::GetPropertyValue(uint32_t id, + uint32_t type, const char* prop_name) { uint64_t value = -1; auto properties = drmModeObjectGetProperties(drm_device_, id, type); @@ -233,7 +235,9 @@ bool NativeWindowDrmEglstream::AssignAtomicRequest(drmModeAtomicReqPtr atomic) { template bool NativeWindowDrmEglstream::AssignAtomicPropertyValue( - drmModeAtomicReqPtr atomic, uint32_t id, uint32_t type, + drmModeAtomicReqPtr atomic, + uint32_t id, + uint32_t type, NativeWindowDrmEglstream::DrmProperty (&table)[N]) { auto properties = drmModeObjectGetProperties(drm_device_, id, type); if (properties) { diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h index cd998fc5..994dfe38 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h @@ -23,7 +23,8 @@ class NativeWindowDrmEglstream : public NativeWindowDrm { bool ShowCursor(double x, double y) override; // |NativeWindowDrm| - bool UpdateCursor(const std::string& cursor_name, double x, + bool UpdateCursor(const std::string& cursor_name, + double x, double y) override; // |NativeWindowDrm| @@ -55,7 +56,9 @@ class NativeWindowDrmEglstream : public NativeWindowDrm { template bool AssignAtomicPropertyValue( - drmModeAtomicReqPtr atomic, uint32_t id, uint32_t type, + drmModeAtomicReqPtr atomic, + uint32_t id, + uint32_t type, NativeWindowDrmEglstream::DrmProperty (&table)[N]); uint32_t drm_plane_id_; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index 8775bb99..a24443a7 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -92,7 +92,8 @@ bool NativeWindowDrmGbm::ShowCursor(double x, double y) { return true; } -bool NativeWindowDrmGbm::UpdateCursor(const std::string& cursor_name, double x, +bool NativeWindowDrmGbm::UpdateCursor(const std::string& cursor_name, + double x, double y) { if (cursor_name.compare(cursor_name_) == 0) { return true; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h index f30113b2..0a062273 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h @@ -24,7 +24,8 @@ class NativeWindowDrmGbm : public NativeWindowDrm { bool ShowCursor(double x, double y) override; // |NativeWindowDrm| - bool UpdateCursor(const std::string& cursor_name, double x, + bool UpdateCursor(const std::string& cursor_name, + double x, double y) override; // |NativeWindowDrm| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h index c8cc41d2..5688058f 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h @@ -13,7 +13,8 @@ namespace flutter { class NativeWindowWayland : public NativeWindow { public: - NativeWindowWayland(wl_compositor* compositor, const size_t width, + NativeWindowWayland(wl_compositor* compositor, + const size_t width, const size_t height); ~NativeWindowWayland(); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc index 063d9143..20486eee 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -9,8 +9,11 @@ namespace flutter { NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( - wl_compositor* compositor, wl_subcompositor* subcompositor, - wl_surface* parent_surface, const size_t width, const size_t height) { + wl_compositor* compositor, + wl_subcompositor* subcompositor, + wl_surface* parent_surface, + const size_t width, + const size_t height) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h index 4670d8bd..d270c338 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -16,7 +16,8 @@ class NativeWindowWaylandDecoration : public NativeWindow { public: NativeWindowWaylandDecoration(wl_compositor* compositor, wl_subcompositor* subcompositor, - wl_surface* parent_surface, const size_t width, + wl_surface* parent_surface, + const size_t width, const size_t height); ~NativeWindowWaylandDecoration(); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc index 310d7b47..05374de3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc @@ -19,8 +19,10 @@ static constexpr char kWmDeleteWindow[] = "WM_DELETE_WINDOW"; static constexpr char kWindowTitle[] = "Flutter for Embedded Linux"; } // namespace -NativeWindowX11::NativeWindowX11(Display* display, VisualID visual_id, - const size_t width, const size_t height) { +NativeWindowX11::NativeWindowX11(Display* display, + VisualID visual_id, + const size_t width, + const size_t height) { XVisualInfo visualTemplate; visualTemplate.visualid = visual_id; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h index 4a77c2c3..03afa8c3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h @@ -13,7 +13,9 @@ namespace flutter { class NativeWindowX11 : public NativeWindow { public: - NativeWindowX11(Display* display, VisualID visual_id, const size_t width, + NativeWindowX11(Display* display, + VisualID visual_id, + const size_t width, const size_t height); ~NativeWindowX11() = default; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index 1c8cdb7d..35af9d04 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -18,8 +18,11 @@ constexpr uint kButtonMargin = 10; } // namespace WindowDecorationsWayland::WindowDecorationsWayland( - wl_display* display, wl_compositor* compositor, - wl_subcompositor* subcompositor, wl_surface* root_surface, int32_t width, + wl_display* display, + wl_compositor* compositor, + wl_subcompositor* subcompositor, + wl_surface* root_surface, + int32_t width, int32_t height) { constexpr bool sub_egl_display = true; @@ -114,6 +117,8 @@ void WindowDecorationsWayland::DestroyContext() { } } -int32_t WindowDecorationsWayland::Height() const { return kTitleBarHeight; } +int32_t WindowDecorationsWayland::Height() const { + return kTitleBarHeight; +} } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 4b71350b..607d0c3e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -26,9 +26,11 @@ namespace flutter { class WindowDecorationsWayland { public: - WindowDecorationsWayland(wl_display* display, wl_compositor* compositor, + WindowDecorationsWayland(wl_display* display, + wl_compositor* compositor, wl_subcompositor* subcompositor, - wl_surface* root_surface, int32_t width, + wl_surface* root_surface, + int32_t width, int32_t height); ~WindowDecorationsWayland(); diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index 1984a53b..73f1330d 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -21,12 +21,14 @@ class WindowBindingHandlerDelegate { // Notifies delegate that backing window mouse pointer button has been // pressed. Typically called by currently configured WindowBindingHandler - virtual void OnPointerDown(double x, double y, + virtual void OnPointerDown(double x, + double y, FlutterPointerMouseButtons button) = 0; // Notifies delegate that backing window mouse pointer button has been // released. Typically called by currently configured WindowBindingHandler - virtual void OnPointerUp(double x, double y, + virtual void OnPointerUp(double x, + double y, FlutterPointerMouseButtons button) = 0; // Notifies delegate that backing window mouse pointer has left the window. @@ -65,8 +67,10 @@ class WindowBindingHandlerDelegate { // Notifies delegate that backing window key has been modifired. // Typically called by currently configured WindowBindingHandler - virtual void OnKeyModifiers(uint32_t mods_depressed, uint32_t mods_latched, - uint32_t mods_locked, uint32_t group) = 0; + virtual void OnKeyModifiers(uint32_t mods_depressed, + uint32_t mods_latched, + uint32_t mods_locked, + uint32_t group) = 0; // Notifies delegate that backing window key has been pressed. // Typically called by currently configured WindowBindingHandler @@ -82,7 +86,10 @@ class WindowBindingHandlerDelegate { // Notifies delegate that backing window size has recevied scroll. // Typically called by currently configured WindowBindingHandler - virtual void OnScroll(double x, double y, double delta_x, double delta_y, + virtual void OnScroll(double x, + double y, + double delta_x, + double delta_y, int scroll_offset_multiplier) = 0; // Notifies delegate that backing window vsync has happened. From 129937a80600a2c90f8488505c77648e937b8cb2 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 9 Nov 2021 11:01:27 +0900 Subject: [PATCH 069/178] Revert: Fix synchronized frame on Wayland (#221) (#235) * Revert: Fix synchronized frame on Wayland (#221) --- .../platform/linux_embedded/surface/elinux_egl_surface.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index b47567f9..8a758174 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -35,8 +35,14 @@ bool ELinuxEGLSurface::MakeCurrent() const { return false; } -#if defined(DISPLAY_BACKEND_TYPE_WAYLAND) +#if defined(ENABLE_EGL_ASYNC_BUFFER_SWAPPING) // Non-blocking when swappipping buffers on Wayland. + // However, we might encounter rendering problems on some Wayland compositors + // (e.g. weston 9.0) when we use them. + // See also: + // - https://github.com/sony/flutter-embedded-linux/issues/230 + // - https://github.com/sony/flutter-embedded-linux/issues/234 + // - https://github.com/sony/flutter-embedded-linux/issues/220 if (eglSwapInterval(display_, 0) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to eglSwapInterval(Free): " << get_egl_error_cause(); From f2e6dec6c4a99610834976b09487368346346366 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 25 Nov 2021 14:05:58 +0900 Subject: [PATCH 070/178] Merge common shared cpp source files 11/25/2021 (#238) * Merged from - https://github.com/flutter/engine/commit/eac4cd2817d764dfa5d84b3d94b9c71d8e2b1787#diff-338cf9d4ad1b92f8828c57038f18706f6762fa2a9aec81e21ce07d1d1cd41508 - https://github.com/flutter/engine/commit/29ea28d67b2d4c9cad0add3cfb9d0c6171146aa1 --- .../common/client_wrapper/include/flutter/encodable_value.h | 3 +++ .../client_wrapper/include/flutter/engine_method_result.h | 2 +- .../common/client_wrapper/include/flutter/texture_registrar.h | 2 +- .../shell/platform/common/client_wrapper/standard_codec.cc | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h index dec1bdfc..3b46f99f 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h @@ -63,7 +63,9 @@ class CustomEncodableValue { ~CustomEncodableValue() = default; // Allow implicit conversion to std::any to allow direct use of any_cast. + // NOLINTNEXTLINE(google-explicit-constructor) operator std::any&() { return value_; } + // NOLINTNEXTLINE(google-explicit-constructor) operator const std::any&() const { return value_; } #if defined(FLUTTER_ENABLE_RTTI) && FLUTTER_ENABLE_RTTI @@ -182,6 +184,7 @@ class EncodableValue : public internal::EncodableValueVariant { // to use it with EncodableValue, so the risk of unintended conversions is // minimal, and it avoids the need for the verbose: // EncodableValue(CustomEncodableValue(...)). + // NOLINTNEXTLINE(google-explicit-constructor) EncodableValue(const CustomEncodableValue& v) : super(v) {} // Override the conversion constructors from std::variant to make them diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/engine_method_result.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/engine_method_result.h index c29ff09b..3cc8b6a2 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/engine_method_result.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/engine_method_result.h @@ -21,7 +21,7 @@ namespace internal { // vary based on the template type. class ReplyManager { public: - ReplyManager(BinaryReply reply_handler_); + explicit ReplyManager(BinaryReply reply_handler_); ~ReplyManager(); // Prevent copying. diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 5b59829f..6aa2c6b1 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -27,7 +27,7 @@ class PixelBufferTexture { // As the callback is usually invoked from the render thread, the callee must // take care of proper synchronization. It also needs to be ensured that the // returned buffer isn't released prior to unregistering this texture. - PixelBufferTexture(CopyBufferCallback copy_buffer_callback) + explicit PixelBufferTexture(CopyBufferCallback copy_buffer_callback) : copy_buffer_callback_(copy_buffer_callback) {} // Returns the callback-provided FlutterDesktopPixelBuffer that contains the diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index f16a0f97..807e0681 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -231,11 +231,11 @@ size_t StandardCodecSerializer::ReadSize(ByteStreamReader* stream) const { if (byte < 254) { return byte; } else if (byte == 254) { - uint16_t value; + uint16_t value = 0; stream->ReadBytes(reinterpret_cast(&value), 2); return value; } else { - uint32_t value; + uint32_t value = 0; stream->ReadBytes(reinterpret_cast(&value), 4); return value; } From f96b35c56310eac57e3d7954cfd0b8568e4da01c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 2 Dec 2021 15:26:05 +0900 Subject: [PATCH 071/178] [drm] Fix: mouse cursor is visible even when no mouse is connected (#239) Fixed https://github.com/sony/flutter-embedded-linux/issues/237 --- .../linux_embedded/window/elinux_window_drm.h | 76 ++++++++++++++++--- 1 file changed, 64 insertions(+), 12 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 724b5fc2..3d916446 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -11,7 +11,9 @@ #include #include +#include #include +#include #include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" @@ -400,23 +402,36 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnDeviceAdded(libinput_event* event) { auto device = libinput_event_get_device(event); - if (view_properties_.use_mouse_cursor && - libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) { - // When launching the application, either route will be used depending on - // the timing. - if (native_window_) { - native_window_->ShowCursor(pointer_x_, pointer_y_); - } else { - is_pending_cursor_add_event_ = true; - } - } + auto device_data = std::make_unique(); + size_t timestamp = + std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); + + device_data->id = timestamp; + device_data->is_pointer_device = false; + libinput_device_set_user_data(device, device_data.get()); + libinput_devices_[timestamp] = std::move(device_data); } void OnDeviceRemoved(libinput_event* event) { auto device = libinput_event_get_device(event); + auto device_data = reinterpret_cast( + libinput_device_get_user_data(device)); + if (view_properties_.use_mouse_cursor && libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER)) { - native_window_->DismissCursor(); + if (device_data && device_data->is_pointer_device) { + if (--libinput_pointer_devices_ == 0) { + native_window_->DismissCursor(); + } + } + } + + if (device_data) { + if (libinput_devices_.count(device_data->id) > 0) { + libinput_devices_.erase(libinput_devices_.find(device_data->id)); + } } } @@ -432,6 +447,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerMotion(libinput_event* event) { + DetectPointerDevice(event); if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); auto dx = libinput_event_pointer_get_dx(pointer_event); @@ -453,6 +469,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerMotionAbsolute(libinput_event* event) { + DetectPointerDevice(event); if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); auto x = libinput_event_pointer_get_absolute_x_transformed( @@ -467,6 +484,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerButton(libinput_event* event) { + DetectPointerDevice(event); if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); auto button = libinput_event_pointer_get_button(pointer_event); @@ -505,6 +523,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerAxis(libinput_event* event) { + DetectPointerDevice(event); if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); if (libinput_event_pointer_has_axis( @@ -520,6 +539,32 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } } + void DetectPointerDevice(libinput_event* event) { + auto device = libinput_event_get_device(event); + auto device_data = reinterpret_cast( + libinput_device_get_user_data(device)); + + // Shows the mouse cursor only when connecting mouse devices. + // The mouse cursor is not displayed by touch inputs. + if (device_data && !device_data->is_pointer_device) { + device_data->is_pointer_device = true; + libinput_pointer_devices_++; + ShowMouseCursor(); + } + } + + void ShowMouseCursor() { + if (view_properties_.use_mouse_cursor && libinput_pointer_devices_ == 1) { + // When launching the application, either route will be used depending on + // the timing. + if (native_window_) { + native_window_->ShowCursor(pointer_x_, pointer_y_); + } else { + is_pending_cursor_add_event_ = true; + } + } + } + void OnTouchDown(libinput_event* event) { if (binding_handler_delegate_) { auto touch_event = libinput_event_get_touch_event(event); @@ -592,6 +637,11 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { kScrollOffsetMultiplier); } + struct LibinputDeviceData { + size_t id; + bool is_pointer_device; + }; + // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr; @@ -601,9 +651,11 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { bool display_valid_; bool is_pending_cursor_add_event_; - sd_event* libinput_event_loop_; libinput* libinput_; + std::unordered_map> + libinput_devices_; + int libinput_pointer_devices_ = 0; sd_event* udev_drm_event_loop_ = nullptr; udev_monitor* udev_monitor_ = nullptr; From 9dec787a64077ba99a229bad0adbb69c52ee874e Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 9 Dec 2021 11:08:12 +0900 Subject: [PATCH 072/178] Merge the latest embedder (v.2.8.0) (#242) Update for v 2.8.0 --- .../shell/platform/embedder/embedder.h | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 0a63b558..e8b769ef 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -313,6 +313,7 @@ typedef bool (*TextureFrameCallback)(void* /* user data */, size_t /* height */, FlutterOpenGLTexture* /* texture out */); typedef void (*VsyncCallback)(void* /* user data */, intptr_t /* baton */); +typedef void (*OnPreEngineRestartCallback)(void* /* user data */); /// A structure to represent the width and height. typedef struct { @@ -371,7 +372,7 @@ typedef uint32_t (*UIntFrameInfoCallback)( /// /// See: \ref FlutterOpenGLRendererConfig.present_with_info. typedef struct { - /// The size of this struct. Must be sizeof(FlutterFrameInfo). + /// The size of this struct. Must be sizeof(FlutterPresentInfo). size_t struct_size; /// Id of the fbo backing the surface that was presented. uint32_t fbo_id; @@ -1394,9 +1395,10 @@ typedef struct { /// `switches.h` engine source file. const char* const* command_line_argv; /// The callback invoked by the engine in order to give the embedder the - /// chance to respond to platform messages from the Dart application. The - /// callback will be invoked on the thread on which the `FlutterEngineRun` - /// call is made. + /// chance to respond to platform messages from the Dart application. + /// The callback will be invoked on the thread on which the `FlutterEngineRun` + /// call is made. The second parameter, `user_data`, is supplied when + /// `FlutterEngineRun` or `FlutterEngineInitialize` is called. FlutterPlatformMessageCallback platform_message_callback; /// The VM snapshot data buffer used in AOT operation. This buffer must be /// mapped in as read-only. For more information refer to the documentation on @@ -1577,6 +1579,16 @@ typedef struct { // or component name to embedder's logger. This string will be passed to to // callbacks on `log_message_callback`. Defaults to "flutter" if unspecified. const char* log_tag; + + // A callback that is invoked right before the engine is restarted. + // + // This optional callback is typically used to reset states to as if the + // engine has just been started, and usually indicates the user has requested + // a hot restart (Shift-R in the Flutter CLI.) It is not called the first time + // the engine starts. + // + // The first argument is the `user_data` from `FlutterEngineInitialize`. + OnPreEngineRestartCallback on_pre_engine_restart_callback; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES From 7e390a500dc4be92d52c7d13d5b061ecce0422ca Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 21 Feb 2022 14:38:59 +0900 Subject: [PATCH 073/178] Add window rotation support (#250) See https://github.com/sony/flutter-embedded-linux/issues/248 --- .../command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- .../flutter-drm-eglstream-backend/main.cc | 1 + .../flutter-drm-gbm-backend/command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- examples/flutter-drm-gbm-backend/main.cc | 1 + .../command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- .../flutter-external-texture-plugin/main.cc | 1 + .../command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- examples/flutter-video-player-plugin/main.cc | 1 + .../flutter-wayland-client/command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- examples/flutter-wayland-client/main.cc | 1 + examples/flutter-x11-client/command_options.h | 62 +++++++++---- .../flutter_embedder_options.h | 40 ++++++-- examples/flutter-x11-client/main.cc | 1 + src/client_wrapper/flutter_view_controller.cc | 8 ++ .../include/flutter/flutter_view_controller.h | 14 +++ .../linux_embedded/flutter_elinux_engine.cc | 5 + .../linux_embedded/flutter_elinux_view.cc | 91 ++++++++++++++++--- .../linux_embedded/flutter_elinux_view.h | 13 +++ .../linux_embedded/public/flutter_elinux.h | 15 +++ .../linux_embedded/window/elinux_window.h | 13 +++ .../linux_embedded/window/elinux_window_drm.h | 21 ++++- .../window/elinux_window_wayland.cc | 16 ++++ .../window/elinux_window_wayland.h | 3 + .../window/elinux_window_x11.cc | 22 ++++- .../linux_embedded/window/elinux_window_x11.h | 3 + .../linux_embedded/window_binding_handler.h | 3 + 31 files changed, 675 insertions(+), 170 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/command_options.h b/examples/flutter-drm-eglstream-backend/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-drm-eglstream-backend/command_options.h +++ b/examples/flutter-drm-eglstream-backend/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-drm-gbm-backend/command_options.h b/examples/flutter-drm-gbm-backend/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-drm-gbm-backend/command_options.h +++ b/examples/flutter-drm-gbm-backend/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-external-texture-plugin/command_options.h b/examples/flutter-external-texture-plugin/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-external-texture-plugin/command_options.h +++ b/examples/flutter-external-texture-plugin/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-video-player-plugin/command_options.h b/examples/flutter-video-player-plugin/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-video-player-plugin/command_options.h +++ b/examples/flutter-video-player-plugin/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-wayland-client/command_options.h b/examples/flutter-wayland-client/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-wayland-client/command_options.h +++ b/examples/flutter-wayland-client/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-x11-client/command_options.h b/examples/flutter-x11-client/command_options.h index 977cdc83..107a152d 100644 --- a/examples/flutter-x11-client/command_options.h +++ b/examples/flutter-x11-client/command_options.h @@ -39,30 +39,40 @@ class CommandOptions { CommandOptions() = default; ~CommandOptions() = default; - void AddWithoutValue(const std::string& name, const std::string& short_name, - const std::string& description, bool required) { + void AddWithoutValue(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required) { Add(name, short_name, description, "", ReaderString(), required, false); } - void AddInt(const std::string& name, const std::string& short_name, - const std::string& description, const int& default_value, + void AddInt(const std::string& name, + const std::string& short_name, + const std::string& description, + const int& default_value, bool required) { Add(name, short_name, description, default_value, ReaderInt(), required, true); } - void AddString(const std::string& name, const std::string& short_name, + void AddString(const std::string& name, + const std::string& short_name, const std::string& description, - const std::string& default_value, bool required) { + const std::string& default_value, + bool required) { Add(name, short_name, description, default_value, ReaderString(), required, true); } template - void Add(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader = F(), bool required = true, bool required_value = true) { + void Add(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader = F(), + bool required = true, + bool required_value = true) { if (options_.find(name) != options_.end()) { std::cerr << "Already registered option: " << name << std::endl; return; @@ -213,7 +223,7 @@ class CommandOptions { } size_t index_adjust = 0; - constexpr int kSpacerNum = 5; + constexpr int kSpacerNum = 10; auto need_value = registration_order_options_[i]->IsRequiredValue(); ostream << kOptionStyleNormal << registration_order_options_[i]->GetName(); @@ -242,8 +252,11 @@ class CommandOptions { class Option { public: - Option(const std::string& name, const std::string& short_name, - const std::string& description, bool required, bool required_value) + Option(const std::string& name, + const std::string& short_name, + const std::string& description, + bool required, + bool required_value) : name_(name), short_name_(short_name), description_(description), @@ -288,9 +301,12 @@ class CommandOptions { template class OptionValue : public Option { public: - OptionValue(const std::string& name, const std::string& short_name, - const std::string& description, const T& default_value, - bool required, bool required_value) + OptionValue(const std::string& name, + const std::string& short_name, + const std::string& description, + const T& default_value, + bool required, + bool required_value) : Option(name, short_name, description, required, required_value), default_value_(default_value), value_(default_value){}; @@ -316,10 +332,18 @@ class CommandOptions { template class OptionValueReader : public OptionValue { public: - OptionValueReader(const std::string& name, const std::string& short_name, - const std::string& description, const T default_value, - F reader, bool required, bool required_value) - : OptionValue(name, short_name, description, default_value, required, + OptionValueReader(const std::string& name, + const std::string& short_name, + const std::string& description, + const T default_value, + F reader, + bool required, + bool required_value) + : OptionValue(name, + short_name, + description, + default_value, + required, required_value), reader_(reader) {} ~OptionValueReader() = default; diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 51e378fc..4c229135 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -14,18 +14,21 @@ class FlutterEmbedderOptions { public: FlutterEmbedderOptions() { - options_.AddString("bundle", "b", "Path to Flutter app bundle", "./bundle", - true); + options_.AddString("bundle", "b", "Path to Flutter project bundle", + "./bundle", true); options_.AddWithoutValue("no-cursor", "n", "No mouse cursor/pointer", false); + options_.AddInt("rotation", "r", + "Window rotation(degree) [0(default)|90|180|270]", 0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); @@ -33,8 +36,8 @@ class FlutterEmbedderOptions { "Enable window decorations", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); - options_.AddInt("width", "w", "Flutter app window width", 1280, false); - options_.AddInt("height", "h", "Flutter app window height", 720, false); + options_.AddInt("width", "w", "Window width", 1280, false); + options_.AddInt("height", "h", "Window height", 720, false); #endif } ~FlutterEmbedderOptions() = default; @@ -48,6 +51,26 @@ class FlutterEmbedderOptions { bundle_path_ = options_.GetValue("bundle"); use_mouse_cursor_ = !options_.Exist("no-cursor"); + if (options_.Exist("rotation")) { + switch (options_.GetValue("rotation")) { + case 90: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_90; + break; + case 180: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_180; + break; + case 270: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_270; + break; + default: + window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; + break; + } + } #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) @@ -86,6 +109,9 @@ class FlutterEmbedderOptions { } int WindowWidth() const { return window_width_; } int WindowHeight() const { return window_height_; } + flutter::FlutterViewController::ViewRotation WindowRotation() const { + return window_view_rotation_; + } private: commandline::CommandOptions options_; @@ -98,6 +124,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewMode::kNormal; int window_width_ = 1280; int window_height_ = 720; + flutter::FlutterViewController::ViewRotation window_view_rotation_ = + flutter::FlutterViewController::ViewRotation::kRotation_0; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 92a6513c..fa4e11b8 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -29,6 +29,7 @@ int main(int argc, char** argv) { view_properties.width = options.WindowWidth(); view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); + view_properties.view_rotation = options.WindowRotation(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index e7b52622..8387919d 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -17,6 +17,14 @@ FlutterViewController::FlutterViewController( FlutterDesktopViewProperties c_view_properties = {}; c_view_properties.width = view_properties.width; c_view_properties.height = view_properties.height; + c_view_properties.view_rotation = + (view_properties.view_rotation == ViewRotation::kRotation_90) + ? FlutterDesktopViewRotation::kRotation_90 + : (view_properties.view_rotation == ViewRotation::kRotation_180) + ? FlutterDesktopViewRotation::kRotation_180 + : (view_properties.view_rotation == ViewRotation::kRotation_270) + ? FlutterDesktopViewRotation::kRotation_270 + : FlutterDesktopViewRotation::kRotation_0; c_view_properties.view_mode = (view_properties.view_mode == ViewMode::kFullscreen) ? FlutterDesktopViewMode::kFullscreen diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index 0d9926df..a5762e47 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -32,6 +32,17 @@ class FlutterViewController { kFullscreen = 1, }; + enum ViewRotation { + // Rotation constant: 0 degree rotation (natural orientation) + kRotation_0 = 0, + // Rotation constant: 90 degree rotation. + kRotation_90 = 1, + // Rotation constant: 180 degree rotation. + kRotation_180 = 2, + // Rotation constant: 270 degree rotation. + kRotation_270 = 3, + }; + // Properties for configuring a Flutter view instance. typedef struct { // View width. @@ -40,6 +51,9 @@ class FlutterViewController { // View height. int height; + // View rotation. + ViewRotation view_rotation; + // View display mode. If you set kFullscreen, the parameters of both `width` // and `height` will be ignored. ViewMode view_mode; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 033cc3d5..6df08e56 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -81,6 +81,11 @@ FlutterRendererConfig GetRendererConfig() { return host->texture_registrar()->PopulateTexture(texture_id, width, height, texture); }; + config.open_gl.surface_transformation = + [](void* user_data) -> FlutterTransformation { + auto host = static_cast(user_data); + return host->view()->GetRootSurfaceTransformation(); + }; return config; } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 9a85b6a9..d5461760 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -5,6 +5,7 @@ #include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" #include +#include #include "flutter/shell/platform/linux_embedded/logger.h" @@ -12,6 +13,22 @@ namespace flutter { namespace { constexpr int kMicrosecondsPerMillisecond = 1000; + +inline FlutterTransformation FlutterTransformationMake(const uint16_t& degree) { + double radian = degree * M_PI / 180.0; + FlutterTransformation transformation = {}; + transformation.scaleX = cos(radian); + transformation.skewX = -sin(radian); + transformation.transX = 0; + transformation.skewY = sin(radian); + transformation.scaleY = cos(radian); + transformation.transY = 0; + transformation.pers0 = 0; + transformation.pers1 = 0; + transformation.pers2 = 1; + return transformation; +} + } // namespace FlutterELinuxView::FlutterELinuxView( @@ -78,7 +95,8 @@ void FlutterELinuxView::OnWindowSizeChanged(size_t width, size_t height) const { } void FlutterELinuxView::OnPointerMove(double x, double y) { - SendPointerMove(x, y); + auto trimmed_xy = GetPointerRotation(x, y); + SendPointerMove(trimmed_xy.first, trimmed_xy.second); } void FlutterELinuxView::OnPointerDown( @@ -87,8 +105,9 @@ void FlutterELinuxView::OnPointerDown( FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; + auto trimmed_xy = GetPointerRotation(x, y); SetMouseButtons(mouse_buttons); - SendPointerDown(x, y); + SendPointerDown(trimmed_xy.first, trimmed_xy.second); } } @@ -96,9 +115,10 @@ void FlutterELinuxView::OnPointerUp(double x, double y, FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { + auto trimmed_xy = GetPointerRotation(x, y); uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; SetMouseButtons(mouse_buttons); - SendPointerUp(x, y); + SendPointerUp(trimmed_xy.first, trimmed_xy.second); } } @@ -110,20 +130,21 @@ void FlutterELinuxView::OnTouchDown(uint32_t time, int32_t id, double x, double y) { + auto trimmed_xy = GetPointerRotation(x, y); auto* point = GgeTouchPoint(id); if (!point) { return; } point->event_mask = TouchEvent::kDown; - point->x = x; - point->y = y; + point->x = trimmed_xy.first; + point->y = trimmed_xy.second; FlutterPointerEvent event = { .struct_size = sizeof(event), .phase = FlutterPointerPhase::kDown, .timestamp = time * kMicrosecondsPerMillisecond, - .x = x, - .y = y, + .x = point->x, + .y = point->y, .device = id, .signal_kind = kFlutterPointerSignalKindNone, .scroll_delta_x = 0, @@ -161,20 +182,21 @@ void FlutterELinuxView::OnTouchMotion(uint32_t time, int32_t id, double x, double y) { + auto trimmed_xy = GetPointerRotation(x, y); auto* point = GgeTouchPoint(id); if (!point) { return; } point->event_mask = TouchEvent::kMotion; - point->x = x; - point->y = y; + point->x = trimmed_xy.first; + point->y = trimmed_xy.second; FlutterPointerEvent event = { .struct_size = sizeof(event), .phase = FlutterPointerPhase::kMove, .timestamp = time * kMicrosecondsPerMillisecond, - .x = x, - .y = y, + .x = point->x, + .y = point->y, .device = id, .signal_kind = kFlutterPointerSignalKindNone, .scroll_delta_x = 0, @@ -225,7 +247,9 @@ void FlutterELinuxView::OnScroll(double x, double delta_x, double delta_y, int scroll_offset_multiplier) { - SendScroll(x, y, delta_x, delta_y, scroll_offset_multiplier); + auto trimmed_xy = GetPointerRotation(x, y); + SendScroll(trimmed_xy.first, trimmed_xy.second, delta_x, delta_y, + scroll_offset_multiplier); } void FlutterELinuxView::OnVsync(uint64_t last_frame_time_nanos, @@ -419,4 +443,47 @@ int32_t FlutterELinuxView::GetFrameRate() { return binding_handler_->GetFrameRate(); } +FlutterTransformation FlutterELinuxView::GetRootSurfaceTransformation() { + auto degree = binding_handler_->GetRotationDegree(); + if (view_rotation_degree_ != degree) { + view_rotation_transformation_ = FlutterTransformationMake(degree); + } + view_rotation_degree_ = degree; + + auto bounds = binding_handler_->GetPhysicalWindowBounds(); + switch (degree) { + case 90: + view_rotation_transformation_.transX = bounds.height; + break; + case 180: + view_rotation_transformation_.transX = bounds.width; + view_rotation_transformation_.transY = bounds.height; + break; + case 270: + view_rotation_transformation_.transY = bounds.width; + break; + default: + break; + } + return view_rotation_transformation_; +} + +std::pair FlutterELinuxView::GetPointerRotation(double x, + double y) { + auto degree = binding_handler_->GetRotationDegree(); + auto bounds = binding_handler_->GetPhysicalWindowBounds(); + std::pair res = {x, y}; + + if (degree == 90) { + res.first = y; + res.second = bounds.height - x; + } else if (degree == 180) { + res.first = bounds.width - x; + res.second = bounds.height - y; + } else if (degree == 270) { + res.first = bounds.width - y; + res.second = x; + } + return res; +} } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index b8e057d0..1133443f 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -61,6 +61,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // Return the currently configured ELinuxRenderSurfaceTarget. ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const; + // Returns the FlutterTransformation of this view. + FlutterTransformation GetRootSurfaceTransformation(); + // Returns the engine backing this view. FlutterELinuxEngine* GetEngine(); @@ -234,6 +237,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // Updates the currently pressed buttons. void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } + // Returns a trimmed pointer of user inputs with the window rotation. + std::pair GetPointerRotation(double x, double y); + // The engine associated with this view. std::unique_ptr engine_; @@ -269,6 +275,13 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // Current user touch event status. touch_event touch_event_; + + // Current view rotation (degree). + uint16_t view_rotation_degree_ = 0; + + // Current view rotation (FlutterTransformation). + FlutterTransformation view_rotation_transformation_ = { + 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 134624d1..dd6da5e2 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -62,6 +62,18 @@ enum FlutterDesktopViewMode { kFullscreen = 1, }; +// The View rotation setting. +enum FlutterDesktopViewRotation { + // Rotation constant: 0 degree rotation (natural orientation) + kRotation_0 = 0, + // Rotation constant: 90 degree rotation. + kRotation_90 = 1, + // Rotation constant: 180 degree rotation. + kRotation_180 = 2, + // Rotation constant: 270 degree rotation. + kRotation_270 = 3, +}; + // Properties for configuring a Flutter view instance. typedef struct { // View width. @@ -70,6 +82,9 @@ typedef struct { // View height. int height; + // View rotation setting. + FlutterDesktopViewRotation view_rotation; + // View display mode. If you set kFullscreen, the parameters of both `width` // and `height` will be ignored. FlutterDesktopViewMode view_mode; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index 476bcf98..d5ac0c4e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -21,8 +21,21 @@ class ELinuxWindow { uint32_t GetCurrentHeight() const { return view_properties_.height; } + void SetRotation(FlutterDesktopViewRotation rotation) { + if (rotation == FlutterDesktopViewRotation::kRotation_90) { + current_rotation_ = 90; + } else if (rotation == FlutterDesktopViewRotation::kRotation_180) { + current_rotation_ = 180; + } else if (rotation == FlutterDesktopViewRotation::kRotation_270) { + current_rotation_ = 270; + } else { + current_rotation_ = 0; + } + } + FlutterDesktopViewProperties view_properties_; double current_scale_ = 1.0; + uint16_t current_rotation_ = 0; double pointer_x_ = 0; double pointer_y_ = 0; std::string clipboard_data_ = ""; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 3d916446..d616a945 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -34,6 +34,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { ELinuxWindowDrm(FlutterDesktopViewProperties view_properties) : display_valid_(false), is_pending_cursor_add_event_(false) { view_properties_ = view_properties; + SetRotation(view_properties_.view_rotation); auto udev = udev_new(); if (!udev) { @@ -111,6 +112,10 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { << " is not set, use " << kDrmDeviceDefaultFilename; device_filename = const_cast(kDrmDeviceDefaultFilename); } + + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } native_window_ = std::make_unique(device_filename); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window"; @@ -163,6 +168,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return render_surface_.get(); } + // |FlutterWindowBindingHandler| + uint16_t GetRotationDegree() const override { return current_rotation_; } + // |FlutterWindowBindingHandler| double GetDpiScale() override { return current_scale_; } @@ -290,10 +298,15 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { if (self->IsUdevEventHotplug(*device) && self->native_window_->ConfigureDisplay()) { - if (self->view_properties_.width != self->native_window_->Width() || - self->view_properties_.height != self->native_window_->Height()) { - self->view_properties_.width = self->native_window_->Width(); - self->view_properties_.height = self->native_window_->Height(); + auto width = self->native_window_->Width(); + auto height = self->native_window_->Height(); + if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { + std::swap(width, height); + } + if (self->view_properties_.width != width || + self->view_properties_.height != height) { + self->view_properties_.width = width; + self->view_properties_.height = height; ELINUX_LOG(INFO) << "Display output resolution: " << self->view_properties_.width << "x" << self->view_properties_.height; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index c196131d..be0c75e7 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -110,6 +110,10 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { } auto self = reinterpret_cast(data); + if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { + std::swap(width, height); + } + int32_t next_width = 0; int32_t next_height = 0; if (is_maximized || is_resizing) { @@ -527,6 +531,10 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { int32_t refresh) -> void { auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { + if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { + std::swap(width, height); + } + ELINUX_LOG(INFO) << "Display output info: width = " << width << ", height = " << height << ", refresh = " << refresh; @@ -818,6 +826,7 @@ ELinuxWindowWayland::ELinuxWindowWayland( frame_rate_(60000), window_decorations_(nullptr) { view_properties_ = view_properties; + SetRotation(view_properties_.view_rotation); wl_display_ = wl_display_connect(nullptr); if (!wl_display_) { @@ -996,6 +1005,10 @@ ELinuxRenderSurfaceTarget* ELinuxWindowWayland::GetRenderSurfaceTarget() const { return render_surface_.get(); } +uint16_t ELinuxWindowWayland::GetRotationDegree() const { + return current_rotation_; +} + double ELinuxWindowWayland::GetDpiScale() { return current_scale_; } @@ -1088,6 +1101,9 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { } } + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } native_window_ = std::make_unique(wl_compositor_, width, height); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 5a73232e..d62ebd5a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -52,6 +52,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const override; + // |FlutterWindowBindingHandler| + uint16_t GetRotationDegree() const override; + // |FlutterWindowBindingHandler| double GetDpiScale() override; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 3d475888..792fa76a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -23,6 +23,7 @@ constexpr int kButton9 = 9; ELinuxWindowX11::ELinuxWindowX11(FlutterDesktopViewProperties view_properties) { view_properties_ = view_properties; + SetRotation(view_properties_.view_rotation); display_ = XOpenDisplay(NULL); if (!display_) { @@ -89,10 +90,16 @@ bool ELinuxWindowX11::DispatchEvent() { } break; case ConfigureNotify: { - if (((event.xconfigure.width != view_properties_.width) || - (event.xconfigure.height != view_properties_.height))) { - view_properties_.width = event.xconfigure.width; - view_properties_.height = event.xconfigure.height; + auto width = event.xconfigure.width; + auto height = event.xconfigure.height; + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } + + if (((width != view_properties_.width) || + (height != view_properties_.height))) { + view_properties_.width = width; + view_properties_.height = height; if (binding_handler_delegate_) { binding_handler_delegate_->OnWindowSizeChanged( view_properties_.width, view_properties_.height); @@ -116,6 +123,9 @@ bool ELinuxWindowX11::CreateRenderSurface(int32_t width, int32_t height) { auto context_egl = std::make_unique(std::make_unique(display_)); + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } native_window_ = std::make_unique( display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), width, height); if (!native_window_->IsValid()) { @@ -143,6 +153,10 @@ ELinuxRenderSurfaceTarget* ELinuxWindowX11::GetRenderSurfaceTarget() const { return render_surface_.get(); } +uint16_t ELinuxWindowX11::GetRotationDegree() const { + return current_rotation_; +} + double ELinuxWindowX11::GetDpiScale() { return current_scale_; } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 7eb73262..80683534 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -37,6 +37,9 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| ELinuxRenderSurfaceTarget* GetRenderSurfaceTarget() const override; + // |FlutterWindowBindingHandler| + uint16_t GetRotationDegree() const override; + // |FlutterWindowBindingHandler| double GetDpiScale() override; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 56957f92..83aa7920 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -47,6 +47,9 @@ class WindowBindingHandler { // such as key presses, mouse position updates etc. virtual void SetView(WindowBindingHandlerDelegate* view) = 0; + // Returns the rotation(degree) for the backing window. + virtual uint16_t GetRotationDegree() const = 0; + // Returns the scale factor for the backing window. virtual double GetDpiScale() = 0; From 6eeb4f210db5aedd15a3840113017edce23afacb Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 11 Mar 2022 10:06:06 +0900 Subject: [PATCH 074/178] Rename enum value of FlutterDesktopViewMode Renamed FlutterDesktopViewMode enum value to avoid conflict with the latest embedder.h --- src/client_wrapper/flutter_view_controller.cc | 2 +- .../shell/platform/linux_embedded/public/flutter_elinux.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 8387919d..4dbd58a4 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -28,7 +28,7 @@ FlutterViewController::FlutterViewController( c_view_properties.view_mode = (view_properties.view_mode == ViewMode::kFullscreen) ? FlutterDesktopViewMode::kFullscreen - : FlutterDesktopViewMode::kNormal; + : FlutterDesktopViewMode::kNormalscreen; c_view_properties.use_mouse_cursor = view_properties.use_mouse_cursor; c_view_properties.use_onscreen_keyboard = view_properties.use_onscreen_keyboard; diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index dd6da5e2..4b7cb0da 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -57,7 +57,7 @@ typedef struct { // The View display mode. enum FlutterDesktopViewMode { // Shows the Flutter view by user specific size. - kNormal = 0, + kNormalscreen = 0, // Shows always the Flutter view by fullscreen. kFullscreen = 1, }; From a07efc4412820c6aebd8fa47e1eb40716bda9841 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 24 Mar 2022 09:50:41 +0900 Subject: [PATCH 075/178] merge embedder.h from flutter/engine (#252) Merged the latest `embedder.h` from https://github.com/flutter/engine/commit/6c67716b081a3614305f99b4e6ade2562f974fee --- .../shell/platform/embedder/embedder.h | 169 +++++++++++++++++- 1 file changed, 168 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index e8b769ef..4cefaab8 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -76,6 +76,7 @@ typedef enum { /// iOS version >= 10.0 (device), 13.0 (simulator) /// macOS version >= 10.14 kMetal, + kVulkan, } FlutterRendererType; /// Additional accessibility features that may be enabled by the platform. @@ -225,6 +226,18 @@ typedef enum { kFlutterTextDirectionLTR = 2, } FlutterTextDirection; +/// Valid values for priority of Thread. +typedef enum { + /// Suitable for threads that shouldn't disrupt high priority work. + kBackground = 0, + /// Default priority level. + kNormal = 1, + /// Suitable for threads which generate data for the display. + kDisplay = 2, + /// Suitable for thread which raster data. + kRaster = 3, +} FlutterThreadPriority; + typedef struct _FlutterEngine* FLUTTER_API_SYMBOL(FlutterEngine); typedef struct { @@ -494,7 +507,7 @@ typedef struct { size_t struct_size; /// Embedder provided unique identifier to the texture buffer. Given that the /// `texture` handle is passed to the engine to render to, the texture buffer - /// is itseld owned by the embedder. This `texture_id` is then also given to + /// is itself owned by the embedder. This `texture_id` is then also given to /// the embedder in the present callback. int64_t texture_id; /// Handle to the MTLTexture that is owned by the embedder. Engine will render @@ -541,6 +554,104 @@ typedef struct { FlutterMetalTextureFrameCallback external_texture_frame_callback; } FlutterMetalRendererConfig; +/// Alias for VkInstance. +typedef void* FlutterVulkanInstanceHandle; + +/// Alias for VkPhysicalDevice. +typedef void* FlutterVulkanPhysicalDeviceHandle; + +/// Alias for VkDevice. +typedef void* FlutterVulkanDeviceHandle; + +/// Alias for VkQueue. +typedef void* FlutterVulkanQueueHandle; + +/// Alias for VkImage. +typedef uint64_t FlutterVulkanImageHandle; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanImage). + size_t struct_size; + /// Handle to the VkImage that is owned by the embedder. The engine will + /// bind this image for writing the frame. + FlutterVulkanImageHandle image; + /// The VkFormat of the image (for example: VK_FORMAT_R8G8B8A8_UNORM). + uint32_t format; +} FlutterVulkanImage; + +/// Callback to fetch a Vulkan function pointer for a given instance. Normally, +/// this should return the results of vkGetInstanceProcAddr. +typedef void* (*FlutterVulkanInstanceProcAddressCallback)( + void* /* user data */, + FlutterVulkanInstanceHandle /* instance */, + const char* /* name */); + +/// Callback for when a VkImage is requested. +typedef FlutterVulkanImage (*FlutterVulkanImageCallback)( + void* /* user data */, + const FlutterFrameInfo* /* frame info */); + +/// Callback for when a VkImage has been written to and is ready for use by the +/// embedder. +typedef bool (*FlutterVulkanPresentCallback)( + void* /* user data */, + const FlutterVulkanImage* /* image */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanRendererConfig). + size_t struct_size; + + /// The Vulkan API version. This should match the value set in + /// VkApplicationInfo::apiVersion when the VkInstance was created. + uint32_t version; + /// VkInstance handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. + FlutterVulkanInstanceHandle instance; + /// VkPhysicalDevice handle. + FlutterVulkanPhysicalDeviceHandle physical_device; + /// VkDevice handle. Must not be destroyed before `FlutterEngineShutdown` is + /// called. + FlutterVulkanDeviceHandle device; + /// The queue family index of the VkQueue supplied in the next field. + uint32_t queue_family_index; + /// VkQueue handle. + FlutterVulkanQueueHandle queue; + /// The number of instance extensions available for enumerating in the next + /// field. + size_t enabled_instance_extension_count; + /// Array of enabled instance extension names. This should match the names + /// passed to `VkInstanceCreateInfo.ppEnabledExtensionNames` when the instance + /// was created, but any subset of enabled instance extensions may be + /// specified. + /// This field is optional; `nullptr` may be specified. + /// This memory is only accessed during the call to FlutterEngineInitialize. + const char** enabled_instance_extensions; + /// The number of device extensions available for enumerating in the next + /// field. + size_t enabled_device_extension_count; + /// Array of enabled logical device extension names. This should match the + /// names passed to `VkDeviceCreateInfo.ppEnabledExtensionNames` when the + /// logical device was created, but any subset of enabled logical device + /// extensions may be specified. + /// This field is optional; `nullptr` may be specified. + /// This memory is only accessed during the call to FlutterEngineInitialize. + /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME + const char** enabled_device_extensions; + /// The callback invoked when resolving Vulkan function pointers. + FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; + /// The callback invoked when the engine requests a VkImage from the embedder + /// for rendering the next frame. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. + FlutterVulkanImageCallback get_next_image_callback; + /// The callback invoked when a VkImage has been written to and is ready for + /// use by the embedder. Prior to calling this callback, the engine performs + /// a host sync, and so the VkImage can be used in a pipeline by the embedder + /// without any additional synchronization. + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. + FlutterVulkanPresentCallback present_image_callback; + +} FlutterVulkanRendererConfig; + typedef struct { /// The size of this struct. Must be sizeof(FlutterSoftwareRendererConfig). size_t struct_size; @@ -557,6 +668,7 @@ typedef struct { FlutterOpenGLRendererConfig open_gl; FlutterSoftwareRendererConfig software; FlutterMetalRendererConfig metal; + FlutterVulkanRendererConfig vulkan; }; } FlutterRendererConfig; @@ -617,6 +729,12 @@ typedef enum { kRemove, /// The pointer moved while up. kHover, + /// A pan/zoom started on this pointer. + kPanZoomStart, + /// The pan/zoom updated. + kPanZoomUpdate, + /// The pan/zoom ended. + kPanZoomEnd, } FlutterPointerPhase; /// The device type that created a pointer event. @@ -624,6 +742,7 @@ typedef enum { kFlutterPointerDeviceKindMouse = 1, kFlutterPointerDeviceKindTouch, kFlutterPointerDeviceKindStylus, + kFlutterPointerDeviceKindTrackpad, } FlutterPointerDeviceKind; /// Flags for the `buttons` field of `FlutterPointerEvent` when `device_kind` @@ -672,6 +791,14 @@ typedef struct { FlutterPointerDeviceKind device_kind; /// The buttons currently pressed, if any. int64_t buttons; + /// The x offset of the pan/zoom in physical pixels. + double pan_x; + /// The y offset of the pan/zoom in physical pixels. + double pan_y; + /// The scale of the pan/zoom, where 1.0 is the initial scale. + double scale; + /// The rotation of the pan/zoom in radians, where 0.0 is the initial angle. + double rotation; } FlutterPointerEvent; typedef enum { @@ -946,6 +1073,9 @@ typedef struct { /// and platform task runners. This makes the Flutter engine use the same /// thread for both task runners. const FlutterTaskRunnerDescription* render_task_runner; + /// Specify a callback that is used to set the thread priority for embedder + /// task runners. + void (*thread_priority_setter)(FlutterThreadPriority); } FlutterCustomTaskRunners; typedef struct { @@ -989,6 +1119,25 @@ typedef struct { }; } FlutterMetalBackingStore; +typedef struct { + /// The size of this struct. Must be sizeof(FlutterVulkanBackingStore). + size_t struct_size; + /// The image that the layer will be rendered to. This image must already be + /// available for the engine to bind for writing when it's given to the engine + /// via the backing store creation callback. The engine will perform a host + /// sync for all layers prior to calling the compositor present callback, and + /// so the written layer images can be freely bound by the embedder without + /// any additional synchronization. + const FlutterVulkanImage* image; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; +} FlutterVulkanBackingStore; + typedef enum { /// Indicates that the Flutter application requested that an opacity be /// applied to the platform view. @@ -1048,6 +1197,8 @@ typedef enum { kFlutterBackingStoreTypeSoftware, /// Specifies a Metal backing store. This is backed by a Metal texture. kFlutterBackingStoreTypeMetal, + /// Specifies a Vulkan backing store. This is backed by a Vulkan VkImage. + kFlutterBackingStoreTypeVulkan, } FlutterBackingStoreType; typedef struct { @@ -1069,6 +1220,8 @@ typedef struct { FlutterSoftwareBackingStore software; // The description of the Metal backing store. FlutterMetalBackingStore metal; + // The description of the Vulkan backing store. + FlutterVulkanBackingStore vulkan; }; } FlutterBackingStore; @@ -2251,6 +2404,17 @@ FlutterEngineResult FlutterEngineNotifyDisplayUpdate( const FlutterEngineDisplay* displays, size_t display_count); +//------------------------------------------------------------------------------ +/// @brief Schedule a new frame to redraw the content. +/// +/// @param[in] engine A running engine instance. +/// +/// @return the result of the call made to the engine. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) + engine); + #endif // !FLUTTER_ENGINE_NO_PROTOTYPES // Typedefs for the function pointers in FlutterEngineProcTable. @@ -2367,6 +2531,8 @@ typedef FlutterEngineResult (*FlutterEngineNotifyDisplayUpdateFnPtr)( FlutterEngineDisplaysUpdateType update_type, const FlutterEngineDisplay* displays, size_t display_count); +typedef FlutterEngineResult (*FlutterEngineScheduleFrameFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine); /// Function-pointer-based versions of the APIs above. typedef struct { @@ -2411,6 +2577,7 @@ typedef struct { FlutterEnginePostCallbackOnAllNativeThreadsFnPtr PostCallbackOnAllNativeThreads; FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate; + FlutterEngineScheduleFrameFnPtr ScheduleFrame; } FlutterEngineProcTable; //------------------------------------------------------------------------------ From 86c676a3dce7989c55768c6839c86674374ee63a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 7 Apr 2022 15:31:28 +0900 Subject: [PATCH 076/178] Merged the latest embedder.h from flutter/engine (04/07/2022) (#255) See https://github.com/flutter/engine/commit/5f2b5660f2551a60021b66cfd267abc2aa97bfec --- src/flutter/shell/platform/embedder/embedder.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 4cefaab8..66a25c7f 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -92,8 +92,12 @@ typedef enum { /// Request that text be rendered at a bold font weight. kFlutterAccessibilityFeatureBoldText = 1 << 3, /// Request that certain animations be simplified and parallax effects - // removed. + /// removed. kFlutterAccessibilityFeatureReduceMotion = 1 << 4, + /// Request that UI be rendered with darker colors. + kFlutterAccessibilityFeatureHighContrast = 1 << 5, + /// Request to show on/off labels inside switches. + kFlutterAccessibilityFeatureOnOffSwitchLabels = 1 << 6, } FlutterAccessibilityFeature; /// The set of possible actions that can be conveyed to a semantics node. @@ -149,6 +153,8 @@ typedef enum { kFlutterSemanticsActionMoveCursorForwardByWord = 1 << 19, /// Move the cursor backward by one word. kFlutterSemanticsActionMoveCursorBackwardByWord = 1 << 20, + /// Replace the current text in the text field. + kFlutterSemanticsActionSetText = 1 << 21, } FlutterSemanticsAction; /// The set of properties that may be associated with a semantics node. @@ -203,6 +209,12 @@ typedef enum { /// `PageView` widget does not have implicit scrolling, so that users don't /// navigate to the next page when reaching the end of the current one. kFlutterSemanticsFlagHasImplicitScrolling = 1 << 18, + /// Whether the value of the semantics node is coming from a multi-line text + /// field. + /// + /// This is used for text fields to distinguish single-line text fields from + /// multi-line ones. + kFlutterSemanticsFlagIsMultiline = 1 << 19, /// Whether the semantic node is read only. /// /// Only applicable when kFlutterSemanticsFlagIsTextField flag is on. From 047c0d1133c64f34076f5bc6f62a9919d53add61 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 8 Apr 2022 14:36:11 +0900 Subject: [PATCH 077/178] Fix drm backends rotation option bug (#257) --- .../linux_embedded/window/elinux_window_drm.h | 57 ++++++++++++------- .../window/native_window_drm.cc | 10 +++- .../linux_embedded/window/native_window_drm.h | 4 +- .../window/native_window_drm_eglstream.cc | 5 +- .../window/native_window_drm_eglstream.h | 3 +- .../window/native_window_drm_gbm.cc | 5 +- .../window/native_window_drm_gbm.h | 2 +- 7 files changed, 54 insertions(+), 32 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index d616a945..55e29854 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -113,10 +113,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { device_filename = const_cast(kDrmDeviceDefaultFilename); } - if (current_rotation_ == 90 || current_rotation_ == 270) { - std::swap(width, height); - } - native_window_ = std::make_unique(device_filename); + native_window_ = std::make_unique(device_filename, current_rotation_); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; @@ -297,7 +294,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } if (self->IsUdevEventHotplug(*device) && - self->native_window_->ConfigureDisplay()) { + self->native_window_->ConfigureDisplay(self->current_rotation_)) { auto width = self->native_window_->Width(); auto height = self->native_window_->Height(); if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { @@ -462,18 +459,22 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnPointerMotion(libinput_event* event) { DetectPointerDevice(event); if (binding_handler_delegate_) { + auto width = view_properties_.width; + auto height = view_properties_.height; + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } + auto pointer_event = libinput_event_get_pointer_event(event); auto dx = libinput_event_pointer_get_dx(pointer_event); auto dy = libinput_event_pointer_get_dy(pointer_event); auto new_pointer_x = pointer_x_ + dx; new_pointer_x = std::max(0.0, new_pointer_x); - new_pointer_x = std::min(static_cast(view_properties_.width - 1), - new_pointer_x); + new_pointer_x = std::min(static_cast(width - 1), new_pointer_x); auto new_pointer_y = pointer_y_ + dy; new_pointer_y = std::max(0.0, new_pointer_y); - new_pointer_y = std::min(static_cast(view_properties_.height - 1), - new_pointer_y); + new_pointer_y = std::min(static_cast(height - 1), new_pointer_y); binding_handler_delegate_->OnPointerMove(new_pointer_x, new_pointer_y); pointer_x_ = new_pointer_x; @@ -482,13 +483,19 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } void OnPointerMotionAbsolute(libinput_event* event) { + auto width = view_properties_.width; + auto height = view_properties_.height; + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } + DetectPointerDevice(event); if (binding_handler_delegate_) { auto pointer_event = libinput_event_get_pointer_event(event); - auto x = libinput_event_pointer_get_absolute_x_transformed( - pointer_event, view_properties_.width); - auto y = libinput_event_pointer_get_absolute_y_transformed( - pointer_event, view_properties_.height); + auto x = libinput_event_pointer_get_absolute_x_transformed(pointer_event, + width); + auto y = libinput_event_pointer_get_absolute_y_transformed(pointer_event, + height); binding_handler_delegate_->OnPointerMove(x, y); pointer_x_ = x; @@ -580,13 +587,17 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnTouchDown(libinput_event* event) { if (binding_handler_delegate_) { + auto width = view_properties_.width; + auto height = view_properties_.height; + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } + auto touch_event = libinput_event_get_touch_event(event); auto time = libinput_event_touch_get_time(touch_event); auto slot = libinput_event_touch_get_seat_slot(touch_event); - auto x = libinput_event_touch_get_x_transformed(touch_event, - view_properties_.width); - auto y = libinput_event_touch_get_y_transformed(touch_event, - view_properties_.height); + auto x = libinput_event_touch_get_x_transformed(touch_event, width); + auto y = libinput_event_touch_get_y_transformed(touch_event, height); binding_handler_delegate_->OnTouchDown(time, slot, x, y); } } @@ -602,13 +613,17 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { void OnTouchMotion(libinput_event* event) { if (binding_handler_delegate_) { + auto width = view_properties_.width; + auto height = view_properties_.height; + if (current_rotation_ == 90 || current_rotation_ == 270) { + std::swap(width, height); + } + auto touch_event = libinput_event_get_touch_event(event); auto time = libinput_event_touch_get_time(touch_event); auto slot = libinput_event_touch_get_seat_slot(touch_event); - auto x = libinput_event_touch_get_x_transformed(touch_event, - view_properties_.width); - auto y = libinput_event_touch_get_y_transformed(touch_event, - view_properties_.height); + auto x = libinput_event_touch_get_x_transformed(touch_event, width); + auto y = libinput_event_touch_get_y_transformed(touch_event, height); binding_handler_delegate_->OnTouchMotion(time, slot, x, y); } } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index cf9c48ff..1f57165c 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -15,14 +15,15 @@ namespace flutter { -NativeWindowDrm::NativeWindowDrm(const char* device_filename) { +NativeWindowDrm::NativeWindowDrm(const char* device_filename, + const uint16_t rotation) { drm_device_ = open(device_filename, O_RDWR | O_CLOEXEC); if (drm_device_ == -1) { ELINUX_LOG(ERROR) << "Couldn't open " << device_filename; return; } - if (!ConfigureDisplay()) { + if (!ConfigureDisplay(rotation)) { return; } @@ -46,7 +47,7 @@ bool NativeWindowDrm::MoveCursor(double x, double y) { return true; } -bool NativeWindowDrm::ConfigureDisplay() { +bool NativeWindowDrm::ConfigureDisplay(const uint16_t rotation) { auto resources = drmModeGetResources(drm_device_); if (!resources) { ELINUX_LOG(ERROR) << "Couldn't get resources"; @@ -64,6 +65,9 @@ bool NativeWindowDrm::ConfigureDisplay() { drm_mode_info_ = connector->modes[0]; width_ = drm_mode_info_.hdisplay; height_ = drm_mode_info_.vdisplay; + if (rotation == 90 || rotation == 270) { + std::swap(width_, height_); + } ELINUX_LOG(INFO) << "resolution: " << width_ << "x" << height_; auto* encoder = FindEncoder(resources, connector); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index 4ec29050..6259f6aa 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -16,10 +16,10 @@ namespace flutter { class NativeWindowDrm : public NativeWindow { public: - NativeWindowDrm(const char* device_filename); + NativeWindowDrm(const char* device_filename, const uint16_t rotation); virtual ~NativeWindowDrm(); - bool ConfigureDisplay(); + bool ConfigureDisplay(const uint16_t rotation); bool MoveCursor(double x, double y); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc index b762321a..a78fd033 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc @@ -18,8 +18,9 @@ namespace { constexpr char kCursorNameNone[] = "none"; } // namespace -NativeWindowDrmEglstream::NativeWindowDrmEglstream(const char* device_filename) - : NativeWindowDrm(device_filename) { +NativeWindowDrmEglstream::NativeWindowDrmEglstream(const char* device_filename, + const uint16_t rotation) + : NativeWindowDrm(device_filename, rotation) { if (!valid_) { return; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h index 994dfe38..f3e469d5 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h @@ -16,7 +16,8 @@ namespace flutter { class NativeWindowDrmEglstream : public NativeWindowDrm { public: - NativeWindowDrmEglstream(const char* device_filename); + NativeWindowDrmEglstream(const char* device_filename, + const uint16_t rotation); ~NativeWindowDrmEglstream(); // |NativeWindowDrm| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index a24443a7..3effb666 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -19,8 +19,9 @@ constexpr uint32_t kCursorBufferWidth = 64; constexpr uint32_t kCursorBufferHeight = 64; } // namespace -NativeWindowDrmGbm::NativeWindowDrmGbm(const char* device_filename) - : NativeWindowDrm(device_filename) { +NativeWindowDrmGbm::NativeWindowDrmGbm(const char* device_filename, + const uint16_t rotation) + : NativeWindowDrm(device_filename, rotation) { if (!valid_) { return; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h index 0a062273..6b9b9ecd 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h @@ -17,7 +17,7 @@ namespace flutter { class NativeWindowDrmGbm : public NativeWindowDrm { public: - NativeWindowDrmGbm(const char* device_filename); + NativeWindowDrmGbm(const char* device_filename, const uint16_t rotation); ~NativeWindowDrmGbm(); // |NativeWindowDrm| From 12cee2fa600271db82b1eb0b4c6ab2abab09e2a6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 13 Apr 2022 10:26:22 +0900 Subject: [PATCH 078/178] Fix uninitialization of member var (#258) --- .../shell/platform/linux_embedded/plugins/text_input_plugin.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h index af9caf27..3f48d9b6 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h @@ -39,7 +39,7 @@ class TextInputPlugin { std::unique_ptr> channel_; // The active client id. - int client_id_; + int client_id_ = 0; // The active model. nullptr if not set. std::unique_ptr active_model_; From 63a688c43e13a6e64561de83de543bb4b34a94dc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 22 Apr 2022 12:45:13 +0900 Subject: [PATCH 079/178] Add AUTHORS file (#259) Signed-off-by: Hidenori.Matsubayashi --- AUTHORS | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 AUTHORS diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 00000000..649f420b --- /dev/null +++ b/AUTHORS @@ -0,0 +1,8 @@ +# Below is a list of people and organizations that have contributed +# to sony/flutter-embedded-linux. Names should be added to the list +# like so: +# +# Name/Organization + +Sony Group Corporation +Hidenori Matsubayashi (hidenori.matsubayashi@gmail.com) From 4280a80ebf320b5dc2166ed9ec40ab14916185c6 Mon Sep 17 00:00:00 2001 From: Cem Philipp Freimoser Date: Sun, 10 Jul 2022 13:25:08 +0000 Subject: [PATCH 080/178] Added Pi 3 Model B to readme --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2244d108..95d6543e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux whi | [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | DRM | :heavy_check_mark: ([#1](https://github.com/sony/flutter-embedded-linux/issues/1))| | [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Raspberry Pi Foundation | Ubuntu 20.10 | Wayland | :heavy_check_mark: | | [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Raspberry Pi Foundation | Ubuntu 20.10 | DRM | :heavy_check_mark: ([#9](https://github.com/sony/flutter-embedded-linux/issues/9)) | +| [Raspberry Pi 3 Model B](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/) | Raspberry Pi Foundation | Raspberry Pi OS bullseye | Wayland | :heavy_check_mark: | | [i.MX 8MQuad EVK](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-applications-processor:MCIMX8M-EVK) | NXP | Sumo (kernel 4.14.98) | Wayland | :heavy_check_mark: | | [i.MX 8M Mini EVKB](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-mini-applications-processor:8MMINILPD4-EVK) | NXP | Zeus (kernel 5.4.70) | Wayland | :heavy_check_mark: | | [RB5 Development Kit](https://developer.qualcomm.com/qualcomm-robotics-rb5-kit) | Qualcomm | Ubuntu 18.04.05 | DRM | :heavy_check_mark: | From fa17772be59e8458d41e1598a1976e52cd27adc8 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 24 Jul 2022 09:25:12 +0900 Subject: [PATCH 081/178] Update embedder header file (#271) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 66a25c7f..43fd5bd5 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -284,6 +284,62 @@ typedef enum { kFlutterOpenGLTargetTypeFramebuffer, } FlutterOpenGLTargetType; +/// A pixel format to be used for software rendering. +/// +/// A single pixel always stored as a POT number of bytes. (so in practice +/// either 1, 2, 4, 8, 16 bytes per pixel) +/// +/// There are two kinds of pixel formats: +/// - formats where all components are 8 bits, called array formats +/// The component order as specified in the pixel format name is the +/// order of the components' bytes in memory, with the leftmost component +/// occupying the lowest memory address. +/// +/// - all other formats are called packed formats, and the component order +/// as specified in the format name refers to the order in the native type. +/// for example, for kRGB565, the R component uses the 5 least significant +/// bits of the uint16_t pixel value. +/// +/// Each pixel format in this list is documented with an example on how to get +/// the color components from the pixel. +/// - for packed formats, p is the pixel value as a word. For example, you can +/// get the pixel value for a RGB565 formatted buffer like this: +/// uint16_t p = ((const uint16_t*) allocation)[row_bytes * y / bpp + x]; +/// (with bpp being the bytes per pixel, so 2 for RGB565) +/// +/// - for array formats, p is a pointer to the pixel value. For example, you +/// can get the p for a RGBA8888 formatted buffer like this: +/// const uint8_t *p = ((const uint8_t*) allocation) + row_bytes*y + x*4; +typedef enum { + /// pixel with 8 bit grayscale value. + /// The grayscale value is the luma value calculated from r, g, b + /// according to BT.709. (gray = r*0.2126 + g*0.7152 + b*0.0722) + kGray8, + + /// pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word. + /// r = p & 0x3F; g = (p>>5) & 0x3F; b = p>>11; + kRGB565, + + /// pixel with 4 bits for alpha, red, green, blue; in 16-bit word. + /// r = p & 0xF; g = (p>>4) & 0xF; b = (p>>8) & 0xF; a = p>>12; + kRGBA4444, + + /// pixel with 8 bits for red, green, blue, alpha. + /// r = p[0]; g = p[1]; b = p[2]; a = p[3]; + kRGBA8888, + + /// pixel with 8 bits for red, green and blue and 8 unused bits. + /// r = p[0]; g = p[1]; b = p[2]; + kRGBX8888, + + /// pixel with 8 bits for blue, green, red and alpha. + /// r = p[2]; g = p[1]; b = p[0]; a = p[3]; + kBGRA8888, + + /// either kBGRA8888 or kRGBA8888 depending on CPU endianess and OS + kNative32, +} FlutterSoftwarePixelFormat; + typedef struct { /// Target texture of the active texture unit (example GL_TEXTURE_2D or /// GL_TEXTURE_RECTANGLE). @@ -773,6 +829,7 @@ typedef enum { typedef enum { kFlutterPointerSignalKindNone, kFlutterPointerSignalKindScroll, + kFlutterPointerSignalKindScrollInertiaCancel, } FlutterPointerSignalKind; typedef struct { @@ -1120,6 +1177,27 @@ typedef struct { VoidCallback destruction_callback; } FlutterSoftwareBackingStore; +typedef struct { + size_t struct_size; + /// A pointer to the raw bytes of the allocation described by this software + /// backing store. + const void* allocation; + /// The number of bytes in a single row of the allocation. + size_t row_bytes; + /// The number of rows in the allocation. + size_t height; + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in the destruction callback below. Embedder resources + /// may be associated with this baton. + void* user_data; + /// The callback invoked by the engine when it no longer needs this backing + /// store. + VoidCallback destruction_callback; + /// The pixel format that the engine should use to render into the allocation. + /// In most cases, kR + FlutterSoftwarePixelFormat pixel_format; +} FlutterSoftwareBackingStore2; + typedef struct { /// The size of this struct. Must be sizeof(FlutterMetalBackingStore). size_t struct_size; @@ -1211,6 +1289,9 @@ typedef enum { kFlutterBackingStoreTypeMetal, /// Specifies a Vulkan backing store. This is backed by a Vulkan VkImage. kFlutterBackingStoreTypeVulkan, + /// Specifies a allocation that the engine should render into using + /// software rendering. + kFlutterBackingStoreTypeSoftware2, } FlutterBackingStoreType; typedef struct { @@ -1230,6 +1311,8 @@ typedef struct { FlutterOpenGLBackingStore open_gl; /// The description of the software backing store. FlutterSoftwareBackingStore software; + /// The description of the software backing store. + FlutterSoftwareBackingStore2 software2; // The description of the Metal backing store. FlutterMetalBackingStore metal; // The description of the Vulkan backing store. From 9ef4043d5e6bc19ad52230430d6f44ebccf0b4bd Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 3 Aug 2022 21:10:58 +0900 Subject: [PATCH 082/178] [Merge] Fix incorrect public C API argument type (#275) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/public/flutter_elinux.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 4b7cb0da..913c1fac 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -195,8 +195,7 @@ FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); // Returns the texture registrar associated with the engine. FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef -FlutterDesktopEngineGetTextureRegistrar( - FlutterDesktopTextureRegistrarRef texture_registrar); +FlutterDesktopEngineGetTextureRegistrar(FlutterDesktopEngineRef engine); #if defined(__cplusplus) } // extern "C" From 8ed1e7e77304882b62feaba1ae9b4672765c6c74 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 3 Aug 2022 22:05:08 +0900 Subject: [PATCH 083/178] Update flutter_texture_registrar APIs (#276) * Update flutter_texture_registrar APIs Signed-off-by: Hidenori Matsubayashi --- cmake/build.cmake | 2 +- .../client_wrapper/core_implementations.cc | 30 ++-- .../include/flutter/texture_registrar.h | 32 +++- .../common/public/flutter_texture_registrar.h | 97 ++++++++++- .../embedder/embedder_struct_macros.h | 32 ++++ .../linux_embedded/external_texture.h | 61 +++++++ .../linux_embedded/external_texture_gl.cc | 153 ------------------ .../linux_embedded/external_texture_gl.h | 56 ------- .../external_texture_pixelbuffer.cc | 82 ++++++++++ .../external_texture_pixelbuffer.h | 52 ++++++ .../linux_embedded/flutter_elinux_engine.cc | 5 +- .../linux_embedded/flutter_elinux_engine.h | 3 + .../flutter_elinux_texture_registrar.cc | 68 ++++++-- .../flutter_elinux_texture_registrar.h | 14 +- 14 files changed, 443 insertions(+), 244 deletions(-) create mode 100644 src/flutter/shell/platform/embedder/embedder_struct_macros.h create mode 100644 src/flutter/shell/platform/linux_embedded/external_texture.h delete mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_gl.cc delete mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_gl.h create mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc create mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h diff --git a/cmake/build.cmake b/cmake/build.cmake index a14bdc0d..c64fd5ce 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -119,7 +119,7 @@ set(ELINUX_COMMON_SRC "src/flutter/shell/platform/linux_embedded/task_runner.cc" "src/flutter/shell/platform/linux_embedded/system_utils.cc" "src/flutter/shell/platform/linux_embedded/logger.cc" - "src/flutter/shell/platform/linux_embedded/external_texture_gl.cc" + "src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc" "src/flutter/shell/platform/linux_embedded/vsync_waiter.cc" "src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc" "src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc" diff --git a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc index 1412db7c..e90b26cd 100644 --- a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -157,25 +157,37 @@ TextureRegistrarImpl::TextureRegistrarImpl( TextureRegistrarImpl::~TextureRegistrarImpl() = default; int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) { + FlutterDesktopTextureInfo info = {}; if (auto pixel_buffer_texture = std::get_if(texture)) { - FlutterDesktopTextureInfo info = {}; info.type = kFlutterDesktopPixelBufferTexture; info.pixel_buffer_config.user_data = pixel_buffer_texture; info.pixel_buffer_config.callback = [](size_t width, size_t height, void* user_data) -> const FlutterDesktopPixelBuffer* { auto texture = static_cast(user_data); - auto buffer = texture->CopyPixelBuffer(width, height); - return buffer; + return texture->CopyPixelBuffer(width, height); }; - - int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture( - texture_registrar_ref_, &info); - return texture_id; + } else if (auto gpu_surface_texture = + std::get_if(texture)) { + info.type = kFlutterDesktopGpuSurfaceTexture; + info.gpu_surface_config.struct_size = + sizeof(FlutterDesktopGpuSurfaceTextureConfig); + info.gpu_surface_config.type = gpu_surface_texture->surface_type(); + info.gpu_surface_config.user_data = gpu_surface_texture; + info.gpu_surface_config.callback = + [](size_t width, size_t height, + void* user_data) -> const FlutterDesktopGpuSurfaceDescriptor* { + auto texture = static_cast(user_data); + return texture->ObtainDescriptor(width, height); + }; + } else { + std::cerr << "Attempting to register unknown texture variant." << std::endl; + return -1; } - std::cerr << "Attempting to register unknown texture variant." << std::endl; - return -1; + int64_t texture_id = FlutterDesktopTextureRegistrarRegisterExternalTexture( + texture_registrar_ref_, &info); + return texture_id; } // namespace flutter bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) { diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 6aa2c6b1..7a2078f1 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -42,10 +42,40 @@ class PixelBufferTexture { const CopyBufferCallback copy_buffer_callback_; }; +// A GPU surface-based texture. +class GpuSurfaceTexture { + public: + // A callback used for retrieving surface descriptors. + typedef std::function< + const FlutterDesktopGpuSurfaceDescriptor*(size_t width, size_t height)> + ObtainDescriptorCallback; + + GpuSurfaceTexture(FlutterDesktopGpuSurfaceType surface_type, + ObtainDescriptorCallback obtain_descriptor_callback) + : surface_type_(surface_type), + obtain_descriptor_callback_(obtain_descriptor_callback) {} + + // Returns the callback-provided FlutterDesktopGpuSurfaceDescriptor that + // contains the surface handle. The intended surface size is specified by + // |width| and |height|. + const FlutterDesktopGpuSurfaceDescriptor* ObtainDescriptor( + size_t width, + size_t height) const { + return obtain_descriptor_callback_(width, height); + } + + // Gets the surface type. + FlutterDesktopGpuSurfaceType surface_type() const { return surface_type_; } + + private: + const FlutterDesktopGpuSurfaceType surface_type_; + const ObtainDescriptorCallback obtain_descriptor_callback_; +}; + // The available texture variants. // Only PixelBufferTexture is currently implemented. // Other variants are expected to be added in the future. -typedef std::variant TextureVariant; +typedef std::variant TextureVariant; // An object keeping track of external textures. // diff --git a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h index b115234e..3ca0785e 100644 --- a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h +++ b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h @@ -23,9 +23,35 @@ typedef struct FlutterDesktopTextureRegistrar* // Additional types may be added in the future. typedef enum { // A Pixel buffer-based texture. - kFlutterDesktopPixelBufferTexture + kFlutterDesktopPixelBufferTexture, + // A platform-specific GPU surface-backed texture. + kFlutterDesktopGpuSurfaceTexture } FlutterDesktopTextureType; +// Supported GPU surface types. +typedef enum { + // Uninitialized. + kFlutterDesktopGpuSurfaceTypeNone, + // A DXGI shared texture handle (Windows only). + // See + // https://docs.microsoft.com/en-us/windows/win32/api/dxgi/nf-dxgi-idxgiresource-getsharedhandle + kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle, + // A |ID3D11Texture2D| (Windows only). + kFlutterDesktopGpuSurfaceTypeD3d11Texture2D, +} FlutterDesktopGpuSurfaceType; + +// Supported pixel formats. +typedef enum { + // Uninitialized. + kFlutterDesktopPixelFormatNone, + // Represents a 32-bit RGBA color format with 8 bits each for red, green, blue + // and alpha. + kFlutterDesktopPixelFormatRGBA8888, + // Represents a 32-bit BGRA color format with 8 bits each for blue, green, red + // and alpha. + kFlutterDesktopPixelFormatBGRA8888 +} FlutterDesktopPixelFormat; + // An image buffer object. typedef struct { // The pixel data buffer. @@ -34,22 +60,72 @@ typedef struct { size_t width; // Height of the pixel buffer. size_t height; + // An optional callback that gets invoked when the |buffer| can be released. + void (*release_callback)(void* release_context); + // Opaque data passed to |release_callback|. + void* release_context; } FlutterDesktopPixelBuffer; +// A GPU surface descriptor. +typedef struct { + // The size of this struct. Must be + // sizeof(FlutterDesktopGpuSurfaceDescriptor). + size_t struct_size; + // The surface handle. The expected type depends on the + // |FlutterDesktopGpuSurfaceType|. + // + // Provide a |ID3D11Texture2D*| when using + // |kFlutterDesktopGpuSurfaceTypeD3d11Texture2D| or a |HANDLE| when using + // |kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle|. + // + // The referenced resource needs to stay valid until it has been opened by + // Flutter. Consider incrementing the resource's reference count in the + // |FlutterDesktopGpuSurfaceTextureCallback| and registering a + // |release_callback| for decrementing the reference count once it has been + // opened. + void* handle; + // The physical width. + size_t width; + // The physical height. + size_t height; + // The visible width. + // It might be less or equal to the physical |width|. + size_t visible_width; + // The visible height. + // It might be less or equal to the physical |height|. + size_t visible_height; + // The pixel format which might be optional depending on the surface type. + FlutterDesktopPixelFormat format; + // An optional callback that gets invoked when the |handle| has been opened. + void (*release_callback)(void* release_context); + // Opaque data passed to |release_callback|. + void* release_context; +} FlutterDesktopGpuSurfaceDescriptor; + // The pixel buffer copy callback definition provided to // the Flutter engine to copy the texture. // It is invoked with the intended surface size specified by |width| and -// |height| and the |user_data| held by FlutterDesktopPixelBufferTextureConfig. +// |height| and the |user_data| held by +// |FlutterDesktopPixelBufferTextureConfig|. // // As this is usually called from the render thread, the callee must take // care of proper synchronization. It also needs to be ensured that the -// returned FlutterDesktopPixelBuffer isn't released prior to unregistering +// returned |FlutterDesktopPixelBuffer| isn't released prior to unregistering // the corresponding texture. typedef const FlutterDesktopPixelBuffer* ( *FlutterDesktopPixelBufferTextureCallback)(size_t width, size_t height, void* user_data); +// The GPU surface callback definition provided to the Flutter engine to obtain +// the surface. It is invoked with the intended surface size specified by +// |width| and |height| and the |user_data| held by +// |FlutterDesktopGpuSurfaceTextureConfig|. +typedef const FlutterDesktopGpuSurfaceDescriptor* ( + *FlutterDesktopGpuSurfaceTextureCallback)(size_t width, + size_t height, + void* user_data); + // An object used to configure pixel buffer textures. typedef struct { // The callback used by the engine to copy the pixel buffer object. @@ -58,10 +134,25 @@ typedef struct { void* user_data; } FlutterDesktopPixelBufferTextureConfig; +// An object used to configure GPU-surface textures. +typedef struct { + // The size of this struct. Must be + // sizeof(FlutterDesktopGpuSurfaceTextureConfig). + size_t struct_size; + // The concrete surface type (e.g. + // |kFlutterDesktopGpuSurfaceTypeDxgiSharedHandle|) + FlutterDesktopGpuSurfaceType type; + // The callback used by the engine to obtain the surface descriptor. + FlutterDesktopGpuSurfaceTextureCallback callback; + // Opaque data that will get passed to the provided |callback|. + void* user_data; +} FlutterDesktopGpuSurfaceTextureConfig; + typedef struct { FlutterDesktopTextureType type; union { FlutterDesktopPixelBufferTextureConfig pixel_buffer_config; + FlutterDesktopGpuSurfaceTextureConfig gpu_surface_config; }; } FlutterDesktopTextureInfo; diff --git a/src/flutter/shell/platform/embedder/embedder_struct_macros.h b/src/flutter/shell/platform/embedder/embedder_struct_macros.h new file mode 100644 index 00000000..8bd30979 --- /dev/null +++ b/src/flutter/shell/platform/embedder/embedder_struct_macros.h @@ -0,0 +1,32 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ + +#include + +// Checks if the given struct contains a member, whether set or not. +#define STRUCT_HAS_MEMBER(pointer, member) \ + ((offsetof(std::remove_pointer::type, member) + \ + sizeof(pointer->member) <= \ + pointer->struct_size)) + +#define SAFE_ACCESS(pointer, member, default_value) \ + ([=]() { \ + if (STRUCT_HAS_MEMBER(pointer, member)) { \ + return pointer->member; \ + } \ + return static_castmember)>((default_value)); \ + })() + +/// Checks if the member exists and is non-null. +#define SAFE_EXISTS(pointer, member) \ + (SAFE_ACCESS(pointer, member, nullptr) != nullptr) + +/// Checks if exactly one of member1 or member2 exists and is non-null. +#define SAFE_EXISTS_ONE_OF(pointer, member1, member2) \ + (SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ diff --git a/src/flutter/shell/platform/linux_embedded/external_texture.h b/src/flutter/shell/platform/linux_embedded/external_texture.h new file mode 100644 index 00000000..e6e92c8f --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/external_texture.h @@ -0,0 +1,61 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_ +#define FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_ + +#include "flutter/shell/platform/embedder/embedder.h" + +#ifdef USE_GLES3 +#include +#else +#include +#include +#endif + +namespace flutter { + +typedef void (*glGenTexturesProc)(GLsizei n, GLuint* textures); +typedef void (*glDeleteTexturesProc)(GLsizei n, const GLuint* textures); +typedef void (*glBindTextureProc)(GLenum target, GLuint texture); +typedef void (*glTexParameteriProc)(GLenum target, GLenum pname, GLint param); +typedef void (*glTexImage2DProc)(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void* data); + +// A struct containing pointers to resolved gl* functions. +struct GlProcs { + glGenTexturesProc glGenTextures; + glDeleteTexturesProc glDeleteTextures; + glBindTextureProc glBindTexture; + glTexParameteriProc glTexParameteri; + glTexImage2DProc glTexImage2D; + bool valid; +}; + +// Abstract external texture. +class ExternalTexture { + public: + virtual ~ExternalTexture() = default; + + // Returns the unique id of this texture. + int64_t texture_id() const { return reinterpret_cast(this); }; + + // Attempts to populate the specified |opengl_texture| with texture details + // such as the name, width, height and the pixel format. + // Returns true on success. + virtual bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) = 0; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_EXTERNAL_TEXTURE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_gl.cc b/src/flutter/shell/platform/linux_embedded/external_texture_gl.cc deleted file mode 100644 index 0b0935ea..00000000 --- a/src/flutter/shell/platform/linux_embedded/external_texture_gl.cc +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "flutter/shell/platform/linux_embedded/external_texture_gl.h" - -#include - -#ifdef USE_GLES3 -#include -#else -#include -#include -#endif - -namespace { - -typedef void (*glGenTexturesProc)(GLsizei n, GLuint* textures); -typedef void (*glDeleteTexturesProc)(GLsizei n, const GLuint* textures); -typedef void (*glBindTextureProc)(GLenum target, GLuint texture); -typedef void (*glTexParameteriProc)(GLenum target, GLenum pname, GLint param); -typedef void (*glTexImage2DProc)(GLenum target, - GLint level, - GLint internalformat, - GLsizei width, - GLsizei height, - GLint border, - GLenum format, - GLenum type, - const void* data); - -// A struct containing pointers to resolved gl* functions. -struct GlProcs { - glGenTexturesProc glGenTextures; - glDeleteTexturesProc glDeleteTextures; - glBindTextureProc glBindTexture; - glTexParameteriProc glTexParameteri; - glTexImage2DProc glTexImage2D; - bool valid; -}; - -static const GlProcs& GlProcs() { - static struct GlProcs procs = {}; - static bool initialized = false; - if (!initialized) { - procs.glGenTextures = - reinterpret_cast(eglGetProcAddress("glGenTextures")); - procs.glDeleteTextures = reinterpret_cast( - eglGetProcAddress("glDeleteTextures")); - procs.glBindTexture = - reinterpret_cast(eglGetProcAddress("glBindTexture")); - procs.glTexParameteri = reinterpret_cast( - eglGetProcAddress("glTexParameteri")); - procs.glTexImage2D = - reinterpret_cast(eglGetProcAddress("glTexImage2D")); - - procs.valid = procs.glGenTextures && procs.glDeleteTextures && - procs.glBindTexture && procs.glTexParameteri && - procs.glTexImage2D; - initialized = true; - } - return procs; -} - -} // namespace - -namespace flutter { - -struct ExternalTextureGLState { - GLuint gl_texture = 0; -}; - -ExternalTextureGL::ExternalTextureGL( - FlutterDesktopPixelBufferTextureCallback texture_callback, - void* user_data) - : state_(std::make_unique()), - texture_callback_(texture_callback), - user_data_(user_data) {} - -ExternalTextureGL::~ExternalTextureGL() { - const auto& gl = GlProcs(); - if (gl.valid && state_->gl_texture != 0) { - gl.glDeleteTextures(1, &state_->gl_texture); - } -} - -bool ExternalTextureGL::PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture) { - if (!CopyPixelBuffer(width, height)) { - return false; - } - - // Populate the texture object used by the engine. - opengl_texture->target = GL_TEXTURE_2D; - opengl_texture->name = state_->gl_texture; -#ifdef USE_GLES3 - opengl_texture->format = GL_RGBA8; -#else - opengl_texture->format = GL_RGBA8_OES; -#endif - opengl_texture->destruction_callback = nullptr; - opengl_texture->user_data = nullptr; - opengl_texture->width = width; - opengl_texture->height = height; - - return true; -} - -bool ExternalTextureGL::CopyPixelBuffer(size_t& width, size_t& height) { - const FlutterDesktopPixelBuffer* pixel_buffer = - texture_callback_(width, height, user_data_); - const auto& gl = GlProcs(); - if (!gl.valid || !pixel_buffer || !pixel_buffer->buffer) { - return false; - } - width = pixel_buffer->width; - height = pixel_buffer->height; - - if (state_->gl_texture == 0) { - gl.glGenTextures(1, &state_->gl_texture); - - gl.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); - -#ifdef USE_GLES3 - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); -#else - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, - GL_CLAMP_TO_BORDER_OES); - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, - GL_CLAMP_TO_BORDER_OES); -#endif - - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - gl.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - } else { - gl.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); - } -#ifdef USE_GLES3 - gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, pixel_buffer->width, - pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, - pixel_buffer->buffer); -#else - gl.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, - pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, - pixel_buffer->buffer); -#endif - return true; -} - -} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_gl.h b/src/flutter/shell/platform/linux_embedded/external_texture_gl.h deleted file mode 100644 index 45819d6c..00000000 --- a/src/flutter/shell/platform/linux_embedded/external_texture_gl.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2013 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_GL_H_ -#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_GL_H_ - -#include - -#include - -#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" -#include "flutter/shell/platform/embedder/embedder.h" - -namespace flutter { - -typedef struct ExternalTextureGLState ExternalTextureGLState; - -// An abstraction of an OpenGL texture. -class ExternalTextureGL { - public: - ExternalTextureGL(FlutterDesktopPixelBufferTextureCallback texture_callback, - void* user_data); - - virtual ~ExternalTextureGL(); - - // Returns the unique id of this texture. - int64_t texture_id() { return reinterpret_cast(this); } - - void MarkFrameAvailable(); - - // Attempts to populate the specified |opengl_texture| with texture details - // such as the name, width, height and the pixel format upon successfully - // copying the buffer provided by |texture_callback_|. See |CopyPixelBuffer|. - // Returns true on success or false if the pixel buffer could not be copied. - bool PopulateTexture(size_t width, - size_t height, - FlutterOpenGLTexture* opengl_texture); - - private: - // Attempts to copy the pixel buffer returned by |texture_callback_| to - // OpenGL. - // The |width| and |height| will be set to the actual bounds of the copied - // pixel buffer. - // Returns true on success or false if the pixel buffer returned - // by |texture_callback_| was invalid. - bool CopyPixelBuffer(size_t& width, size_t& height); - - std::unique_ptr state_; - FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; - void* user_data_ = nullptr; -}; - -} // namespace flutter - -#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_GL_H_ diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc b/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc new file mode 100644 index 00000000..1b962691 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc @@ -0,0 +1,82 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h" + +namespace flutter { + +struct ExternalTexturePixelBufferState { + GLuint gl_texture = 0; +}; + +ExternalTexturePixelBuffer::ExternalTexturePixelBuffer( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data, + const GlProcs& gl_procs) + : state_(std::make_unique()), + texture_callback_(texture_callback), + user_data_(user_data), + gl_(gl_procs) {} + +ExternalTexturePixelBuffer::~ExternalTexturePixelBuffer() { + if (state_->gl_texture != 0) { + gl_.glDeleteTextures(1, &state_->gl_texture); + } +} + +bool ExternalTexturePixelBuffer::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + if (!CopyPixelBuffer(width, height)) { + return false; + } + + // Populate the texture object used by the engine. + opengl_texture->target = GL_TEXTURE_2D; + opengl_texture->name = state_->gl_texture; +#ifdef USE_GLES3 + opengl_texture->format = GL_RGBA8; +#else + opengl_texture->format = GL_RGBA8_OES; +#endif + opengl_texture->destruction_callback = nullptr; + opengl_texture->user_data = nullptr; + opengl_texture->width = width; + opengl_texture->height = height; + + return true; +} + +bool ExternalTexturePixelBuffer::CopyPixelBuffer(size_t& width, + size_t& height) { + const FlutterDesktopPixelBuffer* pixel_buffer = + texture_callback_(width, height, user_data_); + if (!pixel_buffer || !pixel_buffer->buffer) { + return false; + } + width = pixel_buffer->width; + height = pixel_buffer->height; + + if (state_->gl_texture == 0) { + gl_.glGenTextures(1, &state_->gl_texture); + + gl_.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + gl_.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + } + gl_.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, pixel_buffer->width, + pixel_buffer->height, 0, GL_RGBA, GL_UNSIGNED_BYTE, + pixel_buffer->buffer); + if (pixel_buffer->release_callback) { + pixel_buffer->release_callback(pixel_buffer->release_context); + } + return true; +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h b/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h new file mode 100644 index 00000000..0d6dc67c --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h @@ -0,0 +1,52 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_PIXELBUFFER_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_PIXELBUFFER_H_ + +#include + +#include + +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" + +#include "flutter/shell/platform/linux_embedded/external_texture.h" + +namespace flutter { + +typedef struct ExternalTexturePixelBufferState ExternalTexturePixelBufferState; + +// An abstraction of an pixel-buffer based texture. +class ExternalTexturePixelBuffer : public ExternalTexture { + public: + ExternalTexturePixelBuffer( + FlutterDesktopPixelBufferTextureCallback texture_callback, + void* user_data, + const GlProcs& gl_procs); + + virtual ~ExternalTexturePixelBuffer(); + + // |ExternalTexture| + bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; + + private: + // Attempts to copy the pixel buffer returned by |texture_callback_| to + // OpenGL. + // The |width| and |height| will be set to the actual bounds of the copied + // pixel buffer. + // Returns true on success or false if the pixel buffer returned + // by |texture_callback_| was invalid. + bool CopyPixelBuffer(size_t& width, size_t& height); + + std::unique_ptr state_; + FlutterDesktopPixelBufferTextureCallback texture_callback_ = nullptr; + void* const user_data_ = nullptr; + const GlProcs& gl_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_PIXELBUFFER_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 6df08e56..38e6a028 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -131,7 +131,10 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) messenger_wrapper_ = std::make_unique(messenger_.get()); message_dispatcher_ = std::make_unique(messenger_.get()); - texture_registrar_ = std::make_unique(this); + + FlutterELinuxTextureRegistrar::ResolveGlFunctions(gl_procs_); + texture_registrar_ = + std::make_unique(this, gl_procs_); // Set up internal channels. // TODO: Replace this with an embedder.h API. See diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 11a378b6..83de54d2 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -158,6 +158,9 @@ class FlutterELinuxEngine { // The texture registrar. std::unique_ptr texture_registrar_; + // Resolved OpenGL functions used by external texture implementations. + GlProcs gl_procs_ = {}; + // The MethodChannel used for communication with the Flutter engine. std::unique_ptr> settings_channel_; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc index 8899c5fc..29fcbdd9 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc @@ -4,38 +4,55 @@ #include "flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h" -#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" - #include #include +#include "flutter/shell/platform/embedder/embedder_struct_macros.h" +#include "flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" +#include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" + +namespace { +static constexpr int64_t kInvalidTexture = -1; +} + namespace flutter { FlutterELinuxTextureRegistrar::FlutterELinuxTextureRegistrar( - FlutterELinuxEngine* engine) - : engine_(engine) {} + FlutterELinuxEngine* engine, + const GlProcs& gl_procs) + : engine_(engine), gl_procs_(gl_procs) {} int64_t FlutterELinuxTextureRegistrar::RegisterTexture( const FlutterDesktopTextureInfo* texture_info) { - if (texture_info->type != kFlutterDesktopPixelBufferTexture) { - std::cerr << "Attempted to register texture of unsupport type." - << std::endl; - return -1; + if (!gl_procs_.valid) { + return kInvalidTexture; } - if (!texture_info->pixel_buffer_config.callback) { - std::cerr << "Invalid pixel buffer texture callback." << std::endl; - return -1; + if (texture_info->type == kFlutterDesktopPixelBufferTexture) { + if (!texture_info->pixel_buffer_config.callback) { + std::cerr << "Invalid pixel buffer texture callback." << std::endl; + return kInvalidTexture; + } + + return EmplaceTexture(std::make_unique( + texture_info->pixel_buffer_config.callback, + texture_info->pixel_buffer_config.user_data, gl_procs_)); + } else if (texture_info->type == kFlutterDesktopGpuSurfaceTexture) { + std::cerr << "GpuSurfaceTexture is not yet supported." << std::endl; + return kInvalidTexture; } - auto texture_gl = std::make_unique( - texture_info->pixel_buffer_config.callback, - texture_info->pixel_buffer_config.user_data); - int64_t texture_id = texture_gl->texture_id(); + std::cerr << "Attempted to register texture of unsupport type." << std::endl; + return kInvalidTexture; +} +int64_t FlutterELinuxTextureRegistrar::EmplaceTexture( + std::unique_ptr texture) { + int64_t texture_id = texture->texture_id(); { std::lock_guard lock(map_mutex_); - textures_[texture_id] = std::move(texture_gl); + textures_[texture_id] = std::move(texture); } engine_->task_runner()->RunNowOrPostTask([engine = engine_, texture_id]() { @@ -74,7 +91,7 @@ bool FlutterELinuxTextureRegistrar::PopulateTexture( size_t width, size_t height, FlutterOpenGLTexture* opengl_texture) { - flutter::ExternalTextureGL* texture; + flutter::ExternalTexture* texture; { std::lock_guard lock(map_mutex_); auto it = textures_.find(texture_id); @@ -86,4 +103,21 @@ bool FlutterELinuxTextureRegistrar::PopulateTexture( return texture->PopulateTexture(width, height, opengl_texture); } +void FlutterELinuxTextureRegistrar::ResolveGlFunctions(GlProcs& procs) { + procs.glGenTextures = + reinterpret_cast(eglGetProcAddress("glGenTextures")); + procs.glDeleteTextures = reinterpret_cast( + eglGetProcAddress("glDeleteTextures")); + procs.glBindTexture = + reinterpret_cast(eglGetProcAddress("glBindTexture")); + procs.glTexParameteri = reinterpret_cast( + eglGetProcAddress("glTexParameteri")); + procs.glTexImage2D = + reinterpret_cast(eglGetProcAddress("glTexImage2D")); + + procs.valid = procs.glGenTextures && procs.glDeleteTextures && + procs.glBindTexture && procs.glTexParameteri && + procs.glTexImage2D; +} + }; // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h index 0b46a1fa..7ad57a2f 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h @@ -9,7 +9,8 @@ #include #include -#include "flutter/shell/platform/linux_embedded/external_texture_gl.h" +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" +#include "flutter/shell/platform/linux_embedded/external_texture.h" namespace flutter { @@ -19,7 +20,8 @@ class FlutterELinuxEngine; // Thread safety: All member methods are thread safe. class FlutterELinuxTextureRegistrar { public: - explicit FlutterELinuxTextureRegistrar(FlutterELinuxEngine* engine); + explicit FlutterELinuxTextureRegistrar(FlutterELinuxEngine* engine, + const GlProcs& gl_procs); // Registers a texture described by the given |texture_info| object. // Returns the non-zero, positive texture id or -1 on error. @@ -41,13 +43,19 @@ class FlutterELinuxTextureRegistrar { size_t height, FlutterOpenGLTexture* texture); + // Populates the OpenGL function pointers in |gl_procs|. + static void ResolveGlFunctions(GlProcs& gl_procs); + private: FlutterELinuxEngine* engine_ = nullptr; + const GlProcs& gl_procs_; // All registered textures, keyed by their IDs. - std::unordered_map> + std::unordered_map> textures_; std::mutex map_mutex_; + + int64_t EmplaceTexture(std::unique_ptr texture); }; }; // namespace flutter From ecc39c2401374771db34ab588e50a9d55189f8dc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 7 Aug 2022 10:36:22 +0900 Subject: [PATCH 084/178] Add EGL alpha component of the color buffer option (#278) * Add EGL alpha component of the color buffer option Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 1 + cmake/build.cmake | 7 ++++++ .../linux_embedded/surface/context_egl.cc | 24 ++++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9fe0192a..7cfedf0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,6 +12,7 @@ project("flutter_elinux" LANGUAGES CXX C) # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) +option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) diff --git a/cmake/build.cmake b/cmake/build.cmake index c64fd5ce..c1ae62e4 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -99,6 +99,13 @@ if(ENABLE_ELINUX_EMBEDDER_LOG) ) endif() +# Enable alpha component of the egl color buffer. +if(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) + add_definitions( + -DENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER + ) +endif() + set(CPP_WRAPPER_SOURCES_CORE "src/flutter/shell/platform/common/client_wrapper/engine_method_result.cc" "src/flutter/shell/platform/common/client_wrapper/standard_codec.cc" diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index 978af656..f723bd57 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -14,17 +14,19 @@ ContextEgl::ContextEgl(std::unique_ptr environment, : environment_(std::move(environment)), config_(nullptr) { EGLint config_count = 0; const EGLint attribs[] = { - // clang-format off - EGL_SURFACE_TYPE, egl_surface_type, - EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, - EGL_RED_SIZE, 8, - EGL_GREEN_SIZE, 8, - EGL_BLUE_SIZE, 8, - EGL_ALPHA_SIZE, 8, - EGL_DEPTH_SIZE, 0, - EGL_STENCIL_SIZE, 0, - EGL_NONE - // clang-format on + // clang-format off + EGL_SURFACE_TYPE, egl_surface_type, + EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, +#if defined(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) + EGL_ALPHA_SIZE, 8, +#endif + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 0, + EGL_NONE + // clang-format on }; if (eglChooseConfig(environment_->Display(), attribs, &config_, 1, &config_count) != EGL_TRUE) { From 8ddb112b192b71acb3fe91ad867b10dff34edd97 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 7 Aug 2022 14:12:19 +0900 Subject: [PATCH 085/178] Update versions of the wayland protocols correctly (#280) * Update versions of the wayland protocols correctly Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_wayland.cc | 38 +++++++++++++------ 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index be0c75e7..31c9fac3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -245,6 +246,8 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { self->wl_keyboard_ = nullptr; } }, + .name = [](void* data, struct wl_seat* wl_seat, const char* name) -> void { + }, }; const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { @@ -259,7 +262,7 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->serial_ = serial; if (self->view_properties_.use_mouse_cursor) { - self->cursor_info_.pointer = wl_pointer; + self->cursor_info_.pointer = self->wl_pointer_; self->cursor_info_.serial = serial; } @@ -1271,41 +1274,50 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, const char* interface, uint32_t version) { if (!strcmp(interface, wl_compositor_interface.name)) { + constexpr uint32_t kMaxVersion = 5; wl_compositor_ = static_cast( - wl_registry_bind(wl_registry, name, &wl_compositor_interface, 1)); + wl_registry_bind(wl_registry, name, &wl_compositor_interface, + std::min(kMaxVersion, version))); return; } if (!strcmp(interface, wl_subcompositor_interface.name)) { - wl_subcompositor_ = static_cast( - wl_registry_bind(wl_registry, name, &wl_subcompositor_interface, 1)); + constexpr uint32_t kMaxVersion = 1; + wl_subcompositor_ = static_cast(wl_registry_bind( + wl_registry, name, &wl_subcompositor_interface, kMaxVersion)); } if (!strcmp(interface, xdg_wm_base_interface.name)) { + constexpr uint32_t kMaxVersion = 3; xdg_wm_base_ = static_cast( - wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, 1)); + wl_registry_bind(wl_registry, name, &xdg_wm_base_interface, + std::min(kMaxVersion, version))); xdg_wm_base_add_listener(xdg_wm_base_, &kXdgWmBaseListener, this); return; } if (!strcmp(interface, wl_seat_interface.name)) { - wl_seat_ = static_cast( - wl_registry_bind(wl_registry, name, &wl_seat_interface, 1)); + constexpr uint32_t kMaxVersion = 4; + wl_seat_ = static_cast(wl_registry_bind( + wl_registry, name, &wl_seat_interface, std::min(kMaxVersion, version))); wl_seat_add_listener(wl_seat_, &kWlSeatListener, this); return; } if (!strcmp(interface, wl_output_interface.name)) { + constexpr uint32_t kMaxVersion = 2; wl_output_ = static_cast( - wl_registry_bind(wl_registry, name, &wl_output_interface, 1)); + wl_registry_bind(wl_registry, name, &wl_output_interface, + std::min(kMaxVersion, version))); wl_output_add_listener(wl_output_, &kWlOutputListener, this); return; } if (!strcmp(interface, wl_shm_interface.name)) { if (view_properties_.use_mouse_cursor) { + constexpr uint32_t kMaxVersion = 1; wl_shm_ = static_cast( - wl_registry_bind(wl_registry, name, &wl_shm_interface, 1)); + wl_registry_bind(wl_registry, name, &wl_shm_interface, kMaxVersion)); wl_cursor_theme_ = wl_cursor_theme_load(nullptr, 32, wl_shm_); if (!wl_cursor_theme_) { ELINUX_LOG(ERROR) << "Failed to load cursor theme."; @@ -1318,18 +1330,22 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, if (!strcmp(interface, kZwpTextInputManagerV1)) { if (view_properties_.use_onscreen_keyboard) { + constexpr uint32_t kMaxVersion = 1; zwp_text_input_manager_v1_ = static_cast(wl_registry_bind( - wl_registry, name, &zwp_text_input_manager_v1_interface, 1)); + wl_registry, name, &zwp_text_input_manager_v1_interface, + kMaxVersion)); } return; } if (!strcmp(interface, kZwpTextInputManagerV3)) { if (view_properties_.use_onscreen_keyboard) { + constexpr uint32_t kMaxVersion = 1; zwp_text_input_manager_v3_ = static_cast(wl_registry_bind( - wl_registry, name, &zwp_text_input_manager_v3_interface, 1)); + wl_registry, name, &zwp_text_input_manager_v3_interface, + std::min(kMaxVersion, version))); } return; } From f1de80f92b03704d54317bb70cf94ec0c87ba24a Mon Sep 17 00:00:00 2001 From: andreadaoud <110679408+andreadaoud@users.noreply.github.com> Date: Fri, 19 Aug 2022 12:12:18 +0800 Subject: [PATCH 086/178] Add support for setting scale factor from parameters (#277) * Add support for setting scale factor from parameters Signed-off-by: Andrea Daoud * Add force scale factor support to command line arguments Signed-off-by: Andrea Daoud * Add myself to AUTHORS Signed-off-by: Andrea Daoud Signed-off-by: Andrea Daoud --- AUTHORS | 1 + .../command_options.h | 13 +++++++++++++ .../flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-drm-eglstream-backend/main.cc | 2 ++ .../flutter-drm-gbm-backend/command_options.h | 13 +++++++++++++ .../flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-drm-gbm-backend/main.cc | 2 ++ .../command_options.h | 13 +++++++++++++ .../flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-external-texture-plugin/main.cc | 2 ++ .../flutter-video-player-plugin/command_options.h | 13 +++++++++++++ .../flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-video-player-plugin/main.cc | 2 ++ examples/flutter-wayland-client/command_options.h | 13 +++++++++++++ .../flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-wayland-client/main.cc | 2 ++ examples/flutter-x11-client/command_options.h | 13 +++++++++++++ .../flutter-x11-client/flutter_embedder_options.h | 15 +++++++++++++++ examples/flutter-x11-client/main.cc | 2 ++ src/client_wrapper/flutter_view_controller.cc | 2 ++ .../include/flutter/flutter_view_controller.h | 4 ++++ .../linux_embedded/public/flutter_elinux.h | 4 ++++ .../linux_embedded/window/elinux_window_drm.h | 2 ++ .../window/elinux_window_wayland.cc | 5 ++++- .../linux_embedded/window/elinux_window_x11.cc | 2 ++ 25 files changed, 199 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 649f420b..8244baf0 100644 --- a/AUTHORS +++ b/AUTHORS @@ -6,3 +6,4 @@ Sony Group Corporation Hidenori Matsubayashi (hidenori.matsubayashi@gmail.com) +Andrea Daoud (andreadaoud6@gmail.com) diff --git a/examples/flutter-drm-eglstream-backend/command_options.h b/examples/flutter-drm-eglstream-backend/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-drm-eglstream-backend/command_options.h +++ b/examples/flutter-drm-eglstream-backend/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-drm-gbm-backend/command_options.h b/examples/flutter-drm-gbm-backend/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-drm-gbm-backend/command_options.h +++ b/examples/flutter-drm-gbm-backend/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-external-texture-plugin/command_options.h b/examples/flutter-external-texture-plugin/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-external-texture-plugin/command_options.h +++ b/examples/flutter-external-texture-plugin/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-video-player-plugin/command_options.h b/examples/flutter-video-player-plugin/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-video-player-plugin/command_options.h +++ b/examples/flutter-video-player-plugin/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-wayland-client/command_options.h b/examples/flutter-wayland-client/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-wayland-client/command_options.h +++ b/examples/flutter-wayland-client/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-x11-client/command_options.h b/examples/flutter-x11-client/command_options.h index 107a152d..ad49e840 100644 --- a/examples/flutter-x11-client/command_options.h +++ b/examples/flutter-x11-client/command_options.h @@ -56,6 +56,15 @@ class CommandOptions { ReaderInt(), required, true); } + void AddDouble(const std::string& name, + const std::string& short_name, + const std::string& description, + const double& default_value, + bool required) { + Add(name, short_name, description, default_value, + ReaderDouble(), required, true); + } + void AddString(const std::string& name, const std::string& short_name, const std::string& description, @@ -250,6 +259,10 @@ class CommandOptions { std::string operator()(const std::string& value) { return value; } }; + struct ReaderDouble { + double operator()(const std::string& value) { return std::stod(value); } + }; + class Option { public: Option(const std::string& name, diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 4c229135..cc8193fc 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -21,6 +21,9 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("force-scale-factor", "s", + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -72,6 +75,14 @@ class FlutterEmbedderOptions { } } + if (options_.Exist("force-scale-factor")) { + is_force_scale_factor_ = true; + scale_factor_ = options_.GetValue("force-scale-factor"); + } else { + is_force_scale_factor_ = false; + scale_factor_ = 1.0; + } + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -112,6 +123,8 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + bool IsForceScaleFactor() const { return is_force_scale_factor_; } + double ScaleFactor() const { return scale_factor_; } private: commandline::CommandOptions options_; @@ -126,6 +139,8 @@ class FlutterEmbedderOptions { int window_height_ = 720; flutter::FlutterViewController::ViewRotation window_view_rotation_ = flutter::FlutterViewController::ViewRotation::kRotation_0; + bool is_force_scale_factor_; + double scale_factor_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index fa4e11b8..fbc049d6 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -33,6 +33,8 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.force_scale_factor = options.IsForceScaleFactor(); + view_properties.scale_factor = options.ScaleFactor(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 4dbd58a4..28996256 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -34,6 +34,8 @@ FlutterViewController::FlutterViewController( view_properties.use_onscreen_keyboard; c_view_properties.use_window_decoration = view_properties.use_window_decoration; + c_view_properties.force_scale_factor = view_properties.force_scale_factor; + c_view_properties.scale_factor = view_properties.scale_factor; controller_ = FlutterDesktopViewControllerCreate(c_view_properties, engine_->RelinquishEngine()); diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index a5762e47..b27506ea 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -67,6 +67,10 @@ class FlutterViewController { // Uses the window decoration such as toolbar and max/min buttons. // This option is only active for Wayland backend. bool use_window_decoration; + + // Force scale factor specified by command line argument + bool force_scale_factor; + double scale_factor; } ViewProperties; // Creates a FlutterView that can be parented into a Windows View hierarchy diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 913c1fac..a8b0b5d8 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -98,6 +98,10 @@ typedef struct { // Uses the window decoration such as toolbar and max/min buttons. // This option is only active for Wayland backend. bool use_window_decoration; + + // Force scale factor specified by command line argument + bool force_scale_factor; + double scale_factor; } FlutterDesktopViewProperties; // ========== View Controller ========== diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 55e29854..0c6f9ea8 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -34,6 +34,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { ELinuxWindowDrm(FlutterDesktopViewProperties view_properties) : display_valid_(false), is_pending_cursor_add_event_(false) { view_properties_ = view_properties; + current_scale_ = + view_properties.force_scale_factor ? view_properties.scale_factor : 1.0; SetRotation(view_properties_.view_rotation); auto udev = udev_new(); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 31c9fac3..282128ca 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -565,7 +565,8 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { .scale = [](void* data, wl_output* wl_output, int32_t scale) -> void { auto self = reinterpret_cast(data); ELINUX_LOG(INFO) << "Display output scale: " << scale; - self->current_scale_ = scale; + if (!self->view_properties_.force_scale_factor) + self->current_scale_ = scale; }, }; @@ -829,6 +830,8 @@ ELinuxWindowWayland::ELinuxWindowWayland( frame_rate_(60000), window_decorations_(nullptr) { view_properties_ = view_properties; + current_scale_ = + view_properties.force_scale_factor ? view_properties.scale_factor : 1.0; SetRotation(view_properties_.view_rotation); wl_display_ = wl_display_connect(nullptr); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 792fa76a..03a52c87 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -23,6 +23,8 @@ constexpr int kButton9 = 9; ELinuxWindowX11::ELinuxWindowX11(FlutterDesktopViewProperties view_properties) { view_properties_ = view_properties; + current_scale_ = + view_properties.force_scale_factor ? view_properties.scale_factor : 1.0; SetRotation(view_properties_.view_rotation); display_ = XOpenDisplay(NULL); From 6df84828d87bf684785d016e83c1bdff10d928c3 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 20 Aug 2022 16:19:26 +0900 Subject: [PATCH 087/178] Remove unnecessary comments (#285) Signed-off-by: Hidenori Matsubayashi --- examples/flutter-drm-eglstream-backend/command_options.h | 4 +--- examples/flutter-drm-gbm-backend/command_options.h | 4 +--- examples/flutter-external-texture-plugin/command_options.h | 4 +--- examples/flutter-video-player-plugin/command_options.h | 4 +--- examples/flutter-wayland-client/command_options.h | 4 +--- examples/flutter-x11-client/command_options.h | 4 +--- 6 files changed, 6 insertions(+), 18 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/command_options.h b/examples/flutter-drm-eglstream-backend/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-drm-eglstream-backend/command_options.h +++ b/examples/flutter-drm-eglstream-backend/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { diff --git a/examples/flutter-drm-gbm-backend/command_options.h b/examples/flutter-drm-gbm-backend/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-drm-gbm-backend/command_options.h +++ b/examples/flutter-drm-gbm-backend/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { diff --git a/examples/flutter-external-texture-plugin/command_options.h b/examples/flutter-external-texture-plugin/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-external-texture-plugin/command_options.h +++ b/examples/flutter-external-texture-plugin/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { diff --git a/examples/flutter-video-player-plugin/command_options.h b/examples/flutter-video-player-plugin/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-video-player-plugin/command_options.h +++ b/examples/flutter-video-player-plugin/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { diff --git a/examples/flutter-wayland-client/command_options.h b/examples/flutter-wayland-client/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-wayland-client/command_options.h +++ b/examples/flutter-wayland-client/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { diff --git a/examples/flutter-x11-client/command_options.h b/examples/flutter-x11-client/command_options.h index ad49e840..b0de9316 100644 --- a/examples/flutter-x11-client/command_options.h +++ b/examples/flutter-x11-client/command_options.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2022 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -13,8 +13,6 @@ #include #include -// todo: Supports other types besides int, string. - namespace commandline { namespace { From c01f99b8f43968d02633ec9e630e2ff6749939ba Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 21 Aug 2022 08:48:34 +0900 Subject: [PATCH 088/178] Add vsync cmake option (default: disabled) (#286) Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 1 + cmake/build.cmake | 7 +++++++ .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 2 +- 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7cfedf0c..f8384def 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ project("flutter_elinux" LANGUAGES CXX C) option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) +option(ENABLE_VSYNC "Enable embedder vsync" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) diff --git a/cmake/build.cmake b/cmake/build.cmake index c1ae62e4..ae4feb48 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -99,6 +99,13 @@ if(ENABLE_ELINUX_EMBEDDER_LOG) ) endif() +# Enable embedder vsync. +if(ENABLE_VSYNC) + add_definitions( + -DENABLE_VSYNC + ) +endif() + # Enable alpha component of the egl color buffer. if(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) add_definitions( diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 38e6a028..df2c6f8d 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -219,7 +219,7 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { // todo: disable vsync temporarily because flutter apps will freeze when we use // this interface. See also: // https://github.com/sony/flutter-embedded-linux/issues/176 -#if 0 +#if defined(ENABLE_VSYNC) // todo: add drm/x11 support. // https://github.com/sony/flutter-embedded-linux/issues/136 // https://github.com/sony/flutter-embedded-linux/issues/137 From 9a1c5e1af740e48763797a6b4718286e6a0a2c2a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 17 Sep 2022 09:38:33 +0900 Subject: [PATCH 089/178] Update README (#291) Signed-off-by: Hidenori Matsubayashi --- README.md | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 95d6543e..85ee9334 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,16 @@ [![build-test](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml/badge.svg)](https://github.com/sony/flutter-embedded-linux/actions/workflows/build-test.yml) -This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. +This project was created to develop **non-official** embedded Linux embeddings of [Flutter](https://flutter.dev/). This embedder is focusing on embedded Linux (eLinux) system use cases. It is also implemented based on Flutter desktop for Windows and has some unique features to use it in embedded systems. -### flutter-elinux -Note that this project is the source code of the embedder. If you develop your flutter app for eLinux, use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. +If you develop flutter apps for eLinux, use [flutter-elinux](https://github.com/sony/flutter-elinux), which is a non-official extension to the [Flutter SDK](https://github.com/flutter/flutter) to build and debug Flutter apps for embedded Linux devices. + +### Repositories + +- [flutter-elinux](https://github.com/sony/flutter-elinux): Flutter tools for eLinux +- [flutter-elinux-plugins](https://github.com/sony/flutter-elinux-plugins): Flutter plugins for eLinux +- [flutter-embedded-linux](https://github.com/sony/flutter-embedded-linux): eLinux embedding for Flutter +- [meta-flutter](https://github.com/sony/meta-flutter): Yocto recipes of eLinux embedding for Flutter ## Objective & Goal Our objective is to use Flutter in embedded systems. We're developing this embedder to use Flutter in embedded products. Ultimately we would like to propose and contribute this software to the mainline of [Flutter Engine](https://github.com/flutter/engine), which means we would like to add an embedded systems version into the Flutter repo for all embedded developers. Please note that this is just our ideal, not the official opinion of the Flutter community. @@ -30,13 +36,6 @@ We would be grateful if you could give us feedback on bugs and new feature reque - API compatibility with Flutter desktop for Windows and GLFW - APIs such as MethodChannel and EventChannel are completely the same with them -## Companion repos -| Repo | Purpose | -| ------------- | ------------- | -| [flutter-elinux](https://github.com/sony/flutter-elinux) | Flutter tools for eLinux | -| [flutter-elinux-plugins](https://github.com/sony/flutter-elinux-plugins) | Flutter plugins for eLinux | -| [meta-flutter](https://github.com/sony/meta-flutter) | Yocto recipes of eLinux embedding for Flutter | - ## Documentation Documentation for this software can be found at [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). From 48a047cf977850b19075ece95f4d8f6079bd389a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 24 Oct 2022 22:51:16 +0900 Subject: [PATCH 090/178] drm: add multiple dri cards support using FLUTTER_DRM_DEVIE env (#295) Fixed https://github.com/sony/flutter-elinux/issues/143 Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/window/elinux_window_drm.h | 54 +++++++++++++++---- 1 file changed, 44 insertions(+), 10 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 0c6f9ea8..e9e5edcc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -13,7 +13,9 @@ #include #include +#include #include +#include #include "flutter/shell/platform/linux_embedded/logger.h" #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" @@ -108,23 +110,42 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| bool CreateRenderSurface(int32_t width, int32_t height) override { + std::vector devices; auto device_filename = std::getenv(kFlutterDrmDeviceEnvironmentKey); - if ((!device_filename) || (device_filename[0] == '\0')) { + if (device_filename && device_filename[0] != '\0') { + devices = split(std::string(device_filename), ':'); + } + if (devices.empty()) { ELINUX_LOG(WARNING) << kFlutterDrmDeviceEnvironmentKey << " is not set, use " << kDrmDeviceDefaultFilename; - device_filename = const_cast(kDrmDeviceDefaultFilename); - } + devices.push_back(const_cast(kDrmDeviceDefaultFilename)); + } + + bool device_found = false; + for (auto i = 0; i < devices.size(); i++) { + native_window_ = + std::make_unique(devices[i].c_str(), current_rotation_); + if (!native_window_->IsValid()) { + ELINUX_LOG(ERROR) << "Failed to create the native window (" + << devices[i] << ")."; + native_window_ = nullptr; + continue; + } - native_window_ = std::make_unique(device_filename, current_rotation_); - if (!native_window_->IsValid()) { - ELINUX_LOG(ERROR) << "Failed to create the native window"; - return false; - } + if (!RegisterUdevDrmEventLoop(devices[i].c_str())) { + ELINUX_LOG(ERROR) << "Failed to register udev drm event loop (" + << devices[i] << ")."; + native_window_ = nullptr; + continue; + } - if (!RegisterUdevDrmEventLoop(device_filename)) { - ELINUX_LOG(ERROR) << "Failed to register udev drm event loop."; + device_found = true; + ELINUX_LOG(INFO) << devices[i] << " was selected as the DRM device."; + } + if (!device_found) { return false; } + display_valid_ = true; render_surface_ = native_window_->CreateRenderSurface(); @@ -667,6 +688,19 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { kScrollOffsetMultiplier); } + std::vector split(std::string s, char delim) { + std::vector res; + std::string item; + std::stringstream ss(s); + + while (getline(ss, item, delim)) { + if (!item.empty()) { + res.push_back(item); + } + } + return res; + } + struct LibinputDeviceData { size_t id; bool is_pointer_device; From 2bbd057d907dbf7a09e211b6976d1ecd725243f6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 3 Nov 2022 13:00:21 +0900 Subject: [PATCH 091/178] Merge common source file from flutter/engine (#296) Signed-off-by: Hidenori Matsubayashi --- .../include/flutter/event_channel.h | 132 ++++++++++-------- 1 file changed, 70 insertions(+), 62 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h index fe0e1414..08c242a2 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h @@ -47,10 +47,13 @@ class EventChannel { // Registers a stream handler on this channel. // If no handler has been registered, any incoming stream setup requests will // be handled silently by providing an empty stream. + // + // Note that the EventChannel does not own the handler and will not + // unregister it on destruction. The caller is responsible for unregistering + // the handler if it should no longer be called. void SetStreamHandler(std::unique_ptr> handler) { if (!handler) { messenger_->SetMessageHandler(name_, nullptr); - is_listening_ = false; return; } @@ -61,69 +64,75 @@ class EventChannel { const MethodCodec* codec = codec_; const std::string channel_name = name_; const BinaryMessenger* messenger = messenger_; - BinaryMessageHandler binary_handler = [shared_handler, codec, channel_name, - messenger, - this](const uint8_t* message, - const size_t message_size, - BinaryReply reply) { - constexpr char kOnListenMethod[] = "listen"; - constexpr char kOnCancelMethod[] = "cancel"; - - std::unique_ptr> method_call = - codec->DecodeMethodCall(message, message_size); - if (!method_call) { - std::cerr << "Unable to construct method call from message on channel: " - << channel_name << std::endl; - reply(nullptr, 0); - return; - } - - const std::string& method = method_call->method_name(); - if (method.compare(kOnListenMethod) == 0) { - if (is_listening_) { - std::unique_ptr> error = - shared_handler->OnCancel(nullptr); - if (error) { - std::cerr << "Failed to cancel existing stream: " - << (error->error_code) << ", " << (error->error_message) - << ", " << (error->error_details); + BinaryMessageHandler binary_handler = + [shared_handler, codec, channel_name, messenger, + // Mutable state to track the handler's listening status. + is_listening = bool(false)](const uint8_t* message, + const size_t message_size, + BinaryReply reply) mutable { + constexpr char kOnListenMethod[] = "listen"; + constexpr char kOnCancelMethod[] = "cancel"; + + std::unique_ptr> method_call = + codec->DecodeMethodCall(message, message_size); + if (!method_call) { + std::cerr + << "Unable to construct method call from message on channel: " + << channel_name << std::endl; + reply(nullptr, 0); + return; } - } - is_listening_ = true; - - std::unique_ptr> result; - auto sink = std::make_unique( - messenger, channel_name, codec); - std::unique_ptr> error = - shared_handler->OnListen(method_call->arguments(), std::move(sink)); - if (error) { - result = codec->EncodeErrorEnvelope( - error->error_code, error->error_message, error->error_details); - } else { - result = codec->EncodeSuccessEnvelope(); - } - reply(result->data(), result->size()); - } else if (method.compare(kOnCancelMethod) == 0) { - std::unique_ptr> result; - if (is_listening_) { - std::unique_ptr> error = - shared_handler->OnCancel(method_call->arguments()); - if (error) { - result = codec->EncodeErrorEnvelope( - error->error_code, error->error_message, error->error_details); + + const std::string& method = method_call->method_name(); + if (method.compare(kOnListenMethod) == 0) { + if (is_listening) { + std::unique_ptr> error = + shared_handler->OnCancel(nullptr); + if (error) { + std::cerr << "Failed to cancel existing stream: " + << (error->error_code) << ", " + << (error->error_message) << ", " + << (error->error_details); + } + } + is_listening = true; + + std::unique_ptr> result; + auto sink = std::make_unique( + messenger, channel_name, codec); + std::unique_ptr> error = + shared_handler->OnListen(method_call->arguments(), + std::move(sink)); + if (error) { + result = codec->EncodeErrorEnvelope(error->error_code, + error->error_message, + error->error_details); + } else { + result = codec->EncodeSuccessEnvelope(); + } + reply(result->data(), result->size()); + } else if (method.compare(kOnCancelMethod) == 0) { + std::unique_ptr> result; + if (is_listening) { + std::unique_ptr> error = + shared_handler->OnCancel(method_call->arguments()); + if (error) { + result = codec->EncodeErrorEnvelope(error->error_code, + error->error_message, + error->error_details); + } else { + result = codec->EncodeSuccessEnvelope(); + } + is_listening = false; + } else { + result = codec->EncodeErrorEnvelope( + "error", "No active stream to cancel", nullptr); + } + reply(result->data(), result->size()); } else { - result = codec->EncodeSuccessEnvelope(); + reply(nullptr, 0); } - is_listening_ = false; - } else { - result = codec->EncodeErrorEnvelope( - "error", "No active stream to cancel", nullptr); - } - reply(result->data(), result->size()); - } else { - reply(nullptr, 0); - } - }; + }; messenger_->SetMessageHandler(name_, std::move(binary_handler)); } @@ -165,7 +174,6 @@ class EventChannel { BinaryMessenger* messenger_; const std::string name_; const MethodCodec* codec_; - bool is_listening_ = false; }; } // namespace flutter From 913c6ed58fa24fda4b9fd9957fe322f9ff4c756e Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 12 Nov 2022 11:23:48 +0900 Subject: [PATCH 092/178] Merge embedder.h from flutter/engine (#299) From https://github.com/flutter/engine/commit/3d9f48580a5cdcc84c64c711980bdc9ef43429d1 Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 148 ++++++++++++++++-- 1 file changed, 134 insertions(+), 14 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 43fd5bd5..7bef2e52 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -227,6 +227,8 @@ typedef enum { kFlutterSemanticsFlagIsSlider = 1 << 23, /// Whether the semantics node represents a keyboard key. kFlutterSemanticsFlagIsKeyboardKey = 1 << 24, + /// Whether the semantics node represents a tristate checkbox in mixed state. + kFlutterSemanticsFlagIsCheckStateMixed = 1 << 25, } FlutterSemanticsFlag; typedef enum { @@ -433,6 +435,16 @@ typedef struct { FlutterSize lower_left_corner_radius; } FlutterRoundedRect; +/// A structure to represent a damage region. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterDamage). + size_t struct_size; + /// The number of rectangles within the damage region. + size_t num_rects; + /// The actual damage region(s) in question. + FlutterRect* damage; +} FlutterDamage; + /// This information is passed to the embedder when requesting a frame buffer /// object. /// @@ -449,6 +461,13 @@ typedef uint32_t (*UIntFrameInfoCallback)( void* /* user data */, const FlutterFrameInfo* /* frame info */); +/// Callback for when a frame buffer object is requested with necessary +/// information for partial repaint. +typedef void (*FlutterFrameBufferWithDamageCallback)( + void* /* user data */, + const intptr_t /* fbo id */, + FlutterDamage* /* existing damage */); + /// This information is passed to the embedder when a surface is presented. /// /// See: \ref FlutterOpenGLRendererConfig.present_with_info. @@ -457,6 +476,10 @@ typedef struct { size_t struct_size; /// Id of the fbo backing the surface that was presented. uint32_t fbo_id; + /// Damage representing the area that the compositor needs to render. + FlutterDamage frame_damage; + /// Damage used to set the buffer's damage region. + FlutterDamage buffer_damage; } FlutterPresentInfo; /// Callback for when a surface is presented. @@ -471,7 +494,10 @@ typedef struct { BoolCallback clear_current; /// Specifying one (and only one) of `present` or `present_with_info` is /// required. Specifying both is an error and engine initialization will be - /// terminated. The return value indicates success of the present call. + /// terminated. The return value indicates success of the present call. If + /// the intent is to use dirty region management, present_with_info must be + /// defined as present will not succeed in communicating information about + /// damage. BoolCallback present; /// Specifying one (and only one) of the `fbo_callback` or /// `fbo_with_frame_info_callback` is required. Specifying both is an error @@ -520,8 +546,27 @@ typedef struct { /// required. Specifying both is an error and engine initialization will be /// terminated. When using this variant, the embedder is passed a /// `FlutterPresentInfo` struct that the embedder can use to release any - /// resources. The return value indicates success of the present call. + /// resources. The return value indicates success of the present call. This + /// callback is essential for dirty region management. If not defined, all the + /// pixels on the screen will be rendered at every frame (regardless of + /// whether damage is actually being computed or not). This is because the + /// information that is passed along to the callback contains the frame and + /// buffer damage that are essential for dirty region management. BoolPresentInfoCallback present_with_info; + /// Specifying this callback is a requirement for dirty region management. + /// Dirty region management will only render the areas of the screen that have + /// changed in between frames, greatly reducing rendering times and energy + /// consumption. To take advantage of these benefits, it is necessary to + /// define populate_existing_damage as a callback that takes user + /// data, an FBO ID, and an existing damage FlutterDamage. The callback should + /// use the given FBO ID to identify the FBO's exisiting damage (i.e. areas + /// that have changed since the FBO was last used) and use it to populate the + /// given existing damage variable. This callback is dependent on either + /// fbo_callback or fbo_with_frame_info_callback being defined as they are + /// responsible for providing populate_existing_damage with the FBO's + /// ID. Not specifying populate_existing_damage will result in full + /// repaint (i.e. rendering all the pixels on the screen at every frame). + FlutterFrameBufferWithDamageCallback populate_existing_damage; } FlutterOpenGLRendererConfig; /// Alias for id. @@ -539,6 +584,12 @@ typedef enum { kRGBA, } FlutterMetalExternalTexturePixelFormat; +/// YUV color space for the YUV external texture. +typedef enum { + kBT601FullRange, + kBT601LimitedRange, +} FlutterMetalExternalTextureYUVColorSpace; + typedef struct { /// The size of this struct. Must be sizeof(FlutterMetalExternalTexture). size_t struct_size; @@ -559,6 +610,8 @@ typedef struct { /// `FlutterEngineUnregisterExternalTexture`, the embedder has to release /// these textures. FlutterMetalTextureHandle* textures; + /// The YUV color space of the YUV external texture. + FlutterMetalExternalTextureYUVColorSpace yuv_color_space; } FlutterMetalExternalTexture; /// Callback to provide an external texture for a given texture_id. @@ -830,6 +883,7 @@ typedef enum { kFlutterPointerSignalKindNone, kFlutterPointerSignalKindScroll, kFlutterPointerSignalKindScrollInertiaCancel, + kFlutterPointerSignalKindScale, } FlutterPointerSignalKind; typedef struct { @@ -977,7 +1031,8 @@ typedef void (*FlutterDataCallback)(const uint8_t* /* data */, typedef int64_t FlutterPlatformViewIdentifier; /// `FlutterSemanticsNode` ID used as a sentinel to signal the end of a batch of -/// semantics node updates. +/// semantics node updates. This is unused if using +/// `FlutterUpdateSemanticsCallback`. FLUTTER_EXPORT extern const int32_t kFlutterSemanticsNodeIdBatchEnd; @@ -986,7 +1041,7 @@ extern const int32_t kFlutterSemanticsNodeIdBatchEnd; /// The semantics tree is maintained during the semantics phase of the pipeline /// (i.e., during PipelineOwner.flushSemantics), which happens after /// compositing. Updates are then pushed to embedders via the registered -/// `FlutterUpdateSemanticsNodeCallback`. +/// `FlutterUpdateSemanticsCallback`. typedef struct { /// The size of this struct. Must be sizeof(FlutterSemanticsNode). size_t struct_size; @@ -1028,8 +1083,8 @@ typedef struct { /// A value that `value` will have after a kFlutterSemanticsActionDecrease` /// action has been performed. const char* decreased_value; - /// The reading direction for `label`, `value`, `hint`, `increasedValue`, and - /// `decreasedValue`. + /// The reading direction for `label`, `value`, `hint`, `increasedValue`, + /// `decreasedValue`, and `tooltip`. FlutterTextDirection text_direction; /// The bounding box for this node in its coordinate system. FlutterRect rect; @@ -1050,10 +1105,13 @@ typedef struct { /// Identifier of the platform view associated with this semantics node, or /// -1 if none. FlutterPlatformViewIdentifier platform_view_id; + /// A textual tooltip attached to the node. + const char* tooltip; } FlutterSemanticsNode; /// `FlutterSemanticsCustomAction` ID used as a sentinel to signal the end of a -/// batch of semantics custom action updates. +/// batch of semantics custom action updates. This is unused if using +/// `FlutterUpdateSemanticsCallback`. FLUTTER_EXPORT extern const int32_t kFlutterSemanticsCustomActionIdBatchEnd; @@ -1080,6 +1138,20 @@ typedef struct { const char* hint; } FlutterSemanticsCustomAction; +/// A batch of updates to semantics nodes and custom actions. +typedef struct { + /// The size of the struct. Must be sizeof(FlutterSemanticsUpdate). + size_t struct_size; + /// The number of semantics node updates. + size_t nodes_count; + // Array of semantics nodes. Has length `nodes_count`. + FlutterSemanticsNode* nodes; + /// The number of semantics custom action updates. + size_t custom_actions_count; + /// Array of semantics custom actions. Has length `custom_actions_count`. + FlutterSemanticsCustomAction* custom_actions; +} FlutterSemanticsUpdate; + typedef void (*FlutterUpdateSemanticsNodeCallback)( const FlutterSemanticsNode* /* semantics node */, void* /* user data */); @@ -1088,6 +1160,10 @@ typedef void (*FlutterUpdateSemanticsCustomActionCallback)( const FlutterSemanticsCustomAction* /* semantics custom action */, void* /* user data */); +typedef void (*FlutterUpdateSemanticsCallback)( + const FlutterSemanticsUpdate* /* semantics update */, + void* /* user data*/); + typedef struct _FlutterTaskRunner* FlutterTaskRunner; typedef struct { @@ -1683,24 +1759,32 @@ typedef struct { /// The callback invoked by the engine in root isolate scope. Called /// immediately after the root isolate has been created and marked runnable. VoidCallback root_isolate_create_callback; - /// The callback invoked by the engine in order to give the embedder the - /// chance to respond to semantics node updates from the Dart application. + /// The legacy callback invoked by the engine in order to give the embedder + /// the chance to respond to semantics node updates from the Dart application. /// Semantics node updates are sent in batches terminated by a 'batch end' /// callback that is passed a sentinel `FlutterSemanticsNode` whose `id` field /// has the value `kFlutterSemanticsNodeIdBatchEnd`. /// /// The callback will be invoked on the thread on which the `FlutterEngineRun` /// call is made. + /// + /// @deprecated Prefer using `update_semantics_callback` instead. If this + /// calback is provided, `update_semantics_callback` must not + /// be provided. FlutterUpdateSemanticsNodeCallback update_semantics_node_callback; - /// The callback invoked by the engine in order to give the embedder the - /// chance to respond to updates to semantics custom actions from the Dart - /// application. Custom action updates are sent in batches terminated by a + /// The legacy callback invoked by the engine in order to give the embedder + /// the chance to respond to updates to semantics custom actions from the Dart + /// application. Custom action updates are sent in batches terminated by a /// 'batch end' callback that is passed a sentinel /// `FlutterSemanticsCustomAction` whose `id` field has the value /// `kFlutterSemanticsCustomActionIdBatchEnd`. /// /// The callback will be invoked on the thread on which the `FlutterEngineRun` /// call is made. + /// + /// @deprecated Prefer using `update_semantics_callback` instead. If this + /// calback is provided, `update_semantics_callback` must not + /// be provided. FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback; /// Path to a directory used to store data that is cached across runs of a @@ -1837,6 +1921,17 @@ typedef struct { // // The first argument is the `user_data` from `FlutterEngineInitialize`. OnPreEngineRestartCallback on_pre_engine_restart_callback; + + /// The callback invoked by the engine in order to give the embedder the + /// chance to respond to updates to semantics nodes and custom actions from + /// the Dart application. + /// + /// The callback will be invoked on the thread on which the `FlutterEngineRun` + /// call is made. + /// + /// If this callback is provided, update_semantics_node_callback and + /// update_semantics_custom_action_callback must not be provided. + FlutterUpdateSemanticsCallback update_semantics_callback; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES @@ -2178,8 +2273,8 @@ FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable( /// @param[in] engine A running engine instance. /// @param[in] enabled When enabled, changes to the semantic contents of the /// window are sent via the -/// `FlutterUpdateSemanticsNodeCallback` registered to -/// `update_semantics_node_callback` in +/// `FlutterUpdateSemanticsCallback` registered to +/// `update_semantics_callback` in /// `FlutterProjectArgs`. /// /// @return The result of the call. @@ -2510,6 +2605,26 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineScheduleFrame(FLUTTER_API_SYMBOL(FlutterEngine) engine); +//------------------------------------------------------------------------------ +/// @brief Schedule a callback to be called after the next frame is drawn. +/// This must be called from the platform thread. The callback is +/// executed only once from the raster thread; embedders must +/// re-thread if necessary. Performing blocking calls +/// in this callback may introduce application jank. +/// +/// @param[in] engine A running engine instance. +/// @param[in] callback The callback to execute. +/// @param[in] user_data A baton passed by the engine to the callback. This +/// baton is not interpreted by the engine in any way. +/// +/// @return The result of the call. +/// +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineSetNextFrameCallback( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + VoidCallback callback, + void* user_data); + #endif // !FLUTTER_ENGINE_NO_PROTOTYPES // Typedefs for the function pointers in FlutterEngineProcTable. @@ -2628,6 +2743,10 @@ typedef FlutterEngineResult (*FlutterEngineNotifyDisplayUpdateFnPtr)( size_t display_count); typedef FlutterEngineResult (*FlutterEngineScheduleFrameFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEngineSetNextFrameCallbackFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + VoidCallback callback, + void* user_data); /// Function-pointer-based versions of the APIs above. typedef struct { @@ -2673,6 +2792,7 @@ typedef struct { PostCallbackOnAllNativeThreads; FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate; FlutterEngineScheduleFrameFnPtr ScheduleFrame; + FlutterEngineSetNextFrameCallbackFnPtr SetNextFrameCallback; } FlutterEngineProcTable; //------------------------------------------------------------------------------ From ee731f304f4e1a3322da048dae5b38baae0d4612 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Nov 2022 12:31:58 +0900 Subject: [PATCH 093/178] Fix uninitialized var for touch_events (#301) Fixed #300 --- .../shell/platform/linux_embedded/flutter_elinux_view.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index 1133443f..cdcb9617 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -176,7 +176,12 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { }; struct touch_event { - touch_point points[10]; + touch_point points[10] = { + {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, + {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, + {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, {false, -1, 0, 0, 0}, + {false, -1, 0, 0, 0}, + }; }; // From 1aaebdac0d26005d50bbe26aa0aa08b78ce9065f Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 10 Dec 2022 10:45:23 +0900 Subject: [PATCH 094/178] Fix code format check errors (#303) Signed-off-by: Hidenori Matsubayashi --- src/client_wrapper/flutter_view_controller.cc | 10 +++++----- .../platform/linux_embedded/flutter_elinux_view.cc | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 28996256..98fce7ee 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -20,11 +20,11 @@ FlutterViewController::FlutterViewController( c_view_properties.view_rotation = (view_properties.view_rotation == ViewRotation::kRotation_90) ? FlutterDesktopViewRotation::kRotation_90 - : (view_properties.view_rotation == ViewRotation::kRotation_180) - ? FlutterDesktopViewRotation::kRotation_180 - : (view_properties.view_rotation == ViewRotation::kRotation_270) - ? FlutterDesktopViewRotation::kRotation_270 - : FlutterDesktopViewRotation::kRotation_0; + : (view_properties.view_rotation == ViewRotation::kRotation_180) + ? FlutterDesktopViewRotation::kRotation_180 + : (view_properties.view_rotation == ViewRotation::kRotation_270) + ? FlutterDesktopViewRotation::kRotation_270 + : FlutterDesktopViewRotation::kRotation_0; c_view_properties.view_mode = (view_properties.view_mode == ViewMode::kFullscreen) ? FlutterDesktopViewMode::kFullscreen diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index d5461760..03eab017 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -301,11 +301,11 @@ void FlutterELinuxView::SetEventPhaseFromCursorButtonState( // For details about this logic, see FlutterPointerPhase in the embedder.h // file. event_data->phase = - mouse_state_.buttons == 0 - ? mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kUp - : FlutterPointerPhase::kHover - : mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kMove - : FlutterPointerPhase::kDown; + mouse_state_.buttons == 0 ? mouse_state_.flutter_state_is_down + ? FlutterPointerPhase::kUp + : FlutterPointerPhase::kHover + : mouse_state_.flutter_state_is_down ? FlutterPointerPhase::kMove + : FlutterPointerPhase::kDown; } void FlutterELinuxView::SendPointerMove(double x, double y) { From 3cdde96d604e3a8b7168a9d5a32b404479007207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Sat, 10 Dec 2022 14:43:08 +0200 Subject: [PATCH 095/178] Use string message codec for lifecycle plugin (#302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- AUTHORS | 1 + cmake/build.cmake | 1 + .../include/flutter/string_message_codec.h | 45 +++++++++++++++++++ .../client_wrapper/string_message_codec.cc | 34 ++++++++++++++ .../plugins/lifecycle_plugin.cc | 14 +++--- .../linux_embedded/plugins/lifecycle_plugin.h | 2 +- 6 files changed, 89 insertions(+), 8 deletions(-) create mode 100644 src/flutter/shell/platform/common/client_wrapper/include/flutter/string_message_codec.h create mode 100644 src/flutter/shell/platform/common/client_wrapper/string_message_codec.cc diff --git a/AUTHORS b/AUTHORS index 8244baf0..6fb4a7df 100644 --- a/AUTHORS +++ b/AUTHORS @@ -7,3 +7,4 @@ Sony Group Corporation Hidenori Matsubayashi (hidenori.matsubayashi@gmail.com) Andrea Daoud (andreadaoud6@gmail.com) +Valentin Hăloiu (valentin.haloiu@gmail.com) diff --git a/cmake/build.cmake b/cmake/build.cmake index ae4feb48..e69ba5ee 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -116,6 +116,7 @@ endif() set(CPP_WRAPPER_SOURCES_CORE "src/flutter/shell/platform/common/client_wrapper/engine_method_result.cc" "src/flutter/shell/platform/common/client_wrapper/standard_codec.cc" + "src/flutter/shell/platform/common/client_wrapper/string_message_codec.cc" ) set(CPP_WRAPPER_SOURCES_PLUGIN "src/flutter/shell/platform/common/client_wrapper/plugin_registrar.cc" diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/string_message_codec.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/string_message_codec.h new file mode 100644 index 00000000..11f31d41 --- /dev/null +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/string_message_codec.h @@ -0,0 +1,45 @@ +// Copyright 2022 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef __CODE_FLUTTER_EMBEDDED_LINUX_SRC_FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STRING_MESSAGE_CODEC_H_ +#define __CODE_FLUTTER_EMBEDDED_LINUX_SRC_FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STRING_MESSAGE_CODEC_H_ + +#include "message_codec.h" + +namespace flutter { + +// A message encoding/decoding mechanism for communications to/from the Flutter +// engine via UTF-8 encoded string messages. +// +// This codec is guaranteed to be compatible with the corresponding +// [StringCodec](https://api.flutter.dev/flutter/services/StringCodec-class.html) +// on the Dart side. These parts of the Flutter SDK are evolved synchronously. +class StringMessageCodec : public MessageCodec { + public: + // Returns the shared instance of the codec. + static const StringMessageCodec& GetInstance(); + + ~StringMessageCodec() = default; + + // Prevent copying. + StringMessageCodec(StringMessageCodec const&) = delete; + StringMessageCodec& operator=(StringMessageCodec const&) = delete; + + protected: + // Instances should be obtained via GetInstance. + StringMessageCodec() = default; + + // |flutter::MessageCodec| + std::unique_ptr DecodeMessageInternal( + const uint8_t* binary_message, + const size_t message_size) const override; + + // |flutter::MessageCodec| + std::unique_ptr> EncodeMessageInternal( + const std::string& message) const override; +}; + +} // namespace flutter + +#endif // __CODE_FLUTTER_EMBEDDED_LINUX_SRC_FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_STRING_MESSAGE_CODEC_H_ diff --git a/src/flutter/shell/platform/common/client_wrapper/string_message_codec.cc b/src/flutter/shell/platform/common/client_wrapper/string_message_codec.cc new file mode 100644 index 00000000..d0c12bac --- /dev/null +++ b/src/flutter/shell/platform/common/client_wrapper/string_message_codec.cc @@ -0,0 +1,34 @@ +// Copyright 2022 Sony Corporation. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "include/flutter/string_message_codec.h" + +#include + +namespace flutter { + +// static +const StringMessageCodec& StringMessageCodec::GetInstance() { + static StringMessageCodec sInstance; + return sInstance; +} + +std::unique_ptr> StringMessageCodec::EncodeMessageInternal( + const std::string& message) const { + return std::make_unique>(message.begin(), message.end()); +} + +std::unique_ptr StringMessageCodec::DecodeMessageInternal( + const uint8_t* binary_message, + const size_t message_size) const { + if (!binary_message) { + return nullptr; + } + + auto raw_message = reinterpret_cast(binary_message); + + return std::make_unique(raw_message, message_size); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc index 59a9fc0f..009d82eb 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc @@ -4,7 +4,7 @@ #include "flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h" -#include "flutter/shell/platform/common/client_wrapper/include/flutter/standard_message_codec.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/string_message_codec.h" #include "flutter/shell/platform/linux_embedded/logger.h" namespace flutter { @@ -18,29 +18,29 @@ constexpr char kDetached[] = "AppLifecycleState.detached"; } // namespace LifecyclePlugin::LifecyclePlugin(BinaryMessenger* messenger) - : channel_(std::make_unique>( + : channel_(std::make_unique>( messenger, kChannelName, - &StandardMessageCodec::GetInstance())) {} + &StringMessageCodec::GetInstance())) {} void LifecyclePlugin::OnInactive() const { ELINUX_LOG(DEBUG) << "App lifecycle changed to inactive state."; - channel_->Send(EncodableValue(std::string(kInactive))); + channel_->Send(std::string(kInactive)); } void LifecyclePlugin::OnResumed() const { ELINUX_LOG(DEBUG) << "App lifecycle changed to resumed state."; - channel_->Send(EncodableValue(std::string(kResumed))); + channel_->Send(std::string(kResumed)); } void LifecyclePlugin::OnPaused() const { ELINUX_LOG(DEBUG) << "App lifecycle changed to paused state."; - channel_->Send(EncodableValue(std::string(kPaused))); + channel_->Send(std::string(kPaused)); } void LifecyclePlugin::OnDetached() const { ELINUX_LOG(DEBUG) << "App lifecycle changed to detached state."; - channel_->Send(EncodableValue(std::string(kDetached))); + channel_->Send(std::string(kDetached)); } } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h index f93881c2..aa9507c2 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h @@ -26,7 +26,7 @@ class LifecyclePlugin { void OnDetached() const; private: - std::unique_ptr> channel_; + std::unique_ptr> channel_; }; } // namespace flutter From bfb616a0f74d2f7f4c2884b48b7ed18046bc064c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Wed, 14 Dec 2022 01:20:53 +0200 Subject: [PATCH 096/178] Add support for HighDPI cursor themes (#304) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../window/elinux_window_wayland.cc | 74 +++++++++++++------ .../window/elinux_window_wayland.h | 20 +++-- 2 files changed, 66 insertions(+), 28 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 282128ca..61c6d6be 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -819,7 +819,6 @@ ELinuxWindowWayland::ELinuxWindowWayland( wl_data_device_(nullptr), wl_data_offer_(nullptr), wl_data_source_(nullptr), - wl_cursor_theme_(nullptr), serial_(0), zwp_text_input_manager_v1_(nullptr), zwp_text_input_manager_v3_(nullptr), @@ -834,6 +833,13 @@ ELinuxWindowWayland::ELinuxWindowWayland( view_properties.force_scale_factor ? view_properties.scale_factor : 1.0; SetRotation(view_properties_.view_rotation); + auto xcursor_size_string = std::getenv(kXcursorSizeEnvironmentKey); + cursor_size_ = + xcursor_size_string ? atoi(xcursor_size_string) : kDefaultPointerSize; + if (cursor_size_ <= 0) { + cursor_size_ = kDefaultPointerSize; + } + wl_display_ = wl_display_connect(nullptr); if (!wl_display_) { ELINUX_LOG(ERROR) << "Failed to connect to the Wayland display."; @@ -889,10 +895,10 @@ ELinuxWindowWayland::~ELinuxWindowWayland() { display_valid_ = false; running_ = false; - if (wl_cursor_theme_) { - wl_cursor_theme_destroy(wl_cursor_theme_); - wl_cursor_theme_ = nullptr; + for (auto theme : wl_cursor_themes_) { + wl_cursor_theme_destroy(theme.second); } + wl_cursor_themes_.clear(); { if (zwp_text_input_v1_) { @@ -1201,7 +1207,7 @@ void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { return; } - auto wl_cursor = GetWlCursor(cursor_name); + auto wl_cursor = GetWlCursor(cursor_name, cursor_size_ * current_scale_); if (!wl_cursor) { return; } @@ -1213,6 +1219,7 @@ void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { image->hotspot_y); wl_surface_attach(wl_cursor_surface_, buffer, 0, 0); wl_surface_damage(wl_cursor_surface_, 0, 0, image->width, image->height); + wl_surface_set_buffer_scale(wl_cursor_surface_, current_scale_); wl_surface_commit(wl_cursor_surface_); } } @@ -1321,12 +1328,6 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, constexpr uint32_t kMaxVersion = 1; wl_shm_ = static_cast( wl_registry_bind(wl_registry, name, &wl_shm_interface, kMaxVersion)); - wl_cursor_theme_ = wl_cursor_theme_load(nullptr, 32, wl_shm_); - if (!wl_cursor_theme_) { - ELINUX_LOG(ERROR) << "Failed to load cursor theme."; - return; - } - CreateSupportedWlCursorList(); } return; } @@ -1378,8 +1379,22 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, void ELinuxWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry, uint32_t name) {} -void ELinuxWindowWayland::CreateSupportedWlCursorList() { - std::vector wl_cursor_themes{ +bool ELinuxWindowWayland::LoadCursorTheme(uint32_t size) { + if (!wl_shm_) { + ELINUX_LOG(ERROR) << "Failed to load cursor theme because shared memory " + "buffers are not available."; + return false; + } + + auto theme = wl_cursor_theme_load(nullptr, size, wl_shm_); + if (!theme) { + ELINUX_LOG(ERROR) << "Failed to load cursor theme for size: " << size; + return false; + } + + wl_cursor_themes_[size] = theme; + + std::vector wl_cursor_names{ kWlCursorThemeLeftPtr, kWlCursorThemeBottomLeftCorner, kWlCursorThemeBottomRightCorner, @@ -1395,18 +1410,24 @@ void ELinuxWindowWayland::CreateSupportedWlCursorList() { kWlCursorThemeWatch, }; - for (const auto& theme : wl_cursor_themes) { - auto wl_cursor = - wl_cursor_theme_get_cursor(wl_cursor_theme_, theme.c_str()); + std::unordered_map cursor_list; + + for (const auto& cursor_name : wl_cursor_names) { + auto wl_cursor = wl_cursor_theme_get_cursor(theme, cursor_name.c_str()); if (!wl_cursor) { - ELINUX_LOG(ERROR) << "Unsupported cursor theme: " << theme.c_str(); + ELINUX_LOG(ERROR) << "Unsupported cursor theme: " << cursor_name.c_str(); continue; } - supported_wl_cursor_list_[theme] = wl_cursor; + cursor_list[cursor_name] = wl_cursor; } + + supported_wl_cursor_list_.insert(std::make_pair(size, cursor_list)); + + return true; } -wl_cursor* ELinuxWindowWayland::GetWlCursor(const std::string& cursor_name) { +wl_cursor* ELinuxWindowWayland::GetWlCursor(const std::string& cursor_name, + uint32_t size) { // Convert the cursor theme name from Flutter's cursor value to Wayland's one. // However, Wayland has not all cursor themes corresponding to Flutter. // If there is no Wayland's cursor theme corresponding to the Flutter's cursor @@ -1450,17 +1471,24 @@ wl_cursor* ELinuxWindowWayland::GetWlCursor(const std::string& cursor_name) { {"zoomOut", ""}, }; + if (supported_wl_cursor_list_.find(size) == supported_wl_cursor_list_.end()) { + if (!LoadCursorTheme(size)) { + return nullptr; + } + } + + auto cursor_list = supported_wl_cursor_list_.at(size); + if (flutter_to_wayland_cursor_map.find(cursor_name) != flutter_to_wayland_cursor_map.end()) { auto theme = flutter_to_wayland_cursor_map.at(cursor_name); - if (!theme.empty() && supported_wl_cursor_list_.find(theme) != - supported_wl_cursor_list_.end()) { - return supported_wl_cursor_list_[theme]; + if (!theme.empty() && cursor_list.find(theme) != cursor_list.end()) { + return cursor_list[theme]; } } ELINUX_LOG(ERROR) << "Unsupported cursor: " << cursor_name.c_str(); - return supported_wl_cursor_list_[kWlCursorThemeLeftPtr]; + return cursor_list[kWlCursorThemeLeftPtr]; } void ELinuxWindowWayland::ShowVirtualKeyboard() { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index d62ebd5a..bd7aadcc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -29,6 +29,10 @@ extern "C" { namespace flutter { +namespace { +constexpr char kXcursorSizeEnvironmentKey[] = "XCURSOR_SIZE"; +} // namespace + class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { public: ELinuxWindowWayland(FlutterDesktopViewProperties view_properties); @@ -90,9 +94,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void WlUnRegistryHandler(wl_registry* wl_registry, uint32_t name); - void CreateSupportedWlCursorList(); + bool LoadCursorTheme(uint32_t size); - wl_cursor* GetWlCursor(const std::string& cursor_name); + wl_cursor* GetWlCursor(const std::string& cursor_name, uint32_t size); void ShowVirtualKeyboard(); @@ -115,6 +119,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { static const wp_presentation_listener kWpPresentationListener; static const wp_presentation_feedback_listener kWpPresentationFeedbackListener; + static constexpr size_t kDefaultPointerSize = 24; // A pointer to a FlutterWindowsView that can be used to update engine // windowing and input state. @@ -149,7 +154,6 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_touch* wl_touch_; wl_keyboard* wl_keyboard_; wl_surface* wl_cursor_surface_; - wl_cursor_theme* wl_cursor_theme_; xdg_wm_base* xdg_wm_base_; xdg_surface* xdg_surface_; xdg_toplevel* xdg_toplevel_; @@ -167,9 +171,15 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { int32_t frame_rate_; CursorInfo cursor_info_; + size_t cursor_size_; + + // List of cursor name and wl_cursor supported by Wayland keyed by their + // (scaled) size. + std::unordered_map> + supported_wl_cursor_list_; - // List of cursor name and wl_cursor supported by Wayland. - std::unordered_map supported_wl_cursor_list_; + // List of loaded Wayland cursor themes keyed by their (scaled) size. + std::unordered_map wl_cursor_themes_; wl_data_device_manager* wl_data_device_manager_; wl_data_device* wl_data_device_; From 905bf392bb11b20ad11228dbeed02f13b4c9794f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Sun, 18 Dec 2022 01:26:03 +0200 Subject: [PATCH 097/178] Clear cursor name when leaving window (#305) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 61c6d6be..89e08fc8 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -282,6 +282,12 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->wl_current_surface_ = surface; self->serial_ = serial; + if (self->view_properties_.use_mouse_cursor) { + // Clear the cursor name in order to make sure it gets redrawn next time + // it enters the surface. + self->cursor_info_.cursor_name.clear(); + } + if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnPointerLeave(); self->pointer_x_ = -1; From 9dd66b9cb69bbfea0bcc39fda10cead94ec4ec5b Mon Sep 17 00:00:00 2001 From: Flafy Date: Wed, 21 Dec 2022 03:17:59 +0200 Subject: [PATCH 098/178] fix: use wayland-protocols from pkg-config rather than system (#306) Signed-off-by: FlafyDev --- AUTHORS | 1 + cmake/build.cmake | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 6fb4a7df..02e75d5d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,3 +8,4 @@ Sony Group Corporation Hidenori Matsubayashi (hidenori.matsubayashi@gmail.com) Andrea Daoud (andreadaoud6@gmail.com) Valentin Hăloiu (valentin.haloiu@gmail.com) +FlafyDev diff --git a/cmake/build.cmake b/cmake/build.cmake index e69ba5ee..8ea841a6 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -38,7 +38,8 @@ elseif(${BACKEND_TYPE} STREQUAL "X11") "src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc") else() include(cmake/generate_wayland_protocols.cmake) - set(_wayland_protocols_xml_dir "$ENV{PKG_CONFIG_SYSROOT_DIR}/usr/share/wayland-protocols") + pkg_get_variable(WAYLAND_PROTOCOLS_DATADIR wayland-protocols pkgdatadir) + set(_wayland_protocols_xml_dir "${WAYLAND_PROTOCOLS_DATADIR}") set(_wayland_protocols_src_dir "${CMAKE_CURRENT_SOURCE_DIR}/src/third_party/wayland/protocols") file(MAKE_DIRECTORY "${_wayland_protocols_src_dir}") From 02263619e09ec639791b0da22adeebf9ed12463d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Tue, 27 Dec 2022 12:24:56 +0200 Subject: [PATCH 099/178] Use scale factor from the window's list of entered outputs (#307) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../window/elinux_window_wayland.cc | 76 ++++++++++++++++++- .../window/elinux_window_wayland.h | 12 ++- 2 files changed, 84 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 89e08fc8..3abeb9a8 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -148,6 +148,40 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { self->running_ = false; }}; +const wl_surface_listener ELinuxWindowWayland::kWlSurfaceListener = { + .enter = + [](void* data, wl_surface* wl_surface, wl_output* output) { + // The compositor can send a null output: crbug.com/1332540 + if (!output) { + ELINUX_LOG(ERROR) << "cannot enter a NULL output"; + return; + } + + const uint32_t output_id = + wl_proxy_get_id(reinterpret_cast(output)); + ELINUX_LOG(TRACE) << "window entered output " << output_id; + auto self = reinterpret_cast(data); + + self->entered_outputs_.insert(output_id); + self->UpdateWindowScale(); + }, + .leave = + [](void* data, wl_surface* wl_surface, wl_output* output) { + // The compositor can send a null output: crbug.com/1332540 + if (!output) { + ELINUX_LOG(ERROR) << "cannot leave a NULL output"; + return; + } + + const uint32_t output_id = + wl_proxy_get_id(reinterpret_cast(output)); + ELINUX_LOG(TRACE) << "window left output " << output_id; + auto self = reinterpret_cast(data); + + self->entered_outputs_.erase(output_id); + self->UpdateWindowScale(); + }}; + const wp_presentation_listener ELinuxWindowWayland::kWpPresentationListener = { .clock_id = [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { @@ -570,9 +604,16 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { .done = [](void* data, wl_output* wl_output) -> void {}, .scale = [](void* data, wl_output* wl_output, int32_t scale) -> void { auto self = reinterpret_cast(data); - ELINUX_LOG(INFO) << "Display output scale: " << scale; - if (!self->view_properties_.force_scale_factor) - self->current_scale_ = scale; + + const uint32_t output_id = + wl_proxy_get_id(reinterpret_cast(wl_output)); + + ELINUX_LOG(INFO) << "Display scale for output(" << output_id + << "): " << scale; + + self->wl_output_scale_factors_[output_id] = scale; + + self->UpdateWindowScale(); }, }; @@ -1125,6 +1166,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { native_window_ = std::make_unique(wl_compositor_, width, height); + wl_surface_add_listener(native_window_->Surface(), &kWlSurfaceListener, this); + xdg_surface_ = xdg_wm_base_get_xdg_surface(xdg_wm_base_, native_window_->Surface()); if (!xdg_surface_) { @@ -1527,4 +1570,31 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { } } +void ELinuxWindowWayland::UpdateWindowScale() { + if (this->view_properties_.force_scale_factor) + return; + + double scale_factor = 1.0; + for (auto output_id : entered_outputs_) { + if (wl_output_scale_factors_.find(output_id) == + wl_output_scale_factors_.end()) + continue; + + auto output_scale_factor = wl_output_scale_factors_.at(output_id); + if (output_scale_factor > scale_factor) + scale_factor = output_scale_factor; + } + + if (this->current_scale_ == scale_factor) + return; + + ELINUX_LOG(TRACE) << "Window scale has changed: " << scale_factor; + this->current_scale_ = scale_factor; + + if (this->binding_handler_delegate_) { + this->binding_handler_delegate_->OnWindowSizeChanged( + this->view_properties_.width, this->view_properties_.height); + } +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index bd7aadcc..b1a0c51e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -10,7 +10,7 @@ #include #include -#include +#include #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" #include "flutter/shell/platform/linux_embedded/window/elinux_window.h" @@ -102,10 +102,14 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { void DismissVirtualKeybaord(); + // Updates the surface scale of the window from the list of entered outputs. + void UpdateWindowScale(); + static const wl_registry_listener kWlRegistryListener; static const xdg_wm_base_listener kXdgWmBaseListener; static const xdg_surface_listener kXdgSurfaceListener; static const xdg_toplevel_listener kXdgToplevelListener; + static const wl_surface_listener kWlSurfaceListener; static const wl_seat_listener kWlSeatListener; static const wl_pointer_listener kWlPointerListener; static const wl_touch_listener kWlTouchListener; @@ -181,6 +185,12 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { // List of loaded Wayland cursor themes keyed by their (scaled) size. std::unordered_map wl_cursor_themes_; + // List of outputs that the window is currently rendered on. + std::unordered_set entered_outputs_; + + // List of output scale factors keyed by their ids. + std::unordered_map wl_output_scale_factors_; + wl_data_device_manager* wl_data_device_manager_; wl_data_device* wl_data_device_; wl_data_offer* wl_data_offer_; From 640a72ff843ecec351a24f86ed8251915d411922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Thu, 29 Dec 2022 02:07:06 +0200 Subject: [PATCH 100/178] Use positive height for button resize argument (#309) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../window/renderer/window_decorations_wayland.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index 35af9d04..7cf26094 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -95,7 +95,7 @@ void WindowDecorationsWayland::Resize(const int32_t width, buttons_[i]->SetPosition( width - kButtonWidth * (i + 1) - kButtonMargin * (i + 1), -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); - buttons_[i]->Resize(kButtonWidth, -kButtonHeight); + buttons_[i]->Resize(kButtonWidth, kButtonHeight); } } From 2790806e8d5528d6227ce79da34eeac4cb5edf3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Thu, 29 Dec 2022 02:13:27 +0200 Subject: [PATCH 101/178] Continue listening to presentation feedback after discarded frame (#310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../linux_embedded/window/elinux_window_wayland.cc | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 3abeb9a8..3b4d0a1f 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -226,7 +226,18 @@ const wp_presentation_feedback_listener }, .discarded = [](void* data, - struct wp_presentation_feedback* wp_presentation_feedback) {}, + struct wp_presentation_feedback* wp_presentation_feedback) { + auto self = reinterpret_cast(data); + + if (self->window_decorations_) { + self->window_decorations_->Draw(); + } + + wp_presentation_feedback_add_listener( + ::wp_presentation_feedback(self->wp_presentation_, + self->native_window_->Surface()), + &kWpPresentationFeedbackListener, data); + }, }; const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { From 1298b57711e9a4d3e6c6a8cf030a84dce5e36a6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Fri, 30 Dec 2022 02:05:55 +0200 Subject: [PATCH 102/178] Fix cursor hotspot for scale factors different than 1 (#311) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 3b4d0a1f..df4ca359 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1274,9 +1274,9 @@ void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { auto image = wl_cursor->images[0]; auto buffer = wl_cursor_image_get_buffer(image); if (buffer) { - wl_pointer_set_cursor(cursor_info_.pointer, cursor_info_.serial, - wl_cursor_surface_, image->hotspot_x, - image->hotspot_y); + wl_pointer_set_cursor( + cursor_info_.pointer, cursor_info_.serial, wl_cursor_surface_, + image->hotspot_x / current_scale_, image->hotspot_y / current_scale_); wl_surface_attach(wl_cursor_surface_, buffer, 0, 0); wl_surface_damage(wl_cursor_surface_, 0, 0, image->width, image->height); wl_surface_set_buffer_scale(wl_cursor_surface_, current_scale_); From 4d30263afbd248074c51629ba292b42e29cb7573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Fri, 30 Dec 2022 02:53:51 +0200 Subject: [PATCH 103/178] Subtract client decorations height from flutter surface height (#312) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../window/elinux_window_wayland.cc | 16 +++++++++++++--- .../window/elinux_window_wayland.h | 3 +++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index df4ca359..8328e127 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -138,8 +138,9 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { self->window_decorations_->Resize(next_width, next_height); } if (self->binding_handler_delegate_) { - self->binding_handler_delegate_->OnWindowSizeChanged(next_width, - next_height); + self->binding_handler_delegate_->OnWindowSizeChanged( + next_width, + next_height - self->WindowDecorationsPhysicalHeight()); } }, .close = @@ -1604,8 +1605,17 @@ void ELinuxWindowWayland::UpdateWindowScale() { if (this->binding_handler_delegate_) { this->binding_handler_delegate_->OnWindowSizeChanged( - this->view_properties_.width, this->view_properties_.height); + this->view_properties_.width, + this->view_properties_.height - + this->WindowDecorationsPhysicalHeight()); } } +uint32_t ELinuxWindowWayland::WindowDecorationsPhysicalHeight() const { + if (!this->window_decorations_) + return 0; + + return this->window_decorations_->Height() * current_scale_; +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index b1a0c51e..476e61a0 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -105,6 +105,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { // Updates the surface scale of the window from the list of entered outputs. void UpdateWindowScale(); + // Get window decorations height in physical pixels. + uint32_t WindowDecorationsPhysicalHeight() const; + static const wl_registry_listener kWlRegistryListener; static const xdg_wm_base_listener kXdgWmBaseListener; static const xdg_surface_listener kXdgSurfaceListener; From 5316c729959078b445ed556623d11dc410c9352a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Fri, 30 Dec 2022 03:03:31 +0200 Subject: [PATCH 104/178] Annotate code with coordinate system information (#313) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../linux_embedded/flutter_elinux_view.cc | 67 ++++++++++--------- .../linux_embedded/flutter_elinux_view.h | 36 ++++++---- .../linux_embedded/surface/surface_base.cc | 6 +- .../linux_embedded/surface/surface_base.h | 4 +- .../surface/surface_decoration.cc | 4 +- .../surface/surface_decoration.h | 6 +- .../linux_embedded/window/elinux_window.h | 4 ++ .../window/elinux_window_wayland.cc | 19 +++--- .../window/elinux_window_wayland.h | 2 +- .../linux_embedded/window/native_window.h | 18 +++-- .../window/native_window_wayland.cc | 19 +++--- .../window/native_window_wayland.h | 8 ++- .../native_window_wayland_decoration.cc | 28 ++++---- .../window/native_window_wayland_decoration.h | 10 +-- .../window/renderer/window_decoration.h | 8 ++- .../renderer/window_decoration_button.cc | 10 +-- .../renderer/window_decoration_button.h | 4 +- .../renderer/window_decoration_titlebar.cc | 11 +-- .../renderer/window_decoration_titlebar.h | 4 +- .../renderer/window_decorations_wayland.cc | 56 +++++++++------- .../renderer/window_decorations_wayland.h | 11 ++- .../linux_embedded/window_binding_handler.h | 4 +- .../window_binding_handler_delegate.h | 30 ++++++--- 23 files changed, 216 insertions(+), 153 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 03eab017..43dfc11e 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -86,36 +86,37 @@ void FlutterELinuxView::RegisterPlatformViewFactory( platform_views_handler_->RegisterViewFactory(view_type, std::move(factory)); } -void FlutterELinuxView::OnWindowSizeChanged(size_t width, size_t height) const { - if (!GetRenderSurfaceTarget()->OnScreenSurfaceResize(width, height)) { +void FlutterELinuxView::OnWindowSizeChanged(size_t width_px, + size_t height_px) const { + if (!GetRenderSurfaceTarget()->OnScreenSurfaceResize(width_px, height_px)) { ELINUX_LOG(ERROR) << "Failed to change surface size."; return; } - SendWindowMetrics(width, height, binding_handler_->GetDpiScale()); + SendWindowMetrics(width_px, height_px, binding_handler_->GetDpiScale()); } -void FlutterELinuxView::OnPointerMove(double x, double y) { - auto trimmed_xy = GetPointerRotation(x, y); +void FlutterELinuxView::OnPointerMove(double x_px, double y_px) { + auto trimmed_xy = GetPointerRotation(x_px, y_px); SendPointerMove(trimmed_xy.first, trimmed_xy.second); } void FlutterELinuxView::OnPointerDown( - double x, - double y, + double x_px, + double y_px, FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { uint64_t mouse_buttons = mouse_state_.buttons | flutter_button; - auto trimmed_xy = GetPointerRotation(x, y); + auto trimmed_xy = GetPointerRotation(x_px, y_px); SetMouseButtons(mouse_buttons); SendPointerDown(trimmed_xy.first, trimmed_xy.second); } } -void FlutterELinuxView::OnPointerUp(double x, - double y, +void FlutterELinuxView::OnPointerUp(double x_px, + double y_px, FlutterPointerMouseButtons flutter_button) { if (flutter_button != 0) { - auto trimmed_xy = GetPointerRotation(x, y); + auto trimmed_xy = GetPointerRotation(x_px, y_px); uint64_t mouse_buttons = mouse_state_.buttons & ~flutter_button; SetMouseButtons(mouse_buttons); SendPointerUp(trimmed_xy.first, trimmed_xy.second); @@ -277,13 +278,13 @@ FlutterELinuxView::touch_point* FlutterELinuxView::GgeTouchPoint(int32_t id) { } // Sends new size information to FlutterEngine. -void FlutterELinuxView::SendWindowMetrics(size_t width, - size_t height, +void FlutterELinuxView::SendWindowMetrics(size_t width_px, + size_t height_px, double dpiScale) const { FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); - event.width = width; - event.height = height; + event.width = width_px; + event.height = height_px; event.pixel_ratio = dpiScale; engine_->SendWindowMetricsEvent(event); } @@ -308,28 +309,28 @@ void FlutterELinuxView::SetEventPhaseFromCursorButtonState( : FlutterPointerPhase::kDown; } -void FlutterELinuxView::SendPointerMove(double x, double y) { +void FlutterELinuxView::SendPointerMove(double x_px, double y_px) { FlutterPointerEvent event = {}; - event.x = x; - event.y = y; + event.x = x_px; + event.y = y_px; SetEventPhaseFromCursorButtonState(&event); SendPointerEventWithData(event); } -void FlutterELinuxView::SendPointerDown(double x, double y) { +void FlutterELinuxView::SendPointerDown(double x_px, double y_px) { FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); - event.x = x; - event.y = y; + event.x = x_px; + event.y = y_px; SendPointerEventWithData(event); SetMouseFlutterStateDown(true); } -void FlutterELinuxView::SendPointerUp(double x, double y) { +void FlutterELinuxView::SendPointerUp(double x_px, double y_px) { FlutterPointerEvent event = {}; SetEventPhaseFromCursorButtonState(&event); - event.x = x; - event.y = y; + event.x = x_px; + event.y = y_px; SendPointerEventWithData(event); if (event.phase == FlutterPointerPhase::kUp) { SetMouseFlutterStateDown(false); @@ -468,21 +469,21 @@ FlutterTransformation FlutterELinuxView::GetRootSurfaceTransformation() { return view_rotation_transformation_; } -std::pair FlutterELinuxView::GetPointerRotation(double x, - double y) { +std::pair FlutterELinuxView::GetPointerRotation(double x_px, + double y_px) { auto degree = binding_handler_->GetRotationDegree(); auto bounds = binding_handler_->GetPhysicalWindowBounds(); - std::pair res = {x, y}; + std::pair res = {x_px, y_px}; if (degree == 90) { - res.first = y; - res.second = bounds.height - x; + res.first = y_px; + res.second = bounds.height - x_px; } else if (degree == 180) { - res.first = bounds.width - x; - res.second = bounds.height - y; + res.first = bounds.width - x_px; + res.second = bounds.height - y_px; } else if (degree == 270) { - res.first = bounds.width - y; - res.second = x; + res.first = bounds.width - y_px; + res.second = x_px; } return res; } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index cdcb9617..d335ecbe 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -82,19 +82,19 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void SendInitialBounds(); // |WindowBindingHandlerDelegate| - void OnWindowSizeChanged(size_t width, size_t height) const override; + void OnWindowSizeChanged(size_t width_px, size_t height_px) const override; // |WindowBindingHandlerDelegate| - void OnPointerMove(double x, double y) override; + void OnPointerMove(double x_px, double y_px) override; // |WindowBindingHandlerDelegate| - void OnPointerDown(double x, - double y, + void OnPointerDown(double x_px, + double y_px, FlutterPointerMouseButtons button) override; // |WindowBindingHandlerDelegate| - void OnPointerUp(double x, - double y, + void OnPointerUp(double x_px, + double y_px, FlutterPointerMouseButtons button) override; // |WindowBindingHandlerDelegate| @@ -188,17 +188,27 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { touch_point* GgeTouchPoint(int32_t id); // Sends a window metrics update to the Flutter engine using current window - // dimensions in physical - void SendWindowMetrics(size_t width, size_t height, double dpiscale) const; + // dimensions in physical pixels. + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. + void SendWindowMetrics(size_t width_px, + size_t height_px, + double dpiscale) const; // Reports a mouse movement to Flutter engine. - void SendPointerMove(double x, double y); + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + void SendPointerMove(double x_px, double y_px); // Reports mouse press to Flutter engine. - void SendPointerDown(double x, double y); + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + void SendPointerDown(double x_px, double y_px); // Reports mouse release to Flutter engine. - void SendPointerUp(double x, double y); + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + void SendPointerUp(double x_px, double y_px); // Reports mouse left the window client area. // @@ -243,7 +253,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void SetMouseButtons(uint64_t buttons) { mouse_state_.buttons = buttons; } // Returns a trimmed pointer of user inputs with the window rotation. - std::pair GetPointerRotation(double x, double y); + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + std::pair GetPointerRotation(double x_px, double y_px); // The engine associated with this view. std::unique_ptr engine_; diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc index f27f4f21..1067ad57 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc @@ -29,9 +29,9 @@ bool SurfaceBase::SetNativeWindow(NativeWindow* window) { return true; }; -bool SurfaceBase::OnScreenSurfaceResize(const size_t width, - const size_t height) { - if (!native_window_->Resize(width, height)) { +bool SurfaceBase::OnScreenSurfaceResize(const size_t width_px, + const size_t height_px) { + if (!native_window_->Resize(width_px, height_px)) { ELINUX_LOG(ERROR) << "Failed to resize."; return false; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_base.h b/src/flutter/shell/platform/linux_embedded/surface/surface_base.h index d1c5e2af..1b7e23a8 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_base.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_base.h @@ -28,7 +28,9 @@ class SurfaceBase { // On-screen surface needs to be recreated after window size changed only when // using DRM-GBM backend. Because gbm-surface is recreated when the window // size changed. - bool OnScreenSurfaceResize(const size_t width, const size_t height); + // @param[in] width_px Physical width of the surface. + // @param[in] height_px Physical height of the surface. + bool OnScreenSurfaceResize(const size_t width_px, const size_t height_px); // Clears current on-screen context. bool ClearCurrentContext() const; diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc index dc7e932c..fb73a275 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc @@ -27,8 +27,8 @@ bool SurfaceDecoration::SetNativeWindow(NativeWindow* window) { return true; }; -bool SurfaceDecoration::Resize(const size_t width, const size_t height) { - if (!native_window_->Resize(width, height)) { +bool SurfaceDecoration::Resize(const size_t width_px, const size_t height_px) { + if (!native_window_->Resize(width_px, height_px)) { ELINUX_LOG(ERROR) << "Failed to resize."; return false; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h index 243a3ee1..1e44ed89 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h @@ -26,8 +26,10 @@ class SurfaceDecoration : public SurfaceGlDelegate { // Sets a netive platform's window. bool SetNativeWindow(NativeWindow* window); - // Changes an decoration surface size. - bool Resize(const size_t width, const size_t height); + // Changes a decoration surface size. + // @param[in] width_px Physical width of the surface. + // @param[in] height_px Physical height of the surface. + bool Resize(const size_t width_px, const size_t height_px); // Clears and destroys current decoration context. void DestroyContext(); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index d5ac0c4e..8c3911c2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -17,8 +17,10 @@ class ELinuxWindow { protected: virtual bool IsValid() const = 0; + // Get current window width in physical pixels. uint32_t GetCurrentWidth() const { return view_properties_.width; } + // Get current window height in physical pixels. uint32_t GetCurrentHeight() const { return view_properties_.height; } void SetRotation(FlutterDesktopViewRotation rotation) { @@ -36,7 +38,9 @@ class ELinuxWindow { FlutterDesktopViewProperties view_properties_; double current_scale_ = 1.0; uint16_t current_rotation_ = 0; + // The x coordinate of the pointer in physical pixels. double pointer_x_ = 0; + // The y coordinate of the pointer in physical pixels. double pointer_y_ = 0; std::string clipboard_data_ = ""; }; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 8328e127..11328e5a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1140,7 +1140,8 @@ bool ELinuxWindowWayland::DispatchEvent() { return true; } -bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { +bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, + int32_t height_px) { if (!display_valid_) { ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; @@ -1157,12 +1158,12 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { } if (view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen) { - width = view_properties_.width; - height = view_properties_.height; + width_px = view_properties_.width; + height_px = view_properties_.height; } - ELINUX_LOG(TRACE) << "Created the Wayland surface: " << width << "x" - << height; + ELINUX_LOG(TRACE) << "Created the Wayland surface: " << width_px << "x" + << height_px; if (view_properties_.use_mouse_cursor) { wl_cursor_surface_ = wl_compositor_create_surface(wl_compositor_); if (!wl_cursor_surface_) { @@ -1173,10 +1174,10 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { } if (current_rotation_ == 90 || current_rotation_ == 270) { - std::swap(width, height); + std::swap(width_px, height_px); } - native_window_ = - std::make_unique(wl_compositor_, width, height); + native_window_ = std::make_unique(wl_compositor_, + width_px, height_px); wl_surface_add_listener(native_window_->Surface(), &kWlSurfaceListener, this); @@ -1212,7 +1213,7 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width, int32_t height) { if (view_properties_.use_window_decoration) { window_decorations_ = std::make_unique( wl_display_, wl_compositor_, wl_subcompositor_, - native_window_->Surface(), width, height); + native_window_->Surface(), width_px, height_px); } return true; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 476e61a0..6860adaf 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -45,7 +45,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { bool DispatchEvent() override; // |FlutterWindowBindingHandler| - bool CreateRenderSurface(int32_t width, int32_t height) override; + bool CreateRenderSurface(int32_t width_px, int32_t height_px) override; // |FlutterWindowBindingHandler| void DestroyRenderSurface() override; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window.h b/src/flutter/shell/platform/linux_embedded/window/native_window.h index bbe80954..2d0f77a2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window.h @@ -21,6 +21,7 @@ class NativeWindow { // Gets a window (GBM surface) for offscreen resource. EGLNativeWindowType WindowOffscreen() const { return window_offscreen_; } + // Get physical width of the window. int32_t Width() const { if (!valid_) { return -1; @@ -28,6 +29,7 @@ class NativeWindow { return width_; } + // Get physical height of the window. int32_t Height() const { if (!valid_) { return -1; @@ -39,12 +41,16 @@ class NativeWindow { // Sets a window position. Basically, this API is used for window decorations // such as titlebar. - virtual void SetPosition(const int32_t x, const int32_t y) { - x_ = x; - y_ = y; + // @param[in] x_dip The x coordinate in logical pixels. + // @param[in] y_dip The y coordinate in logical pixels. + virtual void SetPosition(const int32_t x_dip, const int32_t y_dip) { + x_ = x_dip; + y_ = y_dip; }; - virtual bool Resize(const size_t width, const size_t height) = 0; + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. + virtual bool Resize(const size_t width_px, const size_t height_px) = 0; // Swaps frame buffers. This API performs processing only for the DRM-GBM // backend. It is prepared to make the interface common. @@ -53,9 +59,13 @@ class NativeWindow { protected: EGLNativeWindowType window_; EGLNativeWindowType window_offscreen_; + // Physical width of the window. int32_t width_; + // Physical height of the window. int32_t height_; + // The x coordinate of the window in logical pixels. int32_t x_; + // The y coordinate of the window in logical pixels. int32_t y_; bool valid_ = false; }; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc index 6f5aa398..c35df018 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc @@ -9,15 +9,15 @@ namespace flutter { NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, - const size_t width, - const size_t height) { + const size_t width_px, + const size_t height_px) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; return; } - window_ = wl_egl_window_create(surface_, width, height); + window_ = wl_egl_window_create(surface_, width_px, height_px); if (!window_) { ELINUX_LOG(ERROR) << "Failed to create the EGL window."; return; @@ -40,8 +40,8 @@ NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, } } - width_ = width; - height_ = height; + width_ = width_px; + height_ = height_px; valid_ = true; } @@ -67,15 +67,16 @@ NativeWindowWayland::~NativeWindowWayland() { } } -bool NativeWindowWayland::Resize(const size_t width, const size_t height) { +bool NativeWindowWayland::Resize(const size_t width_px, + const size_t height_px) { if (!valid_) { ELINUX_LOG(ERROR) << "Failed to resize the window."; return false; } - wl_egl_window_resize(window_, width, height, 0, 0); + wl_egl_window_resize(window_, width_px, height_px, 0, 0); - width_ = width; - height_ = height; + width_ = width_px; + height_ = height_px; return true; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h index 5688058f..b28b0f93 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h @@ -13,13 +13,15 @@ namespace flutter { class NativeWindowWayland : public NativeWindow { public: + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. NativeWindowWayland(wl_compositor* compositor, - const size_t width, - const size_t height); + const size_t width_px, + const size_t height_px); ~NativeWindowWayland(); // |NativeWindow| - bool Resize(const size_t width, const size_t height) override; + bool Resize(const size_t width_px, const size_t height_px) override; wl_surface* Surface() const { return surface_; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc index 20486eee..56eea3eb 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -12,8 +12,8 @@ NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* parent_surface, - const size_t width, - const size_t height) { + const size_t width_px, + const size_t height_px) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; @@ -35,8 +35,8 @@ NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( return; } - width_ = width; - height_ = height; + width_ = width_px; + height_ = height_px; valid_ = true; } @@ -52,29 +52,29 @@ NativeWindowWaylandDecoration::~NativeWindowWaylandDecoration() { } } -bool NativeWindowWaylandDecoration::Resize(const size_t width, - const size_t height) { +bool NativeWindowWaylandDecoration::Resize(const size_t width_px, + const size_t height_px) { if (!valid_) { ELINUX_LOG(ERROR) << "Failed to resize the window."; return false; } - width_ = width; - height_ = height; - wl_egl_window_resize(window_, width, height, 0, 0); + width_ = width_px; + height_ = height_px; + wl_egl_window_resize(window_, width_px, height_px, 0, 0); return true; } -void NativeWindowWaylandDecoration::SetPosition(const int32_t x, - const int32_t y) { +void NativeWindowWaylandDecoration::SetPosition(const int32_t x_dip, + const int32_t y_dip) { if (!valid_) { ELINUX_LOG(ERROR) << "Failed to set the position of the window."; return; } - x_ = x; - y_ = y; - wl_subsurface_set_position(subsurface_, x, y); + x_ = x_dip; + y_ = y_dip; + wl_subsurface_set_position(subsurface_, x_dip, y_dip); } } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h index d270c338..72664006 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -14,18 +14,20 @@ namespace flutter { class NativeWindowWaylandDecoration : public NativeWindow { public: + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. NativeWindowWaylandDecoration(wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* parent_surface, - const size_t width, - const size_t height); + const size_t width_px, + const size_t height_px); ~NativeWindowWaylandDecoration(); // |NativeWindow| - bool Resize(const size_t width, const size_t height) override; + bool Resize(const size_t width_px, const size_t height_px) override; // |NativeWindow| - void SetPosition(const int32_t x, const int32_t y) override; + void SetPosition(const int32_t x_dip, const int32_t y_dip) override; wl_surface* Surface() const { return surface_; } diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h index d722d54c..eb98d9a1 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h @@ -28,9 +28,13 @@ class WindowDecoration { virtual void Draw() = 0; - virtual void SetPosition(const int32_t x, const int32_t y) = 0; + // @param[in] x_dip The x coordinate in logical pixels. + // @param[in] y_dip The y coordinate in logical pixels. + virtual void SetPosition(const int32_t x_dip, const int32_t y_dip) = 0; - virtual void Resize(const int32_t width, const int32_t height) = 0; + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. + virtual void Resize(const size_t width_px, const size_t height_px) = 0; void DestroyContext() const { render_surface_->DestroyContext(); }; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc index 60f071a7..aff6d693 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc @@ -198,12 +198,14 @@ void WindowDecorationButton::Draw() { render_surface_->GLContextPresent(0); } -void WindowDecorationButton::SetPosition(const int32_t x, const int32_t y) { - native_window_->SetPosition(x, y); +void WindowDecorationButton::SetPosition(const int32_t x_dip, + const int32_t y_dip) { + native_window_->SetPosition(x_dip, y_dip); } -void WindowDecorationButton::Resize(const int32_t width, const int32_t height) { - render_surface_->Resize(width, height); +void WindowDecorationButton::Resize(const size_t width_px, + const size_t height_px) { + render_surface_->Resize(width_px, height_px); } void WindowDecorationButton::LoadShader() { diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h index 89e8fc95..19eee254 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h @@ -21,10 +21,10 @@ class WindowDecorationButton : public WindowDecoration { void Draw() override; // |WindowDecoration| - void SetPosition(const int32_t x, const int32_t y) override; + void SetPosition(const int32_t x_dip, const int32_t y_dip) override; // |WindowDecoration| - void Resize(const int32_t width, const int32_t height) override; + void Resize(const size_t width_px, const size_t height_px) override; private: void LoadShader(); diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc index 47b8e69c..240418d9 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc @@ -69,13 +69,14 @@ void WindowDecorationTitlebar::Draw() { render_surface_->GLContextPresent(0); } -void WindowDecorationTitlebar::SetPosition(const int32_t x, const int32_t y) { - native_window_->SetPosition(x, y); +void WindowDecorationTitlebar::SetPosition(const int32_t x_dip, + const int32_t y_dip) { + native_window_->SetPosition(x_dip, y_dip); } -void WindowDecorationTitlebar::Resize(const int32_t width, - const int32_t height) { - render_surface_->Resize(width, height); +void WindowDecorationTitlebar::Resize(const size_t width_px, + const size_t height_px) { + render_surface_->Resize(width_px, height_px); } } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h index 9cb5fce5..74a53ed4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h @@ -19,10 +19,10 @@ class WindowDecorationTitlebar : public WindowDecoration { void Draw() override; // |WindowDecoration| - void SetPosition(const int32_t x, const int32_t y) override; + void SetPosition(const int32_t x_dip, const int32_t y_dip) override; // |WindowDecoration| - void Resize(const int32_t width, const int32_t height) override; + void Resize(const size_t width_px, const size_t height_px) override; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index 7cf26094..dd172296 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -10,11 +10,11 @@ namespace flutter { namespace { -constexpr uint kTitleBarHeight = 30; +constexpr uint kTitleBarHeightDIP = 30; -constexpr uint kButtonWidth = 15; -constexpr uint kButtonHeight = 15; -constexpr uint kButtonMargin = 10; +constexpr uint kButtonWidthDIP = 15; +constexpr uint kButtonHeightDIP = 15; +constexpr uint kButtonMarginDIP = 10; } // namespace WindowDecorationsWayland::WindowDecorationsWayland( @@ -22,53 +22,57 @@ WindowDecorationsWayland::WindowDecorationsWayland( wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* root_surface, - int32_t width, - int32_t height) { + int32_t width_dip, + int32_t height_dip) { constexpr bool sub_egl_display = true; // title-bar. titlebar_ = std::make_unique( - std::make_unique( - compositor, subcompositor, root_surface, width, kTitleBarHeight), + std::make_unique(compositor, subcompositor, + root_surface, width_dip, + kTitleBarHeightDIP), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display)))); - titlebar_->SetPosition(0, -kTitleBarHeight); + titlebar_->SetPosition(0, -kTitleBarHeightDIP); // close button. auto type = WindowDecorationButton::DecorationType::CLOSE_BUTTON; buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + compositor, subcompositor, root_surface, kButtonWidthDIP, + kButtonHeightDIP), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( - width - kButtonWidth - kButtonMargin, - -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + width_dip - kButtonWidthDIP - kButtonMarginDIP, + -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); // maximise button. type = WindowDecorationButton::DecorationType::MAXIMISE_BUTTON; buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + compositor, subcompositor, root_surface, kButtonWidthDIP, + kButtonHeightDIP), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( - width - kButtonWidth * 2 - kButtonMargin * 2, - -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + width_dip - kButtonWidthDIP * 2 - kButtonMarginDIP * 2, + -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); // minimise button. type = WindowDecorationButton::DecorationType::MINIMISE_BUTTON; buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidth, kButtonHeight), + compositor, subcompositor, root_surface, kButtonWidthDIP, + kButtonHeightDIP), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( - width - kButtonWidth * 3 - kButtonMargin * 3, - -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); + width_dip - kButtonWidthDIP * 3 - kButtonMarginDIP * 3, + -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); } WindowDecorationsWayland::~WindowDecorationsWayland() { @@ -86,16 +90,16 @@ void WindowDecorationsWayland::Draw() { } } -void WindowDecorationsWayland::Resize(const int32_t width, - const int32_t height) { - titlebar_->SetPosition(0, -kTitleBarHeight); - titlebar_->Resize(width, kTitleBarHeight); +void WindowDecorationsWayland::Resize(const int32_t width_dip, + const int32_t height_dip) { + titlebar_->SetPosition(0, -kTitleBarHeightDIP); + titlebar_->Resize(width_dip, kTitleBarHeightDIP); for (auto i = 0; i < buttons_.size(); i++) { buttons_[i]->SetPosition( - width - kButtonWidth * (i + 1) - kButtonMargin * (i + 1), - -(kButtonHeight + (kTitleBarHeight - kButtonHeight) / 2)); - buttons_[i]->Resize(kButtonWidth, kButtonHeight); + width_dip - kButtonWidthDIP * (i + 1) - kButtonMarginDIP * (i + 1), + -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); + buttons_[i]->Resize(kButtonWidthDIP, kButtonHeightDIP); } } @@ -118,7 +122,7 @@ void WindowDecorationsWayland::DestroyContext() { } int32_t WindowDecorationsWayland::Height() const { - return kTitleBarHeight; + return kTitleBarHeightDIP; } } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 607d0c3e..43f265b6 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -26,21 +26,26 @@ namespace flutter { class WindowDecorationsWayland { public: + // @param[in] width_dip Logical width of the window (i.e. surface width). + // @param[in] height_dip Logical height of the window (i.e. surface height). WindowDecorationsWayland(wl_display* display, wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* root_surface, - int32_t width, - int32_t height); + int32_t width_dip, + int32_t height_dip); ~WindowDecorationsWayland(); void Draw(); - void Resize(const int32_t width, const int32_t height); + // @param[in] width_dip Logical width of the window (i.e. surface width). + // @param[in] height_dip Logical height of the window (i.e. surface height). + void Resize(const int32_t width_dip, const int32_t height_dip); bool IsMatched(wl_surface* surface, WindowDecoration::DecorationType decoration_type) const; + // Get height in logical pixels. int32_t Height() const; private: diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index 83aa7920..ce8fffb4 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -34,7 +34,9 @@ class WindowBindingHandler { virtual bool DispatchEvent() = 0; // Create a surface. - virtual bool CreateRenderSurface(int32_t width, int32_t height) = 0; + // @param[in] width_px Physical width of the surface. + // @param[in] height_px Physical height of the surface. + virtual bool CreateRenderSurface(int32_t width_px, int32_t height_px) = 0; // Destroy a surface which is currently used. virtual void DestroyRenderSurface() = 0; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index 73f1330d..944e0e07 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -11,24 +11,32 @@ namespace flutter { class WindowBindingHandlerDelegate { public: - // Notifies delegate that backing window size has changed. - // Typically called by currently configured WindowBindingHandler - virtual void OnWindowSizeChanged(size_t width, size_t height) const = 0; - - // Notifies delegate that backing window mouse has moved. - // Typically called by currently configured WindowBindingHandler - virtual void OnPointerMove(double x, double y) = 0; + // Notifies delegate that backing window size has changed. Typically called by + // currently configured WindowBindingHandler + // @param[in] width_px Physical width of the window. + // @param[in] height_px Physical height of the window. + virtual void OnWindowSizeChanged(size_t width_px, size_t height_px) const = 0; + + // Notifies delegate that backing window mouse has moved. Typically called by + // currently configured WindowBindingHandler + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + virtual void OnPointerMove(double x_px, double y_px) = 0; // Notifies delegate that backing window mouse pointer button has been // pressed. Typically called by currently configured WindowBindingHandler - virtual void OnPointerDown(double x, - double y, + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + virtual void OnPointerDown(double x_px, + double y_px, FlutterPointerMouseButtons button) = 0; // Notifies delegate that backing window mouse pointer button has been // released. Typically called by currently configured WindowBindingHandler - virtual void OnPointerUp(double x, - double y, + // @param[in] x_px The x coordinate of the pointer event in physical pixels. + // @param[in] y_px The y coordinate of the pointer event in physical pixels. + virtual void OnPointerUp(double x_px, + double y_px, FlutterPointerMouseButtons button) = 0; // Notifies delegate that backing window mouse pointer has left the window. From d88c3c55d9bce06a864f5b51a6d5a9a71293a336 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Fri, 30 Dec 2022 21:34:43 +0200 Subject: [PATCH 105/178] Add HighDPI support for Wayland (#314) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../linux_embedded/public/flutter_elinux.h | 4 +- .../linux_embedded/window/elinux_window.h | 8 ++- .../window/elinux_window_wayland.cc | 54 ++++++++++++------- .../native_window_wayland_decoration.cc | 9 ++++ .../window/native_window_wayland_decoration.h | 4 ++ .../window/renderer/window_decoration.h | 4 ++ .../renderer/window_decoration_button.cc | 4 ++ .../renderer/window_decoration_button.h | 3 ++ .../renderer/window_decoration_titlebar.cc | 4 ++ .../renderer/window_decoration_titlebar.h | 3 ++ .../renderer/window_decorations_wayland.cc | 31 ++++++----- .../renderer/window_decorations_wayland.h | 9 +++- 12 files changed, 99 insertions(+), 38 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index a8b0b5d8..22115437 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -76,10 +76,10 @@ enum FlutterDesktopViewRotation { // Properties for configuring a Flutter view instance. typedef struct { - // View width. + // View width in logical pixels. int width; - // View height. + // View height in logical pixels. int height; // View rotation setting. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index 8c3911c2..eaec182d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -18,10 +18,14 @@ class ELinuxWindow { virtual bool IsValid() const = 0; // Get current window width in physical pixels. - uint32_t GetCurrentWidth() const { return view_properties_.width; } + uint32_t GetCurrentWidth() const { + return view_properties_.width * current_scale_; + } // Get current window height in physical pixels. - uint32_t GetCurrentHeight() const { return view_properties_.height; } + uint32_t GetCurrentHeight() const { + return view_properties_.height * current_scale_; + } void SetRotation(FlutterDesktopViewRotation rotation) { if (rotation == FlutterDesktopViewRotation::kRotation_90) { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 11328e5a..106d2a86 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -135,12 +135,14 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { self->view_properties_.width = next_width; self->view_properties_.height = next_height; if (self->window_decorations_) { - self->window_decorations_->Resize(next_width, next_height); + self->window_decorations_->Resize(next_width, next_height, + self->current_scale_); } if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnWindowSizeChanged( - next_width, - next_height - self->WindowDecorationsPhysicalHeight()); + next_width * self->current_scale_, + next_height * self->current_scale_ - + self->WindowDecorationsPhysicalHeight()); } }, .close = @@ -313,11 +315,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { } if (self->binding_handler_delegate_) { - double x = wl_fixed_to_double(surface_x); - double y = wl_fixed_to_double(surface_y); - self->binding_handler_delegate_->OnPointerMove(x, y); - self->pointer_x_ = x; - self->pointer_y_ = y; + double x_px = wl_fixed_to_double(surface_x) * self->current_scale_; + double y_px = wl_fixed_to_double(surface_y) * self->current_scale_; + self->binding_handler_delegate_->OnPointerMove(x_px, y_px); + self->pointer_x_ = x_px; + self->pointer_y_ = y_px; } }, .leave = [](void* data, @@ -347,11 +349,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { wl_fixed_t surface_y) -> void { auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { - double x = wl_fixed_to_double(surface_x); - double y = wl_fixed_to_double(surface_y); - self->binding_handler_delegate_->OnPointerMove(x, y); - self->pointer_x_ = x; - self->pointer_y_ = y; + double x_px = wl_fixed_to_double(surface_x) * self->current_scale_; + double y_px = wl_fixed_to_double(surface_y) * self->current_scale_; + self->binding_handler_delegate_->OnPointerMove(x_px, y_px); + self->pointer_x_ = x_px; + self->pointer_y_ = y_px; } }, .button = [](void* data, @@ -604,7 +606,10 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { self->view_properties_.height = height; if (self->window_decorations_) { - self->window_decorations_->Resize(width, height); + int32_t width_dip = width / self->current_scale_; + int32_t height_dip = height / self->current_scale_; + self->window_decorations_->Resize(width_dip, height_dip, + self->current_scale_); } if (self->binding_handler_delegate_) { @@ -1158,8 +1163,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, } if (view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen) { - width_px = view_properties_.width; - height_px = view_properties_.height; + width_px = view_properties_.width * current_scale_; + height_px = view_properties_.height * current_scale_; } ELINUX_LOG(TRACE) << "Created the Wayland surface: " << width_px << "x" @@ -1192,6 +1197,7 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, xdg_toplevel_ = xdg_surface_get_toplevel(xdg_surface_); xdg_toplevel_set_title(xdg_toplevel_, "Flutter"); xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this); + wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_); wl_surface_commit(native_window_->Surface()); { @@ -1211,9 +1217,11 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, render_surface_->SetNativeWindow(native_window_.get()); if (view_properties_.use_window_decoration) { + int32_t width_dip = width_px / current_scale_; + int32_t height_dip = height_px / current_scale_; window_decorations_ = std::make_unique( wl_display_, wl_compositor_, wl_subcompositor_, - native_window_->Surface(), width_px, height_px); + native_window_->Surface(), width_dip, height_dip, current_scale_); } return true; @@ -1604,10 +1612,18 @@ void ELinuxWindowWayland::UpdateWindowScale() { ELINUX_LOG(TRACE) << "Window scale has changed: " << scale_factor; this->current_scale_ = scale_factor; + wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_); + + if (this->window_decorations_) { + this->window_decorations_->Resize(this->view_properties_.width, + this->view_properties_.height, + this->current_scale_); + } + if (this->binding_handler_delegate_) { this->binding_handler_delegate_->OnWindowSizeChanged( - this->view_properties_.width, - this->view_properties_.height - + this->view_properties_.width * this->current_scale_, + this->view_properties_.height * this->current_scale_ - this->WindowDecorationsPhysicalHeight()); } } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc index 56eea3eb..6595dbc3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -77,4 +77,13 @@ void NativeWindowWaylandDecoration::SetPosition(const int32_t x_dip, wl_subsurface_set_position(subsurface_, x_dip, y_dip); } +void NativeWindowWaylandDecoration::SetScaleFactor(float scale_factor) { + if (!valid_) { + ELINUX_LOG(ERROR) << "Failed to set the scale factor of the window."; + return; + } + + wl_surface_set_buffer_scale(surface_, scale_factor); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h index 72664006..c48c0954 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -29,6 +29,10 @@ class NativeWindowWaylandDecoration : public NativeWindow { // |NativeWindow| void SetPosition(const int32_t x_dip, const int32_t y_dip) override; + // Sets the scale factor for the next commit. Scale factor persists until a + // new one is set. + void SetScaleFactor(float scale_factor); + wl_surface* Surface() const { return surface_; } private: diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h index eb98d9a1..9b36eebf 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration.h @@ -36,6 +36,10 @@ class WindowDecoration { // @param[in] height_px Physical height of the window. virtual void Resize(const size_t width_px, const size_t height_px) = 0; + // Sets the scale factor for the next commit. Scale factor persists until a + // new one is set. + virtual void SetScaleFactor(float scale_factor) = 0; + void DestroyContext() const { render_surface_->DestroyContext(); }; wl_surface* Surface() const { return native_window_->Surface(); }; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc index aff6d693..d7964d8c 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc @@ -208,6 +208,10 @@ void WindowDecorationButton::Resize(const size_t width_px, render_surface_->Resize(width_px, height_px); } +void WindowDecorationButton::SetScaleFactor(float scale_factor) { + native_window_->SetScaleFactor(scale_factor); +} + void WindowDecorationButton::LoadShader() { if (shader_) { return; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h index 19eee254..abd4e04a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.h @@ -26,6 +26,9 @@ class WindowDecorationButton : public WindowDecoration { // |WindowDecoration| void Resize(const size_t width_px, const size_t height_px) override; + // |WindowDecoration| + void SetScaleFactor(float scale_factor) override; + private: void LoadShader(); diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc index 240418d9..fd9f2da3 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.cc @@ -79,4 +79,8 @@ void WindowDecorationTitlebar::Resize(const size_t width_px, render_surface_->Resize(width_px, height_px); } +void WindowDecorationTitlebar::SetScaleFactor(float scale_factor) { + native_window_->SetScaleFactor(scale_factor); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h index 74a53ed4..a8ce9093 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_titlebar.h @@ -23,6 +23,9 @@ class WindowDecorationTitlebar : public WindowDecoration { // |WindowDecoration| void Resize(const size_t width_px, const size_t height_px) override; + + // |WindowDecoration| + void SetScaleFactor(float scale_factor) override; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index dd172296..d118573b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -23,14 +23,15 @@ WindowDecorationsWayland::WindowDecorationsWayland( wl_subcompositor* subcompositor, wl_surface* root_surface, int32_t width_dip, - int32_t height_dip) { + int32_t height_dip, + double pixel_ratio) { constexpr bool sub_egl_display = true; // title-bar. titlebar_ = std::make_unique( - std::make_unique(compositor, subcompositor, - root_surface, width_dip, - kTitleBarHeightDIP), + std::make_unique( + compositor, subcompositor, root_surface, width_dip * pixel_ratio, + kTitleBarHeightDIP * pixel_ratio), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display)))); titlebar_->SetPosition(0, -kTitleBarHeightDIP); @@ -40,8 +41,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidthDIP, - kButtonHeightDIP), + compositor, subcompositor, root_surface, + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( @@ -53,8 +54,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidthDIP, - kButtonHeightDIP), + compositor, subcompositor, root_surface, + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( @@ -66,8 +67,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( buttons_.push_back(std::make_unique( type, std::make_unique( - compositor, subcompositor, root_surface, kButtonWidthDIP, - kButtonHeightDIP), + compositor, subcompositor, root_surface, + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display))))); buttons_[type]->SetPosition( @@ -91,15 +92,19 @@ void WindowDecorationsWayland::Draw() { } void WindowDecorationsWayland::Resize(const int32_t width_dip, - const int32_t height_dip) { + const int32_t height_dip, + double pixel_ratio) { + titlebar_->SetScaleFactor(pixel_ratio); titlebar_->SetPosition(0, -kTitleBarHeightDIP); - titlebar_->Resize(width_dip, kTitleBarHeightDIP); + titlebar_->Resize(width_dip * pixel_ratio, kTitleBarHeightDIP * pixel_ratio); for (auto i = 0; i < buttons_.size(); i++) { + buttons_[i]->SetScaleFactor(pixel_ratio); buttons_[i]->SetPosition( width_dip - kButtonWidthDIP * (i + 1) - kButtonMarginDIP * (i + 1), -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); - buttons_[i]->Resize(kButtonWidthDIP, kButtonHeightDIP); + buttons_[i]->Resize(kButtonWidthDIP * pixel_ratio, + kButtonHeightDIP * pixel_ratio); } } diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 43f265b6..9910841e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -28,19 +28,24 @@ class WindowDecorationsWayland { public: // @param[in] width_dip Logical width of the window (i.e. surface width). // @param[in] height_dip Logical height of the window (i.e. surface height). + // @param[in] pixel_ratio Physical / logical pixels ratio. WindowDecorationsWayland(wl_display* display, wl_compositor* compositor, wl_subcompositor* subcompositor, wl_surface* root_surface, int32_t width_dip, - int32_t height_dip); + int32_t height_dip, + double pixel_ratio); ~WindowDecorationsWayland(); void Draw(); // @param[in] width_dip Logical width of the window (i.e. surface width). // @param[in] height_dip Logical height of the window (i.e. surface height). - void Resize(const int32_t width_dip, const int32_t height_dip); + // @param[in] pixel_ratio Physical / logical pixels ratio. + void Resize(const int32_t width_dip, + const int32_t height_dip, + double pixel_ratio); bool IsMatched(wl_surface* surface, WindowDecoration::DecorationType decoration_type) const; From 916143556b510e6bf7fb6e52fdb9ede1c27ec85f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Mon, 2 Jan 2023 01:50:56 +0200 Subject: [PATCH 106/178] Make window title and app ID configurable (#316) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-drm-eglstream-backend/main.cc | 2 ++ .../flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-drm-gbm-backend/main.cc | 2 ++ .../flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-external-texture-plugin/main.cc | 2 ++ .../flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-video-player-plugin/main.cc | 2 ++ .../flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-wayland-client/main.cc | 2 ++ .../flutter-x11-client/flutter_embedder_options.h | 13 +++++++++++-- examples/flutter-x11-client/main.cc | 2 ++ src/client_wrapper/flutter_view_controller.cc | 6 ++++++ .../include/flutter/flutter_view_controller.h | 8 ++++++++ .../platform/linux_embedded/public/flutter_elinux.h | 7 +++++++ .../linux_embedded/window/elinux_window_wayland.cc | 7 ++++++- 16 files changed, 105 insertions(+), 13 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index cc8193fc..45fd4b32 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -22,8 +22,8 @@ class FlutterEmbedderOptions { "Window rotation(degree) [0(default)|90|180|270]", 0, false); options_.AddDouble("force-scale-factor", "s", - "Force a scale factor instead using default value", 1.0, - false); + "Force a scale factor instead using default value", 1.0, + false); #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -33,6 +33,9 @@ class FlutterEmbedderOptions { options_.AddInt("width", "w", "Window width", 1280, false); options_.AddInt("height", "h", "Window height", 720, false); #else // FLUTTER_TARGET_BACKEND_WAYLAND + options_.AddString("title", "t", "Window title", "Flutter", false); + options_.AddString("app-id", "a", "XDG App ID", "dev.flutter.elinux", + false); options_.AddWithoutValue("onscreen-keyboard", "k", "Enable on-screen keyboard", false); options_.AddWithoutValue("window-decoration", "d", @@ -53,6 +56,8 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -112,6 +117,8 @@ class FlutterEmbedderOptions { } std::string BundlePath() const { return bundle_path_; } + std::string WindowTitle() const { return window_title_; } + std::string WindowAppID() const { return window_app_id_; } bool IsUseMouseCursor() const { return use_mouse_cursor_; } bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } bool IsUseWindowDecoraation() const { return use_window_decoration_; } @@ -130,6 +137,8 @@ class FlutterEmbedderOptions { commandline::CommandOptions options_; std::string bundle_path_; + std::string window_title_; + std::string window_app_id_; bool use_mouse_cursor_ = true; bool use_onscreen_keyboard_ = false; bool use_window_decoration_ = false; diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index fbc049d6..eb8a6d28 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -30,6 +30,8 @@ int main(int argc, char** argv) { view_properties.height = options.WindowHeight(); view_properties.view_mode = options.WindowViewMode(); view_properties.view_rotation = options.WindowRotation(); + view_properties.title = options.WindowTitle(); + view_properties.app_id = options.WindowAppID(); view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 98fce7ee..8891bc87 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -29,6 +29,12 @@ FlutterViewController::FlutterViewController( (view_properties.view_mode == ViewMode::kFullscreen) ? FlutterDesktopViewMode::kFullscreen : FlutterDesktopViewMode::kNormalscreen; + c_view_properties.title = view_properties.title.has_value() + ? (*view_properties.title).c_str() + : nullptr; + c_view_properties.app_id = view_properties.app_id.has_value() + ? (*view_properties.app_id).c_str() + : nullptr; c_view_properties.use_mouse_cursor = view_properties.use_mouse_cursor; c_view_properties.use_onscreen_keyboard = view_properties.use_onscreen_keyboard; diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index b27506ea..64fdad43 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -9,6 +9,7 @@ #include #include +#include #include "dart_project.h" #include "flutter_engine.h" @@ -58,6 +59,13 @@ class FlutterViewController { // and `height` will be ignored. ViewMode view_mode; + // View title. + std::optional title; + + // View XDG application ID. As a best practice, it is suggested to select an + // app ID that matches the basename of the application's .desktop file. + std::optional app_id; + // Uses mouse cursor. bool use_mouse_cursor; diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 22115437..eb3989e5 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -89,6 +89,13 @@ typedef struct { // and `height` will be ignored. FlutterDesktopViewMode view_mode; + // View title. + const char* title; + + // View XDG application ID. As a best practice, it is suggested to select an + // app ID that matches the basename of the application's .desktop file. + const char* app_id; + // Uses mouse cursor. bool use_mouse_cursor; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 106d2a86..d63cc030 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1195,7 +1195,12 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, xdg_surface_add_listener(xdg_surface_, &kXdgSurfaceListener, this); xdg_toplevel_ = xdg_surface_get_toplevel(xdg_surface_); - xdg_toplevel_set_title(xdg_toplevel_, "Flutter"); + if (view_properties_.title != nullptr) { + xdg_toplevel_set_title(xdg_toplevel_, view_properties_.title); + } + if (view_properties_.app_id != nullptr) { + xdg_toplevel_set_app_id(xdg_toplevel_, view_properties_.app_id); + } xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this); wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_); wl_surface_commit(native_window_->Surface()); From cfd702d4885138ffc010adc36a7936c4e295eb8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Tue, 3 Jan 2023 01:28:30 +0200 Subject: [PATCH 107/178] Set decoration button GL viewport to fix resize issues (#317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Valentin Hăloiu --- .../window/renderer/window_decoration_button.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc index d7964d8c..a13b8954 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decoration_button.cc @@ -21,6 +21,7 @@ struct GlProcs { PFNGLENABLEPROC glEnable; PFNGLCLEARCOLORPROC glClearColor; PFNGLCLEARPROC glClear; + PFNGLVIEWPORTPROC glViewport; PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; PFNGLDRAWARRAYSPROC glDrawArrays; @@ -41,6 +42,8 @@ static const GlProcs& GlProcs() { eglGetProcAddress("glClearColor")); procs.glClear = reinterpret_cast(eglGetProcAddress("glClear")); + procs.glViewport = + reinterpret_cast(eglGetProcAddress("glViewport")); procs.glEnableVertexAttribArray = reinterpret_cast( eglGetProcAddress("glEnableVertexAttribArray")); @@ -61,7 +64,7 @@ static const GlProcs& GlProcs() { procs.valid = procs.glEnable && procs.glClearColor && procs.glClear && procs.glEnableVertexAttribArray && procs.glLineWidth && procs.glVertexAttribPointer && procs.glDrawArrays && - procs.glDisableVertexAttribArray && + procs.glDisableVertexAttribArray && procs.glViewport && procs.glBindAttribLocation && procs.glUseProgram; if (!procs.valid) { ELINUX_LOG(ERROR) << "Failed to load GlProcs"; @@ -116,6 +119,7 @@ void WindowDecorationButton::Draw() { { gl.glClearColor(100 / 255.0f, 100 / 255.0f, 100 / 255.0f, 1.0f); gl.glClear(GL_COLOR_BUFFER_BIT); + gl.glViewport(0, 0, native_window_->Width(), native_window_->Height()); { if (!shader_) { LoadShader(); From ad3847b9b85fdc3526b577e3752d0419f19ffc41 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 3 Jan 2023 11:58:54 +0900 Subject: [PATCH 108/178] Fixed #318 (#319) Fixed #318 Signed-off-by: Hidenori Matsubayashi --- .../flutter-drm-eglstream-backend/flutter_embedder_options.h | 4 ++-- examples/flutter-drm-gbm-backend/flutter_embedder_options.h | 4 ++-- .../flutter_embedder_options.h | 4 ++-- .../flutter-video-player-plugin/flutter_embedder_options.h | 4 ++-- examples/flutter-wayland-client/flutter_embedder_options.h | 4 ++-- examples/flutter-x11-client/flutter_embedder_options.h | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 45fd4b32..612b88aa 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -56,8 +56,6 @@ class FlutterEmbedderOptions { } bundle_path_ = options_.GetValue("bundle"); - window_title_ = options_.GetValue("title"); - window_app_id_ = options_.GetValue("app-id"); use_mouse_cursor_ = !options_.Exist("no-cursor"); if (options_.Exist("rotation")) { switch (options_.GetValue("rotation")) { @@ -103,6 +101,8 @@ class FlutterEmbedderOptions { window_width_ = options_.GetValue("width"); window_height_ = options_.GetValue("height"); #else // FLUTTER_TARGET_BACKEND_WAYLAND + window_title_ = options_.GetValue("title"); + window_app_id_ = options_.GetValue("app-id"); use_onscreen_keyboard_ = options_.Exist("onscreen-keyboard"); use_window_decoration_ = options_.Exist("window-decoration"); window_view_mode_ = From ce3a7f50c14982cfda869d8c84a98bd648c3b6ca Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 3 Jan 2023 12:57:19 +0900 Subject: [PATCH 109/178] Add x11 window title support (#320) Signed-off-by: Hidenori Matsubayashi --- .../flutter_embedder_options.h | 2 ++ .../flutter-drm-gbm-backend/flutter_embedder_options.h | 2 ++ .../flutter_embedder_options.h | 2 ++ .../flutter-video-player-plugin/flutter_embedder_options.h | 2 ++ examples/flutter-wayland-client/flutter_embedder_options.h | 2 ++ examples/flutter-x11-client/flutter_embedder_options.h | 2 ++ .../platform/linux_embedded/window/elinux_window_x11.cc | 3 ++- .../platform/linux_embedded/window/native_window_x11.cc | 7 +++---- .../platform/linux_embedded/window/native_window_x11.h | 1 + 9 files changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 612b88aa..dede8b9e 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -28,6 +28,7 @@ class FlutterEmbedderOptions { defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. #elif defined(FLUTTER_TARGET_BACKEND_X11) + options_.AddString("title", "t", "Window title", "Flutter", false); options_.AddWithoutValue("fullscreen", "f", "Always full-screen display", false); options_.AddInt("width", "w", "Window width", 1280, false); @@ -94,6 +95,7 @@ class FlutterEmbedderOptions { #elif defined(FLUTTER_TARGET_BACKEND_X11) use_onscreen_keyboard_ = false; use_window_decoration_ = false; + window_title_ = options_.GetValue("title"); window_view_mode_ = options_.Exist("fullscreen") ? flutter::FlutterViewController::ViewMode::kFullscreen diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 03a52c87..9d52a494 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -129,7 +129,8 @@ bool ELinuxWindowX11::CreateRenderSurface(int32_t width, int32_t height) { std::swap(width, height); } native_window_ = std::make_unique( - display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), width, height); + display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), + view_properties_.title, width, height); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc index 05374de3..1266b6f0 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc @@ -16,11 +16,11 @@ namespace flutter { namespace { static constexpr char kWmDeleteWindow[] = "WM_DELETE_WINDOW"; -static constexpr char kWindowTitle[] = "Flutter for Embedded Linux"; } // namespace NativeWindowX11::NativeWindowX11(Display* display, VisualID visual_id, + const char* title, const size_t width, const size_t height) { XVisualInfo visualTemplate; @@ -59,11 +59,10 @@ NativeWindowX11::NativeWindowX11(Display* display, // Set the window title. { XTextProperty property; - property.value = - reinterpret_cast(const_cast(kWindowTitle)); + property.value = reinterpret_cast(const_cast(title)); property.encoding = XA_STRING; property.format = 8; - property.nitems = std::strlen(kWindowTitle); + property.nitems = std::strlen(title); XSetWMName(display, window_, &property); } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h index 03afa8c3..ed39458e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h @@ -15,6 +15,7 @@ class NativeWindowX11 : public NativeWindow { public: NativeWindowX11(Display* display, VisualID visual_id, + const char* title, const size_t width, const size_t height); ~NativeWindowX11() = default; From a03e1861f806e2bb459789d1075fb47eb9f64258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20H=C4=83loiu?= Date: Thu, 5 Jan 2023 01:04:32 +0200 Subject: [PATCH 110/178] Always respect XDG configure size regardless of state (#321) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous logic was ignoring most of the toplevel configure events unless the window was maximized or was being resized. This pull-request removes that check in order to always respect the size suggested by the compositor. This is particularly important for tiling compositors (e.g.: sway) where the window can be arbitrarily resized by the compositor even when it's not maximized (e.g.: when it's part of a tiled layout). The screen recordings below show some comparison videos of the old and new behavior. Signed-off-by: Valentin Hăloiu --- .../window/elinux_window_wayland.cc | 28 ++----------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index d63cc030..86eb33ad 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -91,36 +91,14 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { int32_t width, int32_t height, wl_array* states) { - auto is_maximized = false; - auto is_resizing = false; - uint32_t* state = static_cast(states->data); - for (auto i = 0; i < states->size; i++) { - switch (*state) { - case XDG_TOPLEVEL_STATE_MAXIMIZED: - is_maximized = true; - break; - case XDG_TOPLEVEL_STATE_RESIZING: - is_resizing = true; - break; - case XDG_TOPLEVEL_STATE_ACTIVATED: - case XDG_TOPLEVEL_STATE_FULLSCREEN: - default: - break; - } - state++; - } - auto self = reinterpret_cast(data); if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { std::swap(width, height); } - int32_t next_width = 0; - int32_t next_height = 0; - if (is_maximized || is_resizing) { - next_width = width; - next_height = height; - } else if (self->restore_window_required_) { + int32_t next_width = width; + int32_t next_height = height; + if (self->restore_window_required_) { self->restore_window_required_ = false; next_width = self->restore_window_width_; next_height = self->restore_window_height_; From 16aac2ca2ba5003a247e8436b9bd67d2d89224c0 Mon Sep 17 00:00:00 2001 From: Makoto Sato <51475851+makotosato-at@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:23:46 +0900 Subject: [PATCH 111/178] Add support EGLImage-based texture (#327) Signed-off-by: Makoto Sato --- AUTHORS | 1 + cmake/build.cmake | 1 + .../client_wrapper/core_implementations.cc | 9 ++ .../include/flutter/texture_registrar.h | 34 ++++++- .../common/public/flutter_texture_registrar.h | 34 ++++++- .../linux_embedded/external_texture.h | 3 + .../external_texture_egl_image.cc | 89 +++++++++++++++++++ .../external_texture_egl_image.h | 54 +++++++++++ .../flutter_elinux_texture_registrar.cc | 16 +++- 9 files changed, 237 insertions(+), 4 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc create mode 100644 src/flutter/shell/platform/linux_embedded/external_texture_egl_image.h diff --git a/AUTHORS b/AUTHORS index 02e75d5d..3a8e080d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -9,3 +9,4 @@ Hidenori Matsubayashi (hidenori.matsubayashi@gmail.com) Andrea Daoud (andreadaoud6@gmail.com) Valentin Hăloiu (valentin.haloiu@gmail.com) FlafyDev +Makoto Sato (makoto.sato@atmark-techno.com) diff --git a/cmake/build.cmake b/cmake/build.cmake index 8ea841a6..42308b4d 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -136,6 +136,7 @@ set(ELINUX_COMMON_SRC "src/flutter/shell/platform/linux_embedded/system_utils.cc" "src/flutter/shell/platform/linux_embedded/logger.cc" "src/flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.cc" + "src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc" "src/flutter/shell/platform/linux_embedded/vsync_waiter.cc" "src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc" "src/flutter/shell/platform/linux_embedded/plugins/keyboard_glfw_util.cc" diff --git a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc index e90b26cd..3aae66ca 100644 --- a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -180,6 +180,15 @@ int64_t TextureRegistrarImpl::RegisterTexture(TextureVariant* texture) { auto texture = static_cast(user_data); return texture->ObtainDescriptor(width, height); }; + } else if (auto egl_image_texture = std::get_if(texture)) { + info.type = kFlutterDesktopEGLImageTexture; + info.egl_image_config.user_data = egl_image_texture; + info.egl_image_config.callback = + [](size_t width, size_t height, void* egl_display, void* egl_context, + void* user_data) -> const FlutterDesktopEGLImage* { + auto texture = static_cast(user_data); + return texture->GetEGLImage(width, height, egl_display, egl_context); + }; } else { std::cerr << "Attempting to register unknown texture variant." << std::endl; return -1; diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 7a2078f1..4abe19d9 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -42,6 +42,38 @@ class PixelBufferTexture { const CopyBufferCallback copy_buffer_callback_; }; +// A EGLImage texture. +class EGLImageTexture { + public: + // A callback used for retrieving pixel buffers. + typedef std::function + GetEGLImageCallback; + + // Creates a EGLImage texture that uses the provided |get_egl_image_cb| to + // retrieve the EGLImage. + // As the callback is usually invoked from the render thread, the callee must + // take care of proper synchronization. It also needs to be ensured that the + // returned buffer isn't released prior to unregistering this texture. + explicit EGLImageTexture(GetEGLImageCallback get_egl_image_callback) + : get_egl_image_callback_(get_egl_image_callback) {} + + // Returns the callback-provided FlutterDesktopEGLImage. + // The intended surface size is specified by |width| and + // |height|. + const FlutterDesktopEGLImage* GetEGLImage(size_t width, + size_t height, + void* egl_display, + void* egl_context) const { + return get_egl_image_callback_(width, height, egl_display, egl_context); + } + + private: + const GetEGLImageCallback get_egl_image_callback_; +}; + // A GPU surface-based texture. class GpuSurfaceTexture { public: @@ -75,7 +107,7 @@ class GpuSurfaceTexture { // The available texture variants. // Only PixelBufferTexture is currently implemented. // Other variants are expected to be added in the future. -typedef std::variant TextureVariant; +typedef std::variant TextureVariant; // An object keeping track of external textures. // diff --git a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h index 3ca0785e..cc0dbd2d 100644 --- a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h +++ b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h @@ -25,7 +25,9 @@ typedef enum { // A Pixel buffer-based texture. kFlutterDesktopPixelBufferTexture, // A platform-specific GPU surface-backed texture. - kFlutterDesktopGpuSurfaceTexture + kFlutterDesktopGpuSurfaceTexture, + // An EGLImage-based texture + kFlutterDesktopEGLImageTexture } FlutterDesktopTextureType; // Supported GPU surface types. @@ -66,6 +68,20 @@ typedef struct { void* release_context; } FlutterDesktopPixelBuffer; +// An EGLImage object. +typedef struct { + // The EGLImage object.(opaque) + const void* egl_image; + // Width of the EGLImage. + size_t width; + // Height of the EGLImage. + size_t height; + // An optional callback that gets invoked when the |egl_image| can be released. + void (*release_callback)(void* release_context); + // Opaque data passed to |release_callback|. + void* release_context; +} FlutterDesktopEGLImage; + // A GPU surface descriptor. typedef struct { // The size of this struct. Must be @@ -126,6 +142,13 @@ typedef const FlutterDesktopGpuSurfaceDescriptor* ( size_t height, void* user_data); +typedef const FlutterDesktopEGLImage* ( + *FlutterDesktopEGLImageTextureCallback)(size_t width, + size_t height, + void* egl_display, + void* egl_context, + void* user_data); + // An object used to configure pixel buffer textures. typedef struct { // The callback used by the engine to copy the pixel buffer object. @@ -148,11 +171,20 @@ typedef struct { void* user_data; } FlutterDesktopGpuSurfaceTextureConfig; +// An object used to configure EGLImage textures. +typedef struct { + // The callback used by the engine to get the EGLImage object. + FlutterDesktopEGLImageTextureCallback callback; + // Opaque data that will get passed to the provided |callback|. + void* user_data; +} FlutterDesktopEGLImageTextureConfig; + typedef struct { FlutterDesktopTextureType type; union { FlutterDesktopPixelBufferTextureConfig pixel_buffer_config; FlutterDesktopGpuSurfaceTextureConfig gpu_surface_config; + FlutterDesktopEGLImageTextureConfig egl_image_config; }; } FlutterDesktopTextureInfo; diff --git a/src/flutter/shell/platform/linux_embedded/external_texture.h b/src/flutter/shell/platform/linux_embedded/external_texture.h index e6e92c8f..0a4ce93d 100644 --- a/src/flutter/shell/platform/linux_embedded/external_texture.h +++ b/src/flutter/shell/platform/linux_embedded/external_texture.h @@ -29,6 +29,8 @@ typedef void (*glTexImage2DProc)(GLenum target, GLenum format, GLenum type, const void* data); +typedef void (*glEGLImageTargetTexture2DOESProc)(GLenum target, + GLeglImageOES image); // A struct containing pointers to resolved gl* functions. struct GlProcs { @@ -37,6 +39,7 @@ struct GlProcs { glBindTextureProc glBindTexture; glTexParameteriProc glTexParameteri; glTexImage2DProc glTexImage2D; + glEGLImageTargetTexture2DOESProc glEGLImageTargetTexture2DOES; bool valid; }; diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc b/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc new file mode 100644 index 00000000..843b2f98 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.cc @@ -0,0 +1,89 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/external_texture_egl_image.h" +#include +#include + +namespace flutter { + +struct ExternalTextureEGLImageState { + GLuint gl_texture = 0; +}; + +ExternalTextureEGLImage::ExternalTextureEGLImage( + FlutterDesktopEGLImageTextureCallback texture_callback, + void* user_data, + const GlProcs& gl_procs) + : state_(std::make_unique()), + texture_callback_(texture_callback), + user_data_(user_data), + gl_(gl_procs) {} + +ExternalTextureEGLImage::~ExternalTextureEGLImage() { + if (state_->gl_texture != 0) { + gl_.glDeleteTextures(1, &state_->gl_texture); + } +} + +bool ExternalTextureEGLImage::PopulateTexture( + size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) { + if (!GetEGLImage(width, height, eglGetCurrentDisplay(), + eglGetCurrentContext())) { + return false; + } + + // Populate the texture object used by the engine. + opengl_texture->target = GL_TEXTURE_2D; + opengl_texture->name = state_->gl_texture; +#ifdef USE_GLES3 + opengl_texture->format = GL_RGBA8; +#else + opengl_texture->format = GL_RGBA8_OES; +#endif + opengl_texture->destruction_callback = nullptr; + opengl_texture->user_data = nullptr; + opengl_texture->width = width; + opengl_texture->height = height; + + return true; +} + +bool ExternalTextureEGLImage::GetEGLImage(size_t& width, + size_t& height, + void* egl_display, + void* egl_context) { + using namespace std; + + const FlutterDesktopEGLImage* egl_image = + texture_callback_(width, height, egl_display, egl_context, user_data_); + if (!egl_image || !egl_image->egl_image) { + return false; + } + width = egl_image->width; + height = egl_image->height; + + if (state_->gl_texture == 0) { + gl_.glGenTextures(1, &state_->gl_texture); + + gl_.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + gl_.glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } else { + gl_.glBindTexture(GL_TEXTURE_2D, state_->gl_texture); + } + gl_.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, + (EGLImageKHR)egl_image->egl_image); + + if (egl_image->release_callback) { + egl_image->release_callback(egl_image->release_context); + } + return true; +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.h b/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.h new file mode 100644 index 00000000..7dfaaeb4 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/external_texture_egl_image.h @@ -0,0 +1,54 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_EGL_IMAGE_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_EGL_IMAGE_H_ + +#include + +#include + +#include "flutter/shell/platform/common/public/flutter_texture_registrar.h" + +#include "flutter/shell/platform/linux_embedded/external_texture.h" + +namespace flutter { + +typedef struct ExternalTextureEGLImageState ExternalTextureEGLImageState; + +// An abstraction of an EGL Image based texture. +class ExternalTextureEGLImage : public ExternalTexture { + public: + ExternalTextureEGLImage( + FlutterDesktopEGLImageTextureCallback texture_callback, + void* user_data, + const GlProcs& gl_procs); + + virtual ~ExternalTextureEGLImage(); + + // |ExternalTexture| + bool PopulateTexture(size_t width, + size_t height, + FlutterOpenGLTexture* opengl_texture) override; + + private: + // Attempts to get the EGLImage returned by |texture_callback_| to + // OpenGL. + // The |width| and |height| will be set to the actual bounds of the EGLImage + // Returns true on success or false if the EGLImage returned + // by |texture_callback_| was invalid. + bool GetEGLImage(size_t& width, + size_t& height, + void* egl_display, + void* egl_context); + + std::unique_ptr state_; + FlutterDesktopEGLImageTextureCallback texture_callback_ = nullptr; + void* const user_data_ = nullptr; + const GlProcs& gl_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_EXTERNAL_TEXTURE_EGL_IMAGE_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc index 29fcbdd9..be4899fe 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc @@ -8,6 +8,7 @@ #include #include "flutter/shell/platform/embedder/embedder_struct_macros.h" +#include "flutter/shell/platform/linux_embedded/external_texture_egl_image.h" #include "flutter/shell/platform/linux_embedded/external_texture_pixelbuffer.h" #include "flutter/shell/platform/linux_embedded/flutter_elinux_engine.h" #include "flutter/shell/platform/linux_embedded/flutter_elinux_view.h" @@ -38,6 +39,15 @@ int64_t FlutterELinuxTextureRegistrar::RegisterTexture( return EmplaceTexture(std::make_unique( texture_info->pixel_buffer_config.callback, texture_info->pixel_buffer_config.user_data, gl_procs_)); + } else if (texture_info->type == kFlutterDesktopEGLImageTexture) { + if (!texture_info->egl_image_config.callback) { + std::cerr << "Invalid EGLImage texture callback." << std::endl; + return kInvalidTexture; + } + + return EmplaceTexture(std::make_unique( + texture_info->egl_image_config.callback, + texture_info->egl_image_config.user_data, gl_procs_)); } else if (texture_info->type == kFlutterDesktopGpuSurfaceTexture) { std::cerr << "GpuSurfaceTexture is not yet supported." << std::endl; return kInvalidTexture; @@ -114,10 +124,12 @@ void FlutterELinuxTextureRegistrar::ResolveGlFunctions(GlProcs& procs) { eglGetProcAddress("glTexParameteri")); procs.glTexImage2D = reinterpret_cast(eglGetProcAddress("glTexImage2D")); - + procs.glEGLImageTargetTexture2DOES = + reinterpret_cast( + eglGetProcAddress("glEGLImageTargetTexture2DOES")); procs.valid = procs.glGenTextures && procs.glDeleteTextures && procs.glBindTexture && procs.glTexParameteri && - procs.glTexImage2D; + procs.glTexImage2D && procs.glEGLImageTargetTexture2DOES; } }; // namespace flutter From c71ea47f50bfa07d6537afdb323e465c03866048 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 25 Feb 2023 17:58:42 +0900 Subject: [PATCH 112/178] add dirty region management (#331) Fixed #326 Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 1 + cmake/build.cmake | 5 + .../linux_embedded/flutter_elinux_engine.cc | 20 +++ .../linux_embedded/flutter_elinux_view.cc | 9 ++ .../linux_embedded/flutter_elinux_view.h | 3 + .../linux_embedded/surface/egl_utils.cc | 15 +- .../linux_embedded/surface/egl_utils.h | 3 +- .../surface/elinux_egl_surface.cc | 153 +++++++++++++++++- .../surface/elinux_egl_surface.h | 33 +++- .../linux_embedded/surface/surface_base.cc | 4 +- .../surface/surface_decoration.cc | 11 +- .../surface/surface_decoration.h | 9 +- .../linux_embedded/surface/surface_gl.cc | 15 +- .../linux_embedded/surface/surface_gl.h | 9 +- .../surface/surface_gl_delegate.h | 10 +- 15 files changed, 286 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8384def..8ef7a33a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ project("flutter_elinux" LANGUAGES CXX C) # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) +option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) option(ENABLE_VSYNC "Enable embedder vsync" OFF) diff --git a/cmake/build.cmake b/cmake/build.cmake index 42308b4d..e97728f1 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -81,6 +81,11 @@ else() "src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc") endif() +# Use flutter dirty region management +if(USE_DIRTY_REGION_MANAGEMENT) + add_definitions(-DUSE_OPENGL_DIRTY_REGION_MANAGEMENT) +endif() + # OpenGL ES version. if(USE_GLES3) add_definitions(-DUSE_GLES3) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index df2c6f8d..87683fa9 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -42,6 +42,25 @@ FlutterRendererConfig GetRendererConfig() { } return host->view()->ClearCurrent(); }; +#if defined(USE_OPENGL_DIRTY_REGION_MANAGEMENT) + config.open_gl.fbo_reset_after_present = false; + config.open_gl.present_with_info = + [](void* user_data, const FlutterPresentInfo* info) -> bool { + auto host = static_cast(user_data); + if (!host->view()) { + return false; + } + return host->view()->PresentWithInfo(info); + }; + config.open_gl.populate_existing_damage = + [](void* user_data, const intptr_t fbo_id, + FlutterDamage* existing_damage) -> void { + auto host = static_cast(user_data); + if (host->view()) { + host->view()->PopulateExistingDamage(fbo_id, existing_damage); + } + }; +#else config.open_gl.present = [](void* user_data) -> bool { auto host = static_cast(user_data); if (!host->view()) { @@ -49,6 +68,7 @@ FlutterRendererConfig GetRendererConfig() { } return host->view()->Present(); }; +#endif config.open_gl.fbo_callback = [](void* user_data) -> uint32_t { auto host = static_cast(user_data); if (!host->view()) { diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 43dfc11e..ce02b388 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -415,6 +415,15 @@ bool FlutterELinuxView::Present() { return GetRenderSurfaceTarget()->GLContextPresent(0); } +bool FlutterELinuxView::PresentWithInfo(const FlutterPresentInfo* info) { + return GetRenderSurfaceTarget()->GLContextPresentWithInfo(info); +} + +void FlutterELinuxView::PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) { + GetRenderSurfaceTarget()->PopulateExistingDamage(fbo_id, existing_damage); +} + uint32_t FlutterELinuxView::GetOnscreenFBO() { return GetRenderSurfaceTarget()->GLContextFBO(); } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index d335ecbe..c554b497 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -75,6 +75,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { bool MakeCurrent(); bool ClearCurrent(); bool Present(); + bool PresentWithInfo(const FlutterPresentInfo* info); + void PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage); uint32_t GetOnscreenFBO(); bool MakeResourceCurrent(); diff --git a/src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc b/src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc index 619c51bf..23647bcd 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc @@ -1,5 +1,5 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,6 +7,7 @@ #include +#include #include #include @@ -40,4 +41,14 @@ std::string get_egl_error_cause() { return nullptr; } -} // namespace flutter \ No newline at end of file +// Auxiliary function used to check if the given list of extensions contains the +// requested extension name. +bool has_egl_extension(const char* extensions, const char* name) { + const char* r = std::strstr(extensions, name); + auto len = std::strlen(name); + + // check that the extension name is terminated by space or null terminator + return r != nullptr && (r[len] == ' ' || r[len] == 0); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/egl_utils.h b/src/flutter/shell/platform/linux_embedded/surface/egl_utils.h index a64196df..80692000 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/egl_utils.h +++ b/src/flutter/shell/platform/linux_embedded/surface/egl_utils.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,6 +10,7 @@ namespace flutter { std::string get_egl_error_cause(); +bool has_egl_extension(const char* extensions, const char* name); } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 8a758174..1e01ca57 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,10 +9,41 @@ namespace flutter { +constexpr size_t kInitialWindowWidthPx = 1280; +constexpr size_t kInitialWindowHeightPx = 720; + +// Maximum damage history - for triple buffering we need to store damage for +// last two frames; Some Android devices (Pixel 4) use quad buffering. +constexpr const int kMaxHistorySize = 10; + ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context) - : surface_(surface), display_(display), context_(context){}; + : surface_(surface), + display_(display), + context_(context), + width_px_(kInitialWindowWidthPx), + height_px_(kInitialWindowHeightPx) { + const char* extensions = eglQueryString(display_, EGL_EXTENSIONS); + + if (has_egl_extension(extensions, "EGL_KHR_partial_update")) { + eglSetDamageRegionKHR_ = reinterpret_cast( + eglGetProcAddress("eglSetDamageRegionKHR")); + } + + if (has_egl_extension(extensions, "EGL_EXT_swap_buffers_with_damage")) { + eglSwapBuffersWithDamageEXT_ = + reinterpret_cast( + eglGetProcAddress("eglSwapBuffersWithDamageEXT")); + } else if (has_egl_extension(extensions, + "EGL_KHR_swap_buffers_with_damage")) { + eglSwapBuffersWithDamageEXT_ = + reinterpret_cast( + eglGetProcAddress("eglSwapBuffersWithDamageKHR")); + } else { + // do nothing. + } +}; ELinuxEGLSurface::~ELinuxEGLSurface() { if (surface_ != EGL_NO_SURFACE) { @@ -28,6 +59,12 @@ bool ELinuxEGLSurface::IsValid() const { return surface_ != EGL_NO_SURFACE; } +void ELinuxEGLSurface::SurfaceResize(const size_t width_px, + const size_t height_px) { + width_px_ = width_px; + height_px_ = height_px; +} + bool ELinuxEGLSurface::MakeCurrent() const { if (eglMakeCurrent(display_, surface_, surface_, context_) != EGL_TRUE) { ELINUX_LOG(ERROR) << "Failed to make the EGL context current: " @@ -54,11 +91,119 @@ bool ELinuxEGLSurface::MakeCurrent() const { bool ELinuxEGLSurface::SwapBuffers() const { if (eglSwapBuffers(display_, surface_) != EGL_TRUE) { - ELINUX_LOG(ERROR) << "Failed to swap the EGL buffer: " - << get_egl_error_cause(); + ELINUX_LOG(ERROR) << "eglSwapBuffers failed: " << get_egl_error_cause(); return false; } return true; } +// Reference of dirty region management: +// https://github.com/flutter/engine/blob/main/examples/glfw_drm/FlutterEmbedderGLFW.cc + +bool ELinuxEGLSurface::SwapBuffers(const FlutterPresentInfo* info) { + // Free the existing damage that was allocated to this frame. + if (existing_damage_map_.find(info->fbo_id) != existing_damage_map_.end() && + existing_damage_map_[info->fbo_id] != nullptr) { + free(existing_damage_map_[info->fbo_id]); + existing_damage_map_[info->fbo_id] = nullptr; + } + + // Set the buffer damage as the damage region. + if (eglSetDamageRegionKHR_) { + auto buffer_rects = RectToInts(info->buffer_damage.damage[0]); + if (eglSetDamageRegionKHR_(display_, surface_, buffer_rects.data(), 1) != + EGL_TRUE) { + ELINUX_LOG(ERROR) << "eglSetDamageRegionKHR failed: " + << get_egl_error_cause(); + return false; + } + } + + // Add frame damage to damage history + damage_history_.push_back(info->frame_damage.damage[0]); + if (damage_history_.size() > kMaxHistorySize) { + damage_history_.pop_front(); + } + + if (eglSwapBuffersWithDamageEXT_) { + auto frame_rects = RectToInts(info->frame_damage.damage[0]); + if (eglSwapBuffersWithDamageEXT_(display_, surface_, frame_rects.data(), + 1) != EGL_TRUE) { + ELINUX_LOG(ERROR) << "eglSwapBuffersWithDamageEXT failed: " + << get_egl_error_cause(); + return false; + } + } else { + // If the required extensions for partial repaint were not provided, do + // full repaint. + if (eglSwapBuffers(display_, surface_) != EGL_TRUE) { + ELINUX_LOG(ERROR) << "eglSwapBuffers failed: " << get_egl_error_cause(); + return false; + } + } + + return true; +} + +void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) { + // Given the FBO age, create existing damage region by joining all frame + // damages since FBO was last used + EGLint age = 0; + if (eglQuerySurface(display_, surface_, EGL_BUFFER_AGE_EXT, &age) != + EGL_TRUE || + age == 0) { + age = 4; // Virtually no driver should have a swapchain length > 4. + } + + existing_damage->num_rects = 1; + + // Allocate the array of rectangles for the existing damage. + existing_damage_map_[fbo_id] = static_cast( + malloc(sizeof(FlutterRect) * existing_damage->num_rects)); + + existing_damage_map_[fbo_id][0] = FlutterRect{ + 0, 0, static_cast(width_px_), static_cast(height_px_)}; + existing_damage->damage = existing_damage_map_[fbo_id]; + + if (age > 1) { + --age; + // join up to (age - 1) last rects from damage history + for (auto i = damage_history_.rbegin(); + i != damage_history_.rend() && age > 0; ++i, --age) { + if (i == damage_history_.rbegin()) { + if (i != damage_history_.rend()) { + existing_damage->damage[0] = {i->left, i->top, i->right, i->bottom}; + } + } else { + // Auxiliary function to union the damage regions comprised by two + // FlutterRect element. It saves the result of this join in the rect + // variable. + FlutterRect* rect = &(existing_damage->damage[0]); + const FlutterRect additional_rect = *i; + + rect->left = std::min(rect->left, additional_rect.left); + rect->top = std::min(rect->top, additional_rect.top); + rect->right = std::max(rect->right, additional_rect.right); + rect->bottom = std::max(rect->bottom, additional_rect.bottom); + } + } + } +} + +// Auxiliary function used to transform a FlutterRect into the format that is +// expected by the EGL functions (i.e. array of EGLint). +std::array ELinuxEGLSurface::RectToInts(const FlutterRect rect) { + EGLint height; + eglQuerySurface(display_, surface_, EGL_HEIGHT, &height); + + std::array res{ + static_cast(rect.left), + height - static_cast(rect.bottom), + static_cast(rect.right) - static_cast(rect.left), + static_cast(rect.bottom) - static_cast(rect.top), + }; + return res; +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h index 452a7df7..d10b709e 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -6,6 +6,13 @@ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_SURFACE_ELINUX_EGL_SURFACE_H_ #include +#include + +#include +#include +#include + +#include "flutter/shell/platform/embedder/embedder.h" namespace flutter { @@ -17,14 +24,38 @@ class ELinuxEGLSurface { bool IsValid() const; + void SurfaceResize(const size_t width_px, const size_t height_px); + bool MakeCurrent() const; bool SwapBuffers() const; + bool SwapBuffers(const FlutterPresentInfo* info); + + void PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage); + private: + // Auxiliary function used to transform a FlutterRect into the format that is + // expected by the EGL functions (i.e. array of EGLint). + std::array RectToInts(const FlutterRect rect); + EGLDisplay display_; EGLSurface surface_; EGLContext context_; + + size_t width_px_; + size_t height_px_; + + PFNEGLSETDAMAGEREGIONKHRPROC eglSetDamageRegionKHR_ = nullptr; + PFNEGLSWAPBUFFERSWITHDAMAGEEXTPROC eglSwapBuffersWithDamageEXT_ = nullptr; + + // Keeps track of the most recent frame damages so that existing damage can + // be easily computed. + std::list damage_history_; + + // Keeps track of the existing damage associated with each FBO ID + std::unordered_map existing_damage_map_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc index 1067ad57..91ca8a1d 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_base.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,6 +31,7 @@ bool SurfaceBase::SetNativeWindow(NativeWindow* window) { bool SurfaceBase::OnScreenSurfaceResize(const size_t width_px, const size_t height_px) { + onscreen_surface_->SurfaceResize(width_px, height_px); if (!native_window_->Resize(width_px, height_px)) { ELINUX_LOG(ERROR) << "Failed to resize."; return false; @@ -44,6 +45,7 @@ bool SurfaceBase::OnScreenSurfaceResize(const size_t width_px, onscreen_surface_ = nullptr; return false; } + onscreen_surface_->SurfaceResize(width_px, height_px); } return true; }; diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc index fb73a275..e33f92f8 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -62,6 +62,15 @@ bool SurfaceDecoration::GLContextPresent(uint32_t fbo_id) const { return surface_->SwapBuffers(); } +bool SurfaceDecoration::GLContextPresentWithInfo( + const FlutterPresentInfo* info) const { + return true; +} + +void SurfaceDecoration::PopulateExistingDamage( + const intptr_t fbo_id, + FlutterDamage* existing_damage) const {} + uint32_t SurfaceDecoration::GLContextFBO() const { return 0; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h index 1e44ed89..8c051712 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_decoration.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -43,6 +43,13 @@ class SurfaceDecoration : public SurfaceGlDelegate { // |SurfaceGlDelegate| bool GLContextPresent(uint32_t fbo_id) const override; + // |SurfaceGlDelegate| + bool GLContextPresentWithInfo(const FlutterPresentInfo* info) const override; + + // |SurfaceGlDelegate| + void PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) const override; + // |SurfaceGlDelegate| uint32_t GLContextFBO() const override; diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc index 7467dd84..cdd0eb40 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,6 +26,19 @@ bool SurfaceGl::GLContextPresent(uint32_t fbo_id) const { return true; } +bool SurfaceGl::GLContextPresentWithInfo(const FlutterPresentInfo* info) const { + if (!onscreen_surface_->SwapBuffers(info)) { + return false; + } + native_window_->SwapBuffers(); + return true; +} + +void SurfaceGl::PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) const { + onscreen_surface_->PopulateExistingDamage(fbo_id, existing_damage); +} + uint32_t SurfaceGl::GLContextFBO() const { return 0; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h index e6b19997..44dee0bd 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,6 +27,13 @@ class SurfaceGl final : public SurfaceBase, public SurfaceGlDelegate { // |SurfaceGlDelegate| bool GLContextPresent(uint32_t fbo_id) const override; + // |SurfaceGlDelegate| + bool GLContextPresentWithInfo(const FlutterPresentInfo* info) const override; + + // |SurfaceGlDelegate| + void PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) const override; + // |SurfaceGlDelegate| uint32_t GLContextFBO() const override; diff --git a/src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h b/src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h index 392b277b..709185f7 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/surface/surface_gl_delegate.h @@ -1,5 +1,5 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -8,6 +8,8 @@ #include +#include "flutter/shell/platform/embedder/embedder.h" + namespace flutter { class SurfaceGlDelegate { @@ -18,6 +20,12 @@ class SurfaceGlDelegate { virtual bool GLContextPresent(uint32_t fbo_id) const = 0; + virtual bool GLContextPresentWithInfo( + const FlutterPresentInfo* info) const = 0; + + virtual void PopulateExistingDamage(const intptr_t fbo_id, + FlutterDamage* existing_damage) const = 0; + virtual uint32_t GLContextFBO() const = 0; virtual void* GlProcResolver(const char* name) const = 0; From 9b58e60c789ef81a6cda0eba9b33170e0db98adc Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 7 Mar 2023 00:21:51 +0900 Subject: [PATCH 113/178] engine: enable fbo_reset_after_present by default (#333) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 87683fa9..069ab7e9 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -42,8 +42,8 @@ FlutterRendererConfig GetRendererConfig() { } return host->view()->ClearCurrent(); }; + config.open_gl.fbo_reset_after_present = true; #if defined(USE_OPENGL_DIRTY_REGION_MANAGEMENT) - config.open_gl.fbo_reset_after_present = false; config.open_gl.present_with_info = [](void* user_data, const FlutterPresentInfo* info) -> bool { auto host = static_cast(user_data); From 393c4e09f56f0f65dcbfa68110147d4846b1f7c6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 4 Apr 2023 10:09:24 +0900 Subject: [PATCH 114/178] wayland: fix "xdg_surface has never been configured" error (#336) Fixed #330 Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_wayland.cc | 90 ++++++++++--------- .../window/elinux_window_wayland.h | 2 + 2 files changed, 49 insertions(+), 43 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 86eb33ad..55d59f1a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -9,8 +9,8 @@ #include #include #include -#include +#include #include #include #include @@ -68,6 +68,8 @@ const xdg_wm_base_listener ELinuxWindowWayland::kXdgWmBaseListener = { const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { .configure = [](void* data, xdg_surface* xdg_surface, uint32_t serial) { + ELINUX_LOG(TRACE) << "xdg_surface_listener.configure"; + auto self = reinterpret_cast(data); constexpr int32_t x = 0; int32_t y = 0; @@ -81,6 +83,9 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { self->view_properties_.width, self->view_properties_.height); xdg_surface_ack_configure(xdg_surface, serial); + if (self->wait_for_configure_) { + self->wait_for_configure_ = false; + } }, }; @@ -91,13 +96,17 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { int32_t width, int32_t height, wl_array* states) { + ELINUX_LOG(TRACE) + << "xdg_toplevel_listener.configure: " << width << ", " << height; + auto self = reinterpret_cast(data); if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { std::swap(width, height); } int32_t next_width = width; - int32_t next_height = height; + int32_t next_height = + height - self->WindowDecorationsPhysicalHeight(); if (self->restore_window_required_) { self->restore_window_required_ = false; next_width = self->restore_window_width_; @@ -112,16 +121,7 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { self->view_properties_.width = next_width; self->view_properties_.height = next_height; - if (self->window_decorations_) { - self->window_decorations_->Resize(next_width, next_height, - self->current_scale_); - } - if (self->binding_handler_delegate_) { - self->binding_handler_delegate_->OnWindowSizeChanged( - next_width * self->current_scale_, - next_height * self->current_scale_ - - self->WindowDecorationsPhysicalHeight()); - } + self->request_redraw_ = true; }, .close = [](void* data, xdg_toplevel* xdg_toplevel) { @@ -582,17 +582,7 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { FlutterDesktopViewMode::kFullscreen) { self->view_properties_.width = width; self->view_properties_.height = height; - - if (self->window_decorations_) { - int32_t width_dip = width / self->current_scale_; - int32_t height_dip = height / self->current_scale_; - self->window_decorations_->Resize(width_dip, height_dip, - self->current_scale_); - } - - if (self->binding_handler_delegate_) { - self->binding_handler_delegate_->OnWindowSizeChanged(width, height); - } + self->request_redraw_ = true; } } }, @@ -895,7 +885,6 @@ ELinuxWindowWayland::ELinuxWindowWayland( } wl_registry_add_listener(wl_registry_, &kWlRegistryListener, this); - wl_display_dispatch(wl_display_); wl_display_roundtrip(wl_display_); if (wl_data_device_manager_ && wl_seat_) { @@ -1085,6 +1074,20 @@ bool ELinuxWindowWayland::DispatchEvent() { return false; } + if (request_redraw_) { + request_redraw_ = false; + if (window_decorations_) { + window_decorations_->Resize(view_properties_.width, + view_properties_.height, current_scale_); + } + if (binding_handler_delegate_) { + binding_handler_delegate_->OnWindowSizeChanged( + view_properties_.width * current_scale_, + view_properties_.height * current_scale_ - + WindowDecorationsPhysicalHeight()); + } + } + // Prepare to call wl_display_read_events. while (wl_display_prepare_read(wl_display_) != 0) { // If Wayland compositor terminates, -1 is returned. @@ -1181,7 +1184,6 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, } xdg_toplevel_add_listener(xdg_toplevel_, &kXdgToplevelListener, this); wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_); - wl_surface_commit(native_window_->Surface()); { auto* callback = wl_surface_frame(native_window_->Surface()); @@ -1195,6 +1197,13 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, } } + if (view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen) { + xdg_toplevel_set_fullscreen(xdg_toplevel_, NULL); + } + + wait_for_configure_ = true; + wl_surface_commit(native_window_->Surface()); + render_surface_ = std::make_unique(std::make_unique( std::make_unique(wl_display_))); render_surface_->SetNativeWindow(native_window_.get()); @@ -1207,6 +1216,11 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, native_window_->Surface(), width_dip, height_dip, current_scale_); } + // Wait for making sure that xdg_surface has been configured. + while (wait_for_configure_) { + wl_display_dispatch(wl_display_); + } + return true; } @@ -1575,7 +1589,7 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { } void ELinuxWindowWayland::UpdateWindowScale() { - if (this->view_properties_.force_scale_factor) + if (view_properties_.force_scale_factor) return; double scale_factor = 1.0; @@ -1589,33 +1603,23 @@ void ELinuxWindowWayland::UpdateWindowScale() { scale_factor = output_scale_factor; } - if (this->current_scale_ == scale_factor) + if (current_scale_ == scale_factor) { return; + } ELINUX_LOG(TRACE) << "Window scale has changed: " << scale_factor; - this->current_scale_ = scale_factor; + current_scale_ = scale_factor; wl_surface_set_buffer_scale(native_window_->Surface(), current_scale_); - - if (this->window_decorations_) { - this->window_decorations_->Resize(this->view_properties_.width, - this->view_properties_.height, - this->current_scale_); - } - - if (this->binding_handler_delegate_) { - this->binding_handler_delegate_->OnWindowSizeChanged( - this->view_properties_.width * this->current_scale_, - this->view_properties_.height * this->current_scale_ - - this->WindowDecorationsPhysicalHeight()); - } + request_redraw_ = true; } uint32_t ELinuxWindowWayland::WindowDecorationsPhysicalHeight() const { - if (!this->window_decorations_) + if (!window_decorations_) { return 0; + } - return this->window_decorations_->Height() * current_scale_; + return window_decorations_->Height() * current_scale_; } } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 6860adaf..00bf0b09 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -145,6 +145,8 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { bool display_valid_; bool running_; + bool wait_for_configure_ = false; + bool request_redraw_ = false; bool maximised_; uint32_t last_frame_time_; From 43caf24dd4a75a967f04760409bcfa3641deffed Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 12 Apr 2023 07:05:12 +0900 Subject: [PATCH 115/178] wayland: add window size clipping (#337) Fixed https://github.com/sony/flutter-elinux/issues/176 Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_wayland.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 55d59f1a..8a84022a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -584,6 +584,25 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { self->view_properties_.height = height; self->request_redraw_ = true; } + + if (self->view_properties_.width > width) { + ELINUX_LOG(WARNING) + << "Requested width size(" << self->view_properties_.width << ") " + << "is larger than display size(" << width + << ")" + ", clipping"; + self->view_properties_.width = width; + self->request_redraw_ = true; + } + if (self->view_properties_.height > height) { + ELINUX_LOG(WARNING) << "Requested height size(" + << self->view_properties_.height << ") " + << "is larger than display size(" << height + << ")" + ", clipping"; + self->view_properties_.height = height; + self->request_redraw_ = true; + } } }, .done = [](void* data, wl_output* wl_output) -> void {}, From 3dedfc0b674c1c5b2e9a4ddc0a86542cfd70ba56 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 29 Apr 2023 22:16:37 +0900 Subject: [PATCH 116/178] embedder: update embedder's header file (#339) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 219 +++++++++++++++--- 1 file changed, 192 insertions(+), 27 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 7bef2e52..1710299f 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -25,9 +25,16 @@ // - Function signatures (names, argument counts, argument order, and argument // type) cannot change. // - The core behavior of existing functions cannot change. +// - Instead of nesting structures by value within another structure, prefer +// nesting by pointer. This ensures that adding members to the nested struct +// does not break the ABI of the parent struct. +// - Instead of array of structures, prefer array of pointers to structures. +// This ensures that array indexing does not break if members are added +// to the structure. // // These changes are allowed: -// - Adding new struct members at the end of a structure. +// - Adding new struct members at the end of a structure as long as the struct +// is not nested within another struct by value. // - Adding new enum members with a new value. // - Renaming a struct member as long as its type, size, and intent remain the // same. @@ -299,8 +306,8 @@ typedef enum { /// /// - all other formats are called packed formats, and the component order /// as specified in the format name refers to the order in the native type. -/// for example, for kRGB565, the R component uses the 5 least significant -/// bits of the uint16_t pixel value. +/// for example, for kFlutterSoftwarePixelFormatRGB565, the R component +/// uses the 5 least significant bits of the uint16_t pixel value. /// /// Each pixel format in this list is documented with an example on how to get /// the color components from the pixel. @@ -316,30 +323,31 @@ typedef enum { /// pixel with 8 bit grayscale value. /// The grayscale value is the luma value calculated from r, g, b /// according to BT.709. (gray = r*0.2126 + g*0.7152 + b*0.0722) - kGray8, + kFlutterSoftwarePixelFormatGray8, /// pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word. /// r = p & 0x3F; g = (p>>5) & 0x3F; b = p>>11; - kRGB565, + kFlutterSoftwarePixelFormatRGB565, /// pixel with 4 bits for alpha, red, green, blue; in 16-bit word. /// r = p & 0xF; g = (p>>4) & 0xF; b = (p>>8) & 0xF; a = p>>12; - kRGBA4444, + kFlutterSoftwarePixelFormatRGBA4444, /// pixel with 8 bits for red, green, blue, alpha. /// r = p[0]; g = p[1]; b = p[2]; a = p[3]; - kRGBA8888, + kFlutterSoftwarePixelFormatRGBA8888, /// pixel with 8 bits for red, green and blue and 8 unused bits. /// r = p[0]; g = p[1]; b = p[2]; - kRGBX8888, + kFlutterSoftwarePixelFormatRGBX8888, /// pixel with 8 bits for blue, green, red and alpha. /// r = p[2]; g = p[1]; b = p[0]; a = p[3]; - kBGRA8888, + kFlutterSoftwarePixelFormatBGRA8888, - /// either kBGRA8888 or kRGBA8888 depending on CPU endianess and OS - kNative32, + /// either kFlutterSoftwarePixelFormatBGRA8888 or + /// kFlutterSoftwarePixelFormatRGBA8888 depending on CPU endianess and OS + kFlutterSoftwarePixelFormatNative32, } FlutterSoftwarePixelFormat; typedef struct { @@ -448,7 +456,9 @@ typedef struct { /// This information is passed to the embedder when requesting a frame buffer /// object. /// -/// See: \ref FlutterOpenGLRendererConfig.fbo_with_frame_info_callback. +/// See: \ref FlutterOpenGLRendererConfig.fbo_with_frame_info_callback, +/// \ref FlutterMetalRendererConfig.get_next_drawable_callback, +/// and \ref FlutterVulkanRendererConfig.get_next_image_callback. typedef struct { /// The size of this struct. Must be sizeof(FlutterFrameInfo). size_t struct_size; @@ -633,6 +643,8 @@ typedef struct { int64_t texture_id; /// Handle to the MTLTexture that is owned by the embedder. Engine will render /// the frame into this texture. + /// + /// A NULL texture is considered invalid. FlutterMetalTextureHandle texture; /// A baton that is not interpreted by the engine in any way. It will be given /// back to the embedder in the destruction callback below. Embedder resources @@ -826,7 +838,7 @@ typedef enum { /// any other buttons are still pressed when one button is released, that /// should be sent as a kMove rather than a kUp. kUp, - /// The pointer, which must have been been up, is now down. + /// The pointer, which must have been up, is now down. /// /// For touch, this means that the pointer has come into contact with the /// screen. For a mouse, it means a button is now pressed. Note that if any @@ -1032,7 +1044,7 @@ typedef int64_t FlutterPlatformViewIdentifier; /// `FlutterSemanticsNode` ID used as a sentinel to signal the end of a batch of /// semantics node updates. This is unused if using -/// `FlutterUpdateSemanticsCallback`. +/// `FlutterUpdateSemanticsCallback2`. FLUTTER_EXPORT extern const int32_t kFlutterSemanticsNodeIdBatchEnd; @@ -1042,6 +1054,11 @@ extern const int32_t kFlutterSemanticsNodeIdBatchEnd; /// (i.e., during PipelineOwner.flushSemantics), which happens after /// compositing. Updates are then pushed to embedders via the registered /// `FlutterUpdateSemanticsCallback`. +/// +/// @deprecated Use `FlutterSemanticsNode2` instead. In order to preserve +/// ABI compatibility for existing users, no new fields will be +/// added to this struct. New fields will continue to be added +/// to `FlutterSemanticsNode2`. typedef struct { /// The size of this struct. Must be sizeof(FlutterSemanticsNode). size_t struct_size; @@ -1109,9 +1126,84 @@ typedef struct { const char* tooltip; } FlutterSemanticsNode; +/// A node in the Flutter semantics tree. +/// +/// The semantics tree is maintained during the semantics phase of the pipeline +/// (i.e., during PipelineOwner.flushSemantics), which happens after +/// compositing. Updates are then pushed to embedders via the registered +/// `FlutterUpdateSemanticsCallback2`. +/// +/// @see https://api.flutter.dev/flutter/semantics/SemanticsNode-class.html +typedef struct { + /// The size of this struct. Must be sizeof(FlutterSemanticsNode). + size_t struct_size; + /// The unique identifier for this node. + int32_t id; + /// The set of semantics flags associated with this node. + FlutterSemanticsFlag flags; + /// The set of semantics actions applicable to this node. + FlutterSemanticsAction actions; + /// The position at which the text selection originates. + int32_t text_selection_base; + /// The position at which the text selection terminates. + int32_t text_selection_extent; + /// The total number of scrollable children that contribute to semantics. + int32_t scroll_child_count; + /// The index of the first visible semantic child of a scroll node. + int32_t scroll_index; + /// The current scrolling position in logical pixels if the node is + /// scrollable. + double scroll_position; + /// The maximum in-range value for `scrollPosition` if the node is scrollable. + double scroll_extent_max; + /// The minimum in-range value for `scrollPosition` if the node is scrollable. + double scroll_extent_min; + /// The elevation along the z-axis at which the rect of this semantics node is + /// located above its parent. + double elevation; + /// Describes how much space the semantics node takes up along the z-axis. + double thickness; + /// A textual description of the node. + const char* label; + /// A brief description of the result of performing an action on the node. + const char* hint; + /// A textual description of the current value of the node. + const char* value; + /// A value that `value` will have after a kFlutterSemanticsActionIncrease` + /// action has been performed. + const char* increased_value; + /// A value that `value` will have after a kFlutterSemanticsActionDecrease` + /// action has been performed. + const char* decreased_value; + /// The reading direction for `label`, `value`, `hint`, `increasedValue`, + /// `decreasedValue`, and `tooltip`. + FlutterTextDirection text_direction; + /// The bounding box for this node in its coordinate system. + FlutterRect rect; + /// The transform from this node's coordinate system to its parent's + /// coordinate system. + FlutterTransformation transform; + /// The number of children this node has. + size_t child_count; + /// Array of child node IDs in traversal order. Has length `child_count`. + const int32_t* children_in_traversal_order; + /// Array of child node IDs in hit test order. Has length `child_count`. + const int32_t* children_in_hit_test_order; + /// The number of custom accessibility action associated with this node. + size_t custom_accessibility_actions_count; + /// Array of `FlutterSemanticsCustomAction` IDs associated with this node. + /// Has length `custom_accessibility_actions_count`. + const int32_t* custom_accessibility_actions; + /// Identifier of the platform view associated with this semantics node, or + /// -1 if none. + FlutterPlatformViewIdentifier platform_view_id; + /// A textual tooltip attached to the node. + const char* tooltip; +} FlutterSemanticsNode2; + /// `FlutterSemanticsCustomAction` ID used as a sentinel to signal the end of a /// batch of semantics custom action updates. This is unused if using -/// `FlutterUpdateSemanticsCallback`. +/// `FlutterUpdateSemanticsCallback2`. FLUTTER_EXPORT extern const int32_t kFlutterSemanticsCustomActionIdBatchEnd; @@ -1124,6 +1216,11 @@ extern const int32_t kFlutterSemanticsCustomActionIdBatchEnd; /// Action overrides are custom actions that the application developer requests /// to be used in place of the standard actions in the `FlutterSemanticsAction` /// enum. +/// +/// @deprecated Use `FlutterSemanticsCustomAction2` instead. In order to +/// preserve ABI compatility for existing users, no new fields +/// will be added to this struct. New fields will continue to +/// be added to `FlutterSemanticsCustomAction2`. typedef struct { /// The size of the struct. Must be sizeof(FlutterSemanticsCustomAction). size_t struct_size; @@ -1138,7 +1235,37 @@ typedef struct { const char* hint; } FlutterSemanticsCustomAction; +/// A custom semantics action, or action override. +/// +/// Custom actions can be registered by applications in order to provide +/// semantic actions other than the standard actions available through the +/// `FlutterSemanticsAction` enum. +/// +/// Action overrides are custom actions that the application developer requests +/// to be used in place of the standard actions in the `FlutterSemanticsAction` +/// enum. +/// +/// @see +/// https://api.flutter.dev/flutter/semantics/CustomSemanticsAction-class.html +typedef struct { + /// The size of the struct. Must be sizeof(FlutterSemanticsCustomAction). + size_t struct_size; + /// The unique custom action or action override ID. + int32_t id; + /// For overridden standard actions, corresponds to the + /// `FlutterSemanticsAction` to override. + FlutterSemanticsAction override_action; + /// The user-readable name of this custom semantics action. + const char* label; + /// The hint description of this custom semantics action. + const char* hint; +} FlutterSemanticsCustomAction2; + /// A batch of updates to semantics nodes and custom actions. +/// +/// @deprecated Use `FlutterSemanticsUpdate2` instead. Adding members +/// to `FlutterSemanticsNode` or `FlutterSemanticsCustomAction` +/// breaks the ABI of this struct. typedef struct { /// The size of the struct. Must be sizeof(FlutterSemanticsUpdate). size_t struct_size; @@ -1152,6 +1279,21 @@ typedef struct { FlutterSemanticsCustomAction* custom_actions; } FlutterSemanticsUpdate; +/// A batch of updates to semantics nodes and custom actions. +typedef struct { + /// The size of the struct. Must be sizeof(FlutterSemanticsUpdate2). + size_t struct_size; + /// The number of semantics node updates. + size_t node_count; + // Array of semantics node pointers. Has length `node_count`. + FlutterSemanticsNode2** nodes; + /// The number of semantics custom action updates. + size_t custom_action_count; + /// Array of semantics custom action pointers. Has length + /// `custom_action_count`. + FlutterSemanticsCustomAction2** custom_actions; +} FlutterSemanticsUpdate2; + typedef void (*FlutterUpdateSemanticsNodeCallback)( const FlutterSemanticsNode* /* semantics node */, void* /* user data */); @@ -1164,6 +1306,10 @@ typedef void (*FlutterUpdateSemanticsCallback)( const FlutterSemanticsUpdate* /* semantics update */, void* /* user data*/); +typedef void (*FlutterUpdateSemanticsCallback2)( + const FlutterSemanticsUpdate2* /* semantics update */, + void* /* user data*/); + typedef struct _FlutterTaskRunner* FlutterTaskRunner; typedef struct { @@ -1768,9 +1914,11 @@ typedef struct { /// The callback will be invoked on the thread on which the `FlutterEngineRun` /// call is made. /// - /// @deprecated Prefer using `update_semantics_callback` instead. If this - /// calback is provided, `update_semantics_callback` must not - /// be provided. + /// @deprecated Use `update_semantics_callback2` instead. Only one of + /// `update_semantics_node_callback`, + /// `update_semantics_callback`, and + /// `update_semantics_callback2` may be provided; the others + /// should be set to null. FlutterUpdateSemanticsNodeCallback update_semantics_node_callback; /// The legacy callback invoked by the engine in order to give the embedder /// the chance to respond to updates to semantics custom actions from the Dart @@ -1782,9 +1930,11 @@ typedef struct { /// The callback will be invoked on the thread on which the `FlutterEngineRun` /// call is made. /// - /// @deprecated Prefer using `update_semantics_callback` instead. If this - /// calback is provided, `update_semantics_callback` must not - /// be provided. + /// @deprecated Use `update_semantics_callback2` instead. Only one of + /// `update_semantics_node_callback`, + /// `update_semantics_callback`, and + /// `update_semantics_callback2` may be provided; the others + /// should be set to null. FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback; /// Path to a directory used to store data that is cached across runs of a @@ -1929,9 +2079,24 @@ typedef struct { /// The callback will be invoked on the thread on which the `FlutterEngineRun` /// call is made. /// - /// If this callback is provided, update_semantics_node_callback and - /// update_semantics_custom_action_callback must not be provided. + /// @deprecated Use `update_semantics_callback2` instead. Only one of + /// `update_semantics_node_callback`, + /// `update_semantics_callback`, and + /// `update_semantics_callback2` may be provided; the others + /// must be set to null. FlutterUpdateSemanticsCallback update_semantics_callback; + + /// The callback invoked by the engine in order to give the embedder the + /// chance to respond to updates to semantics nodes and custom actions from + /// the Dart application. + /// + /// The callback will be invoked on the thread on which the `FlutterEngineRun` + /// call is made. + /// + /// Only one of `update_semantics_node_callback`, `update_semantics_callback`, + /// and `update_semantics_callback2` may be provided; the others must be set + /// to null. + FlutterUpdateSemanticsCallback2 update_semantics_callback2; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES @@ -2273,8 +2438,8 @@ FlutterEngineResult FlutterEngineMarkExternalTextureFrameAvailable( /// @param[in] engine A running engine instance. /// @param[in] enabled When enabled, changes to the semantic contents of the /// window are sent via the -/// `FlutterUpdateSemanticsCallback` registered to -/// `update_semantics_callback` in +/// `FlutterUpdateSemanticsCallback2` registered to +/// `update_semantics_callback2` in /// `FlutterProjectArgs`. /// /// @return The result of the call. @@ -2301,7 +2466,7 @@ FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures( /// @brief Dispatch a semantics action to the specified semantics node. /// /// @param[in] engine A running engine instance. -/// @param[in] identifier The semantics action identifier. +/// @param[in] node_id The semantics node identifier. /// @param[in] action The semantics action. /// @param[in] data Data associated with the action. /// @param[in] data_length The data length. @@ -2311,7 +2476,7 @@ FlutterEngineResult FlutterEngineUpdateAccessibilityFeatures( FLUTTER_EXPORT FlutterEngineResult FlutterEngineDispatchSemanticsAction( FLUTTER_API_SYMBOL(FlutterEngine) engine, - uint64_t id, + uint64_t node_id, FlutterSemanticsAction action, const uint8_t* data, size_t data_length); From 048334d81725493da5c3b766a507930c064a1980 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 16 Jun 2023 09:23:27 +0900 Subject: [PATCH 117/178] readme: remove description related to tested devices (#343) This change moves the description related to tested devices to Wiki. Signed-off-by: Hidenori Matsubayashi --- README.md | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/README.md b/README.md index 85ee9334..cd06c6b8 100644 --- a/README.md +++ b/README.md @@ -40,34 +40,7 @@ We would be grateful if you could give us feedback on bugs and new feature reque Documentation for this software can be found at [Wiki](https://github.com/sony/flutter-embedded-linux/wiki). ## Supported platforms -This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. - -### Tested devices -| Board / SoC | Vendor | OS / BSP | Backend | Status | -| :-------------: | :-------------: | :-------------: | :-------------: | :-------------: | -| [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | Wayland | :heavy_check_mark: | -| [Jetson Nano](https://developer.nvidia.com/embedded/jetson-nano-developer-kit) | NVIDIA | JetPack 4.3 | DRM | :heavy_check_mark: ([#1](https://github.com/sony/flutter-embedded-linux/issues/1))| -| [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Raspberry Pi Foundation | Ubuntu 20.10 | Wayland | :heavy_check_mark: | -| [Raspberry Pi 4 Model B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/) | Raspberry Pi Foundation | Ubuntu 20.10 | DRM | :heavy_check_mark: ([#9](https://github.com/sony/flutter-embedded-linux/issues/9)) | -| [Raspberry Pi 3 Model B](https://www.raspberrypi.com/products/raspberry-pi-3-model-b/) | Raspberry Pi Foundation | Raspberry Pi OS bullseye | Wayland | :heavy_check_mark: | -| [i.MX 8MQuad EVK](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-applications-processor:MCIMX8M-EVK) | NXP | Sumo (kernel 4.14.98) | Wayland | :heavy_check_mark: | -| [i.MX 8M Mini EVKB](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/evaluation-kit-for-the-i-mx-8m-mini-applications-processor:8MMINILPD4-EVK) | NXP | Zeus (kernel 5.4.70) | Wayland | :heavy_check_mark: | -| [RB5 Development Kit](https://developer.qualcomm.com/qualcomm-robotics-rb5-kit) | Qualcomm | Ubuntu 18.04.05 | DRM | :heavy_check_mark: | -| Zynq | Xilinx | - | - | Not tested | -| Desktop (x86_64) | Intel | Ubuntu 20.04 | Wayland | :heavy_check_mark: | -| Desktop (x86_64) | Intel | Ubuntu 20.04 | DRM | :heavy_check_mark: | -| Desktop (x86_64) | Intel | Ubuntu 20.04 | X11 | :heavy_check_mark: | -| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | Wayland | :heavy_check_mark: | -| QEMU (x86_64) | QEMU | [AGL (Automotive Grade Linux)](https://wiki.automotivelinux.org/) koi | DRM | :heavy_check_mark: | - -Note - - i.MX 8M platforms don't support applications using EGL on GBM, which means the DRM-GBM backend won't work on i.MX 8M devices. - -### Tested Wayland compositors -||||||||||| -| :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | :-: | -[Weston](https://gitlab.freedesktop.org/wayland/weston/-/blob/master/README.md) | :heavy_check_mark: | [Sway](https://swaywm.org/) | :heavy_check_mark: | [Wayfire](https://wayfire.org/) | :heavy_check_mark: | [Gnome](https://www.gnome.org/) | :heavy_check_mark: | [Phosh](https://source.puri.sm/Librem5/phosh) | :heavy_check_mark: | -| [Cage](https://www.hjdskes.nl/projects/cage/) | :heavy_check_mark: | [Lomiri](https://lomiri.com/) | :heavy_check_mark: | [Plasma Wayland](https://community.kde.org/Plasma/Wayland) | :heavy_check_mark: | [Plasma Mobile](https://www.plasma-mobile.org/) | :heavy_check_mark: | [GlacierUX](https://wiki.merproject.org/wiki/Nemo/Glacier) | :heavy_check_mark: | +This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. See [Support status](https://github.com/sony/flutter-elinux/wiki/Support-status) for details. ## Contributing **Now, we cannot accept any Pull Request (PR).** Because We are building a system (e.g. CLA) to accept PRs, so please wait for a while the system is getting ready! However, we are always welcome to report bugs and request new features by creating issues. From cff33ca5aaabf5adf5e4cb965ea743c9e5ab7043 Mon Sep 17 00:00:00 2001 From: t123yh Date: Tue, 20 Jun 2023 10:46:26 +0800 Subject: [PATCH 118/178] Enhancements to initialization code in drm backend (#344) * Check if drm_crtc is nullptr before attempting to set mode In native_window_drm, there's no check against null drm_crtc. So if drm_crtc is null, and SwapBuffers() is called, a Segmentation Fault will occur. This adds check against it. Signed-off-by: Yunhao Tian * Add logic to initialize drm encoder and crtc In RK3399 board, when the system just booted up, there's no encoder attached to connector, and no crtc attached to encoder. In this case drm backend will fail to get an encoder. This commit adds code to find suitable encoder and crtc from resources, when absent. Signed-off-by: Yunhao Tian * Add myself to AUTHORS --------- Signed-off-by: Yunhao Tian --- AUTHORS | 1 + .../window/native_window_drm.cc | 55 +++++++++++++++++-- .../window/native_window_drm_gbm.cc | 12 ++-- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/AUTHORS b/AUTHORS index 3a8e080d..34746af2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,3 +10,4 @@ Andrea Daoud (andreadaoud6@gmail.com) Valentin Hăloiu (valentin.haloiu@gmail.com) FlafyDev Makoto Sato (makoto.sato@atmark-techno.com) +Yunhao Tian (t123yh@outlook.com) diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index 1f57165c..22e6e7d9 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -77,8 +77,18 @@ bool NativeWindowDrm::ConfigureDisplay(const uint16_t rotation) { drmModeFreeResources(resources); return false; } - if (encoder->crtc_id) { - drm_crtc_ = drmModeGetCrtc(drm_device_, encoder->crtc_id); + if (!encoder->crtc_id) { + // if there is no current CRTC, make sure to attach a suitable one + for (int c = 0; c < resources->count_crtcs; c++) { + if (encoder->possible_crtcs & (1 << c)) { + encoder->crtc_id = resources->crtcs[c]; + break; + } + } + } + drm_crtc_ = drmModeGetCrtc(drm_device_, encoder->crtc_id); + if (!drm_crtc_) { + ELINUX_LOG(WARNING) << "Couldn't find a suitable crtc"; } drmModeFreeEncoder(encoder); @@ -103,11 +113,44 @@ drmModeConnectorPtr NativeWindowDrm::FindConnector(drmModeResPtr resources) { drmModeEncoder* NativeWindowDrm::FindEncoder(drmModeRes* resources, drmModeConnector* connector) { - if (connector->encoder_id) { - return drmModeGetEncoder(drm_device_, connector->encoder_id); + drmModeEncoder* encoder = nullptr; + // Find a suitable encoder + for (int e = 0; e < resources->count_encoders; e++) { + bool found = false; + encoder = drmModeGetEncoder(drm_device_, resources->encoders[e]); + for (int ce = 0; ce < connector->count_encoders; ce++) { + if (encoder && encoder->encoder_id == connector->encoders[ce]) { + ELINUX_LOG(DEBUG) << "Using encoder id " << encoder->encoder_id; + found = true; + break; + } + } + if (found) + break; + drmModeFreeEncoder(encoder); + encoder = nullptr; } - // no encoder found - return nullptr; + + // If encoder is not connected to the connector, + // try to find a suitable one + if (!encoder) { + for (int e = 0; e < connector->count_encoders; e++) { + encoder = drmModeGetEncoder(drm_device_, connector->encoders[e]); + for (int c = 0; c < resources->count_crtcs; c++) { + if (encoder->possible_crtcs & (1 << c)) { + encoder->crtc_id = resources->crtcs[c]; + break; + } + } + if (encoder->crtc_id) + break; + drmModeFreeEncoder(encoder); + encoder = nullptr; + } + } + + // Will return nullptr if a suitable encoder is still not found + return encoder; } const uint32_t* NativeWindowDrm::GetCursorData(const std::string& cursor_name) { diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index 3effb666..8c342c00 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -175,10 +175,14 @@ void NativeWindowDrmGbm::SwapBuffers() { if (result != 0) { ELINUX_LOG(ERROR) << "Failed to add a framebuffer. (" << result << ")"; } - result = drmModeSetCrtc(drm_device_, drm_crtc_->crtc_id, fb, 0, 0, - &drm_connector_id_, 1, &drm_mode_info_); - if (result != 0) { - ELINUX_LOG(ERROR) << "Failed to set crct mode. (" << result << ")"; + if (!drm_crtc_) { + ELINUX_LOG(ERROR) << "crtc is null, cannot set mode."; + } else { + result = drmModeSetCrtc(drm_device_, drm_crtc_->crtc_id, fb, 0, 0, + &drm_connector_id_, 1, &drm_mode_info_); + if (result != 0) { + ELINUX_LOG(ERROR) << "Failed to set crct mode. (" << result << ")"; + } } if (gbm_previous_bo_) { From 23a83396202fd349cdbe222bfe53b42f09d73393 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 17 Jul 2023 08:53:46 +0200 Subject: [PATCH 119/178] embedder: don't use reference params in C APIs (#345) (#346) flutter_elinux.h is a C API, so reference parameters are unavailable. Change FlutterDesktopViewControllerCreate() and FlutterDesktopEngineCreate() to instead take a pointer. Based fix for upstream issue (flutter/engine#25439). Developer's Certificate of Origin 1.1 By making a contribution to this project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved. --- AUTHORS | 1 + src/client_wrapper/flutter_engine.cc | 2 +- src/client_wrapper/flutter_view_controller.cc | 2 +- .../platform/linux_embedded/flutter_elinux.cc | 14 +++++++------- .../linux_embedded/public/flutter_elinux.h | 4 ++-- 5 files changed, 12 insertions(+), 11 deletions(-) diff --git a/AUTHORS b/AUTHORS index 34746af2..1812758d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,3 +11,4 @@ Valentin Hăloiu (valentin.haloiu@gmail.com) FlafyDev Makoto Sato (makoto.sato@atmark-techno.com) Yunhao Tian (t123yh@outlook.com) +Luke Howard diff --git a/src/client_wrapper/flutter_engine.cc b/src/client_wrapper/flutter_engine.cc index a1fc0c46..4cf26678 100644 --- a/src/client_wrapper/flutter_engine.cc +++ b/src/client_wrapper/flutter_engine.cc @@ -30,7 +30,7 @@ FlutterEngine::FlutterEngine(const DartProject& project) { c_engine_properties.dart_entrypoint_argv = entrypoint_argv.size() > 0 ? entrypoint_argv.data() : nullptr; - engine_ = FlutterDesktopEngineCreate(c_engine_properties); + engine_ = FlutterDesktopEngineCreate(&c_engine_properties); auto core_messenger = FlutterDesktopEngineGetMessenger(engine_); messenger_ = std::make_unique(core_messenger); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 8891bc87..3d9b7ea8 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -43,7 +43,7 @@ FlutterViewController::FlutterViewController( c_view_properties.force_scale_factor = view_properties.force_scale_factor; c_view_properties.scale_factor = view_properties.scale_factor; - controller_ = FlutterDesktopViewControllerCreate(c_view_properties, + controller_ = FlutterDesktopViewControllerCreate(&c_view_properties, engine_->RelinquishEngine()); if (!controller_) { std::cerr << "Failed to create view controller." << std::endl; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 1279155b..1ac196b7 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -72,21 +72,21 @@ uint64_t FlutterDesktopEngineProcessMessages(FlutterDesktopEngineRef engine) { } FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( - const FlutterDesktopViewProperties& view_properties, + const FlutterDesktopViewProperties* view_properties, FlutterDesktopEngineRef engine) { std::unique_ptr window_wrapper = #if defined(DISPLAY_BACKEND_TYPE_DRM_GBM) std::make_unique>( - view_properties); + *view_properties); #elif defined(DISPLAY_BACKEND_TYPE_DRM_EGLSTREAM) std::make_unique< flutter::ELinuxWindowDrm>( - view_properties); + *view_properties); #elif defined(DISPLAY_BACKEND_TYPE_X11) - std::make_unique(view_properties); + std::make_unique(*view_properties); #else - std::make_unique(view_properties); + std::make_unique(*view_properties); #endif auto state = std::make_unique(); @@ -134,8 +134,8 @@ int32_t FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view) { } FlutterDesktopEngineRef FlutterDesktopEngineCreate( - const FlutterDesktopEngineProperties& engine_properties) { - flutter::FlutterProjectBundle project(engine_properties); + const FlutterDesktopEngineProperties* engine_properties) { + flutter::FlutterProjectBundle project(*engine_properties); auto engine = std::make_unique(project); return HandleForEngine(engine.release()); } diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index eb3989e5..d97d5fa0 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -128,7 +128,7 @@ typedef struct { // an error. FLUTTER_EXPORT FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( - const FlutterDesktopViewProperties& view_properties, + const FlutterDesktopViewProperties* view_properties, FlutterDesktopEngineRef engine); // Shuts down the engine instance associated with |controller|, and cleans up @@ -161,7 +161,7 @@ FlutterDesktopViewGetFrameRate(FlutterDesktopViewRef view); // The caller owns the returned reference, and is responsible for calling // FlutterDesktopEngineDestroy. FLUTTER_EXPORT FlutterDesktopEngineRef FlutterDesktopEngineCreate( - const FlutterDesktopEngineProperties& engine_properties); + const FlutterDesktopEngineProperties* engine_properties); // Shuts down and destroys the given engine instance. Returns true if the // shutdown was successful, or if the engine was not running. From 5c86492e74ab7130778656f7763550121254036e Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 17 Jul 2023 13:21:37 +0200 Subject: [PATCH 120/178] embedder: locking and refcount support in FlutterDesktopMessenger (#347) Import locking and reference counting support for FlutterDesktopMessenger from upstream (#345) --- .../common/public/flutter_messenger.h | 47 ++++++++++++++++ .../platform/linux_embedded/flutter_elinux.cc | 35 ++++++++++-- .../linux_embedded/flutter_elinux_engine.cc | 6 +- .../linux_embedded/flutter_elinux_engine.h | 7 ++- .../linux_embedded/flutter_elinux_state.h | 56 ++++++++++++++++++- 5 files changed, 140 insertions(+), 11 deletions(-) diff --git a/src/flutter/shell/platform/common/public/flutter_messenger.h b/src/flutter/shell/platform/common/public/flutter_messenger.h index 854ff985..87c33beb 100644 --- a/src/flutter/shell/platform/common/public/flutter_messenger.h +++ b/src/flutter/shell/platform/common/public/flutter_messenger.h @@ -87,6 +87,53 @@ FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback( FlutterDesktopMessageCallback callback, void* user_data); +// Increments the reference count for the |messenger|. +// +// Operation is thread-safe. +// +// See also: |FlutterDesktopMessengerRelease| +FLUTTER_EXPORT FlutterDesktopMessengerRef +FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger); + +// Decrements the reference count for the |messenger|. +// +// Operation is thread-safe. +// +// See also: |FlutterDesktopMessengerAddRef| +FLUTTER_EXPORT void FlutterDesktopMessengerRelease( + FlutterDesktopMessengerRef messenger); + +// Returns `true` if the |FlutterDesktopMessengerRef| still references a running +// engine. +// +// This check should be made inside of a |FlutterDesktopMessengerLock| and +// before any other calls are made to the FlutterDesktopMessengerRef when using +// it from a thread other than the platform thread. +FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable( + FlutterDesktopMessengerRef messenger); + +// Locks the `FlutterDesktopMessengerRef` ensuring that +// |FlutterDesktopMessengerIsAvailable| does not change while locked. +// +// All calls to the FlutterDesktopMessengerRef from threads other than the +// platform thread should happen inside of a lock. +// +// Operation is thread-safe. +// +// Returns the |messenger| value. +// +// See also: |FlutterDesktopMessengerUnlock| +FLUTTER_EXPORT FlutterDesktopMessengerRef +FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger); + +// Unlocks the `FlutterDesktopMessengerRef`. +// +// Operation is thread-safe. +// +// See also: |FlutterDesktopMessengerLock| +FLUTTER_EXPORT void FlutterDesktopMessengerUnlock( + FlutterDesktopMessengerRef messenger); + #if defined(__cplusplus) } // extern "C" #endif diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 1ac196b7..990a2cdc 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -204,8 +204,8 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, const size_t message_size, const FlutterDesktopBinaryReply reply, void* user_data) { - return messenger->engine->SendPlatformMessage(channel, message, message_size, - reply, user_data); + return messenger->GetEngine()->SendPlatformMessage( + channel, message, message_size, reply, user_data); } bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, @@ -221,15 +221,40 @@ void FlutterDesktopMessengerSendResponse( const FlutterDesktopMessageResponseHandle* handle, const uint8_t* data, size_t data_length) { - messenger->engine->SendPlatformMessageResponse(handle, data, data_length); + messenger->GetEngine()->SendPlatformMessageResponse(handle, data, + data_length); } void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger, const char* channel, FlutterDesktopMessageCallback callback, void* user_data) { - messenger->engine->message_dispatcher()->SetMessageCallback(channel, callback, - user_data); + messenger->GetEngine()->message_dispatcher()->SetMessageCallback( + channel, callback, user_data); +} + +FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef( + FlutterDesktopMessengerRef messenger) { + messenger->AddRef(); + return messenger; +} + +void FlutterDesktopMessengerRelease(FlutterDesktopMessengerRef messenger) { + messenger->Release(); +} + +bool FlutterDesktopMessengerIsAvailable(FlutterDesktopMessengerRef messenger) { + return messenger->GetEngine() != nullptr; +} + +FlutterDesktopMessengerRef FlutterDesktopMessengerLock( + FlutterDesktopMessengerRef messenger) { + messenger->GetMutex().lock(); + return messenger; +} + +void FlutterDesktopMessengerUnlock(FlutterDesktopMessengerRef messenger) { + messenger->GetMutex().unlock(); } FlutterDesktopTextureRegistrarRef FlutterDesktopRegistrarGetTextureRegistrar( diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 069ab7e9..c0ef315c 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -143,8 +143,10 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) }); // Set up the legacy structs backing the API handles. - messenger_ = std::make_unique(); - messenger_->engine = this; + messenger_ = FlutterDesktopMessengerReferenceOwner( + FlutterDesktopMessengerAddRef(new FlutterDesktopMessenger()), + &FlutterDesktopMessengerRelease); + messenger_->SetEngine(this); plugin_registrar_ = std::make_unique(); plugin_registrar_->engine = this; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 83de54d2..11283307 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -27,6 +27,10 @@ namespace flutter { class FlutterELinuxView; +using FlutterDesktopMessengerReferenceOwner = + std::unique_ptr; + class FlutterELinuxEngine { public: explicit FlutterELinuxEngine(const FlutterProjectBundle& project); @@ -144,7 +148,8 @@ class FlutterELinuxEngine { std::unique_ptr task_runner_; // The plugin messenger handle given to API clients. - std::unique_ptr messenger_; + FlutterDesktopMessengerReferenceOwner messenger_ = { + nullptr, [](FlutterDesktopMessengerRef ref) {}}; // A wrapper around messenger_ for interacting with client_wrapper-level APIs. std::unique_ptr messenger_wrapper_; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h index 92a9d582..8248f7e8 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h @@ -5,7 +5,15 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ +#include #include +#include + +#if __has_include() +#include +#else +#define SWIFT_SHARED_REFERENCE(_retain, _release) +#endif #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" @@ -38,8 +46,50 @@ struct FlutterDesktopPluginRegistrar { // Wrapper to distinguish the messenger ref from the engine ref given out // in the C API. struct FlutterDesktopMessenger { - // The engine that owns this state object. - flutter::FlutterELinuxEngine* engine = nullptr; -}; + FlutterDesktopMessenger() = default; + + /// Increments the reference count. + /// + /// Thread-safe. + void AddRef() { ref_count_.fetch_add(1); } + + /// Decrements the reference count and deletes the object if the count has + /// gone to zero. + /// + /// Thread-safe. + void Release() { + int32_t old_count = ref_count_.fetch_sub(1); + if (old_count <= 1) { + delete this; + } + } + + /// Getter for the engine field. + flutter::FlutterELinuxEngine* GetEngine() const { return engine_; } + + /// Setter for the engine field. + /// Thread-safe. + void SetEngine(flutter::FlutterELinuxEngine* engine) { + std::scoped_lock lock(mutex_); + engine_ = engine; + } + + /// Returns the mutex associated with the |FlutterDesktopMessenger|. + /// + /// This mutex is used to synchronize reading or writing state inside the + /// |FlutterDesktopMessenger| (ie |engine_|). + std::mutex& GetMutex() { return mutex_; } + + FlutterDesktopMessenger(const FlutterDesktopMessenger& value) = delete; + FlutterDesktopMessenger& operator=(const FlutterDesktopMessenger& value) = + delete; + + private: + // The engine that backs this messenger. + flutter::FlutterELinuxEngine* engine_; + std::atomic ref_count_ = 0; + std::mutex mutex_; +} SWIFT_SHARED_REFERENCE(FlutterDesktopMessengerAddRef, + FlutterDesktopMessengerRelease); #endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_FLUTTER_ELINUX_STATE_H_ From 05b0377d52662a33d53370f745e2f127d4ec0248 Mon Sep 17 00:00:00 2001 From: Makoto Sato <51475851+makotosato-at@users.noreply.github.com> Date: Wed, 2 Aug 2023 17:56:13 +0900 Subject: [PATCH 121/178] wayland: fix fullscreen not working on Wayland (#351) Signed-off-by: Makoto Sato --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 8a84022a..64b72e4e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -86,6 +86,7 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { if (self->wait_for_configure_) { self->wait_for_configure_ = false; } + self->request_redraw_ = true; }, }; From 22fe98d26fade7503b0c6b793fd93c4432474604 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Aug 2023 08:58:50 +0000 Subject: [PATCH 122/178] embedder: update embedder's header file (#353) Merged from https://github.com/flutter/engine/commit/b0d97ba45f46c95a1328cd7b4c8787a62638aeea Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index 1710299f..a1e9036b 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -236,6 +236,11 @@ typedef enum { kFlutterSemanticsFlagIsKeyboardKey = 1 << 24, /// Whether the semantics node represents a tristate checkbox in mixed state. kFlutterSemanticsFlagIsCheckStateMixed = 1 << 25, + /// The semantics node has the quality of either being "expanded" or + /// "collapsed". + kFlutterSemanticsFlagHasExpandedState = 1 << 26, + /// Whether a semantic node that hasExpandedState is currently expanded. + kFlutterSemanticsFlagIsExpanded = 1 << 27, } FlutterSemanticsFlag; typedef enum { @@ -676,9 +681,13 @@ typedef struct { FlutterMetalCommandQueueHandle present_command_queue; /// The callback that gets invoked when the engine requests the embedder for a /// texture to render to. + /// + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterMetalTextureCallback get_next_drawable_callback; /// The callback presented to the embedder to present a fully populated metal /// texture to the user. + /// + /// Not used if a FlutterCompositor is supplied in FlutterProjectArgs. FlutterMetalPresentCallback present_drawable_callback; /// When the embedder specifies that a texture has a frame available, the /// engine will call this method (on an internal engine managed thread) so @@ -805,6 +814,11 @@ typedef struct { }; } FlutterRendererConfig; +/// Display refers to a graphics hardware system consisting of a framebuffer, +/// typically a monitor or a screen. This ID is unique per display and is +/// stable until the Flutter application restarts. +typedef uint64_t FlutterEngineDisplayId; + typedef struct { /// The size of this struct. Must be sizeof(FlutterWindowMetricsEvent). size_t struct_size; @@ -826,6 +840,8 @@ typedef struct { double physical_view_inset_bottom; /// Left inset of window. double physical_view_inset_left; + /// The identifier of the display the view is rendering on. + FlutterEngineDisplayId display_id; } FlutterWindowMetricsEvent; /// The phase of the pointer event. @@ -1653,11 +1669,6 @@ typedef const FlutterLocale* (*FlutterComputePlatformResolvedLocaleCallback)( const FlutterLocale** /* supported_locales*/, size_t /* Number of locales*/); -/// Display refers to a graphics hardware system consisting of a framebuffer, -/// typically a monitor or a screen. This ID is unique per display and is -/// stable until the Flutter application restarts. -typedef uint64_t FlutterEngineDisplayId; - typedef struct { /// This size of this struct. Must be sizeof(FlutterDisplay). size_t struct_size; @@ -1673,6 +1684,16 @@ typedef struct { /// This represents the refresh period in frames per second. This value may be /// zero if the device is not running or unavailable or unknown. double refresh_rate; + + /// The width of the display, in physical pixels. + size_t width; + + /// The height of the display, in physical pixels. + size_t height; + + /// The pixel ratio of the display, which is used to convert physical pixels + /// to logical pixels. + double device_pixel_ratio; } FlutterEngineDisplay; /// The update type parameter that is passed to From a17214315034cd0dceda828fd1bc0ba24c2ec013 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Aug 2023 09:16:18 +0000 Subject: [PATCH 123/178] elinux: fix missing FlutterDesktopPluginRegistrarGetView() header (#354) Fixed #348 Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/public/flutter_elinux.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index d97d5fa0..5693f095 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -200,6 +200,10 @@ FLUTTER_EXPORT FlutterDesktopPluginRegistrarRef FlutterDesktopEngineGetPluginRegistrar(FlutterDesktopEngineRef engine, const char* plugin_name); +// Returns the view associated with this registrar's engine instance. +FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( + FlutterDesktopPluginRegistrarRef registrar); + // Returns the messenger associated with the engine. FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); From 9f08f4ce8d0c0e3ff21c581404919a78e7ee3f26 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Aug 2023 12:28:45 +0000 Subject: [PATCH 124/178] impeller: add impeller initial implementation (#355) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/common/engine_switches.cc | 2 - .../platform/linux_embedded/flutter_elinux.cc | 5 +- .../linux_embedded/flutter_elinux_engine.cc | 10 ++++ .../linux_embedded/flutter_elinux_engine.h | 8 +++ .../linux_embedded/flutter_elinux_view.cc | 5 +- .../linux_embedded/flutter_project_bundle.cc | 17 +++++- .../linux_embedded/flutter_project_bundle.h | 6 ++ .../linux_embedded/surface/context_egl.cc | 57 +++++++++++++++++-- .../linux_embedded/surface/context_egl.h | 1 + .../linux_embedded/window/elinux_window_drm.h | 8 ++- .../window/elinux_window_wayland.cc | 10 ++-- .../window/elinux_window_wayland.h | 6 +- .../window/elinux_window_x11.cc | 10 ++-- .../linux_embedded/window/elinux_window_x11.h | 6 +- .../linux_embedded/window/native_window_drm.h | 5 +- .../window/native_window_drm_eglstream.cc | 5 +- .../window/native_window_drm_eglstream.h | 4 +- .../window/native_window_drm_gbm.cc | 7 ++- .../window/native_window_drm_gbm.h | 4 +- .../renderer/window_decorations_wayland.cc | 15 +++-- .../renderer/window_decorations_wayland.h | 3 +- .../linux_embedded/window_binding_handler.h | 9 ++- 22 files changed, 155 insertions(+), 48 deletions(-) diff --git a/src/flutter/shell/platform/common/engine_switches.cc b/src/flutter/shell/platform/common/engine_switches.cc index 5c750f13..37b98fae 100644 --- a/src/flutter/shell/platform/common/engine_switches.cc +++ b/src/flutter/shell/platform/common/engine_switches.cc @@ -16,7 +16,6 @@ std::vector GetSwitchesFromEnvironment() { // Read engine switches from the environment in debug/profile. If release mode // support is needed in the future, it should likely use a whitelist. #ifndef FLUTTER_RELEASE -#ifndef WINUWP const char* switch_count_key = "FLUTTER_ENGINE_SWITCHES"; const int kMaxSwitchCount = 50; const char* switch_count_string = std::getenv(switch_count_key); @@ -37,7 +36,6 @@ std::vector GetSwitchesFromEnvironment() { << ", but " << switch_key.str() << " is missing." << std::endl; } } -#endif // !WINUWP #endif // !FLUTTER_RELEASE return switches; } diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 990a2cdc..99313f2d 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -92,13 +92,10 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( auto state = std::make_unique(); state->view = std::make_unique(std::move(window_wrapper)); - if (!state->view->CreateRenderSurface()) { - return nullptr; - } - // Take ownership of the engine, starting it if necessary. state->view->SetEngine( std::unique_ptr(EngineFromHandle(engine))); + state->view->CreateRenderSurface(); if (!state->view->GetEngine()->running()) { if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) { return nullptr; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index c0ef315c..d081cdfb 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -142,6 +142,11 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) } }); + // Check for impeller support. + auto& switches = project_->GetSwitches(); + enable_impeller_ = std::find(switches.begin(), switches.end(), + "--enable-impeller=true") != switches.end(); + // Set up the legacy structs backing the API handles. messenger_ = FlutterDesktopMessengerReferenceOwner( FlutterDesktopMessengerAddRef(new FlutterDesktopMessenger()), @@ -173,6 +178,11 @@ FlutterELinuxEngine::~FlutterELinuxEngine() { Stop(); } +void FlutterELinuxEngine::SetSwitches( + const std::vector& switches) { + project_->SetSwitches(switches); +} + bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { if (!project_->HasValidPaths()) { ELINUX_LOG(ERROR) << "Missing or unresolvable paths to assets."; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 11283307..e6595262 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -68,6 +68,9 @@ class FlutterELinuxEngine { void SetPluginRegistrarDestructionCallback( FlutterDesktopOnPluginRegistrarDestroyed callback); + // Sets switches member to the given switches. + void SetSwitches(const std::vector& switches); + FlutterDesktopMessengerRef messenger() { return messenger_.get(); } IncomingMessageDispatcher* message_dispatcher() { @@ -121,6 +124,9 @@ class FlutterELinuxEngine { void OnVsync(uint64_t last_frame_time_nanos, uint64_t vsync_interval_time_nanos); + // Gets the status whether Impeller is enabled. + bool IsImpellerEnabled() const { return enable_impeller_; } + private: // Allows swapping out embedder_api_ calls in tests. friend class EngineEmbedderApiModifier; @@ -176,6 +182,8 @@ class FlutterELinuxEngine { // The vsync waiter. std::unique_ptr vsync_waiter_; + + bool enable_impeller_ = false; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index ce02b388..131d114c 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -434,7 +434,10 @@ bool FlutterELinuxView::MakeResourceCurrent() { bool FlutterELinuxView::CreateRenderSurface() { PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); - return binding_handler_->CreateRenderSurface(bounds.width, bounds.height); + auto impeller_enable = engine_.get()->IsImpellerEnabled(); + std::cout << "impeller: " << impeller_enable << std::endl; + return binding_handler_->CreateRenderSurface(bounds.width, bounds.height, + impeller_enable); } void FlutterELinuxView::DestroyRenderSurface() { diff --git a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc index bd974261..31681244 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.cc @@ -85,8 +85,23 @@ UniqueAotDataPtr FlutterProjectBundle::LoadAotData( return UniqueAotDataPtr(data); } +void FlutterProjectBundle::SetSwitches( + const std::vector& switches) { + engine_switches_ = switches; +} + const std::vector FlutterProjectBundle::GetSwitches() { - return GetSwitchesFromEnvironment(); + if (engine_switches_.size() == 0) { + return GetSwitchesFromEnvironment(); + } + std::vector switches; + switches.insert(switches.end(), engine_switches_.begin(), + engine_switches_.end()); + + auto env_switches = GetSwitchesFromEnvironment(); + switches.insert(switches.end(), env_switches.begin(), env_switches.end()); + + return switches; } const std::string FlutterProjectBundle::GetExecutableDirectory() { diff --git a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h index fdec398d..503fcd38 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_project_bundle.h @@ -45,6 +45,9 @@ class FlutterProjectBundle { // Returns any switches that should be passed to the engine. const std::vector GetSwitches(); + // Sets engine switches. + void SetSwitches(const std::vector& switches); + // Attempts to load AOT data for this bundle. The returned data must be // retained until any engine instance it is passed to has been shut down. // @@ -69,6 +72,9 @@ class FlutterProjectBundle { // Dart entrypoint arguments. std::vector dart_entrypoint_arguments_; + + // Engine switches. + std::vector engine_switches_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index f723bd57..bea6dbb4 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -10,6 +10,7 @@ namespace flutter { ContextEgl::ContextEgl(std::unique_ptr environment, + bool enable_impeller, EGLint egl_surface_type) : environment_(std::move(environment)), config_(nullptr) { EGLint config_count = 0; @@ -28,11 +29,57 @@ ContextEgl::ContextEgl(std::unique_ptr environment, EGL_NONE // clang-format on }; - if (eglChooseConfig(environment_->Display(), attribs, &config_, 1, - &config_count) != EGL_TRUE) { - ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: " - << get_egl_error_cause(); - return; + const EGLint impeller_config_attributes[] = { + // clang-format off + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, +#if defined(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) + EGL_ALPHA_SIZE, 8, +#endif + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 1, + EGL_SAMPLES, 4, + EGL_NONE + // clang-format on + }; + const EGLint impeller_config_attributes_no_msaa[] = { + // clang-format off + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, +#if defined(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) + EGL_ALPHA_SIZE, 8, +#endif + EGL_DEPTH_SIZE, 0, + EGL_STENCIL_SIZE, 8, + EGL_NONE + // clang-format on + }; + + if (enable_impeller) { + // First try the MSAA configuration. + if ((eglChooseConfig(environment_->Display(), impeller_config_attributes, + &config_, 1, &config_count) == EGL_FALSE) || + (config_count == 0)) { + // Next fall back to disabled MSAA. + if ((eglChooseConfig(environment_->Display(), + impeller_config_attributes_no_msaa, &config_, 1, + &config_count) == EGL_FALSE) || + (config_count == 0)) { + ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: " + << get_egl_error_cause(); + return; + } + } + } else { + if (eglChooseConfig(environment_->Display(), attribs, &config_, 1, + &config_count) != EGL_TRUE) { + ELINUX_LOG(ERROR) << "Failed to choose EGL surface config: " + << get_egl_error_cause(); + return; + } } if (config_count == 0 || config_ == nullptr) { diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.h b/src/flutter/shell/platform/linux_embedded/surface/context_egl.h index b443e191..4950a816 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.h +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.h @@ -18,6 +18,7 @@ namespace flutter { class ContextEgl { public: ContextEgl(std::unique_ptr environment, + bool enable_impeller, EGLint egl_surface_type = EGL_WINDOW_BIT); ~ContextEgl() = default; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index e9e5edcc..beaec990 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -109,7 +109,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - bool CreateRenderSurface(int32_t width, int32_t height) override { + bool CreateRenderSurface(int32_t width, + int32_t height, + bool enable_impeller) override { std::vector devices; auto device_filename = std::getenv(kFlutterDrmDeviceEnvironmentKey); if (device_filename && device_filename[0] != '\0') { @@ -148,7 +150,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { display_valid_ = true; - render_surface_ = native_window_->CreateRenderSurface(); + render_surface_ = native_window_->CreateRenderSurface(enable_impeller); if (!render_surface_->SetNativeWindow(native_window_.get())) { return false; } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 64b72e4e..2e684e56 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -1147,7 +1147,8 @@ bool ELinuxWindowWayland::DispatchEvent() { } bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, - int32_t height_px) { + int32_t height_px, + bool enable_impeller) { if (!display_valid_) { ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; @@ -1225,7 +1226,7 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, wl_surface_commit(native_window_->Surface()); render_surface_ = std::make_unique(std::make_unique( - std::make_unique(wl_display_))); + std::make_unique(wl_display_), enable_impeller)); render_surface_->SetNativeWindow(native_window_.get()); if (view_properties_.use_window_decoration) { @@ -1233,7 +1234,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, int32_t height_dip = height_px / current_scale_; window_decorations_ = std::make_unique( wl_display_, wl_compositor_, wl_subcompositor_, - native_window_->Surface(), width_dip, height_dip, current_scale_); + native_window_->Surface(), width_dip, height_dip, current_scale_, + enable_impeller); } // Wait for making sure that xdg_surface has been configured. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 00bf0b09..fad7dc1d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -45,7 +45,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { bool DispatchEvent() override; // |FlutterWindowBindingHandler| - bool CreateRenderSurface(int32_t width_px, int32_t height_px) override; + bool CreateRenderSurface(int32_t width_px, + int32_t height_px, + bool enable_impeller) override; // |FlutterWindowBindingHandler| void DestroyRenderSurface() override; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 9d52a494..15ede0d4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -121,9 +121,11 @@ bool ELinuxWindowX11::DispatchEvent() { return true; } -bool ELinuxWindowX11::CreateRenderSurface(int32_t width, int32_t height) { - auto context_egl = - std::make_unique(std::make_unique(display_)); +bool ELinuxWindowX11::CreateRenderSurface(int32_t width, + int32_t height, + bool enable_impeller) { + auto context_egl = std::make_unique( + std::make_unique(display_), enable_impeller); if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width, height); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 80683534..9d364526 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -26,7 +26,9 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { bool DispatchEvent() override; // |FlutterWindowBindingHandler| - bool CreateRenderSurface(int32_t width, int32_t height) override; + bool CreateRenderSurface(int32_t width, + int32_t height, + bool enable_impeller) override; // |FlutterWindowBindingHandler| void DestroyRenderSurface() override; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index 6259f6aa..9a40b100 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,7 +31,8 @@ class NativeWindowDrm : public NativeWindow { virtual bool DismissCursor() = 0; - virtual std::unique_ptr CreateRenderSurface() = 0; + virtual std::unique_ptr CreateRenderSurface( + bool enable_impeller) = 0; protected: drmModeConnectorPtr FindConnector(drmModeResPtr resources); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc index a78fd033..97242219 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -91,7 +91,8 @@ bool NativeWindowDrmEglstream::DismissCursor() { return true; } -std::unique_ptr NativeWindowDrmEglstream::CreateRenderSurface() { +std::unique_ptr NativeWindowDrmEglstream::CreateRenderSurface( + bool enable_impeller) { return std::make_unique(std::make_unique( std::make_unique())); } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h index f3e469d5..27561a61 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,7 +32,7 @@ class NativeWindowDrmEglstream : public NativeWindowDrm { bool DismissCursor() override; // |NativeWindowDrm| - std::unique_ptr CreateRenderSurface() override; + std::unique_ptr CreateRenderSurface(bool enable_impeller) override; // |NativeWindow| bool Resize(const size_t width, const size_t height) override; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index 8c342c00..10f4779c 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -129,9 +129,10 @@ bool NativeWindowDrmGbm::DismissCursor() { return true; } -std::unique_ptr NativeWindowDrmGbm::CreateRenderSurface() { +std::unique_ptr NativeWindowDrmGbm::CreateRenderSurface( + bool enable_impeller) { return std::make_unique(std::make_unique( - std::make_unique(gbm_device_))); + std::make_unique(gbm_device_), enable_impeller)); } bool NativeWindowDrmGbm::IsNeedRecreateSurfaceAfterResize() const { diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h index 6b9b9ecd..e888b269 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h @@ -1,4 +1,4 @@ -// Copyright 2021 Sony Corporation. All rights reserved. +// Copyright 2023 Sony Corporation. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,7 +32,7 @@ class NativeWindowDrmGbm : public NativeWindowDrm { bool DismissCursor() override; // |NativeWindowDrm| - std::unique_ptr CreateRenderSurface() override; + std::unique_ptr CreateRenderSurface(bool enable_impeller) override; // |NativeWindow| bool IsNeedRecreateSurfaceAfterResize() const override; diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index d118573b..531cb5bc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -24,7 +24,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( wl_surface* root_surface, int32_t width_dip, int32_t height_dip, - double pixel_ratio) { + double pixel_ratio, + bool enable_impeller) { constexpr bool sub_egl_display = true; // title-bar. @@ -33,7 +34,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( compositor, subcompositor, root_surface, width_dip * pixel_ratio, kTitleBarHeightDIP * pixel_ratio), std::make_unique(std::make_unique( - std::make_unique(display, sub_egl_display)))); + std::make_unique(display, sub_egl_display), + enable_impeller))); titlebar_->SetPosition(0, -kTitleBarHeightDIP); // close button. @@ -44,7 +46,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( compositor, subcompositor, root_surface, kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( - std::make_unique(display, sub_egl_display))))); + std::make_unique(display, sub_egl_display), + enable_impeller)))); buttons_[type]->SetPosition( width_dip - kButtonWidthDIP - kButtonMarginDIP, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); @@ -57,7 +60,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( compositor, subcompositor, root_surface, kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( - std::make_unique(display, sub_egl_display))))); + std::make_unique(display, sub_egl_display), + enable_impeller)))); buttons_[type]->SetPosition( width_dip - kButtonWidthDIP * 2 - kButtonMarginDIP * 2, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); @@ -70,7 +74,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( compositor, subcompositor, root_surface, kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), std::make_unique(std::make_unique( - std::make_unique(display, sub_egl_display))))); + std::make_unique(display, sub_egl_display), + enable_impeller)))); buttons_[type]->SetPosition( width_dip - kButtonWidthDIP * 3 - kButtonMarginDIP * 3, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 9910841e..3e60b3ed 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -35,7 +35,8 @@ class WindowDecorationsWayland { wl_surface* root_surface, int32_t width_dip, int32_t height_dip, - double pixel_ratio); + double pixel_ratio, + bool enable_impeller); ~WindowDecorationsWayland(); void Draw(); diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h index ce8fffb4..34499df8 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler.h @@ -34,9 +34,12 @@ class WindowBindingHandler { virtual bool DispatchEvent() = 0; // Create a surface. - // @param[in] width_px Physical width of the surface. - // @param[in] height_px Physical height of the surface. - virtual bool CreateRenderSurface(int32_t width_px, int32_t height_px) = 0; + // @param[in] width_px Physical width of the surface. + // @param[in] height_px Physical height of the surface. + // @param[in] enable_impeller Enable impeller. + virtual bool CreateRenderSurface(int32_t width_px, + int32_t height_px, + bool enable_impeller) = 0; // Destroy a surface which is currently used. virtual void DestroyRenderSurface() = 0; From 9dcb3d4d053e7c0b4edf1d39654b76b6449b5ea6 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Aug 2023 12:52:15 +0000 Subject: [PATCH 125/178] impeller: remove unnecessary debug comment (#356) Signed-off-by: Hidenori Matsubayashi --- src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 131d114c..2f4d8548 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -435,7 +435,6 @@ bool FlutterELinuxView::MakeResourceCurrent() { bool FlutterELinuxView::CreateRenderSurface() { PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); auto impeller_enable = engine_.get()->IsImpellerEnabled(); - std::cout << "impeller: " << impeller_enable << std::endl; return binding_handler_->CreateRenderSurface(bounds.width, bounds.height, impeller_enable); } From bfcffb300f1a3448e45741f92e9ba1d350e86eff Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 4 Aug 2023 14:30:40 +0000 Subject: [PATCH 126/178] wayland: re-enable vsync (#357) Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ef7a33a..723556b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the displ option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) -option(ENABLE_VSYNC "Enable embedder vsync" OFF) +option(ENABLE_VSYNC "Enable embedder vsync" ON) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) From 070302587ece6c79b0b2b2b16dc0c7236eb5ba57 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 5 Aug 2023 07:12:42 +0000 Subject: [PATCH 127/178] wayland: add xdg-decoration support (#358) I've tested this change on Sway. Fixed #216 Signed-off-by: Hidenori Matsubayashi --- cmake/build.cmake | 6 ++ .../window/elinux_window_wayland.cc | 82 +++++++++++++++++-- .../window/elinux_window_wayland.h | 10 +++ 3 files changed, 91 insertions(+), 7 deletions(-) diff --git a/cmake/build.cmake b/cmake/build.cmake index e97728f1..cde9cc92 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -63,6 +63,11 @@ else() CODE_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.c" HEADER_FILE "${_wayland_protocols_src_dir}/presentation-time-protocol.h") + generate_wayland_client_protocol( + PROTOCOL_FILE "${_wayland_protocols_xml_dir}/unstable/xdg-decoration/xdg-decoration-unstable-v1.xml" + CODE_FILE "${_wayland_protocols_src_dir}/xdg-decoration-unstable-v1-protocol.c" + HEADER_FILE "${_wayland_protocols_src_dir}/xdg-decoration-unstable-v1-protocol.h") + add_definitions(-DFLUTTER_TARGET_BACKEND_WAYLAND) add_definitions(-DDISPLAY_BACKEND_TYPE_WAYLAND) set(DISPLAY_BACKEND_SRC @@ -70,6 +75,7 @@ else() "${_wayland_protocols_src_dir}/text-input-unstable-v1-protocol.c" "${_wayland_protocols_src_dir}/text-input-unstable-v3-protocol.c" "${_wayland_protocols_src_dir}/presentation-time-protocol.c" + "${_wayland_protocols_src_dir}/xdg-decoration-unstable-v1-protocol.c" "src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc" "src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc" diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 2e684e56..5d5ee1bf 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -23,6 +23,7 @@ namespace flutter { namespace { constexpr char kZwpTextInputManagerV1[] = "zwp_text_input_manager_v1"; constexpr char kZwpTextInputManagerV3[] = "zwp_text_input_manager_v3"; +constexpr char kZxdgDecorationManagerV1[] = "zxdg_decoration_manager_v1"; constexpr char kWlCursorThemeBottomLeftCorner[] = "bottom_left_corner"; constexpr char kWlCursorThemeBottomRightCorner[] = "bottom_right_corner"; @@ -73,7 +74,7 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { auto self = reinterpret_cast(data); constexpr int32_t x = 0; int32_t y = 0; - if (self->view_properties_.use_window_decoration) { + if (self->window_decorations_) { // TODO: Moves the window to the bottom to show the window // decorations, but the bottom area of the window will be hidden // because of this shifting. @@ -851,6 +852,28 @@ const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { uint32_t dnd_action) -> void {}, }; +const zxdg_toplevel_decoration_v1_listener + ELinuxWindowWayland::kZxdgToplevelDecorationV1Listener = { + .configure = + [](void* data, + struct zxdg_toplevel_decoration_v1* zxdg_toplevel_decoration_v1, + uint32_t mode) -> void { + ELINUX_LOG(INFO) + << "zxdg_toplevel_decoration_v1_listener.configure: mode is " + << ((mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE) + ? "server-side" + : "client-side"); + auto self = reinterpret_cast(data); + if (self->view_properties_.use_window_decoration && + mode == ZXDG_TOPLEVEL_DECORATION_V1_MODE_CLIENT_SIDE && + !self->window_decorations_) { + int32_t width_dip = self->view_properties_.width; + int32_t height_dip = self->view_properties_.height; + self->CreateDecoration(width_dip, height_dip); + } + }, +}; + ELinuxWindowWayland::ELinuxWindowWayland( FlutterDesktopViewProperties view_properties) : cursor_info_({"", 0, nullptr}), @@ -973,6 +996,18 @@ ELinuxWindowWayland::~ELinuxWindowWayland() { } } + { + if (zxdg_decoration_manager_v1_) { + zxdg_decoration_manager_v1_destroy(zxdg_decoration_manager_v1_); + zxdg_decoration_manager_v1_ = nullptr; + } + + if (zxdg_toplevel_decoration_v1_) { + zxdg_toplevel_decoration_v1_destroy(zxdg_toplevel_decoration_v1_); + zxdg_toplevel_decoration_v1_ = nullptr; + } + } + if (wl_data_offer_) { wl_data_offer_destroy(wl_data_offer_); wl_data_offer_ = nullptr; @@ -1149,6 +1184,8 @@ bool ELinuxWindowWayland::DispatchEvent() { bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, int32_t height_px, bool enable_impeller) { + enable_impeller_ = enable_impeller; + if (!display_valid_) { ELINUX_LOG(ERROR) << "Wayland display is invalid."; return false; @@ -1230,12 +1267,22 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, render_surface_->SetNativeWindow(native_window_.get()); if (view_properties_.use_window_decoration) { - int32_t width_dip = width_px / current_scale_; - int32_t height_dip = height_px / current_scale_; - window_decorations_ = std::make_unique( - wl_display_, wl_compositor_, wl_subcompositor_, - native_window_->Surface(), width_dip, height_dip, current_scale_, - enable_impeller); + if (zxdg_decoration_manager_v1_) { + ELINUX_LOG(INFO) << "Use server-side xdg-decoration mode"; + zxdg_toplevel_decoration_v1_ = + zxdg_decoration_manager_v1_get_toplevel_decoration( + zxdg_decoration_manager_v1_, xdg_toplevel_); + zxdg_toplevel_decoration_v1_set_mode( + zxdg_toplevel_decoration_v1_, + ZXDG_TOPLEVEL_DECORATION_V1_MODE_SERVER_SIDE); + zxdg_toplevel_decoration_v1_add_listener( + zxdg_toplevel_decoration_v1_, &kZxdgToplevelDecorationV1Listener, + this); + } else { + int32_t width_dip = width_px / current_scale_; + int32_t height_dip = height_px / current_scale_; + CreateDecoration(width_dip, height_dip); + } } // Wait for making sure that xdg_surface has been configured. @@ -1246,6 +1293,18 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, return true; } +void ELinuxWindowWayland::CreateDecoration(int32_t width_dip, + int32_t height_dip) { + if (window_decorations_) { + ELINUX_LOG(WARNING) << "Window decoration has already created"; + return; + } + + window_decorations_ = std::make_unique( + wl_display_, wl_compositor_, wl_subcompositor_, native_window_->Surface(), + width_dip, height_dip, current_scale_, enable_impeller_); +} + void ELinuxWindowWayland::DestroyRenderSurface() { // destroy the main surface before destroying the client window on Wayland. if (window_decorations_) { @@ -1463,6 +1522,15 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, this); return; } + + if (!strcmp(interface, kZxdgDecorationManagerV1)) { + constexpr uint32_t kMaxVersion = 1; + zxdg_decoration_manager_v1_ = + static_cast(wl_registry_bind( + wl_registry, name, &zxdg_decoration_manager_v1_interface, + std::min(kMaxVersion, version))); + return; + } } void ELinuxWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry, diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index fad7dc1d..6ba5f722 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -24,6 +24,7 @@ extern "C" { #include "wayland/protocols/presentation-time-protocol.h" #include "wayland/protocols/text-input-unstable-v1-client-protocol.h" #include "wayland/protocols/text-input-unstable-v3-client-protocol.h" +#include "wayland/protocols/xdg-decoration-unstable-v1-protocol.h" #include "wayland/protocols/xdg-shell-client-protocol.h" } @@ -107,6 +108,8 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { // Updates the surface scale of the window from the list of entered outputs. void UpdateWindowScale(); + void CreateDecoration(int32_t width_dip, int32_t height_dip); + // Get window decorations height in physical pixels. uint32_t WindowDecorationsPhysicalHeight() const; @@ -128,6 +131,8 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { static const wp_presentation_listener kWpPresentationListener; static const wp_presentation_feedback_listener kWpPresentationFeedbackListener; + static const zxdg_toplevel_decoration_v1_listener + kZxdgToplevelDecorationV1Listener; static constexpr size_t kDefaultPointerSize = 24; // A pointer to a FlutterWindowsView that can be used to update engine @@ -151,6 +156,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { bool request_redraw_ = false; bool maximised_; uint32_t last_frame_time_; + bool enable_impeller_ = false; // Indicates that exists a keyboard show request from Flutter Engine. bool is_requested_show_virtual_keyboard_; @@ -175,6 +181,10 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { zwp_text_input_v1* zwp_text_input_v1_; zwp_text_input_v3* zwp_text_input_v3_; + // xdg-decoration protocol for window decoration (server-side). + zxdg_decoration_manager_v1* zxdg_decoration_manager_v1_ = nullptr; + zxdg_toplevel_decoration_v1* zxdg_toplevel_decoration_v1_ = nullptr; + // Frame information for Vsync events. wp_presentation* wp_presentation_; uint32_t wp_presentation_clk_id_; From 266a92fc5a949be5754720e92184bcf5865dd862 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 5 Aug 2023 12:31:34 +0000 Subject: [PATCH 128/178] wayland: fix wrong height when using decoration option (#359) This change fixes a wrong height size when decoration ("-d") option is used. Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 5d5ee1bf..562c9df9 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -107,8 +107,7 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { } int32_t next_width = width; - int32_t next_height = - height - self->WindowDecorationsPhysicalHeight(); + int32_t next_height = height; if (self->restore_window_required_) { self->restore_window_required_ = false; next_width = self->restore_window_width_; From 589c117b73e56de30a907ae3b4498724ae32d75a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 5 Aug 2023 13:58:47 +0000 Subject: [PATCH 129/178] wayland: delete old todo comment for vsync (#360) Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index d081cdfb..d2510cd0 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -248,9 +248,6 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { auto host = static_cast(user_data); return host->HandlePlatformMessage(engine_message); }; -// todo: disable vsync temporarily because flutter apps will freeze when we use -// this interface. See also: -// https://github.com/sony/flutter-embedded-linux/issues/176 #if defined(ENABLE_VSYNC) // todo: add drm/x11 support. // https://github.com/sony/flutter-embedded-linux/issues/136 From 83d9b6f3cea741ed6d738d824bdda4fb2af23604 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 6 Aug 2023 07:58:32 +0000 Subject: [PATCH 130/178] client_wrapper: merge common/client_wrapper (#361) Merged the latest source files from flutter/engine repo. * src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h => https://github.com/flutter/engine/commit/a3c5a319fccb7b137949ee7f410bf2510148dd3d * src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h src/flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler.h => https://github.com/flutter/engine/commit/52574efd2a88390575423b6407ffd13a39f58429 * src/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h => https://github.com/flutter/engine/commit/4165d4b9b6f1843e91ccbf13a4c12a32d48ca648 * src/flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h => https://github.com/flutter/engine/commit/6d263ea56a62a9cec738f5cfa6c1afcacfd14e9d * src/flutter/shell/platform/common/client_wrapper/standard_codec.cc => https://github.com/flutter/engine/commit/71ee5f19bc164c140055007d39bb3240d04a2376 Signed-off-by: Hidenori Matsubayashi --- .../include/flutter/encodable_value.h | 7 +++++++ .../include/flutter/event_channel.h | 4 ++-- .../include/flutter/event_stream_handler.h | 17 ++++++++++------- .../include/flutter/method_channel.h | 7 ++++--- .../include/flutter/plugin_registrar.h | 4 ++-- .../common/client_wrapper/standard_codec.cc | 2 +- 6 files changed, 26 insertions(+), 15 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h index 3b46f99f..3a191205 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h @@ -215,6 +215,13 @@ class EncodableValue : public internal::EncodableValueVariant { } return std::get(*this); } + + // Explicitly provide operator<, delegating to std::variant's operator<. + // There are issues with with the way the standard library-provided + // < and <=> comparisons interact with classes derived from variant. + friend bool operator<(const EncodableValue& lhs, const EncodableValue& rhs) { + return static_cast(lhs) < static_cast(rhs); + } }; } // namespace flutter diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h index 08c242a2..6a3ef09b 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h @@ -106,7 +106,7 @@ class EventChannel { if (error) { result = codec->EncodeErrorEnvelope(error->error_code, error->error_message, - error->error_details); + error->error_details.get()); } else { result = codec->EncodeSuccessEnvelope(); } @@ -119,7 +119,7 @@ class EventChannel { if (error) { result = codec->EncodeErrorEnvelope(error->error_code, error->error_message, - error->error_details); + error->error_details.get()); } else { result = codec->EncodeSuccessEnvelope(); } diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler.h index 9eced6cf..9c1d8941 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_stream_handler.h @@ -5,6 +5,9 @@ #ifndef FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_ #define FLUTTER_SHELL_PLATFORM_COMMON_CLIENT_WRAPPER_INCLUDE_FLUTTER_EVENT_STREAM_HANDLER_H_ +#include +#include + #include "event_sink.h" namespace flutter { @@ -13,16 +16,16 @@ class EncodableValue; template struct StreamHandlerError { - const std::string& error_code; - const std::string& error_message; - const T* error_details; + const std::string error_code; + const std::string error_message; + const std::unique_ptr error_details; - StreamHandlerError(const std::string& error_code, - const std::string& error_message, - const T* error_details) + StreamHandlerError(const std::string error_code, + const std::string error_message, + std::unique_ptr&& error_details) : error_code(error_code), error_message(error_message), - error_details(error_details) {} + error_details(std::move(error_details)) {} }; // Handler for stream setup and teardown requests. diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h index e9ed6161..6e39a644 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/method_channel.h @@ -91,9 +91,10 @@ class MethodChannel { // Registers a handler that should be called any time a method call is // received on this channel. A null handler will remove any previous handler. // - // Note that the MethodChannel does not own the handler, and will not - // unregister it on destruction, so the caller is responsible for - // unregistering explicitly if it should no longer be called. + // The handler will be owned by the underlying BinaryMessageHandler. + // Destroying the MethodChannel will not unregister the handler, so + // the caller is responsible for unregistering explicitly if the handler + // stops being valid before the engine is destroyed. void SetMethodCallHandler(MethodCallHandler handler) const { if (!handler) { messenger_->SetMessageHandler(name_, nullptr); diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h index 858119e3..15cf9968 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h @@ -49,8 +49,8 @@ class PluginRegistrar { // Takes ownership of |plugin|. // // Plugins are not required to call this method if they have other lifetime - // management, but this is a convient place for plugins to be owned to ensure - // that they stay valid for any registered callbacks. + // management, but this is a convenient place for plugins to be owned to + // ensure that they stay valid for any registered callbacks. void AddPlugin(std::unique_ptr plugin); protected: diff --git a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc index 807e0681..5e93d407 100644 --- a/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc +++ b/src/flutter/shell/platform/common/client_wrapper/standard_codec.cc @@ -98,7 +98,7 @@ EncodableValue StandardCodecSerializer::ReadValue( void StandardCodecSerializer::WriteValue(const EncodableValue& value, ByteStreamWriter* stream) const { stream->WriteByte(static_cast(EncodedTypeForValue(value))); - // TODO: Consider replacing this this with a std::visitor. + // TODO(cbracken): Consider replacing this with std::visit. switch (value.index()) { case 0: case 1: From e5646da717f756ae0f13a1f6d5c771bb5218a465 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 7 Aug 2023 12:11:28 +0000 Subject: [PATCH 131/178] cmake: add ENABLE_EGL_ASYNC_BUFFER_SWAPPING option (#362) This change adds ENABLE_EGL_ASYNC_BUFFER_SWAPPING not to sync compositor redraw (vblank). Related issue #220 Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 1 + cmake/build.cmake | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 723556b3..4e7f0691 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,7 @@ option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) option(ENABLE_VSYNC "Enable embedder vsync" ON) +option(ENABLE_EGL_ASYNC_BUFFER_SWAPPING "Do not sync to compositor redraw (eglSwapInterval 0)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) diff --git a/cmake/build.cmake b/cmake/build.cmake index cde9cc92..56eda140 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -118,6 +118,13 @@ if(ENABLE_VSYNC) ) endif() +# Do not sync to compositor redraw (eglSwapInterval 0). +if(ENABLE_EGL_ASYNC_BUFFER_SWAPPING) + add_definitions( + -DENABLE_EGL_ASYNC_BUFFER_SWAPPING + ) +endif() + # Enable alpha component of the egl color buffer. if(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) add_definitions( From eb2687ada4ab4f53504de37886eb6d72ebd400ec Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 7 Aug 2023 13:39:47 +0000 Subject: [PATCH 132/178] egl: add async buffer swapping command option (#363) Fixed #220 Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 1 - cmake/build.cmake | 7 --- .../flutter_embedder_options.h | 50 +++++++++++++++---- .../flutter-drm-eglstream-backend/main.cc | 1 + .../flutter_embedder_options.h | 50 +++++++++++++++---- examples/flutter-drm-gbm-backend/main.cc | 1 + .../flutter_embedder_options.h | 50 +++++++++++++++---- .../flutter-external-texture-plugin/main.cc | 1 + .../flutter_embedder_options.h | 50 +++++++++++++++---- examples/flutter-video-player-plugin/main.cc | 1 + .../flutter_embedder_options.h | 50 +++++++++++++++---- examples/flutter-wayland-client/main.cc | 1 + .../flutter_embedder_options.h | 50 +++++++++++++++---- examples/flutter-x11-client/main.cc | 1 + src/client_wrapper/flutter_view_controller.cc | 1 + .../include/flutter/flutter_view_controller.h | 5 ++ .../linux_embedded/public/flutter_elinux.h | 5 ++ .../linux_embedded/surface/context_egl.cc | 5 +- .../surface/context_egl_stream.cc | 2 +- .../surface/elinux_egl_surface.cc | 14 +++--- .../surface/elinux_egl_surface.h | 6 ++- .../linux_embedded/window/elinux_window_drm.h | 4 +- .../window/elinux_window_wayland.cc | 7 +-- .../window/elinux_window_x11.cc | 2 +- .../linux_embedded/window/native_window.h | 3 ++ .../window/native_window_drm.cc | 4 +- .../linux_embedded/window/native_window_drm.h | 4 +- .../window/native_window_drm_eglstream.cc | 6 ++- .../window/native_window_drm_eglstream.h | 3 +- .../window/native_window_drm_gbm.cc | 6 ++- .../window/native_window_drm_gbm.h | 4 +- .../window/native_window_wayland.cc | 4 +- .../window/native_window_wayland.h | 3 +- .../native_window_wayland_decoration.cc | 4 +- .../window/native_window_wayland_decoration.h | 3 +- .../window/native_window_x11.cc | 4 +- .../linux_embedded/window/native_window_x11.h | 3 +- .../renderer/window_decorations_wayland.cc | 14 ++++-- .../renderer/window_decorations_wayland.h | 3 +- 39 files changed, 329 insertions(+), 104 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e7f0691..723556b3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,6 @@ option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) option(ENABLE_VSYNC "Enable embedder vsync" ON) -option(ENABLE_EGL_ASYNC_BUFFER_SWAPPING "Do not sync to compositor redraw (eglSwapInterval 0)" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) diff --git a/cmake/build.cmake b/cmake/build.cmake index 56eda140..cde9cc92 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -118,13 +118,6 @@ if(ENABLE_VSYNC) ) endif() -# Do not sync to compositor redraw (eglSwapInterval 0). -if(ENABLE_EGL_ASYNC_BUFFER_SWAPPING) - add_definitions( - -DENABLE_EGL_ASYNC_BUFFER_SWAPPING - ) -endif() - # Enable alpha component of the egl color buffer. if(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER) add_definitions( diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index dede8b9e..8a5cfd41 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -24,6 +24,10 @@ class FlutterEmbedderOptions { options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); + options_.AddWithoutValue( + "async-vblank", "v", + "Don't sync to compositor redraw/vblank (eglSwapInterval 0)", false); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) // no more options. @@ -87,6 +91,8 @@ class FlutterEmbedderOptions { scale_factor_ = 1.0; } + enable_vsync_ = !options_.Exist("async-vblank"); + #if defined(FLUTTER_TARGET_BACKEND_GBM) || \ defined(FLUTTER_TARGET_BACKEND_EGLSTREAM) use_onscreen_keyboard_ = false; @@ -118,22 +124,45 @@ class FlutterEmbedderOptions { return true; } - std::string BundlePath() const { return bundle_path_; } - std::string WindowTitle() const { return window_title_; } - std::string WindowAppID() const { return window_app_id_; } - bool IsUseMouseCursor() const { return use_mouse_cursor_; } - bool IsUseOnscreenKeyboard() const { return use_onscreen_keyboard_; } - bool IsUseWindowDecoraation() const { return use_window_decoration_; } + std::string BundlePath() const { + return bundle_path_; + } + std::string WindowTitle() const { + return window_title_; + } + std::string WindowAppID() const { + return window_app_id_; + } + bool IsUseMouseCursor() const { + return use_mouse_cursor_; + } + bool IsUseOnscreenKeyboard() const { + return use_onscreen_keyboard_; + } + bool IsUseWindowDecoraation() const { + return use_window_decoration_; + } flutter::FlutterViewController::ViewMode WindowViewMode() const { return window_view_mode_; } - int WindowWidth() const { return window_width_; } - int WindowHeight() const { return window_height_; } + int WindowWidth() const { + return window_width_; + } + int WindowHeight() const { + return window_height_; + } flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } - bool IsForceScaleFactor() const { return is_force_scale_factor_; } - double ScaleFactor() const { return scale_factor_; } + bool IsForceScaleFactor() const { + return is_force_scale_factor_; + } + double ScaleFactor() const { + return scale_factor_; + } + bool EnableVsync() const { + return enable_vsync_; + } private: commandline::CommandOptions options_; @@ -152,6 +181,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + bool enable_vsync_; }; #endif // FLUTTER_EMBEDDER_OPTIONS_ diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index eb8a6d28..e1da779c 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -37,6 +37,7 @@ int main(int argc, char** argv) { view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); + view_properties.enable_vsync = options.EnableVsync(); // The Flutter instance hosted by this window. FlutterWindow window(view_properties, project); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 3d9b7ea8..9b412a3a 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -42,6 +42,7 @@ FlutterViewController::FlutterViewController( view_properties.use_window_decoration; c_view_properties.force_scale_factor = view_properties.force_scale_factor; c_view_properties.scale_factor = view_properties.scale_factor; + c_view_properties.enable_vsync = view_properties.enable_vsync; controller_ = FlutterDesktopViewControllerCreate(&c_view_properties, engine_->RelinquishEngine()); diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index 64fdad43..b0403c5c 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -79,6 +79,11 @@ class FlutterViewController { // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; + + // Enable Vsync. + // True: Sync to compositor redraw/v-blank (eglSwapInterval 1) + // False: Do not sync to compositor redraw/v-blank (eglSwapInterval 0) + bool enable_vsync; } ViewProperties; // Creates a FlutterView that can be parented into a Windows View hierarchy diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 5693f095..d5f22347 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -109,6 +109,11 @@ typedef struct { // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; + + // Enable Vsync. + // True: Sync to compositor redraw/v-blank (eglSwapInterval 1) + // False: Do not sync to compositor redraw/v-blank (eglSwapInterval 0) + bool enable_vsync; } FlutterDesktopViewProperties; // ========== View Controller ========== diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index bea6dbb4..ac87ab10 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -119,7 +119,7 @@ std::unique_ptr ContextEgl::CreateOnscreenSurface( << get_egl_error_cause(); } return std::make_unique(surface, environment_->Display(), - context_); + context_, window->EnableVsync()); } std::unique_ptr ContextEgl::CreateOffscreenSurface( @@ -151,7 +151,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( } #endif return std::make_unique(surface, environment_->Display(), - resource_context_); + resource_context_, + window->EnableVsync()); } bool ContextEgl::IsValid() const { diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc index 40822ccb..2f1df0c5 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc @@ -65,7 +65,7 @@ std::unique_ptr ContextEglStream::CreateOnscreenSurface( ELINUX_LOG(ERROR) << "Failed to create EGL stream producer surface"; } return std::make_unique(surface, environment_->Display(), - context_); + context_, window->EnableVsync()); } bool ContextEglStream::SetEglExtensionFunctionPointers() { diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 1e01ca57..07fede87 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -18,10 +18,12 @@ constexpr const int kMaxHistorySize = 10; ELinuxEGLSurface::ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, - EGLContext context) + EGLContext context, + bool vsync_enabled) : surface_(surface), display_(display), context_(context), + vsync_enabled_(vsync_enabled), width_px_(kInitialWindowWidthPx), height_px_(kInitialWindowHeightPx) { const char* extensions = eglQueryString(display_, EGL_EXTENSIONS); @@ -72,7 +74,6 @@ bool ELinuxEGLSurface::MakeCurrent() const { return false; } -#if defined(ENABLE_EGL_ASYNC_BUFFER_SWAPPING) // Non-blocking when swappipping buffers on Wayland. // However, we might encounter rendering problems on some Wayland compositors // (e.g. weston 9.0) when we use them. @@ -80,11 +81,12 @@ bool ELinuxEGLSurface::MakeCurrent() const { // - https://github.com/sony/flutter-embedded-linux/issues/230 // - https://github.com/sony/flutter-embedded-linux/issues/234 // - https://github.com/sony/flutter-embedded-linux/issues/220 - if (eglSwapInterval(display_, 0) != EGL_TRUE) { - ELINUX_LOG(ERROR) << "Failed to eglSwapInterval(Free): " - << get_egl_error_cause(); + if (!vsync_enabled_) { + if (eglSwapInterval(display_, 0) != EGL_TRUE) { + ELINUX_LOG(ERROR) << "Failed to eglSwapInterval(Free): " + << get_egl_error_cause(); + } } -#endif return true; } diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h index d10b709e..885b1138 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.h @@ -19,7 +19,10 @@ namespace flutter { class ELinuxEGLSurface { public: // Note that EGLSurface will be destroyed in this class's destructor. - ELinuxEGLSurface(EGLSurface surface, EGLDisplay display, EGLContext context); + ELinuxEGLSurface(EGLSurface surface, + EGLDisplay display, + EGLContext context, + bool vsync_enabled); ~ELinuxEGLSurface(); bool IsValid() const; @@ -43,6 +46,7 @@ class ELinuxEGLSurface { EGLDisplay display_; EGLSurface surface_; EGLContext context_; + bool vsync_enabled_; size_t width_px_; size_t height_px_; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index beaec990..92c70ad7 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -125,8 +125,8 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { bool device_found = false; for (auto i = 0; i < devices.size(); i++) { - native_window_ = - std::make_unique(devices[i].c_str(), current_rotation_); + native_window_ = std::make_unique( + devices[i].c_str(), current_rotation_, view_properties_.enable_vsync); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window (" << devices[i] << ")."; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 562c9df9..9d2cd7c8 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1219,8 +1219,8 @@ bool ELinuxWindowWayland::CreateRenderSurface(int32_t width_px, if (current_rotation_ == 90 || current_rotation_ == 270) { std::swap(width_px, height_px); } - native_window_ = std::make_unique(wl_compositor_, - width_px, height_px); + native_window_ = std::make_unique( + wl_compositor_, width_px, height_px, view_properties_.enable_vsync); wl_surface_add_listener(native_window_->Surface(), &kWlSurfaceListener, this); @@ -1301,7 +1301,8 @@ void ELinuxWindowWayland::CreateDecoration(int32_t width_dip, window_decorations_ = std::make_unique( wl_display_, wl_compositor_, wl_subcompositor_, native_window_->Surface(), - width_dip, height_dip, current_scale_, enable_impeller_); + width_dip, height_dip, current_scale_, enable_impeller_, + view_properties_.enable_vsync); } void ELinuxWindowWayland::DestroyRenderSurface() { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index 15ede0d4..ea4e4dfc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -132,7 +132,7 @@ bool ELinuxWindowX11::CreateRenderSurface(int32_t width, } native_window_ = std::make_unique( display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), - view_properties_.title, width, height); + view_properties_.title, width, height, view_properties_.enable_vsync); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window.h b/src/flutter/shell/platform/linux_embedded/window/native_window.h index 2d0f77a2..a224b79a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window.h @@ -37,6 +37,8 @@ class NativeWindow { return height_; } + bool EnableVsync() const { return enable_vsync_; } + virtual bool IsNeedRecreateSurfaceAfterResize() const { return false; } // Sets a window position. Basically, this API is used for window decorations @@ -59,6 +61,7 @@ class NativeWindow { protected: EGLNativeWindowType window_; EGLNativeWindowType window_offscreen_; + bool enable_vsync_; // Physical width of the window. int32_t width_; // Physical height of the window. diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index 22e6e7d9..97d8363c 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -16,7 +16,8 @@ namespace flutter { NativeWindowDrm::NativeWindowDrm(const char* device_filename, - const uint16_t rotation) { + const uint16_t rotation, + bool enable_vsync) { drm_device_ = open(device_filename, O_RDWR | O_CLOEXEC); if (drm_device_ == -1) { ELINUX_LOG(ERROR) << "Couldn't open " << device_filename; @@ -27,6 +28,7 @@ NativeWindowDrm::NativeWindowDrm(const char* device_filename, return; } + enable_vsync_ = enable_vsync; valid_ = true; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index 9a40b100..2a21b569 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -16,7 +16,9 @@ namespace flutter { class NativeWindowDrm : public NativeWindow { public: - NativeWindowDrm(const char* device_filename, const uint16_t rotation); + NativeWindowDrm(const char* device_filename, + const uint16_t rotation, + bool enable_vsync); virtual ~NativeWindowDrm(); bool ConfigureDisplay(const uint16_t rotation); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc index 97242219..48f8e969 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.cc @@ -19,12 +19,14 @@ constexpr char kCursorNameNone[] = "none"; } // namespace NativeWindowDrmEglstream::NativeWindowDrmEglstream(const char* device_filename, - const uint16_t rotation) - : NativeWindowDrm(device_filename, rotation) { + const uint16_t rotation, + bool enable_vsync) + : NativeWindowDrm(device_filename, rotation, enable_vsync) { if (!valid_) { return; } + enable_vsync_ = enable_vsync; valid_ = ConfigureDisplayAdditional(); // drmIsMaster() is a relatively new API, and the main target of EGLStream is diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h index 27561a61..4bbe59bc 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_eglstream.h @@ -17,7 +17,8 @@ namespace flutter { class NativeWindowDrmEglstream : public NativeWindowDrm { public: NativeWindowDrmEglstream(const char* device_filename, - const uint16_t rotation); + const uint16_t rotation, + bool enable_vsync); ~NativeWindowDrmEglstream(); // |NativeWindowDrm| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc index 10f4779c..4565fcb8 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.cc @@ -20,11 +20,13 @@ constexpr uint32_t kCursorBufferHeight = 64; } // namespace NativeWindowDrmGbm::NativeWindowDrmGbm(const char* device_filename, - const uint16_t rotation) - : NativeWindowDrm(device_filename, rotation) { + const uint16_t rotation, + bool enable_vsync) + : NativeWindowDrm(device_filename, rotation, enable_vsync) { if (!valid_) { return; } + enable_vsync_ = enable_vsync; if (!drmIsMaster(drm_device_)) { ELINUX_LOG(ERROR) diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h index e888b269..d0a2ca5f 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm_gbm.h @@ -17,7 +17,9 @@ namespace flutter { class NativeWindowDrmGbm : public NativeWindowDrm { public: - NativeWindowDrmGbm(const char* device_filename, const uint16_t rotation); + NativeWindowDrmGbm(const char* device_filename, + const uint16_t rotation, + bool enable_vsync); ~NativeWindowDrmGbm(); // |NativeWindowDrm| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc index c35df018..46087281 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.cc @@ -10,7 +10,8 @@ namespace flutter { NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, const size_t width_px, - const size_t height_px) { + const size_t height_px, + bool enable_vsync) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; @@ -40,6 +41,7 @@ NativeWindowWayland::NativeWindowWayland(wl_compositor* compositor, } } + enable_vsync_ = enable_vsync; width_ = width_px; height_ = height_px; valid_ = true; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h index b28b0f93..c7b8c275 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland.h @@ -17,7 +17,8 @@ class NativeWindowWayland : public NativeWindow { // @param[in] height_px Physical height of the window. NativeWindowWayland(wl_compositor* compositor, const size_t width_px, - const size_t height_px); + const size_t height_px, + bool enable_vsync); ~NativeWindowWayland(); // |NativeWindow| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc index 6595dbc3..5f813962 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.cc @@ -13,7 +13,8 @@ NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( wl_subcompositor* subcompositor, wl_surface* parent_surface, const size_t width_px, - const size_t height_px) { + const size_t height_px, + bool enable_vsync) { surface_ = wl_compositor_create_surface(compositor); if (!surface_) { ELINUX_LOG(ERROR) << "Failed to create the compositor surface."; @@ -35,6 +36,7 @@ NativeWindowWaylandDecoration::NativeWindowWaylandDecoration( return; } + enable_vsync_ = enable_vsync; width_ = width_px; height_ = height_px; valid_ = true; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h index c48c0954..dc84f3f4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_wayland_decoration.h @@ -20,7 +20,8 @@ class NativeWindowWaylandDecoration : public NativeWindow { wl_subcompositor* subcompositor, wl_surface* parent_surface, const size_t width_px, - const size_t height_px); + const size_t height_px, + bool enable_vsync); ~NativeWindowWaylandDecoration(); // |NativeWindow| diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc index 1266b6f0..51f3cc11 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc @@ -22,7 +22,8 @@ NativeWindowX11::NativeWindowX11(Display* display, VisualID visual_id, const char* title, const size_t width, - const size_t height) { + const size_t height, + bool enable_vsync) { XVisualInfo visualTemplate; visualTemplate.visualid = visual_id; @@ -68,6 +69,7 @@ NativeWindowX11::NativeWindowX11(Display* display, XMapWindow(display, window_); + enable_vsync_ = enable_vsync; width_ = width; height_ = height; valid_ = true; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h index ed39458e..878d864d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h @@ -17,7 +17,8 @@ class NativeWindowX11 : public NativeWindow { VisualID visual_id, const char* title, const size_t width, - const size_t height); + const size_t height, + bool enable_vsync); ~NativeWindowX11() = default; // |NativeWindow| diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index 531cb5bc..5aa5fb59 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -25,14 +25,15 @@ WindowDecorationsWayland::WindowDecorationsWayland( int32_t width_dip, int32_t height_dip, double pixel_ratio, - bool enable_impeller) { + bool enable_impeller, + bool enable_vsync) { constexpr bool sub_egl_display = true; // title-bar. titlebar_ = std::make_unique( std::make_unique( compositor, subcompositor, root_surface, width_dip * pixel_ratio, - kTitleBarHeightDIP * pixel_ratio), + kTitleBarHeightDIP * pixel_ratio, enable_vsync), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display), enable_impeller))); @@ -44,7 +45,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( type, std::make_unique( compositor, subcompositor, root_surface, - kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio, + enable_vsync), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display), enable_impeller)))); @@ -58,7 +60,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( type, std::make_unique( compositor, subcompositor, root_surface, - kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio, + enable_vsync), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display), enable_impeller)))); @@ -72,7 +75,8 @@ WindowDecorationsWayland::WindowDecorationsWayland( type, std::make_unique( compositor, subcompositor, root_surface, - kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio), + kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio, + enable_vsync), std::make_unique(std::make_unique( std::make_unique(display, sub_egl_display), enable_impeller)))); diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h index 3e60b3ed..910bf009 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.h @@ -36,7 +36,8 @@ class WindowDecorationsWayland { int32_t width_dip, int32_t height_dip, double pixel_ratio, - bool enable_impeller); + bool enable_impeller, + bool enable_vsync); ~WindowDecorationsWayland(); void Draw(); From 8d8ab0a823219a5b849da61d9a90ad5695712965 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Tue, 8 Aug 2023 14:03:32 +0000 Subject: [PATCH 133/178] plugins: add settings_plugin (#364) Related issue #2 Signed-off-by: Hidenori Matsubayashi --- cmake/build.cmake | 1 + .../linux_embedded/flutter_elinux_engine.cc | 23 ++----- .../linux_embedded/flutter_elinux_engine.h | 7 +- .../linux_embedded/flutter_elinux_view.cc | 12 ++++ .../linux_embedded/flutter_elinux_view.h | 7 ++ .../linux_embedded/plugins/settings_plugin.cc | 67 +++++++++++++++++++ .../linux_embedded/plugins/settings_plugin.h | 56 ++++++++++++++++ .../window_binding_handler_delegate.h | 3 + 8 files changed, 153 insertions(+), 23 deletions(-) create mode 100644 src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc create mode 100644 src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h diff --git a/cmake/build.cmake b/cmake/build.cmake index cde9cc92..7bd34f7e 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -157,6 +157,7 @@ set(ELINUX_COMMON_SRC "src/flutter/shell/platform/linux_embedded/plugins/navigation_plugin.cc" "src/flutter/shell/platform/linux_embedded/plugins/platform_plugin.cc" "src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc" + "src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc" "src/flutter/shell/platform/linux_embedded/plugins/text_input_plugin.cc" "src/flutter/shell/platform/linux_embedded/surface/context_egl.cc" "src/flutter/shell/platform/linux_embedded/surface/egl_utils.cc" diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index d2510cd0..e71961e8 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -163,14 +163,6 @@ FlutterELinuxEngine::FlutterELinuxEngine(const FlutterProjectBundle& project) texture_registrar_ = std::make_unique(this, gl_procs_); - // Set up internal channels. - // TODO: Replace this with an embedder.h API. See - // https://github.com/flutter/flutter/issues/71099 - settings_channel_ = - std::make_unique>( - messenger_wrapper_.get(), "flutter/settings", - &JsonMessageCodec::GetInstance()); - vsync_waiter_ = std::make_unique(); } @@ -285,7 +277,10 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { return false; } - SendSystemSettings(); + // TODO: add theme initial value support. + view_->UpdateHighContrastEnabled(false); + + SendSystemLocales(); return true; } @@ -389,7 +384,7 @@ void FlutterELinuxEngine::ReloadSystemFonts() { embedder_api_.ReloadSystemFonts(engine_); } -void FlutterELinuxEngine::SendSystemSettings() { +void FlutterELinuxEngine::SendSystemLocales() { auto languages = flutter::GetPreferredLanguageInfo(); auto flutter_locales = flutter::ConvertToFlutterLocale(languages); @@ -405,14 +400,6 @@ void FlutterELinuxEngine::SendSystemSettings() { if (result != kSuccess) { ELINUX_LOG(ERROR) << "Failed to set up Flutter locales."; } - - rapidjson::Document settings(rapidjson::kObjectType); - auto& allocator = settings.GetAllocator(); - // todo: Use set values instead of fixed values. - settings.AddMember("alwaysUse24HourFormat", true, allocator); - settings.AddMember("textScaleFactor", 1.0, allocator); - settings.AddMember("platformBrightness", "light", allocator); - settings_channel_->Send(settings); } bool FlutterELinuxEngine::RegisterExternalTexture(int64_t texture_id) { diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index e6595262..c05c1fa3 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -131,11 +131,11 @@ class FlutterELinuxEngine { // Allows swapping out embedder_api_ calls in tests. friend class EngineEmbedderApiModifier; - // Sends system settings (e.g., locale) to the engine. + // Sends system locales to the engine. // // Should be called just after the engine is run, and after any relevant // system changes. - void SendSystemSettings(); + void SendSystemLocales(); // The handle to the embedder.h engine instance. FLUTTER_API_SYMBOL(FlutterEngine) engine_ = nullptr; @@ -172,9 +172,6 @@ class FlutterELinuxEngine { // Resolved OpenGL functions used by external texture implementations. GlProcs gl_procs_ = {}; - // The MethodChannel used for communication with the Flutter engine. - std::unique_ptr> settings_channel_; - // A callback to be called when the engine (and thus the plugin registrar) // is being destroyed. FlutterDesktopOnPluginRegistrarDestroyed diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 2f4d8548..c5c22693 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -60,6 +60,10 @@ void FlutterELinuxView::SetEngine(std::unique_ptr engine) { // Set up the system channel handlers. auto internal_plugin_messenger = internal_plugin_registrar_->messenger(); + + // Set up internal channels. + // TODO: Replace this with an embedder.h API. See + // https://github.com/flutter/flutter/issues/71099 keyboard_handler_ = std::make_unique(internal_plugin_messenger); textinput_handler_ = std::make_unique( @@ -74,6 +78,8 @@ void FlutterELinuxView::SetEngine(std::unique_ptr engine) { std::make_unique(internal_plugin_messenger); platform_views_handler_ = std::make_unique(internal_plugin_messenger); + settings_handler_ = std::make_unique( + internal_plugin_messenger, binding_handler_.get()); PhysicalWindowBounds bounds = binding_handler_->GetPhysicalWindowBounds(); SendWindowMetrics(bounds.width, bounds.height, @@ -498,4 +504,10 @@ std::pair FlutterELinuxView::GetPointerRotation(double x_px, } return res; } + +void FlutterELinuxView::UpdateHighContrastEnabled(bool enabled) { + // TODO: add UpdateAccessibilityFeatures support + settings_handler_->UpdateHighContrastMode(enabled); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index c554b497..1a5ff519 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -19,6 +19,7 @@ #include "flutter/shell/platform/linux_embedded/plugins/navigation_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/platform_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h" +#include "flutter/shell/platform/linux_embedded/plugins/settings_plugin.h" #include "flutter/shell/platform/linux_embedded/plugins/text_input_plugin.h" #include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" #include "flutter/shell/platform/linux_embedded/public/flutter_platform_views.h" @@ -144,6 +145,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { void OnVsync(uint64_t frame_start_time_nanos, uint64_t frame_target_time_nanos) override; + // |WindowBindingHandlerDelegate| + void UpdateHighContrastEnabled(bool enabled) override; + private: // Struct holding the mouse state. The engine doesn't keep track of which // mouse buttons have been pressed, so it's the embedding's responsibility. @@ -290,6 +294,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // Handler for flutter/platform_views channel. std::unique_ptr platform_views_handler_; + // Handler for flutter/settings channel. + std::unique_ptr settings_handler_; + // Currently configured WindowBindingHandler for view. std::unique_ptr binding_handler_; diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc new file mode 100644 index 00000000..3492cdb5 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc @@ -0,0 +1,67 @@ +// Copyright 2023 Sony Corporation. All rights reserved. +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/linux_embedded/plugins/settings_plugin.h" + +#include "flutter/shell/platform/common/json_message_codec.h" + +namespace flutter { + +namespace { +constexpr char kChannelName[] = "flutter/settings"; + +constexpr char kAlwaysUse24HourFormat[] = "alwaysUse24HourFormat"; +constexpr char kTextScaleFactor[] = "textScaleFactor"; +constexpr char kPlatformBrightness[] = "platformBrightness"; + +constexpr char kPlatformBrightnessDark[] = "dark"; +constexpr char kPlatformBrightnessLight[] = "light"; +} // namespace + +SettingsPlugin::SettingsPlugin(BinaryMessenger* messenger, + WindowBindingHandler* delegate) + : channel_(std::make_unique>( + messenger, + kChannelName, + &JsonMessageCodec::GetInstance())), + delegate_(delegate) {} + +void SettingsPlugin::SendSettings() { + rapidjson::Document settings(rapidjson::kObjectType); + auto& allocator = settings.GetAllocator(); + settings.AddMember(kAlwaysUse24HourFormat, GetAlwaysUse24HourFormat(), + allocator); + settings.AddMember(kTextScaleFactor, GetTextScaleFactor(), allocator); + + if (GetPreferredBrightness() == PlatformBrightness::kDark) { + settings.AddMember(kPlatformBrightness, kPlatformBrightnessDark, allocator); + } else { + settings.AddMember(kPlatformBrightness, kPlatformBrightnessLight, + allocator); + } + channel_->Send(settings); +} + +bool SettingsPlugin::GetAlwaysUse24HourFormat() { + // The current OS does not have 24 hour format factor. + return true; +} + +float SettingsPlugin::GetTextScaleFactor() { + // The current OS does not have text scale factor. + return 1.0; +} + +SettingsPlugin::PlatformBrightness SettingsPlugin::GetPreferredBrightness() { + // The current OS does not have brightness factor. + return PlatformBrightness::kLight; +} + +void SettingsPlugin::UpdateHighContrastMode(bool is_high_contrast) { + is_high_contrast_ = is_high_contrast; + SendSettings(); +} + +} // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h new file mode 100644 index 00000000..25f10585 --- /dev/null +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h @@ -0,0 +1,56 @@ +// Copyright 2023 Sony Corporation. All rights reserved. +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_SETTINGS_PLUGIN_H_ +#define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_SETTINGS_PLUGIN_H_ + +#include + +#include + +#include "flutter/shell/platform/common/client_wrapper/include/flutter/basic_message_channel.h" +#include "flutter/shell/platform/common/client_wrapper/include/flutter/binary_messenger.h" +#include "flutter/shell/platform/linux_embedded/window_binding_handler.h" + +namespace flutter { + +// Abstract settings plugin. +// +// Used to look up and notify Flutter of user-configured system settings. +// These are typically set in the control panel. +class SettingsPlugin { + public: + enum struct PlatformBrightness { kDark, kLight }; + + explicit SettingsPlugin(BinaryMessenger* messenger, + WindowBindingHandler* delegate); + ~SettingsPlugin() = default; + + // Sends settings (e.g., platform brightness) to the engine. + void SendSettings(); + + // Update the high contrast status of the system. + void UpdateHighContrastMode(bool is_high_contrast); + + private: + // Returns `true` if the user uses 24 hour time. + bool GetAlwaysUse24HourFormat(); + + // Returns the user-preferred text scale factor. + float GetTextScaleFactor(); + + // Returns the user-preferred brightness. + PlatformBrightness GetPreferredBrightness(); + + bool is_high_contrast_ = false; + + private: + std::unique_ptr> channel_; + WindowBindingHandler* delegate_; +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_PLUGINS_SETTINGS_PLUGIN_H_ diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index 944e0e07..fd7369e4 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -104,6 +104,9 @@ class WindowBindingHandlerDelegate { // Typically called by currently configured WindowBindingHandler virtual void OnVsync(uint64_t last_frame_time_nanos, uint64_t vsync_interval_time_nanos) = 0; + + // Update the status of the high contrast feature + virtual void UpdateHighContrastEnabled(bool enabled) = 0; }; } // namespace flutter From d562681fd4589e7462f4c49c131798e8e8552fa1 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 9 Aug 2023 11:06:56 +0000 Subject: [PATCH 134/178] wayland: add trace level logs to wayland listeners (#365) This change adds trace level logs to improve logging and debuggability. Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_wayland.cc | 189 +++++++++++++++--- 1 file changed, 158 insertions(+), 31 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 9d2cd7c8..08ea910d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -50,20 +50,26 @@ const wl_registry_listener ELinuxWindowWayland::kWlRegistryListener = { uint32_t name, const char* interface, uint32_t version) { + ELINUX_LOG(TRACE) << "wl_registry_listener.global"; + auto self = reinterpret_cast(data); self->WlRegistryHandler(wl_registry, name, interface, version); }, .global_remove = [](void* data, wl_registry* wl_registry, uint32_t name) { + ELINUX_LOG(TRACE) << "wl_registry_listener.global_remove"; + auto self = reinterpret_cast(data); self->WlUnRegistryHandler(wl_registry, name); }, }; const xdg_wm_base_listener ELinuxWindowWayland::kXdgWmBaseListener = { - .ping = [](void* data, - xdg_wm_base* xdg_wm_base, - uint32_t serial) { xdg_wm_base_pong(xdg_wm_base, serial); }, + .ping = + [](void* data, xdg_wm_base* xdg_wm_base, uint32_t serial) { + ELINUX_LOG(TRACE) << "xdg_wm_base_listener.ping"; + xdg_wm_base_pong(xdg_wm_base, serial); + }, }; const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { @@ -120,12 +126,16 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { return; } + ELINUX_LOG(TRACE) + << "request redraw: " << next_width << ", " << next_height; self->view_properties_.width = next_width; self->view_properties_.height = next_height; self->request_redraw_ = true; }, .close = [](void* data, xdg_toplevel* xdg_toplevel) { + ELINUX_LOG(TRACE) << "xdg_toplevel_listener.close"; + auto self = reinterpret_cast(data); self->running_ = false; }}; @@ -133,6 +143,8 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { const wl_surface_listener ELinuxWindowWayland::kWlSurfaceListener = { .enter = [](void* data, wl_surface* wl_surface, wl_output* output) { + ELINUX_LOG(TRACE) << "wl_surface_listener.enter"; + // The compositor can send a null output: crbug.com/1332540 if (!output) { ELINUX_LOG(ERROR) << "cannot enter a NULL output"; @@ -149,6 +161,8 @@ const wl_surface_listener ELinuxWindowWayland::kWlSurfaceListener = { }, .leave = [](void* data, wl_surface* wl_surface, wl_output* output) { + ELINUX_LOG(TRACE) << "wl_surface_listener.leave"; + // The compositor can send a null output: crbug.com/1332540 if (!output) { ELINUX_LOG(ERROR) << "cannot leave a NULL output"; @@ -167,9 +181,11 @@ const wl_surface_listener ELinuxWindowWayland::kWlSurfaceListener = { const wp_presentation_listener ELinuxWindowWayland::kWpPresentationListener = { .clock_id = [](void* data, wp_presentation* wp_presentation, uint32_t clk_id) { + ELINUX_LOG(TRACE) << "wp_presentation_listener.clock_id"; + auto self = reinterpret_cast(data); self->wp_presentation_clk_id_ = clk_id; - ELINUX_LOG(TRACE) << "presentation info: clk_id = " << clk_id; + ELINUX_LOG(TRACE) << "clk_id = " << clk_id; }, }; @@ -178,7 +194,10 @@ const wp_presentation_feedback_listener .sync_output = [](void* data, struct wp_presentation_feedback* wp_presentation_feedback, - wl_output* output) {}, + wl_output* output) { + ELINUX_LOG(TRACE) + << "wp_presentation_feedback_listener.sync_output"; + }, .presented = [](void* data, struct wp_presentation_feedback* wp_presentation_feedback, @@ -189,6 +208,9 @@ const wp_presentation_feedback_listener uint32_t seq_hi, uint32_t seq_lo, uint32_t flags) { + ELINUX_LOG(TRACE) + << "wp_presentation_feedback_listener.presented"; + auto self = reinterpret_cast(data); self->last_frame_time_nanos_ = (((static_cast(tv_sec_hi) << 32) + tv_sec_lo) * @@ -209,8 +231,10 @@ const wp_presentation_feedback_listener .discarded = [](void* data, struct wp_presentation_feedback* wp_presentation_feedback) { - auto self = reinterpret_cast(data); + ELINUX_LOG(TRACE) + << "wp_presentation_feedback_listener.discarded"; + auto self = reinterpret_cast(data); if (self->window_decorations_) { self->window_decorations_->Draw(); } @@ -225,6 +249,8 @@ const wp_presentation_feedback_listener const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { .done = [](void* data, wl_callback* wl_callback, uint32_t time) { + ELINUX_LOG(TRACE) << "wl_callback_listener.done"; + // The presentation-time is an extended protocol and isn't supported // by all compositors. This path is for when it wasn't supported. auto self = reinterpret_cast(data); @@ -246,8 +272,9 @@ const wl_callback_listener ELinuxWindowWayland::kWlSurfaceFrameListener = { const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { .capabilities = [](void* data, wl_seat* seat, uint32_t caps) -> void { - auto self = reinterpret_cast(data); + ELINUX_LOG(TRACE) << "wl_seat_listener.capabilities"; + auto self = reinterpret_cast(data); if ((caps & WL_SEAT_CAPABILITY_POINTER) && !self->wl_pointer_) { self->wl_pointer_ = wl_seat_get_pointer(seat); wl_pointer_add_listener(self->wl_pointer_, &kWlPointerListener, self); @@ -274,6 +301,7 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { } }, .name = [](void* data, struct wl_seat* wl_seat, const char* name) -> void { + ELINUX_LOG(TRACE) << "wl_seat_listener.name"; }, }; @@ -284,6 +312,8 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { wl_surface* surface, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + ELINUX_LOG(TRACE) << "wl_pointer_listener.enter"; + auto self = reinterpret_cast(data); self->wl_current_surface_ = surface; self->serial_ = serial; @@ -305,6 +335,8 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { wl_pointer* pointer, uint32_t serial, wl_surface* surface) -> void { + ELINUX_LOG(TRACE) << "wl_pointer_listener.leave"; + auto self = reinterpret_cast(data); self->wl_current_surface_ = surface; self->serial_ = serial; @@ -326,6 +358,8 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { uint32_t time, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + ELINUX_LOG(TRACE) << "wl_pointer_listener.motion"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x_px = wl_fixed_to_double(surface_x) * self->current_scale_; @@ -341,6 +375,8 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { uint32_t time, uint32_t button, uint32_t status) -> void { + ELINUX_LOG(TRACE) << "wl_pointer_listener.button"; + auto self = reinterpret_cast(data); self->serial_ = serial; @@ -428,6 +464,8 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { uint32_t time, uint32_t axis, wl_fixed_t value) -> void { + ELINUX_LOG(TRACE) << "wl_pointer_listener.axis"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double delta = wl_fixed_to_double(value); @@ -450,6 +488,8 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + ELINUX_LOG(TRACE) << "wl_touch_listener.down"; + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { @@ -463,6 +503,8 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { uint32_t serial, uint32_t time, int32_t id) -> void { + ELINUX_LOG(TRACE) << "wl_touch_listener.up"; + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { @@ -475,6 +517,8 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { int32_t id, wl_fixed_t surface_x, wl_fixed_t surface_y) -> void { + ELINUX_LOG(TRACE) << "wl_touch_listener.motion"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { double x = wl_fixed_to_double(surface_x); @@ -484,6 +528,8 @@ const wl_touch_listener ELinuxWindowWayland::kWlTouchListener = { }, .frame = [](void* data, wl_touch* wl_touch) -> void {}, .cancel = [](void* data, wl_touch* wl_touch) -> void { + ELINUX_LOG(TRACE) << "wl_touch_listener.cancel"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnTouchCancel(); @@ -497,6 +543,8 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { uint32_t format, int fd, uint32_t size) -> void { + ELINUX_LOG(TRACE) << "wl_keyboard_listener.keymap"; + auto self = reinterpret_cast(data); assert(format == WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1); if (self->binding_handler_delegate_) { @@ -508,6 +556,8 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { uint32_t serial, wl_surface* surface, wl_array* keys) -> void { + ELINUX_LOG(TRACE) << "wl_keyboard_listener.enter"; + auto self = reinterpret_cast(data); self->serial_ = serial; }, @@ -515,6 +565,8 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { wl_keyboard* wl_keyboard, uint32_t serial, wl_surface* surface) -> void { + ELINUX_LOG(TRACE) << "wl_keyboard_listener.leave"; + auto self = reinterpret_cast(data); self->serial_ = serial; }, @@ -524,6 +576,8 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { uint32_t time, uint32_t key, uint32_t state) -> void { + ELINUX_LOG(TRACE) << "wl_keyboard_listener.key"; + auto self = reinterpret_cast(data); self->serial_ = serial; if (self->binding_handler_delegate_) { @@ -538,6 +592,8 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { uint32_t mods_latched, uint32_t mods_locked, uint32_t group) -> void { + ELINUX_LOG(TRACE) << "wl_keyboard_listener.modifiers"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnKeyModifiers( @@ -545,7 +601,7 @@ const wl_keyboard_listener ELinuxWindowWayland::kWlKeyboardListener = { } }, .repeat_info = [](void* data, wl_keyboard* wl_keyboard, int rate, int delay) - -> void {}, + -> void { ELINUX_LOG(TRACE) << "wl_keyboard_listener.repeat_info"; }, }; const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { @@ -558,13 +614,17 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { int32_t subpixel, const char* make, const char* model, - int32_t output_transform) -> void {}, + int32_t output_transform) -> void { + ELINUX_LOG(TRACE) << "wl_output_listener.geometry"; + }, .mode = [](void* data, wl_output* wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh) -> void { + ELINUX_LOG(TRACE) << "wl_output_listener.mode"; + auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { @@ -606,10 +666,13 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { } } }, - .done = [](void* data, wl_output* wl_output) -> void {}, + .done = [](void* data, wl_output* wl_output) -> void { + ELINUX_LOG(TRACE) << "wl_output_listener.done"; + }, .scale = [](void* data, wl_output* wl_output, int32_t scale) -> void { - auto self = reinterpret_cast(data); + ELINUX_LOG(TRACE) << "wl_output_listener.scale"; + auto self = reinterpret_cast(data); const uint32_t output_id = wl_proxy_get_id(reinterpret_cast(wl_output)); @@ -627,6 +690,8 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = .enter = [](void* data, zwp_text_input_v1* zwp_text_input_v1, wl_surface* surface) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.enter"; + auto self = reinterpret_cast(data); // If there is no input data, the backspace key cannot be used, // so set dummy data. @@ -636,6 +701,8 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = } }, .leave = [](void* data, zwp_text_input_v1* zwp_text_input_v1) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.leave"; + auto self = reinterpret_cast(data); if (self->zwp_text_input_v1_) { zwp_text_input_v1_hide_input_panel(self->zwp_text_input_v1_); @@ -643,15 +710,21 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = }, .modifiers_map = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - wl_array* map) -> void {}, + wl_array* map) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.modifiers_map"; + }, .input_panel_state = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - uint32_t state) -> void {}, + uint32_t state) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.input_panel_state"; + }, .preedit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, const char* text, const char* commit) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.preedit_string"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); @@ -668,14 +741,20 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = zwp_text_input_v1* zwp_text_input_v1, uint32_t index, uint32_t length, - uint32_t style) -> void {}, + uint32_t style) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.preedit_styling"; + }, .preedit_cursor = [](void* data, zwp_text_input_v1* zwp_text_input_v1, - int32_t index) -> void {}, + int32_t index) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.preedit_cursor"; + }, .commit_string = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, const char* text) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.commit_string"; + // commit_string is notified only when the space key is pressed. auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { @@ -691,11 +770,16 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = .cursor_position = [](void* data, zwp_text_input_v1* zwp_text_input_v1, int32_t index, - int32_t anchor) -> void {}, + int32_t anchor) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.cursor_position"; + }, .delete_surrounding_text = [](void* data, zwp_text_input_v1* zwp_text_input_v1, int32_t index, uint32_t length) -> void { + ELINUX_LOG(TRACE) + << "zwp_text_input_v1_listener.delete_surrounding_text"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_) { self->binding_handler_delegate_->OnVirtualSpecialKey(KEY_BACKSPACE); @@ -714,6 +798,8 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = uint32_t sym, uint32_t state, uint32_t modifiers) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.keysym"; + auto self = reinterpret_cast(data); if ((state == WL_KEYBOARD_KEY_STATE_PRESSED) && (self->binding_handler_delegate_)) { @@ -744,11 +830,15 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = .language = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, - const char* language) -> void {}, + const char* language) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.language"; + }, .text_direction = [](void* data, zwp_text_input_v1* zwp_text_input_v1, uint32_t serial, - uint32_t direction) -> void {}, + uint32_t direction) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v1_listener.text_direction"; + }, }; const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = @@ -756,6 +846,8 @@ const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = .enter = [](void* data, zwp_text_input_v3* zwp_text_input_v3, wl_surface* surface) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v3_listener.enter"; + // To appear the on-screen keyboard when the user returns to a Flutter // app which needs to show the on-screen keyboard. auto self = reinterpret_cast(data); @@ -765,15 +857,21 @@ const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = }, .leave = [](void* data, zwp_text_input_v3* zwp_text_input_v3, - wl_surface* surface) -> void {}, + wl_surface* surface) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v3_listener.leave"; + }, .preedit_string = [](void* data, zwp_text_input_v3* zwp_text_input_v3, const char* text, int32_t cursor_begin, - int32_t cursor_end) -> void {}, + int32_t cursor_end) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v3_listener.preedit_string"; + }, .commit_string = [](void* data, zwp_text_input_v3* zwp_text_input_v3, const char* text) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v3_listener.commit_string"; + auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { self->binding_handler_delegate_->OnVirtualKey(text[0]); @@ -782,33 +880,50 @@ const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = .delete_surrounding_text = [](void* data, zwp_text_input_v3* zwp_text_input_v3, uint32_t before_length, - uint32_t after_length) -> void {}, + uint32_t after_length) -> void { + ELINUX_LOG(TRACE) + << "zwp_text_input_v3_listener.delete_surrounding_text"; + }, .done = [](void* data, zwp_text_input_v3* zwp_text_input_v3, - uint32_t serial) -> void {}, + uint32_t serial) -> void { + ELINUX_LOG(TRACE) << "zwp_text_input_v3_listener.done"; + }, }; const wl_data_device_listener ELinuxWindowWayland::kWlDataDeviceListener = { .data_offer = [](void* data, wl_data_device* wl_data_device, - wl_data_offer* offer) -> void {}, + wl_data_offer* offer) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.data_offer"; + }, .enter = [](void* data, wl_data_device* wl_data_device, uint32_t serial, wl_surface* surface, wl_fixed_t x, wl_fixed_t y, - wl_data_offer* offer) -> void {}, - .leave = [](void* data, wl_data_device* wl_data_device) -> void {}, + wl_data_offer* offer) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.enter"; + }, + .leave = [](void* data, wl_data_device* wl_data_device) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.leave"; + }, .motion = [](void* data, wl_data_device* wl_data_device, uint32_t time, wl_fixed_t x, - wl_fixed_t y) -> void {}, - .drop = [](void* data, wl_data_device* wl_data_device) -> void {}, + wl_fixed_t y) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.motion"; + }, + .drop = [](void* data, wl_data_device* wl_data_device) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.drop"; + }, .selection = [](void* data, wl_data_device* wl_data_device, wl_data_offer* offer) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.selection"; + auto self = reinterpret_cast(data); if (self->wl_data_offer_) { wl_data_offer_destroy(self->wl_data_offer_); @@ -820,11 +935,15 @@ const wl_data_device_listener ELinuxWindowWayland::kWlDataDeviceListener = { const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { .target = [](void* data, wl_data_source* wl_data_source, - const char* mime_type) -> void {}, + const char* mime_type) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.target"; + }, .send = [](void* data, wl_data_source* wl_data_source, const char* mime_type, int32_t fd) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.send"; + if (strcmp(mime_type, kClipboardMimeTypeText)) { ELINUX_LOG(ERROR) << "Not expected mime_type: " << mime_type; return; @@ -836,6 +955,8 @@ const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { close(fd); }, .cancelled = [](void* data, wl_data_source* wl_data_source) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.cancelled"; + auto self = reinterpret_cast(data); self->clipboard_data_ = ""; if (self->wl_data_source_) { @@ -844,11 +965,17 @@ const wl_data_source_listener ELinuxWindowWayland::kWlDataSourceListener = { } }, .dnd_drop_performed = [](void* data, - wl_data_source* wl_data_source) -> void {}, - .dnd_finished = [](void* data, wl_data_source* wl_data_source) -> void {}, + wl_data_source* wl_data_source) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.dnd_drop_performed"; + }, + .dnd_finished = [](void* data, wl_data_source* wl_data_source) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.dnd_finished"; + }, .action = [](void* data, wl_data_source* wl_data_source, - uint32_t dnd_action) -> void {}, + uint32_t dnd_action) -> void { + ELINUX_LOG(TRACE) << "wl_data_device_listener.action"; + }, }; const zxdg_toplevel_decoration_v1_listener From fe14f60aec0c7e929e055983d73b3e9bba8e04a5 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 9 Aug 2023 12:31:50 +0000 Subject: [PATCH 135/178] wayland: fix layout is skewed issue when using decoration option (#366) This change fixes the layout issue that is skewed when using decoration option. Related PR #359 Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/window/elinux_window.h | 2 ++ .../window/elinux_window_wayland.cc | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index eaec182d..8c4e9d15 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -40,6 +40,8 @@ class ELinuxWindow { } FlutterDesktopViewProperties view_properties_; + int32_t display_max_width_ = -1; + int32_t display_max_height_ = -1; double current_scale_ = 1.0; uint16_t current_rotation_ = 0; // The x coordinate of the pointer in physical pixels. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 08ea910d..1c74ad08 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -78,17 +78,28 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { ELINUX_LOG(TRACE) << "xdg_surface_listener.configure"; auto self = reinterpret_cast(data); - constexpr int32_t x = 0; - int32_t y = 0; if (self->window_decorations_) { - // TODO: Moves the window to the bottom to show the window - // decorations, but the bottom area of the window will be hidden - // because of this shifting. + // Shift the window position to the bottom to show decoration + // even when the window is displayed in the upper left corner + // of the screen + constexpr int32_t x = 0; + int32_t y = 0; y = -self->window_decorations_->Height(); + + auto width = self->view_properties_.width; + auto height = self->view_properties_.height; + if (!self->maximised_) { + height -= y; + } + + // clip + if (self->display_max_height_ > 0) { + height = std::min(height, self->display_max_height_); + } + + xdg_surface_set_window_geometry(xdg_surface, x, y, width, height); } - xdg_surface_set_window_geometry(xdg_surface, x, y, - self->view_properties_.width, - self->view_properties_.height); + xdg_surface_ack_configure(xdg_surface, serial); if (self->wait_for_configure_) { self->wait_for_configure_ = false; @@ -634,6 +645,9 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { ELINUX_LOG(INFO) << "Display output info: width = " << width << ", height = " << height << ", refresh = " << refresh; + self->display_max_width_ = width; + self->display_max_height_ = height; + // Some composers send 0 for the refresh value. if (refresh != 0) { self->frame_rate_ = refresh; From c5a7852198a9821d4c58a5c33bf0185b57a2c05a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 10 Aug 2023 13:18:23 +0000 Subject: [PATCH 136/178] settings_plugin: add text-scaling-factor commandline option (#367) This change adds text-scaling-factor to command-line option. Related issue #2 Signed-off-by: Hidenori Matsubayashi --- .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-drm-eglstream-backend/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-drm-gbm-backend/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-external-texture-plugin/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-video-player-plugin/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-wayland-client/main.cc | 1 + .../flutter-x11-client/flutter_embedder_options.h | 8 ++++++++ examples/flutter-x11-client/main.cc | 1 + src/client_wrapper/flutter_view_controller.cc | 1 + .../include/flutter/flutter_view_controller.h | 3 +++ .../platform/linux_embedded/flutter_elinux.cc | 3 +++ .../linux_embedded/flutter_elinux_engine.cc | 14 +++++++++----- .../linux_embedded/flutter_elinux_engine.h | 3 +++ .../platform/linux_embedded/flutter_elinux_view.cc | 4 ++++ .../platform/linux_embedded/flutter_elinux_view.h | 3 +++ .../linux_embedded/plugins/settings_plugin.cc | 8 ++++++-- .../linux_embedded/plugins/settings_plugin.h | 8 +++++--- .../linux_embedded/public/flutter_elinux.h | 3 +++ .../window_binding_handler_delegate.h | 3 +++ 23 files changed, 97 insertions(+), 10 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 8a5cfd41..04138b3f 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -21,6 +21,8 @@ class FlutterEmbedderOptions { options_.AddInt("rotation", "r", "Window rotation(degree) [0(default)|90|180|270]", 0, false); + options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -83,6 +85,8 @@ class FlutterEmbedderOptions { } } + text_scale_factor_ = options_.GetValue("text-scaling-factor"); + if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; scale_factor_ = options_.GetValue("force-scale-factor"); @@ -154,6 +158,9 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation WindowRotation() const { return window_view_rotation_; } + double TextScaleFactor() const { + return text_scale_factor_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -181,6 +188,7 @@ class FlutterEmbedderOptions { flutter::FlutterViewController::ViewRotation::kRotation_0; bool is_force_scale_factor_; double scale_factor_; + double text_scale_factor_; bool enable_vsync_; }; diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index e1da779c..37b179e0 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -35,6 +35,7 @@ int main(int argc, char** argv) { view_properties.use_mouse_cursor = options.IsUseMouseCursor(); view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); + view_properties.text_scale_factor = options.TextScaleFactor(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 9b412a3a..42e3d217 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -40,6 +40,7 @@ FlutterViewController::FlutterViewController( view_properties.use_onscreen_keyboard; c_view_properties.use_window_decoration = view_properties.use_window_decoration; + c_view_properties.text_scale_factor = view_properties.text_scale_factor; c_view_properties.force_scale_factor = view_properties.force_scale_factor; c_view_properties.scale_factor = view_properties.scale_factor; c_view_properties.enable_vsync = view_properties.enable_vsync; diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index b0403c5c..1659a561 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -76,6 +76,9 @@ class FlutterViewController { // This option is only active for Wayland backend. bool use_window_decoration; + // Text scaling factor. + double text_scale_factor; + // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 99313f2d..4ceb5986 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -100,6 +100,9 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( if (!state->view->GetEngine()->RunWithEntrypoint(nullptr)) { return nullptr; } + + const float text_scaling_factor = view_properties->text_scale_factor; + state->view->GetEngine()->SetSystemSettings(text_scaling_factor); } // Must happen after engine is running. diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index e71961e8..76e83b30 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -277,11 +277,6 @@ bool FlutterELinuxEngine::RunWithEntrypoint(const char* entrypoint) { return false; } - // TODO: add theme initial value support. - view_->UpdateHighContrastEnabled(false); - - SendSystemLocales(); - return true; } @@ -384,6 +379,15 @@ void FlutterELinuxEngine::ReloadSystemFonts() { embedder_api_.ReloadSystemFonts(engine_); } +void FlutterELinuxEngine::SetSystemSettings(float text_scaling_factor) { + view_->UpdateTextScaleFactor(text_scaling_factor); + + // TODO: add theme initial value support. + view_->UpdateHighContrastEnabled(false); + + SendSystemLocales(); +} + void FlutterELinuxEngine::SendSystemLocales() { auto languages = flutter::GetPreferredLanguageInfo(); auto flutter_locales = flutter::ConvertToFlutterLocale(languages); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index c05c1fa3..57087073 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -127,6 +127,9 @@ class FlutterELinuxEngine { // Gets the status whether Impeller is enabled. bool IsImpellerEnabled() const { return enable_impeller_; } + // Sets system settings. + void SetSystemSettings(float text_scaling_factor); + private: // Allows swapping out embedder_api_ calls in tests. friend class EngineEmbedderApiModifier; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index c5c22693..ec625d62 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -510,4 +510,8 @@ void FlutterELinuxView::UpdateHighContrastEnabled(bool enabled) { settings_handler_->UpdateHighContrastMode(enabled); } +void FlutterELinuxView::UpdateTextScaleFactor(float factor) { + settings_handler_->UpdateTextScaleFactor(factor); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index 1a5ff519..977bd3e1 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -148,6 +148,9 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // |WindowBindingHandlerDelegate| void UpdateHighContrastEnabled(bool enabled) override; + // |WindowBindingHandlerDelegate| + void UpdateTextScaleFactor(float factor) override; + private: // Struct holding the mouse state. The engine doesn't keep track of which // mouse buttons have been pressed, so it's the embedding's responsibility. diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc index 3492cdb5..6e118739 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc @@ -50,8 +50,12 @@ bool SettingsPlugin::GetAlwaysUse24HourFormat() { } float SettingsPlugin::GetTextScaleFactor() { - // The current OS does not have text scale factor. - return 1.0; + return text_scaling_factor_; +} + +void SettingsPlugin::UpdateTextScaleFactor(float factor) { + text_scaling_factor_ = factor; + SendSettings(); } SettingsPlugin::PlatformBrightness SettingsPlugin::GetPreferredBrightness() { diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h index 25f10585..0029f695 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h @@ -34,6 +34,9 @@ class SettingsPlugin { // Update the high contrast status of the system. void UpdateHighContrastMode(bool is_high_contrast); + // Update the text scale factor of the system. + void UpdateTextScaleFactor(float factor); + private: // Returns `true` if the user uses 24 hour time. bool GetAlwaysUse24HourFormat(); @@ -44,11 +47,10 @@ class SettingsPlugin { // Returns the user-preferred brightness. PlatformBrightness GetPreferredBrightness(); - bool is_high_contrast_ = false; - - private: std::unique_ptr> channel_; WindowBindingHandler* delegate_; + bool is_high_contrast_ = false; + float text_scaling_factor_ = 1.0; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index d5f22347..97d93436 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -106,6 +106,9 @@ typedef struct { // This option is only active for Wayland backend. bool use_window_decoration; + // Text scaling factor. + double text_scale_factor; + // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index fd7369e4..3bc6429d 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -107,6 +107,9 @@ class WindowBindingHandlerDelegate { // Update the status of the high contrast feature virtual void UpdateHighContrastEnabled(bool enabled) = 0; + + // Update the status of the text scaling factor feature + virtual void UpdateTextScaleFactor(float factor) = 0; }; } // namespace flutter From 36af86f40527a41d3ff245f2f33ade9c421cc073 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 11 Aug 2023 01:50:36 +0000 Subject: [PATCH 137/178] wayland: fix missing scaling of decoration buttons (#368) This change fixes wrong placement of decoration buttons. Signed-off-by: Hidenori Matsubayashi --- .../window/renderer/window_decorations_wayland.cc | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc index 5aa5fb59..b6c63c3b 100644 --- a/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/renderer/window_decorations_wayland.cc @@ -51,7 +51,7 @@ WindowDecorationsWayland::WindowDecorationsWayland( std::make_unique(display, sub_egl_display), enable_impeller)))); buttons_[type]->SetPosition( - width_dip - kButtonWidthDIP - kButtonMarginDIP, + width_dip * pixel_ratio - kButtonWidthDIP - kButtonMarginDIP, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); // maximise button. @@ -66,7 +66,7 @@ WindowDecorationsWayland::WindowDecorationsWayland( std::make_unique(display, sub_egl_display), enable_impeller)))); buttons_[type]->SetPosition( - width_dip - kButtonWidthDIP * 2 - kButtonMarginDIP * 2, + width_dip * pixel_ratio - kButtonWidthDIP * 2 - kButtonMarginDIP * 2, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); // minimise button. @@ -81,7 +81,7 @@ WindowDecorationsWayland::WindowDecorationsWayland( std::make_unique(display, sub_egl_display), enable_impeller)))); buttons_[type]->SetPosition( - width_dip - kButtonWidthDIP * 3 - kButtonMarginDIP * 3, + width_dip * pixel_ratio - kButtonWidthDIP * 3 - kButtonMarginDIP * 3, -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); } @@ -110,7 +110,8 @@ void WindowDecorationsWayland::Resize(const int32_t width_dip, for (auto i = 0; i < buttons_.size(); i++) { buttons_[i]->SetScaleFactor(pixel_ratio); buttons_[i]->SetPosition( - width_dip - kButtonWidthDIP * (i + 1) - kButtonMarginDIP * (i + 1), + width_dip * pixel_ratio - kButtonWidthDIP * (i + 1) - + kButtonMarginDIP * (i + 1), -(kButtonHeightDIP + (kTitleBarHeightDIP - kButtonHeightDIP) / 2)); buttons_[i]->Resize(kButtonWidthDIP * pixel_ratio, kButtonHeightDIP * pixel_ratio); From d496f1f63efaa1aeda5f55e81a1306343cc3ca94 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 16 Aug 2023 04:47:35 +0000 Subject: [PATCH 138/178] accessibility: add --enable-high-contrast option (#370) This change add "--enable-high-contrast" command-line option to request that UI be rendered with darker colors. Related issues #2, #168 Signed-off-by: Hidenori Matsubayashi --- .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-drm-eglstream-backend/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-drm-gbm-backend/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-external-texture-plugin/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-video-player-plugin/main.cc | 1 + .../flutter_embedder_options.h | 8 ++++++++ examples/flutter-wayland-client/main.cc | 1 + .../flutter-x11-client/flutter_embedder_options.h | 8 ++++++++ examples/flutter-x11-client/main.cc | 1 + src/client_wrapper/flutter_view_controller.cc | 1 + .../include/flutter/flutter_view_controller.h | 3 +++ .../shell/platform/linux_embedded/flutter_elinux.cc | 3 ++- .../linux_embedded/flutter_elinux_engine.cc | 13 ++++++++----- .../platform/linux_embedded/flutter_elinux_engine.h | 5 ++++- .../platform/linux_embedded/flutter_elinux_view.cc | 11 ++++++++++- .../linux_embedded/plugins/settings_plugin.cc | 9 +++++++-- .../linux_embedded/plugins/settings_plugin.h | 4 ++++ .../platform/linux_embedded/public/flutter_elinux.h | 3 +++ 21 files changed, 96 insertions(+), 10 deletions(-) diff --git a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-eglstream-backend/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-drm-eglstream-backend/main.cc b/examples/flutter-drm-eglstream-backend/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-drm-eglstream-backend/main.cc +++ b/examples/flutter-drm-eglstream-backend/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-drm-gbm-backend/flutter_embedder_options.h +++ b/examples/flutter-drm-gbm-backend/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-drm-gbm-backend/main.cc b/examples/flutter-drm-gbm-backend/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-drm-gbm-backend/main.cc +++ b/examples/flutter-drm-gbm-backend/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-external-texture-plugin/flutter_embedder_options.h b/examples/flutter-external-texture-plugin/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-external-texture-plugin/flutter_embedder_options.h +++ b/examples/flutter-external-texture-plugin/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-external-texture-plugin/main.cc b/examples/flutter-external-texture-plugin/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-external-texture-plugin/main.cc +++ b/examples/flutter-external-texture-plugin/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-video-player-plugin/flutter_embedder_options.h b/examples/flutter-video-player-plugin/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-video-player-plugin/flutter_embedder_options.h +++ b/examples/flutter-video-player-plugin/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-video-player-plugin/main.cc b/examples/flutter-video-player-plugin/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-video-player-plugin/main.cc +++ b/examples/flutter-video-player-plugin/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-wayland-client/flutter_embedder_options.h b/examples/flutter-wayland-client/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-wayland-client/flutter_embedder_options.h +++ b/examples/flutter-wayland-client/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-wayland-client/main.cc b/examples/flutter-wayland-client/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-wayland-client/main.cc +++ b/examples/flutter-wayland-client/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/examples/flutter-x11-client/flutter_embedder_options.h b/examples/flutter-x11-client/flutter_embedder_options.h index 04138b3f..41d0bd10 100644 --- a/examples/flutter-x11-client/flutter_embedder_options.h +++ b/examples/flutter-x11-client/flutter_embedder_options.h @@ -23,6 +23,9 @@ class FlutterEmbedderOptions { false); options_.AddDouble("text-scaling-factor", "x", "Text scaling factor", 1.0, false); + options_.AddWithoutValue("enable-high-contrast", "i", + "Request that UI be rendered with darker colors.", + false); options_.AddDouble("force-scale-factor", "s", "Force a scale factor instead using default value", 1.0, false); @@ -86,6 +89,7 @@ class FlutterEmbedderOptions { } text_scale_factor_ = options_.GetValue("text-scaling-factor"); + enable_high_contrast_ = options_.Exist("enable-high-contrast"); if (options_.Exist("force-scale-factor")) { is_force_scale_factor_ = true; @@ -161,6 +165,9 @@ class FlutterEmbedderOptions { double TextScaleFactor() const { return text_scale_factor_; } + bool EnableHighContrast() const { + return enable_high_contrast_; + } bool IsForceScaleFactor() const { return is_force_scale_factor_; } @@ -189,6 +196,7 @@ class FlutterEmbedderOptions { bool is_force_scale_factor_; double scale_factor_; double text_scale_factor_; + bool enable_high_contrast_; bool enable_vsync_; }; diff --git a/examples/flutter-x11-client/main.cc b/examples/flutter-x11-client/main.cc index 37b179e0..579daee6 100644 --- a/examples/flutter-x11-client/main.cc +++ b/examples/flutter-x11-client/main.cc @@ -36,6 +36,7 @@ int main(int argc, char** argv) { view_properties.use_onscreen_keyboard = options.IsUseOnscreenKeyboard(); view_properties.use_window_decoration = options.IsUseWindowDecoraation(); view_properties.text_scale_factor = options.TextScaleFactor(); + view_properties.enable_high_contrast = options.EnableHighContrast(); view_properties.force_scale_factor = options.IsForceScaleFactor(); view_properties.scale_factor = options.ScaleFactor(); view_properties.enable_vsync = options.EnableVsync(); diff --git a/src/client_wrapper/flutter_view_controller.cc b/src/client_wrapper/flutter_view_controller.cc index 42e3d217..47f81529 100644 --- a/src/client_wrapper/flutter_view_controller.cc +++ b/src/client_wrapper/flutter_view_controller.cc @@ -41,6 +41,7 @@ FlutterViewController::FlutterViewController( c_view_properties.use_window_decoration = view_properties.use_window_decoration; c_view_properties.text_scale_factor = view_properties.text_scale_factor; + c_view_properties.enable_high_contrast = view_properties.enable_high_contrast; c_view_properties.force_scale_factor = view_properties.force_scale_factor; c_view_properties.scale_factor = view_properties.scale_factor; c_view_properties.enable_vsync = view_properties.enable_vsync; diff --git a/src/client_wrapper/include/flutter/flutter_view_controller.h b/src/client_wrapper/include/flutter/flutter_view_controller.h index 1659a561..2abf0e6a 100644 --- a/src/client_wrapper/include/flutter/flutter_view_controller.h +++ b/src/client_wrapper/include/flutter/flutter_view_controller.h @@ -79,6 +79,9 @@ class FlutterViewController { // Text scaling factor. double text_scale_factor; + // Enable high contrast. Request that UI be rendered with darker colors. + bool enable_high_contrast; + // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index 4ceb5986..d3c3dee3 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -102,7 +102,8 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate( } const float text_scaling_factor = view_properties->text_scale_factor; - state->view->GetEngine()->SetSystemSettings(text_scaling_factor); + state->view->GetEngine()->SetSystemSettings( + text_scaling_factor, view_properties->enable_high_contrast); } // Must happen after engine is running. diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 76e83b30..8354eaf1 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -379,12 +379,10 @@ void FlutterELinuxEngine::ReloadSystemFonts() { embedder_api_.ReloadSystemFonts(engine_); } -void FlutterELinuxEngine::SetSystemSettings(float text_scaling_factor) { +void FlutterELinuxEngine::SetSystemSettings(float text_scaling_factor, + bool enable_high_contrast) { view_->UpdateTextScaleFactor(text_scaling_factor); - - // TODO: add theme initial value support. - view_->UpdateHighContrastEnabled(false); - + view_->UpdateHighContrastEnabled(enable_high_contrast); SendSystemLocales(); } @@ -437,4 +435,9 @@ void FlutterELinuxEngine::OnVsync(uint64_t last_frame_time_nanos, frame_target_time_nanos); } +void FlutterELinuxEngine::UpdateAccessibilityFeatures( + FlutterAccessibilityFeature flags) { + embedder_api_.UpdateAccessibilityFeatures(engine_, flags); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 57087073..28bbf43c 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -128,7 +128,10 @@ class FlutterELinuxEngine { bool IsImpellerEnabled() const { return enable_impeller_; } // Sets system settings. - void SetSystemSettings(float text_scaling_factor); + void SetSystemSettings(float text_scaling_factor, bool enable_high_contrast); + + // Updates accessibility, e.g. switch to high contrast mode + void UpdateAccessibilityFeatures(FlutterAccessibilityFeature flags); private: // Allows swapping out embedder_api_ calls in tests. diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index ec625d62..745ee3cb 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -506,7 +506,16 @@ std::pair FlutterELinuxView::GetPointerRotation(double x_px, } void FlutterELinuxView::UpdateHighContrastEnabled(bool enabled) { - // TODO: add UpdateAccessibilityFeatures support + int flags = 0; + if (enabled) { + flags |= + FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast; + } else { + flags &= + ~FlutterAccessibilityFeature::kFlutterAccessibilityFeatureHighContrast; + } + engine_.get()->UpdateAccessibilityFeatures( + static_cast(flags)); settings_handler_->UpdateHighContrastMode(enabled); } diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc index 6e118739..7603bfe9 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.cc @@ -45,8 +45,13 @@ void SettingsPlugin::SendSettings() { } bool SettingsPlugin::GetAlwaysUse24HourFormat() { - // The current OS does not have 24 hour format factor. - return true; + return is_always_use_24hour_format_; +} + +void SettingsPlugin::UpdateAlwaysUse24HourFormat( + bool is_always_use_24hour_format) { + is_always_use_24hour_format_ = is_always_use_24hour_format; + SendSettings(); } float SettingsPlugin::GetTextScaleFactor() { diff --git a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h index 0029f695..03a1be37 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/settings_plugin.h @@ -31,6 +31,9 @@ class SettingsPlugin { // Sends settings (e.g., platform brightness) to the engine. void SendSettings(); + // Update the always use 24hour-format status of the system. + void UpdateAlwaysUse24HourFormat(bool is_always_use_24hour_format); + // Update the high contrast status of the system. void UpdateHighContrastMode(bool is_high_contrast); @@ -50,6 +53,7 @@ class SettingsPlugin { std::unique_ptr> channel_; WindowBindingHandler* delegate_; bool is_high_contrast_ = false; + bool is_always_use_24hour_format_ = true; float text_scaling_factor_ = 1.0; }; diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 97d93436..2597aa47 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -109,6 +109,9 @@ typedef struct { // Text scaling factor. double text_scale_factor; + // Enable high contrast. Request that UI be rendered with darker colors. + bool enable_high_contrast; + // Force scale factor specified by command line argument bool force_scale_factor; double scale_factor; From f177e1034e2608598ede827f99066638e1266c29 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 16 Aug 2023 13:56:14 +0000 Subject: [PATCH 139/178] touch-input: fix app crashes on any touch input (#371) This change adds a touch pointer state check and increase device id from touch inputs to fix https://github.com/sony/flutter-elinux/issues/126. Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/flutter_elinux_view.cc | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 745ee3cb..c1bb4803 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -137,6 +137,13 @@ void FlutterELinuxView::OnTouchDown(uint32_t time, int32_t id, double x, double y) { + // Increase device-id to avoid + // "FML_DCHECK(states_.find(pointer_data.device) == states_.end());" + // exception in flutter/engine. + // This is because "device-id = 0" is used for mouse inputs. + // See engine/lib/ui/window/pointer_data_packet_converter.cc + id += 1; + auto trimmed_xy = GetPointerRotation(x, y); auto* point = GgeTouchPoint(id); if (!point) { @@ -163,10 +170,25 @@ void FlutterELinuxView::OnTouchDown(uint32_t time, } void FlutterELinuxView::OnTouchUp(uint32_t time, int32_t id) { + // Increase device-id to avoid + // "FML_DCHECK(states_.find(pointer_data.device) == states_.end());" + // exception in flutter/engine. + // This is because "device-id = 0" is used for mouse inputs. + // See engine/lib/ui/window/pointer_data_packet_converter.cc + id += 1; + auto* point = GgeTouchPoint(id); if (!point) { return; } + + // Makes sure we have an existing touch pointer in down state to + // avoid "FML_DCHECK(iter != states_.end())" exception in flutter/engine. + // See engine/lib/ui/window/pointer_data_packet_converter.cc + if (point->event_mask != TouchEvent::kDown && + point->event_mask != TouchEvent::kMotion) { + return; + } point->event_mask = TouchEvent::kUp; FlutterPointerEvent event = { @@ -189,11 +211,26 @@ void FlutterELinuxView::OnTouchMotion(uint32_t time, int32_t id, double x, double y) { + // Increase device-id to avoid avoid + // "FML_DCHECK(states_.find(pointer_data.device) == states_.end());" + // exception in flutter/engine. + // This is because "device-id = 0" is used for mouse inputs. + // See engine/lib/ui/window/pointer_data_packet_converter.cc + id += 1; + auto trimmed_xy = GetPointerRotation(x, y); auto* point = GgeTouchPoint(id); if (!point) { return; } + + // Makes sure we have an existing touch pointer in down state to + // avoid "FML_DCHECK(iter != states_.end())" exception in flutter/engine. + // See engine/lib/ui/window/pointer_data_packet_converter.cc + if (point->event_mask != TouchEvent::kDown && + point->event_mask != TouchEvent::kMotion) { + return; + } point->event_mask = TouchEvent::kMotion; point->x = trimmed_xy.first; point->y = trimmed_xy.second; From 23589c382dbddf8542da4c72aff4ff42a96dca44 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 17 Aug 2023 05:30:00 +0000 Subject: [PATCH 140/178] common: fix syntax error in event_channel.h (#372) This change fixes the following build error in event_channel.h. ----- /home/hidenori/work/flutter/flutter-elinux-plugins/packages/camera/example/elinux/flutter/ephemeral/cpp_client_wrapper/include/flutter/e vent_channel.h:95:27: error: invalid operands to binary expression ('basic_ostream>' and 'const std::unique_ptr') << (error->error_details); ^ ~~~~~~~~~~~~~~~~~~~~~~ /home/hidenori/work/flutter/flutter-elinux-plugins/packages/camera/example/elinux/flutter/ephemeral/.plugin_symlinks/camera_elinux/elinu x/channels/event_channel_image_stream.cc:44:18: note: in instantiation of member function 'flutter::EventChannel<>::SetStreamHandler' requested here event_channel->SetStreamHandler(std::move(event_channel_handler)); ^ /usr/bin/../lib/gcc/aarch64-linux-gnu/11/../../../../include/c++/11/system_error:279:5: note: candidate function template not viable: no known conversion from 'const std::unique_ptr' to 'const std::error_code' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __os, const error_code& __e) ^ /usr/bin/../lib/gcc/aarch64-linux-gnu/11/../../../../include/c++/11/ostream:518:5: note: candidate function template not viable: no known conversion from 'const std::unique_ptr' to 'char' for 2nd argument operator<<(basic_ostream<_CharT, _Traits>& __out, char __c) ----- Signed-off-by: Hidenori Matsubayashi --- .../common/client_wrapper/include/flutter/event_channel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h index 6a3ef09b..c96e6408 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/event_channel.h @@ -92,7 +92,7 @@ class EventChannel { std::cerr << "Failed to cancel existing stream: " << (error->error_code) << ", " << (error->error_message) << ", " - << (error->error_details); + << (error->error_details.get()); } } is_listening = true; From 7f83ccb9a9790ab31758e76b3b5498be2af32af7 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 17 Aug 2023 20:39:32 +0000 Subject: [PATCH 141/178] lifecycle_plugin: add hidden state (#373) This change adds a new state hidden to lifecycle plugin. Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/plugins/lifecycle_plugin.cc | 7 +++++++ .../platform/linux_embedded/plugins/lifecycle_plugin.h | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc index 009d82eb..002457db 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.cc @@ -15,6 +15,8 @@ constexpr char kInactive[] = "AppLifecycleState.inactive"; constexpr char kResumed[] = "AppLifecycleState.resumed"; constexpr char kPaused[] = "AppLifecycleState.paused"; constexpr char kDetached[] = "AppLifecycleState.detached"; +constexpr char kHidden[] = "AppLifecycleState.hidden"; + } // namespace LifecyclePlugin::LifecyclePlugin(BinaryMessenger* messenger) @@ -43,4 +45,9 @@ void LifecyclePlugin::OnDetached() const { channel_->Send(std::string(kDetached)); } +void LifecyclePlugin::OnHidden() const { + ELINUX_LOG(DEBUG) << "App lifecycle changed to hidden state."; + channel_->Send(std::string(kHidden)); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h index aa9507c2..784fbd61 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/lifecycle_plugin.h @@ -25,6 +25,8 @@ class LifecyclePlugin { void OnDetached() const; + void OnHidden() const; + private: std::unique_ptr> channel_; }; From 549415f9f70698661fad9fdf64055f1af67040b0 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Aug 2023 01:23:13 +0000 Subject: [PATCH 142/178] wayland: add notification of display changes to embedder (#374) This change adds notification of display changes to embedder support in Wayland backend. Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/flutter_elinux_engine.cc | 8 ++++++++ .../linux_embedded/flutter_elinux_engine.h | 5 +++++ .../linux_embedded/flutter_elinux_view.cc | 19 +++++++++++++++++++ .../linux_embedded/flutter_elinux_view.h | 6 ++++++ .../linux_embedded/window/elinux_window.h | 17 +++++++++++++++++ .../linux_embedded/window/elinux_window_drm.h | 4 ---- .../window/elinux_window_wayland.cc | 2 +- .../window/elinux_window_wayland.h | 5 ----- .../linux_embedded/window/elinux_window_x11.h | 4 ---- .../window_binding_handler_delegate.h | 10 ++++++++++ 10 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 8354eaf1..2fbec1eb 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -440,4 +440,12 @@ void FlutterELinuxEngine::UpdateAccessibilityFeatures( embedder_api_.UpdateAccessibilityFeatures(engine_, flags); } +void FlutterELinuxEngine::UpdateDisplayInfo( + FlutterEngineDisplaysUpdateType update_type, + const FlutterEngineDisplay* displays, + size_t display_count) { + embedder_api_.NotifyDisplayUpdate(engine_, update_type, displays, + display_count); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 28bbf43c..b705941e 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -133,6 +133,11 @@ class FlutterELinuxEngine { // Updates accessibility, e.g. switch to high contrast mode void UpdateAccessibilityFeatures(FlutterAccessibilityFeature flags); + // Update display information. + void UpdateDisplayInfo(FlutterEngineDisplaysUpdateType update_type, + const FlutterEngineDisplay* displays, + size_t display_count); + private: // Allows swapping out embedder_api_ calls in tests. friend class EngineEmbedderApiModifier; diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index c1bb4803..68d0bac4 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -560,4 +560,23 @@ void FlutterELinuxView::UpdateTextScaleFactor(float factor) { settings_handler_->UpdateTextScaleFactor(factor); } +void FlutterELinuxView::UpdateDisplayInfo(double refresh_rate, + size_t width_px, + size_t height_px, + double pixel_ratio) { + const FlutterEngineDisplaysUpdateType update_type = + kFlutterEngineDisplaysUpdateTypeStartup; + const FlutterEngineDisplay displays = { + .struct_size = sizeof(FlutterEngineDisplay), + .display_id = 0, + .single_display = true, + .refresh_rate = refresh_rate, + .width = width_px, + .height = height_px, + .device_pixel_ratio = pixel_ratio, + }; + const size_t display_count = 1; + engine_.get()->UpdateDisplayInfo(update_type, &displays, display_count); +} + } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index 977bd3e1..08740eff 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -151,6 +151,12 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // |WindowBindingHandlerDelegate| void UpdateTextScaleFactor(float factor) override; + // |WindowBindingHandlerDelegate| + void UpdateDisplayInfo(double refresh_rate, + size_t width_px, + size_t height_px, + double pixel_ratio) override; + private: // Struct holding the mouse state. The engine doesn't keep track of which // mouse buttons have been pressed, so it's the embedding's responsibility. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h index 8c4e9d15..e9b6bf66 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window.h @@ -5,7 +5,10 @@ #ifndef FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ #define FLUTTER_SHELL_PLATFORM_LINUX_EMBEDDED_WINDOW_ELINUX_WINDOW_H_ +#include + #include "flutter/shell/platform/linux_embedded/public/flutter_elinux.h" +#include "flutter/shell/platform/linux_embedded/window_binding_handler.h" namespace flutter { @@ -39,9 +42,23 @@ class ELinuxWindow { } } + void NotifyDisplayInfoUpdates() const { + if (binding_handler_delegate_) { + binding_handler_delegate_->UpdateDisplayInfo( + std::trunc(1000000.0 / frame_rate_), GetCurrentWidth(), + GetCurrentHeight(), current_scale_); + } + } + FlutterDesktopViewProperties view_properties_; + + // A pointer to a FlutterWindowsView that can be used to update engine + // windowing and input state. + WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr; + int32_t display_max_width_ = -1; int32_t display_max_height_ = -1; + int32_t frame_rate_ = 60000; double current_scale_ = 1.0; uint16_t current_rotation_ = 0; // The x coordinate of the pointer in physical pixels. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 92c70ad7..272bc9be 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -708,10 +708,6 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { bool is_pointer_device; }; - // A pointer to a FlutterWindowsView that can be used to update engine - // windowing and input state. - WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr; - std::unique_ptr native_window_; std::unique_ptr render_surface_; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 1c74ad08..1f62cf31 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1041,7 +1041,6 @@ ELinuxWindowWayland::ELinuxWindowWayland( zwp_text_input_v3_(nullptr), wp_presentation_(nullptr), wp_presentation_clk_id_(UINT32_MAX), - frame_rate_(60000), window_decorations_(nullptr) { view_properties_ = view_properties; current_scale_ = @@ -1281,6 +1280,7 @@ bool ELinuxWindowWayland::DispatchEvent() { view_properties_.height * current_scale_ - WindowDecorationsPhysicalHeight()); } + NotifyDisplayInfoUpdates(); } // Prepare to call wl_display_read_events. diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 6ba5f722..2d1343d5 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -135,10 +135,6 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { kZxdgToplevelDecorationV1Listener; static constexpr size_t kDefaultPointerSize = 24; - // A pointer to a FlutterWindowsView that can be used to update engine - // windowing and input state. - WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr; - std::unique_ptr native_window_; std::unique_ptr render_surface_; @@ -189,7 +185,6 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wp_presentation* wp_presentation_; uint32_t wp_presentation_clk_id_; uint64_t last_frame_time_nanos_; - int32_t frame_rate_; CursorInfo cursor_info_; size_t cursor_size_; diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h index 9d364526..eb11171e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.h @@ -70,10 +70,6 @@ class ELinuxWindowX11 : public ELinuxWindow, public WindowBindingHandler { int16_t x, int16_t y); - // A pointer to a FlutterWindowsView that can be used to update engine - // windowing and input state. - WindowBindingHandlerDelegate* binding_handler_delegate_ = nullptr; - Display* display_ = nullptr; std::unique_ptr native_window_; std::unique_ptr render_surface_; diff --git a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h index 3bc6429d..ad51a5d2 100644 --- a/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h +++ b/src/flutter/shell/platform/linux_embedded/window_binding_handler_delegate.h @@ -110,6 +110,16 @@ class WindowBindingHandlerDelegate { // Update the status of the text scaling factor feature virtual void UpdateTextScaleFactor(float factor) = 0; + + // Update the status of the corresponding to display changes. + // @param[in] refresh_rate Refresh rate of the display. + // @param[in] width_px Physical width of the display. + // @param[in] height_px Physical height of the display. + // @param[in] pixel_ratio Pixel ratio of the display. + virtual void UpdateDisplayInfo(double refresh_rate, + size_t width_px, + size_t height_px, + double pixel_ratio) = 0; }; } // namespace flutter From a33ae027cee6792a4e142d8d5c135544f66ea1f7 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 18 Aug 2023 22:04:24 +0000 Subject: [PATCH 143/178] wayland: disable vsync waiter (#376) Disable vsync waiter as it may be causing rendering issues. Related issue (maybe) https://github.com/sony/flutter-elinux/issues/205 Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 723556b3..19abd447 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the displ option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) -option(ENABLE_VSYNC "Enable embedder vsync" ON) +option(ENABLE_VSYNC "Enable embedder vsync" OFF) # todo: need to investigate https://github.com/sony/flutter-embedded-linux/pull/376 when enabling this option. option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) From 3113b7b097cd9b17767a9b1d27cec9c262565233 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 20 Aug 2023 12:10:54 +0000 Subject: [PATCH 144/178] platform-views: implement more APIs in platform views (#375) Related issue: https://github.com/sony/flutter-embedded-linux/issues/41 Signed-off-by: Hidenori Matsubayashi --- .../plugins/platform_views_plugin.cc | 116 ++++++++++++++++-- .../plugins/platform_views_plugin.h | 20 +++ .../public/flutter_platform_views.h | 11 +- 3 files changed, 136 insertions(+), 11 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc index 85c553e8..c2bc5cf2 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -21,12 +21,16 @@ constexpr char kAcceptGestureMethod[] = "acceptGesture"; constexpr char kRejectGestureMethod[] = "rejectGesture"; constexpr char kEnterMethod[] = "enter"; constexpr char kExitMethod[] = "exit"; +constexpr char kOffsetMethod[] = "offset"; constexpr char kViewTypeKey[] = "viewType"; constexpr char kIdKey[] = "id"; constexpr char kWidthKey[] = "width"; constexpr char kHeightKey[] = "height"; constexpr char kParamsKey[] = "params"; + +constexpr char kTopKey[] = "top"; +constexpr char kLeftKey[] = "left"; } // namespace PlatformViewsPlugin::PlatformViewsPlugin(BinaryMessenger* messenger) @@ -63,6 +67,7 @@ void PlatformViewsPlugin::RegisterViewFactory( << view_type; return; } + ELINUX_LOG(DEBUG) << view_type << " was registered"; platform_view_factories_[view_type] = std::move(factory); } @@ -78,13 +83,13 @@ void PlatformViewsPlugin::HandleMethodCall( } else if (method.compare(kDisposeMethod) == 0) { PlatformViewsDispose(arguments, std::move(result)); } else if (method.compare(kResizeMethod) == 0) { - result->NotImplemented(); + PlatformViewsResize(arguments, std::move(result)); } else if (method.compare(kSetDirectionMethod) == 0) { result->NotImplemented(); } else if (method.compare(kClearFocusMethod) == 0) { - result->NotImplemented(); + PlatformViewsClearFocus(arguments, std::move(result)); } else if (method.compare(kTouchMethod) == 0) { - result->NotImplemented(); + PlatformViewsTouch(arguments, std::move(result)); } else if (method.compare(kAcceptGestureMethod) == 0) { result->NotImplemented(); } else if (method.compare(kRejectGestureMethod) == 0) { @@ -93,6 +98,8 @@ void PlatformViewsPlugin::HandleMethodCall( result->NotImplemented(); } else if (method.compare(kExitMethod) == 0) { result->NotImplemented(); + } else if (method.compare(kOffsetMethod) == 0) { + PlatformViewsOffset(arguments, std::move(result)); } else { ELINUX_LOG(WARNING) << "Platform Views unexpected method is called: " << method; @@ -109,10 +116,6 @@ void PlatformViewsPlugin::PlatformViewsCreate( return; } auto view_id = LookupEncodableMap(arguments, kIdKey); - if (!view_id) { - result->Error("Couldn't find the view id in the arguments"); - return; - } auto view_width = LookupEncodableMap(arguments, kWidthKey); if (!view_width) { result->Error("Couldn't find width in the arguments"); @@ -153,17 +156,110 @@ void PlatformViewsPlugin::PlatformViewsDispose( const flutter::EncodableValue& arguments, std::unique_ptr> result) { auto view_id = LookupEncodableMap(arguments, kIdKey); - if (!view_id) { + ELINUX_LOG(DEBUG) << "Dispose the platform view: id = " << view_id; + if (platform_views_.find(view_id) == platform_views_.end()) { result->Error("Couldn't find the view id in the arguments"); return; } + platform_views_[view_id]->Dispose(); + result->Success(); +} - ELINUX_LOG(DEBUG) << "Dispose the platform view: id = " << view_id; +void PlatformViewsPlugin::PlatformViewsClearFocus( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto view_id = LookupEncodableMap(arguments, kIdKey); + ELINUX_LOG(DEBUG) << "ClearFocus the platform view: id = " << view_id; if (platform_views_.find(view_id) == platform_views_.end()) { result->Error("Couldn't find the view id in the arguments"); return; } - platform_views_[view_id]->Dispose(); + platform_views_[view_id]->SetFocus(false); + platform_views_[view_id]->ClearFocus(); + + result->Success(); +} + +void PlatformViewsPlugin::PlatformViewsResize( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto view_id = LookupEncodableMap(arguments, kIdKey); + auto view_width = LookupEncodableMap(arguments, kWidthKey); + if (!view_width) { + result->Error("Couldn't find width in the arguments"); + return; + } + auto view_height = LookupEncodableMap(arguments, kHeightKey); + if (!view_height) { + result->Error("Couldn't find height in the arguments"); + return; + } + + ELINUX_LOG(DEBUG) << "Resize the platform view: id = " << view_id + << ", width = " << view_width + << ", height = " << view_height; + if (platform_views_.find(view_id) == platform_views_.end()) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + + if (!view_width || !view_height) { + result->Error("width and height must be greater than zero"); + return; + } + + platform_views_[view_id]->Resize(view_width, view_height); + + result->Success(arguments); +} + +void PlatformViewsPlugin::PlatformViewsTouch( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto list = std::get(arguments); + auto view_id = std::get(list[0]); + auto event_type = std::get(list[3]); + auto device_id = std::get(list[11]); + + auto pointer_coords = std::get(list[6]); + if (pointer_coords.size() < 1) { + result->Error("Couldn't find the pointer_coords in the arguments"); + return; + } + auto pointer_coord = std::get(pointer_coords[0]); + auto x = std::get(pointer_coord[7]); + auto y = std::get(pointer_coord[8]); + + ELINUX_LOG(ERROR) << "Touch the platform view: id = " << view_id + << ", device_id = " << device_id + << ", event_type = " << event_type << ", x = " << x + << ", y = " << y; + if (platform_views_.find(view_id) == platform_views_.end()) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + + platform_views_[view_id]->Touch(device_id, event_type, x, y); + + result->Success(); +} + +void PlatformViewsPlugin::PlatformViewsOffset( + const flutter::EncodableValue& arguments, + std::unique_ptr> result) { + auto view_id = LookupEncodableMap(arguments, kIdKey); + auto view_top = LookupEncodableMap(arguments, kTopKey); + auto view_left = LookupEncodableMap(arguments, kLeftKey); + ELINUX_LOG(DEBUG) << "Offset the platform view: " + << "id = " << view_id << ", top = " << view_top + << ", left = " << view_left; + if (platform_views_.find(view_id) == platform_views_.end()) { + result->Error("Couldn't find the view id in the arguments"); + return; + } + + platform_views_[view_id]->Offset(view_top, view_left); + result->Success(); } diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h index 2530481f..8c17e078 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.h @@ -52,6 +52,26 @@ class PlatformViewsPlugin { const flutter::EncodableValue& arguments, std::unique_ptr> result); + // Called when "clearFocus" method is called + void PlatformViewsClearFocus( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + + // Called when "resize" method is called + void PlatformViewsResize( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + + // Called when "touch" method is called + void PlatformViewsTouch( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + + // Called when "offset" method is called + void PlatformViewsOffset( + const flutter::EncodableValue& arguments, + std::unique_ptr> result); + // Method channel instance. std::unique_ptr> channel_; diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h index 5ecb2f30..a1ff65ec 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h @@ -9,10 +9,11 @@ #include #include +#include +#include #include "flutter_export.h" #include "flutter_messenger.h" -#include "plugin_registrar.h" class FlutterDesktopPlatformView { public: @@ -31,12 +32,20 @@ class FlutterDesktopPlatformView { void SetFocus(bool focus) { focused_ = focus; } + virtual void ClearFocus() = 0; + bool IsFocused() const { return focused_; } void SetTextureId(int texture_id) { texture_id_ = texture_id; } int GetTextureId() const { return texture_id_; } + virtual void Resize(double width, double height) = 0; + + virtual void Touch(int device_id, int event_type, double x, double y) = 0; + + virtual void Offset(double top, double left) = 0; + private: flutter::PluginRegistrar* registrar_; int view_id_; From 0501df9c1d2ff71aa346541020de7bf3a5e25d35 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 20 Aug 2023 12:22:45 +0000 Subject: [PATCH 145/178] github-actions: update actions/checkout from v2 to v3 (#377) This change updates actions/checkout version from v2 to v3. Signed-off-by: Hidenori Matsubayashi --- .github/workflows/build-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index ddd680ed..69b58791 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install libraries run: | From 98e15f31976b8712949afe963322e950de7cfdb2 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 21 Aug 2023 11:21:44 +0000 Subject: [PATCH 146/178] platform-views: fix wrong log level (#378) This change fixes a wrong log level setting in platform-views implementation. Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/plugins/platform_views_plugin.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc index c2bc5cf2..81b29462 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -230,7 +230,7 @@ void PlatformViewsPlugin::PlatformViewsTouch( auto x = std::get(pointer_coord[7]); auto y = std::get(pointer_coord[8]); - ELINUX_LOG(ERROR) << "Touch the platform view: id = " << view_id + ELINUX_LOG(TRACE) << "Touch the platform view: id = " << view_id << ", device_id = " << device_id << ", event_type = " << event_type << ", x = " << x << ", y = " << y; From 311e9f189a55971c997916c13df49d5e46df4d26 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 21 Aug 2023 12:23:50 +0000 Subject: [PATCH 147/178] platform-views: fix wrong size of texture id (#379) This change fixes wrong size of texture id. Related issue: #41 Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/public/flutter_platform_views.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h index a1ff65ec..0e7c9d52 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_platform_views.h @@ -36,9 +36,9 @@ class FlutterDesktopPlatformView { bool IsFocused() const { return focused_; } - void SetTextureId(int texture_id) { texture_id_ = texture_id; } + void SetTextureId(int64_t texture_id) { texture_id_ = texture_id; } - int GetTextureId() const { return texture_id_; } + int64_t GetTextureId() const { return texture_id_; } virtual void Resize(double width, double height) = 0; @@ -49,7 +49,7 @@ class FlutterDesktopPlatformView { private: flutter::PluginRegistrar* registrar_; int view_id_; - int texture_id_; + int64_t texture_id_; bool focused_; }; From c696e5b2fcedc9ad9752d8c113bc1f9cdc39be64 Mon Sep 17 00:00:00 2001 From: Snarpix Date: Fri, 25 Aug 2023 23:30:36 +0200 Subject: [PATCH 148/178] Fixed ContextEgl construction for eglstreams. Added support for Nvidia Tegra TX1/TX2 (#381) Signed-off-by: Stanislav Shmarov --- AUTHORS | 1 + .../surface/context_egl_stream.cc | 2 +- .../linux_embedded/window/elinux_window_drm.h | 47 ++++++++++--------- .../window/native_window_drm.cc | 6 ++- .../linux_embedded/window/native_window_drm.h | 2 + 5 files changed, 34 insertions(+), 24 deletions(-) diff --git a/AUTHORS b/AUTHORS index 1812758d..d82960b5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -12,3 +12,4 @@ FlafyDev Makoto Sato (makoto.sato@atmark-techno.com) Yunhao Tian (t123yh@outlook.com) Luke Howard +Stanislav Shmarov diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc index 2f1df0c5..61d699f7 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc @@ -11,7 +11,7 @@ namespace flutter { ContextEglStream::ContextEglStream( std::unique_ptr environment) - : ContextEgl(std::move(environment), EGL_STREAM_BIT_KHR) { + : ContextEgl(std::move(environment), false, EGL_STREAM_BIT_KHR) { if (!valid_) { return; } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 272bc9be..8b6c0767 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -262,29 +263,31 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } constexpr char kFileNameSeparator[] = "/"; - auto pos = device_filename.find_last_of(kFileNameSeparator); - if (pos == std::string::npos) { - ELINUX_LOG(ERROR) << "Failed to get device name position."; - udev_unref(udev); - return false; - } + if (device_filename != "drm-nvdc") { + auto pos = device_filename.find_last_of(kFileNameSeparator); + if (pos == std::string::npos) { + ELINUX_LOG(ERROR) << "Failed to get device name position."; + udev_unref(udev); + return false; + } - auto device_name = device_filename.substr(pos + 1); - auto device = udev_device_new_from_subsystem_sysname( - udev, kUdevMonitorSubsystemDrm, device_name.c_str()); - if (!device) { - ELINUX_LOG(ERROR) << "Failed to get device from " << device_name; - udev_unref(udev); - return false; - } + auto device_name = device_filename.substr(pos + 1); + auto device = udev_device_new_from_subsystem_sysname( + udev, kUdevMonitorSubsystemDrm, device_name.c_str()); + if (!device) { + ELINUX_LOG(ERROR) << "Failed to get device from " << device_name; + udev_unref(udev); + return false; + } - auto sysnum = udev_device_get_sysnum(device); - if (!sysnum) { - ELINUX_LOG(ERROR) << "Failed to get device id."; - udev_unref(udev); - return false; + auto sysnum = udev_device_get_sysnum(device); + if (!sysnum) { + ELINUX_LOG(ERROR) << "Failed to get device id."; + udev_unref(udev); + return false; + } + drm_device_id_ = std::atoi(sysnum); } - drm_device_id_ = std::atoi(sysnum); udev_unref(udev); if (sd_event_new(&udev_drm_event_loop_) < 0) { @@ -348,7 +351,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { if (!sysnum) { ELINUX_LOG(ERROR) << "Failed to get device id."; return false; - } else if (std::atoi(sysnum) != drm_device_id_) { + } else if (drm_device_id_ && std::atoi(sysnum) != *drm_device_id_) { ELINUX_LOG(ERROR) << "Not expected device id."; return false; } @@ -721,7 +724,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { sd_event* udev_drm_event_loop_ = nullptr; udev_monitor* udev_monitor_ = nullptr; - int drm_device_id_; + std::optional drm_device_id_; }; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index 97d8363c..59a29021 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -18,7 +18,11 @@ namespace flutter { NativeWindowDrm::NativeWindowDrm(const char* device_filename, const uint16_t rotation, bool enable_vsync) { - drm_device_ = open(device_filename, O_RDWR | O_CLOEXEC); + if (!strcmp("drm-nvdc", device_filename)) { + drm_device_ = drmOpen(device_filename, nullptr); + } else { + drm_device_ = open(device_filename, O_RDWR | O_CLOEXEC); + } if (drm_device_ == -1) { ELINUX_LOG(ERROR) << "Couldn't open " << device_filename; return; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index 2a21b569..bae9ec06 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -7,6 +7,8 @@ #include +#include +#include #include #include "flutter/shell/platform/linux_embedded/surface/surface_gl.h" From 6d652df06f94ffd42bd330bde9d77971db92985e Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 21 Sep 2023 11:37:54 +0000 Subject: [PATCH 149/178] engine: disable fbo_reset_after_present to avoid flicker issues on some H/W (#385) See https://github.com/sony/flutter-embedded-linux/issues/334 Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 2fbec1eb..798aa139 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -42,7 +42,10 @@ FlutterRendererConfig GetRendererConfig() { } return host->view()->ClearCurrent(); }; - config.open_gl.fbo_reset_after_present = true; + // Temporary disabled fbo_reset_after_present to avoid flicker and other + // rendering issues on some H/W. See + // https://github.com/sony/flutter-embedded-linux/issues/334 + config.open_gl.fbo_reset_after_present = false; #if defined(USE_OPENGL_DIRTY_REGION_MANAGEMENT) config.open_gl.present_with_info = [](void* user_data, const FlutterPresentInfo* info) -> bool { From ac2a2c66427b5bbb2af6338312f3b27dc04556ab Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 22 Sep 2023 10:48:50 +0000 Subject: [PATCH 150/178] Revert "engine: disable fbo_reset_after_present to avoid flicker issues on some H/W (#385)" (#386) This reverts commit 6d652df06f94ffd42bd330bde9d77971db92985e. Related issue #334 --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 798aa139..2fbec1eb 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -42,10 +42,7 @@ FlutterRendererConfig GetRendererConfig() { } return host->view()->ClearCurrent(); }; - // Temporary disabled fbo_reset_after_present to avoid flicker and other - // rendering issues on some H/W. See - // https://github.com/sony/flutter-embedded-linux/issues/334 - config.open_gl.fbo_reset_after_present = false; + config.open_gl.fbo_reset_after_present = true; #if defined(USE_OPENGL_DIRTY_REGION_MANAGEMENT) config.open_gl.present_with_info = [](void* user_data, const FlutterPresentInfo* info) -> bool { From 820ee198b3a888cbe9dd06a9fffb3930c7166fc0 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 29 Sep 2023 18:00:52 +0900 Subject: [PATCH 151/178] WAR: temporarily disable partial repaints (#388) This change disables the partial repaints temporarily because of the flicker issue. Once the root cause in flutter/engine was fixed and its change propagated to the stable channel, this will be lifted up. See https://github.com/sony/flutter-embedded-linux/issues/334 for the details. Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/surface/elinux_egl_surface.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 07fede87..2efe002b 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -168,6 +168,11 @@ void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id, 0, 0, static_cast(width_px_), static_cast(height_px_)}; existing_damage->damage = existing_damage_map_[fbo_id]; + // Temporarily disabled partial repaints due to + // https://github.com/sony/flutter-embedded-linux/issues/334. Once + // https://github.com/flutter/engine/pull/45611 was merged and propagated to + // the stable channel, this will be lifted up. +#if 0 if (age > 1) { --age; // join up to (age - 1) last rects from damage history @@ -191,6 +196,7 @@ void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id, } } } +#endif } // Auxiliary function used to transform a FlutterRect into the format that is From 32d8a7a83481150e0226787c7dbfb42d741e6d5c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 30 Sep 2023 08:30:13 +0900 Subject: [PATCH 152/178] x11: support fullscreen option (#389) This change adds fullscreen option support. Related issues: - https://github.com/sony/flutter-embedded-linux/issues/37 - https://github.com/sony/flutter-elinux/issues/136 Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_x11.cc | 3 ++- .../window/native_window_x11.cc | 21 ++++++++++++++----- .../linux_embedded/window/native_window_x11.h | 3 ++- 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc index ea4e4dfc..862c4d64 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_x11.cc @@ -132,7 +132,8 @@ bool ELinuxWindowX11::CreateRenderSurface(int32_t width, } native_window_ = std::make_unique( display_, context_egl->GetAttrib(EGL_NATIVE_VISUAL_ID), - view_properties_.title, width, height, view_properties_.enable_vsync); + view_properties_.title, width, height, view_properties_.enable_vsync, + view_properties_.view_mode == FlutterDesktopViewMode::kFullscreen); if (!native_window_->IsValid()) { ELINUX_LOG(ERROR) << "Failed to create the native window"; return false; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc index 51f3cc11..e6da1ea1 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.cc @@ -23,7 +23,8 @@ NativeWindowX11::NativeWindowX11(Display* display, const char* title, const size_t width, const size_t height, - bool enable_vsync) { + bool enable_vsync, + bool fullscreen) { XVisualInfo visualTemplate; visualTemplate.visualid = visual_id; @@ -44,10 +45,20 @@ NativeWindowX11::NativeWindowX11(Display* display, ButtonReleaseMask | PointerMotionMask | EnterWindowMask | LeaveWindowMask | FocusChangeMask | StructureNotifyMask; - window_ = - XCreateWindow(display, RootWindow(display, visual->screen), 0, 0, width, - height, 0, visual->depth, InputOutput, visual->visual, - CWBorderPixel | CWColormap | CWEventMask, &windowAttribs); + auto window_width = width; + auto window_height = height; + if (fullscreen) { + XWindowAttributes attr; + XGetWindowAttributes(display, RootWindow(display, visual->screen), &attr); + window_width = attr.width; + window_height = attr.height; + windowAttribs.override_redirect = True; + } + + window_ = XCreateWindow( + display, RootWindow(display, visual->screen), 0, 0, window_width, + window_height, 0, visual->depth, InputOutput, visual->visual, + CWBorderPixel | CWColormap | CWEventMask, &windowAttribs); if (!window_) { ELINUX_LOG(ERROR) << "Failed to the create window."; return; diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h index 878d864d..9cb9f786 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_x11.h @@ -18,7 +18,8 @@ class NativeWindowX11 : public NativeWindow { const char* title, const size_t width, const size_t height, - bool enable_vsync); + bool enable_vsync, + bool fullscreen); ~NativeWindowX11() = default; // |NativeWindow| From 6add553a4ff72b11c11466999b8f030e8e033a65 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 1 Oct 2023 07:30:38 +0900 Subject: [PATCH 153/178] wayland: fix wrong scale factor logic in xdg_toplevel_listener (#390) This change fixes a wrong scale factor logic in configure callback of xdg_toplevel_listener when the scale value is not 1.0. Signed-off-by: Hidenori Matsubayashi --- .../window/elinux_window_wayland.cc | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 1f62cf31..eaa62469 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -123,24 +123,24 @@ const xdg_toplevel_listener ELinuxWindowWayland::kXdgToplevelListener = { std::swap(width, height); } - int32_t next_width = width; - int32_t next_height = height; + int32_t next_width_dip = width / self->current_scale_; + int32_t next_height_dip = height / self->current_scale_; if (self->restore_window_required_) { self->restore_window_required_ = false; - next_width = self->restore_window_width_; - next_height = self->restore_window_height_; + next_width_dip = self->restore_window_width_; + next_height_dip = self->restore_window_height_; } - if (!next_width || !next_height || - (self->view_properties_.width == next_width && - self->view_properties_.height == next_height)) { + if (!next_width_dip || !next_height_dip || + (self->view_properties_.width == next_width_dip && + self->view_properties_.height == next_height_dip)) { return; } - ELINUX_LOG(TRACE) - << "request redraw: " << next_width << ", " << next_height; - self->view_properties_.width = next_width; - self->view_properties_.height = next_height; + ELINUX_LOG(TRACE) << "request redraw: " << next_width_dip << ", " + << next_height_dip; + self->view_properties_.width = next_width_dip; + self->view_properties_.height = next_height_dip; self->request_redraw_ = true; }, .close = @@ -1274,6 +1274,11 @@ bool ELinuxWindowWayland::DispatchEvent() { window_decorations_->Resize(view_properties_.width, view_properties_.height, current_scale_); } + + ELINUX_LOG(ERROR) << "width: " << view_properties_.width; + ELINUX_LOG(ERROR) << "height: " << view_properties_.height; + ELINUX_LOG(ERROR) << "current_scale: " << current_scale_; + if (binding_handler_delegate_) { binding_handler_delegate_->OnWindowSizeChanged( view_properties_.width * current_scale_, @@ -1820,8 +1825,9 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { } void ELinuxWindowWayland::UpdateWindowScale() { - if (view_properties_.force_scale_factor) + if (view_properties_.force_scale_factor) { return; + } double scale_factor = 1.0; for (auto output_id : entered_outputs_) { From 5bee5a884549db2e624ac4bb746720f42ba75264 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sun, 1 Oct 2023 07:41:32 +0900 Subject: [PATCH 154/178] egl: update commets for eglSwapInterval (#391) Signed-off-by: Hidenori Matsubayashi --- .../platform/linux_embedded/surface/elinux_egl_surface.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 2efe002b..576fcf6e 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -75,8 +75,14 @@ bool ELinuxEGLSurface::MakeCurrent() const { } // Non-blocking when swappipping buffers on Wayland. + // OpenGL swap intervals can be used to prevent screen tearing. + // If enabled, the raster thread blocks until the v-blank. + // This is unnecessary if DWM composition is enabled. + // See: https://www.khronos.org/opengl/wiki/Swap_Interval + // See: https://learn.microsoft.com/windows/win32/dwm/composition-ovw + // // However, we might encounter rendering problems on some Wayland compositors - // (e.g. weston 9.0) when we use them. + // (e.g. weston 9.0). // See also: // - https://github.com/sony/flutter-embedded-linux/issues/230 // - https://github.com/sony/flutter-embedded-linux/issues/234 From 505468a7476665f4b2c06fa919d05a54c9e2f097 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 2 Oct 2023 12:33:18 +0900 Subject: [PATCH 155/178] engine: add text_scaling_factor option value check (#393) Fixed #392 Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/linux_embedded/flutter_elinux_engine.cc | 5 +++++ .../platform/linux_embedded/window/elinux_window_wayland.cc | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 2fbec1eb..9e49c9e4 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -381,6 +381,11 @@ void FlutterELinuxEngine::ReloadSystemFonts() { void FlutterELinuxEngine::SetSystemSettings(float text_scaling_factor, bool enable_high_contrast) { + if (text_scaling_factor == 0) { + ELINUX_LOG(WARNING) << "text-scaling-factor value must be greater than 0"; + text_scaling_factor = 1.0; + } + view_->UpdateTextScaleFactor(text_scaling_factor); view_->UpdateHighContrastEnabled(enable_high_contrast); SendSystemLocales(); diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index eaa62469..12c682c9 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1275,10 +1275,6 @@ bool ELinuxWindowWayland::DispatchEvent() { view_properties_.height, current_scale_); } - ELINUX_LOG(ERROR) << "width: " << view_properties_.width; - ELINUX_LOG(ERROR) << "height: " << view_properties_.height; - ELINUX_LOG(ERROR) << "current_scale: " << current_scale_; - if (binding_handler_delegate_) { binding_handler_delegate_->OnWindowSizeChanged( view_properties_.width * current_scale_, From d5fe4688c4cb758bfa1db8305b5c867b85e42e5c Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 30 Oct 2023 21:11:19 +0900 Subject: [PATCH 156/178] wayland: fix wrong xdg_surface buffer size issue (#397) This change fixes https://github.com/sony/flutter-embedded-linux/issues/396. Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/window/elinux_window_wayland.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 12c682c9..f0e9e254 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -78,16 +78,16 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { ELINUX_LOG(TRACE) << "xdg_surface_listener.configure"; auto self = reinterpret_cast(data); + constexpr int32_t x = 0; + int32_t y = 0; + auto width = self->view_properties_.width; + auto height = self->view_properties_.height; + if (self->window_decorations_) { // Shift the window position to the bottom to show decoration // even when the window is displayed in the upper left corner // of the screen - constexpr int32_t x = 0; - int32_t y = 0; y = -self->window_decorations_->Height(); - - auto width = self->view_properties_.width; - auto height = self->view_properties_.height; if (!self->maximised_) { height -= y; } @@ -96,9 +96,8 @@ const xdg_surface_listener ELinuxWindowWayland::kXdgSurfaceListener = { if (self->display_max_height_ > 0) { height = std::min(height, self->display_max_height_); } - - xdg_surface_set_window_geometry(xdg_surface, x, y, width, height); } + xdg_surface_set_window_geometry(xdg_surface, x, y, width, height); xdg_surface_ack_configure(xdg_surface, serial); if (self->wait_for_configure_) { From 1902050004452cb90d8d3d92489c6324e3c6e327 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 4 Nov 2023 20:32:00 +0900 Subject: [PATCH 157/178] embedder: merge embedder.h from flutter/engine (#394) Merged from https://github.com/flutter/engine/commit/f358bde6ce0e54bd5eb5fc6e2910d291b7578548 Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 137 +++++++++++++++++- 1 file changed, 134 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index a1e9036b..cfef518d 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -25,9 +25,9 @@ // - Function signatures (names, argument counts, argument order, and argument // type) cannot change. // - The core behavior of existing functions cannot change. -// - Instead of nesting structures by value within another structure, prefer -// nesting by pointer. This ensures that adding members to the nested struct -// does not break the ABI of the parent struct. +// - Instead of nesting structures by value within another structure/union, +// prefer nesting by pointer. This ensures that adding members to the nested +// struct does not break the ABI of the parent struct/union. // - Instead of array of structures, prefer array of pointers to structures. // This ensures that array indexing does not break if members are added // to the structure. @@ -757,6 +757,11 @@ typedef struct { /// The queue family index of the VkQueue supplied in the next field. uint32_t queue_family_index; /// VkQueue handle. + /// The queue should not be used without protection from a mutex to make sure + /// it is not used simultaneously with other threads. That mutex should match + /// the one injected via the |get_instance_proc_address_callback|. + /// There is a proposal to remove the need for the mutex at + /// https://github.com/flutter/flutter/issues/134573. FlutterVulkanQueueHandle queue; /// The number of instance extensions available for enumerating in the next /// field. @@ -780,6 +785,12 @@ typedef struct { /// For example: VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME const char** enabled_device_extensions; /// The callback invoked when resolving Vulkan function pointers. + /// At a bare minimum this should be used to swap out any calls that operate + /// on vkQueue's for threadsafe variants that obtain locks for their duration. + /// The functions to swap out are "vkQueueSubmit" and "vkQueueWaitIdle". An + /// example of how to do that can be found in the test + /// "EmbedderTest.CanSwapOutVulkanCalls" unit-test in + /// //shell/platform/embedder/tests/embedder_vk_unittests.cc. FlutterVulkanInstanceProcAddressCallback get_instance_proc_address_callback; /// The callback invoked when the engine requests a VkImage from the embedder /// for rendering the next frame. @@ -1064,6 +1075,57 @@ typedef int64_t FlutterPlatformViewIdentifier; FLUTTER_EXPORT extern const int32_t kFlutterSemanticsNodeIdBatchEnd; +// The enumeration of possible string attributes that affect how assistive +// technologies announce a string. +// +// See dart:ui's implementers of the StringAttribute abstract class. +typedef enum { + // Indicates the string should be announced character by character. + kSpellOut, + // Indicates the string should be announced using the specified locale. + kLocale, +} FlutterStringAttributeType; + +// Indicates the assistive technology should announce out the string character +// by character. +// +// See dart:ui's SpellOutStringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterSpellOutStringAttribute). + size_t struct_size; +} FlutterSpellOutStringAttribute; + +// Indicates the assistive technology should announce the string using the +// specified locale. +// +// See dart:ui's LocaleStringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterLocaleStringAttribute). + size_t struct_size; + // The locale of this attribute. + const char* locale; +} FlutterLocaleStringAttribute; + +// Indicates how the assistive technology should treat the string. +// +// See dart:ui's StringAttribute. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterStringAttribute). + size_t struct_size; + // The position this attribute starts. + size_t start; + // The next position after the attribute ends. + size_t end; + /// The type of the attribute described by the subsequent union. + FlutterStringAttributeType type; + union { + // Indicates the string should be announced character by character. + const FlutterSpellOutStringAttribute* spell_out; + // Indicates the string should be announced using the specified locale. + const FlutterLocaleStringAttribute* locale; + }; +} FlutterStringAttribute; + /// A node that represents some semantic data. /// /// The semantics tree is maintained during the semantics phase of the pipeline @@ -1215,6 +1277,31 @@ typedef struct { FlutterPlatformViewIdentifier platform_view_id; /// A textual tooltip attached to the node. const char* tooltip; + // The number of string attributes associated with the `label`. + size_t label_attribute_count; + // Array of string attributes associated with the `label`. + // Has length `label_attribute_count`. + const FlutterStringAttribute** label_attributes; + // The number of string attributes associated with the `hint`. + size_t hint_attribute_count; + // Array of string attributes associated with the `hint`. + // Has length `hint_attribute_count`. + const FlutterStringAttribute** hint_attributes; + // The number of string attributes associated with the `value`. + size_t value_attribute_count; + // Array of string attributes associated with the `value`. + // Has length `value_attribute_count`. + const FlutterStringAttribute** value_attributes; + // The number of string attributes associated with the `increased_value`. + size_t increased_value_attribute_count; + // Array of string attributes associated with the `increased_value`. + // Has length `increased_value_attribute_count`. + const FlutterStringAttribute** increased_value_attributes; + // The number of string attributes associated with the `decreased_value`. + size_t decreased_value_attribute_count; + // Array of string attributes associated with the `decreased_value`. + // Has length `decreased_value_attribute_count`. + const FlutterStringAttribute** decreased_value_attributes; } FlutterSemanticsNode2; /// `FlutterSemanticsCustomAction` ID used as a sentinel to signal the end of a @@ -1326,6 +1413,20 @@ typedef void (*FlutterUpdateSemanticsCallback2)( const FlutterSemanticsUpdate2* /* semantics update */, void* /* user data*/); +/// An update to whether a message channel has a listener set or not. +typedef struct { + // The size of the struct. Must be sizeof(FlutterChannelUpdate). + size_t struct_size; + /// The name of the channel. + const char* channel; + /// True if a listener has been set, false if one has been cleared. + bool listening; +} FlutterChannelUpdate; + +typedef void (*FlutterChannelUpdateCallback)( + const FlutterChannelUpdate* /* channel update */, + void* /* user data */); + typedef struct _FlutterTaskRunner* FlutterTaskRunner; typedef struct { @@ -1573,6 +1674,27 @@ typedef enum { kFlutterLayerContentTypePlatformView, } FlutterLayerContentType; +/// A region represented by a collection of non-overlapping rectangles. +typedef struct { + /// The size of this struct. Must be sizeof(FlutterRegion). + size_t struct_size; + /// Number of rectangles in the region. + size_t rects_count; + /// The rectangles that make up the region. + FlutterRect* rects; +} FlutterRegion; + +/// Contains additional information about the backing store provided +/// during presentation to the embedder. +typedef struct { + size_t struct_size; + + /// The area of the backing store that contains Flutter contents. Pixels + /// outside of this area are transparent and the embedder may choose not + /// to render them. Coordinates are in physical pixels. + FlutterRegion* paint_region; +} FlutterBackingStorePresentInfo; + typedef struct { /// This size of this struct. Must be sizeof(FlutterLayer). size_t struct_size; @@ -1592,6 +1714,10 @@ typedef struct { FlutterPoint offset; /// The size of the layer (in physical pixels). FlutterSize size; + + /// Extra information for the backing store that the embedder may + /// use during presentation. + FlutterBackingStorePresentInfo* backing_store_present_info; } FlutterLayer; typedef bool (*FlutterBackingStoreCreateCallback)( @@ -2118,6 +2244,11 @@ typedef struct { /// and `update_semantics_callback2` may be provided; the others must be set /// to null. FlutterUpdateSemanticsCallback2 update_semantics_callback2; + + /// The callback invoked by the engine in response to a channel listener + /// being registered on the framework side. The callback is invoked from + /// a task posted to the platform thread. + FlutterChannelUpdateCallback channel_update_callback; } FlutterProjectArgs; #ifndef FLUTTER_ENGINE_NO_PROTOTYPES From bd5e4b67aad84d42c42aa7222fde33274baa08bf Mon Sep 17 00:00:00 2001 From: Makoto Sato <51475851+makotosato-at@users.noreply.github.com> Date: Thu, 9 Nov 2023 18:35:25 +0900 Subject: [PATCH 158/178] egl_stream: add cast to EGLAttrib (#400) Signed-off-by: Makoto Sato --- .../shell/platform/linux_embedded/surface/context_egl_stream.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc index 61d699f7..4a13f498 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl_stream.cc @@ -28,7 +28,7 @@ std::unique_ptr ContextEglStream::CreateOnscreenSurface( EGLOutputLayerEXT layer; EGLAttrib layer_attribs[] = { // clang-format off - EGL_DRM_PLANE_EXT, static_cast(window)->PlaneId(), + EGL_DRM_PLANE_EXT, static_cast(static_cast(window)->PlaneId()), EGL_NONE // clang-format on }; From 6b14cf0887fef389a2df23336947245e6d2ce10a Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Thu, 16 Nov 2023 19:35:02 +0900 Subject: [PATCH 159/178] Revert "WAR: temporarily disable partial repaints (#388)" (#401) This reverts commit 820ee198b3a888cbe9dd06a9fffb3930c7166fc0. --- .../platform/linux_embedded/surface/elinux_egl_surface.cc | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc index 576fcf6e..914ab736 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/elinux_egl_surface.cc @@ -174,11 +174,6 @@ void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id, 0, 0, static_cast(width_px_), static_cast(height_px_)}; existing_damage->damage = existing_damage_map_[fbo_id]; - // Temporarily disabled partial repaints due to - // https://github.com/sony/flutter-embedded-linux/issues/334. Once - // https://github.com/flutter/engine/pull/45611 was merged and propagated to - // the stable channel, this will be lifted up. -#if 0 if (age > 1) { --age; // join up to (age - 1) last rects from damage history @@ -202,7 +197,6 @@ void ELinuxEGLSurface::PopulateExistingDamage(const intptr_t fbo_id, } } } -#endif } // Auxiliary function used to transform a FlutterRect into the format that is From c22c4ff9ebd7b79e7e8a951e9831fda2bbf8a281 Mon Sep 17 00:00:00 2001 From: Fredrik Magnussen Date: Tue, 28 Nov 2023 14:38:55 +0100 Subject: [PATCH 160/178] Fixes issue #403: Segmentation fault when updating destroyed mouse pointer (#404) * Fixes issue #403: Segmentation fault when updating destroyed mouse pointer. Signed-off-by: fredrmag --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index f0e9e254..067c1f87 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -1481,6 +1481,9 @@ void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { if (view_properties_.use_mouse_cursor) { + if (!wl_pointer_) { + return; + } if (cursor_name.compare(cursor_info_.cursor_name) == 0) { return; } From eec5bc9917e13c6ee78faa28c06a98c6ca38c7a9 Mon Sep 17 00:00:00 2001 From: Makoto Sato <51475851+makotosato-at@users.noreply.github.com> Date: Mon, 11 Dec 2023 15:55:37 +0900 Subject: [PATCH 161/178] wayland: fix wp_presentation_feedback leak (#405) Signed-off-by: Makoto Sato --- .../platform/linux_embedded/window/elinux_window_wayland.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 067c1f87..fa147f6e 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -233,6 +233,7 @@ const wp_presentation_feedback_listener self->window_decorations_->Draw(); } + wp_presentation_feedback_destroy(wp_presentation_feedback); wp_presentation_feedback_add_listener( ::wp_presentation_feedback(self->wp_presentation_, self->native_window_->Surface()), @@ -249,6 +250,7 @@ const wp_presentation_feedback_listener self->window_decorations_->Draw(); } + wp_presentation_feedback_destroy(wp_presentation_feedback); wp_presentation_feedback_add_listener( ::wp_presentation_feedback(self->wp_presentation_, self->native_window_->Surface()), From 28de1eb56d6afff0ae7bdc68787a0ae620ccc51d Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Wed, 13 Dec 2023 06:39:31 +0900 Subject: [PATCH 162/178] WAR: disable USE_DIRTY_REGION_MANAGEMENT option (#406) This change disables 'dirty-region-management' feature to prevent a fricker issue. See #334 for the details. Signed-off-by: Hidenori Matsubayashi --- CMakeLists.txt | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 19abd447..0150694c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,13 @@ project("flutter_elinux" LANGUAGES CXX C) # Build options. option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) -option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" ON) +# Disabled USE_DIRTY_REGION_MANAGEMENT due flicker issue. +# See https://github.com/sony/flutter-embedded-linux/issues/334 +option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" OFF) option(USE_GLES3 "Use OpenGL ES3 (default is OpenGL ES2)" OFF) option(ENABLE_EGL_ALPHA_COMPONENT_OF_COLOR_BUFFER "Enable alpha component of the EGL color buffer" ON) -option(ENABLE_VSYNC "Enable embedder vsync" OFF) # todo: need to investigate https://github.com/sony/flutter-embedded-linux/pull/376 when enabling this option. + # todo: need to investigate https://github.com/sony/flutter-embedded-linux/pull/376 when enabling this option. +option(ENABLE_VSYNC "Enable embedder vsync" OFF) option(BUILD_ELINUX_SO "Build .so file of elinux embedder" OFF) option(ENABLE_ELINUX_EMBEDDER_LOG "Enable logger of eLinux embedder" ON) option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) From 185d73a596b7be5793f0febc0967f0e576cb8ce7 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Fri, 16 Feb 2024 20:05:56 +0900 Subject: [PATCH 163/178] embedder: merge embedder.h from flutter/engine (#408) Merged from https://github.com/flutter/engine/commits/3.19.0/shell/platform/embedder/embedder.h Signed-off-by: Hidenori Matsubayashi --- src/flutter/common/constants.h | 38 +++++++++++++++++++ .../shell/platform/embedder/embedder.h | 28 ++++++++++++-- .../embedder/embedder_struct_macros.h | 6 +-- .../linux_embedded/flutter_elinux_view.cc | 13 +++++++ 4 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 src/flutter/common/constants.h diff --git a/src/flutter/common/constants.h b/src/flutter/common/constants.h new file mode 100644 index 00000000..668aa4f6 --- /dev/null +++ b/src/flutter/common/constants.h @@ -0,0 +1,38 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_COMMON_CONSTANTS_H_ +#define FLUTTER_COMMON_CONSTANTS_H_ + +namespace flutter { +constexpr double kMegaByteSizeInBytes = (1 << 20); + +// The ID for the implicit view if the implicit view is enabled. +// +// The implicit view is a compatibility mechanism to help the transition from +// the older single-view APIs to the newer multi-view APIs. The two sets of APIs +// use different models for view management. The implicit view mechanism allows +// single-view APIs to operate a special view as if other views don't exist. +// +// In the regular multi-view model, all views should be created by +// `Shell::AddView` before being used, and removed by `Shell::RemoveView` to +// signify that they are gone. If a view is added or removed, the framework +// (`PlatformDispatcher`) will be notified. New view IDs are always unique, +// never reused. Operating a non-existing view is an error. +// +// The implicit view is another special view in addition to the "regular views" +// as above. The shell starts up having the implicit view, which has a fixed +// view ID of `kFlutterImplicitViewId` and is available throughout the lifetime +// of the shell. `Shell::AddView` or `RemoveView` must not be called for this +// view. Even when the window that shows the view is closed, the framework is +// unaware and might continue rendering into or operating this view. +// +// The single-view APIs, which are APIs that do not specify view IDs, operate +// the implicit view. The multi-view APIs can operate all views, including the +// implicit view if the target ID is `kFlutterImplicitViewId`, unless specified +// otherwise. +constexpr int64_t kFlutterImplicitViewId = 0; +} // namespace flutter + +#endif // FLUTTER_COMMON_CONSTANTS_H_ diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index cfef518d..d8adf5e7 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_EMBEDDER_H_ -#define FLUTTER_EMBEDDER_H_ +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_ #include #include @@ -266,6 +266,12 @@ typedef enum { typedef struct _FlutterEngine* FLUTTER_API_SYMBOL(FlutterEngine); +/// Unique identifier for views. +/// +/// View IDs are generated by the embedder and are +/// opaque to the engine; the engine does not interpret view IDs in any way. +typedef int64_t FlutterViewId; + typedef struct { /// horizontal scale factor double scaleX; @@ -961,6 +967,8 @@ typedef struct { double scale; /// The rotation of the pan/zoom in radians, where 0.0 is the initial angle. double rotation; + /// The identifier of the view that received the pointer event. + FlutterViewId view_id; } FlutterPointerEvent; typedef enum { @@ -969,6 +977,14 @@ typedef enum { kFlutterKeyEventTypeRepeat, } FlutterKeyEventType; +typedef enum { + kFlutterKeyEventDeviceTypeKeyboard = 1, + kFlutterKeyEventDeviceTypeDirectionalPad, + kFlutterKeyEventDeviceTypeGamepad, + kFlutterKeyEventDeviceTypeJoystick, + kFlutterKeyEventDeviceTypeHdmi, +} FlutterKeyEventDeviceType; + /// A structure to represent a key event. /// /// Sending `FlutterKeyEvent` via `FlutterEngineSendKeyEvent` results in a @@ -1032,6 +1048,8 @@ typedef struct { /// An event being synthesized means that the `timestamp` might greatly /// deviate from the actual time when the event occurs physically. bool synthesized; + /// The source device for the key event. + FlutterKeyEventDeviceType device_type; } FlutterKeyEvent; typedef void (*FlutterKeyEventCallback)(bool /* handled */, @@ -2253,6 +2271,8 @@ typedef struct { #ifndef FLUTTER_ENGINE_NO_PROTOTYPES +// NOLINTBEGIN(google-objc-function-naming) + //------------------------------------------------------------------------------ /// @brief Creates the necessary data structures to launch a Flutter Dart /// application in AOT mode. The data may only be collected after @@ -3124,8 +3144,10 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineGetProcAddresses( FlutterEngineProcTable* table); +// NOLINTEND(google-objc-function-naming) + #if defined(__cplusplus) } // extern "C" #endif -#endif // FLUTTER_EMBEDDER_H_ +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_H_ diff --git a/src/flutter/shell/platform/embedder/embedder_struct_macros.h b/src/flutter/shell/platform/embedder/embedder_struct_macros.h index 8bd30979..483fd2ab 100644 --- a/src/flutter/shell/platform/embedder/embedder_struct_macros.h +++ b/src/flutter/shell/platform/embedder/embedder_struct_macros.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ -#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STRUCT_MACROS_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STRUCT_MACROS_H_ #include @@ -29,4 +29,4 @@ #define SAFE_EXISTS_ONE_OF(pointer, member1, member2) \ (SAFE_EXISTS(pointer, member1) != SAFE_EXISTS(pointer, member2)) -#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_SAFE_ACCESS_H_ +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STRUCT_MACROS_H_ diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc index 68d0bac4..9775d200 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.cc @@ -7,6 +7,7 @@ #include #include +#include "flutter/common/constants.h" #include "flutter/shell/platform/linux_embedded/logger.h" namespace flutter { @@ -165,6 +166,9 @@ void FlutterELinuxView::OnTouchDown(uint32_t time, .scroll_delta_y = 0, .device_kind = kFlutterPointerDeviceKindTouch, .buttons = 0, + // TODO: Use the correct view ID for pointer events once the + // eLinux embedder supports multiple views. + .view_id = flutter::kFlutterImplicitViewId, }; engine_->SendPointerEvent(event); } @@ -203,6 +207,9 @@ void FlutterELinuxView::OnTouchUp(uint32_t time, int32_t id) { .scroll_delta_y = 0, .device_kind = kFlutterPointerDeviceKindTouch, .buttons = 0, + // TODO: Use the correct view ID for pointer events once the + // eLinux embedder supports multiple views. + .view_id = flutter::kFlutterImplicitViewId, }; engine_->SendPointerEvent(event); } @@ -247,6 +254,9 @@ void FlutterELinuxView::OnTouchMotion(uint32_t time, .scroll_delta_y = 0, .device_kind = kFlutterPointerDeviceKindTouch, .buttons = 0, + // TODO: Use the correct view ID for pointer events once the + // eLinux embedder supports multiple views. + .view_id = flutter::kFlutterImplicitViewId, }; engine_->SendPointerEvent(event); } @@ -424,6 +434,9 @@ void FlutterELinuxView::SendPointerEventWithData( FlutterPointerEvent event = event_data; event.device_kind = kFlutterPointerDeviceKindMouse; event.buttons = mouse_state_.buttons; + // TODO: Use the correct view ID for pointer events once the + // eLinux embedder supports multiple views. + event.view_id = flutter::kFlutterImplicitViewId; // Set metadata that's always the same regardless of the event. event.struct_size = sizeof(event); From a73994f40470adafec1c24570926ff18079c0f26 Mon Sep 17 00:00:00 2001 From: Makoto Sato <51475851+makotosato-at@users.noreply.github.com> Date: Thu, 28 Mar 2024 16:39:49 +0900 Subject: [PATCH 164/178] wayland: fix screen rotation issue on Wayland (#411) Signed-off-by: Makoto Sato --- .../linux_embedded/window/elinux_window_wayland.cc | 8 +++++++- .../linux_embedded/window/elinux_window_wayland.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index fa147f6e..78220b1d 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -628,6 +628,8 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { const char* model, int32_t output_transform) -> void { ELINUX_LOG(TRACE) << "wl_output_listener.geometry"; + auto self = reinterpret_cast(data); + self->transform_ = output_transform; }, .mode = [](void* data, wl_output* wl_output, @@ -639,7 +641,11 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { auto self = reinterpret_cast(data); if (flags & WL_OUTPUT_MODE_CURRENT) { - if (self->current_rotation_ == 90 || self->current_rotation_ == 270) { + if (self->current_rotation_ == 90 || self->current_rotation_ == 270 || + self->transform_ == WL_OUTPUT_TRANSFORM_90 || + self->transform_ == WL_OUTPUT_TRANSFORM_270 || + self->transform_ == WL_OUTPUT_TRANSFORM_FLIPPED_90 || + self->transform_ == WL_OUTPUT_TRANSFORM_FLIPPED_270) { std::swap(width, height); } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index 2d1343d5..dcfe1bb4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -153,6 +153,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { bool maximised_; uint32_t last_frame_time_; bool enable_impeller_ = false; + int32_t transform_ = WL_OUTPUT_TRANSFORM_NORMAL; // Indicates that exists a keyboard show request from Flutter Engine. bool is_requested_show_virtual_keyboard_; From f296db8ed6c75cf5b0bb5c1bc1414038f43a1ef3 Mon Sep 17 00:00:00 2001 From: Sebastian Urban Date: Wed, 8 May 2024 23:09:02 +0200 Subject: [PATCH 165/178] wayland: text input protocol uses UTF-8 encoding (#415) * wayland: text input protocol uses UTF-8 encoding The Wayland text input protocol sends text in UTF-8 encoding, but the Flutter TextInputModel expects UTF-16. This adds the missing conversion from UTF-8 to UTF-16. Signed-off-by: Sebastian Urban * Add Sebastian Urban to AUTHORS --------- Signed-off-by: Sebastian Urban --- AUTHORS | 1 + .../window/elinux_window_wayland.cc | 17 ++++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/AUTHORS b/AUTHORS index d82960b5..98613147 100644 --- a/AUTHORS +++ b/AUTHORS @@ -13,3 +13,4 @@ Makoto Sato (makoto.sato@atmark-techno.com) Yunhao Tian (t123yh@outlook.com) Luke Howard Stanislav Shmarov +Sebastian Urban diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 78220b1d..debed756 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -13,6 +13,8 @@ #include #include #include +#include +#include #include #include "flutter/shell/platform/linux_embedded/logger.h" @@ -748,7 +750,10 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { - self->binding_handler_delegate_->OnVirtualKey(text[0]); + std::wstring_convert, char16_t> + utf8_converter; + std::u16string utf16_text = utf8_converter.from_bytes(text); + self->binding_handler_delegate_->OnVirtualKey(utf16_text[0]); } if (self->zwp_text_input_v1_) { zwp_text_input_v1_reset(self->zwp_text_input_v1_); @@ -779,7 +784,10 @@ const zwp_text_input_v1_listener ELinuxWindowWayland::kZwpTextInputV1Listener = // commit_string is notified only when the space key is pressed. auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { - self->binding_handler_delegate_->OnVirtualKey(text[0]); + std::wstring_convert, char16_t> + utf8_converter; + std::u16string utf16_text = utf8_converter.from_bytes(text); + self->binding_handler_delegate_->OnVirtualKey(utf16_text[0]); } // If there is no input data, the backspace key cannot be used, // so set dummy data. @@ -895,7 +903,10 @@ const zwp_text_input_v3_listener ELinuxWindowWayland::kZwpTextInputV3Listener = auto self = reinterpret_cast(data); if (self->binding_handler_delegate_ && strlen(text)) { - self->binding_handler_delegate_->OnVirtualKey(text[0]); + std::wstring_convert, char16_t> + utf8_converter; + std::u16string utf16_text = utf8_converter.from_bytes(text); + self->binding_handler_delegate_->OnVirtualKey(utf16_text[0]); } }, .delete_surrounding_text = [](void* data, From 97438621dbd6b5899859c052ad2ef55843373de4 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Sat, 18 May 2024 06:15:47 +0900 Subject: [PATCH 166/178] embedder: merge embedder.h from flutter/engine (#416) Merged from https://github.com/flutter/engine/commits/3.22.0/shell/platform/embedder/embedder.h Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 116 +++++++++++++++++- 1 file changed, 113 insertions(+), 3 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index d8adf5e7..d26e2215 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -831,6 +831,53 @@ typedef struct { }; } FlutterRendererConfig; +typedef struct { + /// The size of this struct. + /// Must be sizeof(FlutterRemoveViewResult). + size_t struct_size; + + /// True if the remove view operation succeeded. + bool removed; + + /// The |FlutterRemoveViewInfo.user_data|. + void* user_data; +} FlutterRemoveViewResult; + +/// The callback invoked by the engine when the engine has attempted to remove +/// a view. +/// +/// The |FlutterRemoveViewResult| will be deallocated once the callback returns. +typedef void (*FlutterRemoveViewCallback)( + const FlutterRemoveViewResult* /* result */); + +typedef struct { + /// The size of this struct. + /// Must be sizeof(FlutterRemoveViewInfo). + size_t struct_size; + + /// The identifier for the view to remove. + /// + /// The implicit view cannot be removed if it is enabled. + FlutterViewId view_id; + + /// A baton that is not interpreted by the engine in any way. + /// It will be given back to the embedder in |remove_view_callback|. + /// Embedder resources may be associated with this baton. + void* user_data; + + /// Called once the engine has attempted to remove the view. + /// This callback is required. + /// + /// The embedder must not destroy the underlying surface until the callback is + /// invoked with a `removed` value of `true`. + /// + /// This callback is invoked on an internal engine managed thread. + /// Embedders must re-thread if necessary. + /// + /// The |result| argument will be deallocated when the callback returns. + FlutterRemoveViewCallback remove_view_callback; +} FlutterRemoveViewInfo; + /// Display refers to a graphics hardware system consisting of a framebuffer, /// typically a monitor or a screen. This ID is unique per display and is /// stable until the Flutter application restarts. @@ -859,6 +906,8 @@ typedef struct { double physical_view_inset_left; /// The identifier of the display the view is rendering on. FlutterEngineDisplayId display_id; + /// The view that this event is describing. + int64_t view_id; } FlutterWindowMetricsEvent; /// The phase of the pointer event. @@ -1736,8 +1785,30 @@ typedef struct { /// Extra information for the backing store that the embedder may /// use during presentation. FlutterBackingStorePresentInfo* backing_store_present_info; + + // Time in nanoseconds at which this frame is scheduled to be presented. 0 if + // not known. See FlutterEngineGetCurrentTime(). + uint64_t presentation_time; } FlutterLayer; +typedef struct { + /// The size of this struct. + /// Must be sizeof(FlutterPresentViewInfo). + size_t struct_size; + + /// The identifier of the target view. + FlutterViewId view_id; + + /// The layers that should be composited onto the view. + const FlutterLayer** layers; + + /// The count of layers. + size_t layers_count; + + /// The |FlutterCompositor.user_data|. + void* user_data; +} FlutterPresentViewInfo; + typedef bool (*FlutterBackingStoreCreateCallback)( const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out, @@ -1751,13 +1822,20 @@ typedef bool (*FlutterLayersPresentCallback)(const FlutterLayer** layers, size_t layers_count, void* user_data); +/// The callback invoked when the embedder should present to a view. +/// +/// The |FlutterPresentViewInfo| will be deallocated once the callback returns. +typedef bool (*FlutterPresentViewCallback)( + const FlutterPresentViewInfo* /* present info */); + typedef struct { /// This size of this struct. Must be sizeof(FlutterCompositor). size_t struct_size; /// A baton that in not interpreted by the engine in any way. If it passed /// back to the embedder in `FlutterCompositor.create_backing_store_callback`, - /// `FlutterCompositor.collect_backing_store_callback` and - /// `FlutterCompositor.present_layers_callback` + /// `FlutterCompositor.collect_backing_store_callback`, + /// `FlutterCompositor.present_layers_callback`, and + /// `FlutterCompositor.present_view_callback`. void* user_data; /// A callback invoked by the engine to obtain a backing store for a specific /// `FlutterLayer`. @@ -1771,10 +1849,23 @@ typedef struct { /// embedder may collect any resources associated with the backing store. FlutterBackingStoreCollectCallback collect_backing_store_callback; /// Callback invoked by the engine to composite the contents of each layer - /// onto the screen. + /// onto the implicit view. + /// + /// DEPRECATED: Use |present_view_callback| to support multiple views. + /// + /// Only one of `present_layers_callback` and `present_view_callback` may be + /// provided. Providing both is an error and engine initialization will + /// terminate. FlutterLayersPresentCallback present_layers_callback; /// Avoid caching backing stores provided by this compositor. bool avoid_backing_store_cache; + /// Callback invoked by the engine to composite the contents of each layer + /// onto the specified view. + /// + /// Only one of `present_layers_callback` and `present_view_callback` may be + /// provided. Providing both is an error and engine initialization will + /// terminate. + FlutterPresentViewCallback present_view_callback; } FlutterCompositor; typedef struct { @@ -2414,6 +2505,25 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineRunInitialized( FLUTTER_API_SYMBOL(FlutterEngine) engine); +//------------------------------------------------------------------------------ +/// @brief Removes a view. +/// +/// This is an asynchronous operation. The view's resources must not +/// be cleaned up until the |remove_view_callback| is invoked with +/// a |removed| value of `true`. +/// +/// @param[in] engine A running engine instance. +/// @param[in] info The remove view arguments. This can be deallocated +/// once |FlutterEngineRemoveView| returns, before +/// |remove_view_callback| is invoked. +/// +/// @return The result of *starting* the asynchronous operation. If +/// `kSuccess`, the |remove_view_callback| will be invoked. +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineRemoveView(FLUTTER_API_SYMBOL(FlutterEngine) + engine, + const FlutterRemoveViewInfo* info); + FLUTTER_EXPORT FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, From 434d509ffefdd1b2ab023ef1ccad7bb4048bd990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93mar=20H=C3=B6gni=20Gu=C3=B0marsson?= Date: Thu, 23 May 2024 23:58:38 +0000 Subject: [PATCH 167/178] Multiple seats (#417) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Added the ability to have multiple seats, this allows f.e. weston screenshare and a local touch input to work at the same time. Signed-off-by: Ómar Högni Guðmarsson --- AUTHORS | 1 + .../window/elinux_window_wayland.cc | 171 ++++++++++-------- .../window/elinux_window_wayland.h | 12 +- 3 files changed, 107 insertions(+), 77 deletions(-) diff --git a/AUTHORS b/AUTHORS index 98613147..151ed913 100644 --- a/AUTHORS +++ b/AUTHORS @@ -14,3 +14,4 @@ Yunhao Tian (t123yh@outlook.com) Luke Howard Stanislav Shmarov Sebastian Urban +Ómar Högni Guðmarsson diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index debed756..33848c83 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -289,29 +289,32 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { ELINUX_LOG(TRACE) << "wl_seat_listener.capabilities"; auto self = reinterpret_cast(data); - if ((caps & WL_SEAT_CAPABILITY_POINTER) && !self->wl_pointer_) { - self->wl_pointer_ = wl_seat_get_pointer(seat); - wl_pointer_add_listener(self->wl_pointer_, &kWlPointerListener, self); - } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && self->wl_pointer_) { - wl_pointer_destroy(self->wl_pointer_); - self->wl_pointer_ = nullptr; + auto [iter_inputs, _] = + self->seat_inputs_map_.emplace(seat, seat_inputs()); + auto& inputs = iter_inputs->second; + + if ((caps & WL_SEAT_CAPABILITY_POINTER) && !inputs.pointer) { + inputs.pointer = wl_seat_get_pointer(seat); + wl_pointer_add_listener(inputs.pointer, &kWlPointerListener, self); + } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && inputs.pointer) { + wl_pointer_destroy(inputs.pointer); + inputs.pointer = nullptr; } - if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !self->wl_touch_) { - self->wl_touch_ = wl_seat_get_touch(seat); - wl_touch_add_listener(self->wl_touch_, &kWlTouchListener, self); - } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && self->wl_touch_) { - wl_touch_destroy(self->wl_touch_); - self->wl_touch_ = nullptr; + if ((caps & WL_SEAT_CAPABILITY_TOUCH) && !inputs.touch) { + inputs.touch = wl_seat_get_touch(seat); + wl_touch_add_listener(inputs.touch, &kWlTouchListener, self); + } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && inputs.touch) { + wl_touch_destroy(inputs.touch); + inputs.touch = nullptr; } - if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !self->wl_keyboard_) { - self->wl_keyboard_ = wl_seat_get_keyboard(seat); - wl_keyboard_add_listener(self->wl_keyboard_, &kWlKeyboardListener, - self); - } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && self->wl_keyboard_) { - wl_keyboard_destroy(self->wl_keyboard_); - self->wl_keyboard_ = nullptr; + if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !inputs.keyboard) { + inputs.keyboard = wl_seat_get_keyboard(seat); + wl_keyboard_add_listener(inputs.keyboard, &kWlKeyboardListener, self); + } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && inputs.keyboard) { + wl_keyboard_destroy(inputs.keyboard); + inputs.keyboard = nullptr; } }, .name = [](void* data, struct wl_seat* wl_seat, const char* name) -> void { @@ -333,7 +336,7 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->serial_ = serial; if (self->view_properties_.use_mouse_cursor) { - self->cursor_info_.pointer = self->wl_pointer_; + self->cursor_info_.pointer = wl_pointer; self->cursor_info_.serial = serial; } @@ -399,7 +402,14 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->window_decorations_->IsMatched( self->wl_current_surface_, WindowDecoration::DecorationType::TITLE_BAR)) { - xdg_toplevel_move(self->xdg_toplevel_, self->wl_seat_, serial); + for (auto& [seat, inputs] : self->seat_inputs_map_) { + if (inputs.pointer == pointer) { + xdg_toplevel_move(self->xdg_toplevel_, seat, serial); + return; + } + } + ELINUX_LOG(TRACE) + << "Failed to find the pointer for moving the window"; return; } @@ -1043,11 +1053,8 @@ ELinuxWindowWayland::ELinuxWindowWayland( wl_compositor_(nullptr), wl_subcompositor_(nullptr), wl_current_surface_(nullptr), - wl_seat_(nullptr), - wl_pointer_(nullptr), - wl_touch_(nullptr), - wl_keyboard_(nullptr), wl_shm_(nullptr), + seat_inputs_map_(), wl_data_device_manager_(nullptr), wl_data_device_(nullptr), wl_data_offer_(nullptr), @@ -1087,34 +1094,37 @@ ELinuxWindowWayland::ELinuxWindowWayland( wl_registry_add_listener(wl_registry_, &kWlRegistryListener, this); wl_display_roundtrip(wl_display_); - if (wl_data_device_manager_ && wl_seat_) { - wl_data_device_ = wl_data_device_manager_get_data_device( - wl_data_device_manager_, wl_seat_); - wl_data_device_add_listener(wl_data_device_, &kWlDataDeviceListener, this); - } + for (auto& [seat, _] : seat_inputs_map_) { + if (wl_data_device_manager_ && seat) { + wl_data_device_ = + wl_data_device_manager_get_data_device(wl_data_device_manager_, seat); + wl_data_device_add_listener(wl_data_device_, &kWlDataDeviceListener, + this); + } - // Setup text-input protocol for onscreen keyboard inputs. - { - if (zwp_text_input_manager_v3_ && wl_seat_) { - zwp_text_input_v3_ = zwp_text_input_manager_v3_get_text_input( - zwp_text_input_manager_v3_, wl_seat_); - if (!zwp_text_input_v3_) { - ELINUX_LOG(ERROR) << "Failed to create the text input manager v3."; - return; - } - zwp_text_input_v3_add_listener(zwp_text_input_v3_, - &kZwpTextInputV3Listener, this); - } else if (zwp_text_input_manager_v1_) { - zwp_text_input_v1_ = zwp_text_input_manager_v1_create_text_input( - zwp_text_input_manager_v1_); - if (!zwp_text_input_v1_) { - ELINUX_LOG(ERROR) << "Failed to create text input manager v1."; - return; + // Setup text-input protocol for onscreen keyboard inputs. + { + if (zwp_text_input_manager_v3_ && seat) { + zwp_text_input_v3_ = zwp_text_input_manager_v3_get_text_input( + zwp_text_input_manager_v3_, seat); + if (!zwp_text_input_v3_) { + ELINUX_LOG(ERROR) << "Failed to create the text input manager v3."; + return; + } + zwp_text_input_v3_add_listener(zwp_text_input_v3_, + &kZwpTextInputV3Listener, this); + } else if (zwp_text_input_manager_v1_) { + zwp_text_input_v1_ = zwp_text_input_manager_v1_create_text_input( + zwp_text_input_manager_v1_); + if (!zwp_text_input_v1_) { + ELINUX_LOG(ERROR) << "Failed to create text input manager v1."; + return; + } + zwp_text_input_v1_add_listener(zwp_text_input_v1_, + &kZwpTextInputV1Listener, this); + } else { + // do nothing. } - zwp_text_input_v1_add_listener(zwp_text_input_v1_, - &kZwpTextInputV1Listener, this); - } else { - // do nothing. } } @@ -1190,26 +1200,29 @@ ELinuxWindowWayland::~ELinuxWindowWayland() { wl_data_device_manager_ = nullptr; } - if (wl_pointer_) { - wl_pointer_destroy(wl_pointer_); - wl_pointer_ = nullptr; - } + for (auto& [seat, inputs] : seat_inputs_map_) { + if (inputs.pointer) { + wl_pointer_destroy(inputs.pointer); + inputs.pointer = nullptr; + } - if (wl_touch_) { - wl_touch_destroy(wl_touch_); - wl_touch_ = nullptr; - } + if (inputs.touch) { + wl_touch_destroy(inputs.touch); + inputs.touch = nullptr; + } - if (wl_keyboard_) { - wl_keyboard_destroy(wl_keyboard_); - wl_keyboard_ = nullptr; - } + if (inputs.keyboard) { + wl_keyboard_destroy(inputs.keyboard); + inputs.keyboard = nullptr; + } - if (wl_seat_) { - wl_seat_destroy(wl_seat_); - wl_seat_ = nullptr; + if (seat) { + wl_seat_destroy(seat); + } } + seat_inputs_map_.clear(); + if (wl_output_) { wl_output_destroy(wl_output_); wl_output_ = nullptr; @@ -1486,7 +1499,7 @@ void ELinuxWindowWayland::DestroyRenderSurface() { void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { // Not supported virtual keyboard. - if (!(zwp_text_input_v1_ || zwp_text_input_v3_) || !wl_seat_) { + if (!(zwp_text_input_v1_ || zwp_text_input_v3_) || seat_inputs_map_.empty()) { return; } @@ -1500,7 +1513,14 @@ void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { if (view_properties_.use_mouse_cursor) { - if (!wl_pointer_) { + wl_pointer* pointer = nullptr; + for (auto& [_, inputs] : seat_inputs_map_) { + if (inputs.pointer != nullptr) { + pointer = inputs.pointer; + break; + } + } + if (!pointer) { return; } if (cursor_name.compare(cursor_info_.cursor_name) == 0) { @@ -1619,9 +1639,12 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, if (!strcmp(interface, wl_seat_interface.name)) { constexpr uint32_t kMaxVersion = 4; - wl_seat_ = static_cast(wl_registry_bind( - wl_registry, name, &wl_seat_interface, std::min(kMaxVersion, version))); - wl_seat_add_listener(wl_seat_, &kWlSeatListener, this); + auto [inserted, _] = + seat_inputs_map_.emplace(static_cast(wl_registry_bind( + wl_registry, name, &wl_seat_interface, + std::min(kMaxVersion, version))), + seat_inputs()); + wl_seat_add_listener(inserted->first, &kWlSeatListener, this); return; } @@ -1826,7 +1849,8 @@ void ELinuxWindowWayland::ShowVirtualKeyboard() { } else { if (native_window_) { zwp_text_input_v1_show_input_panel(zwp_text_input_v1_); - zwp_text_input_v1_activate(zwp_text_input_v1_, wl_seat_, + zwp_text_input_v1_activate(zwp_text_input_v1_, + seat_inputs_map_.begin()->first, native_window_->Surface()); } } @@ -1837,7 +1861,8 @@ void ELinuxWindowWayland::DismissVirtualKeybaord() { zwp_text_input_v3_disable(zwp_text_input_v3_); zwp_text_input_v3_commit(zwp_text_input_v3_); } else { - zwp_text_input_v1_deactivate(zwp_text_input_v1_, wl_seat_); + zwp_text_input_v1_deactivate(zwp_text_input_v1_, + seat_inputs_map_.begin()->first); } } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index dcfe1bb4..a4e454c4 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -34,6 +34,13 @@ namespace { constexpr char kXcursorSizeEnvironmentKey[] = "XCURSOR_SIZE"; } // namespace +// Track input devices for each seat +struct seat_inputs { + wl_pointer* pointer = nullptr; + wl_touch* touch = nullptr; + wl_keyboard* keyboard = nullptr; +}; + class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { public: ELinuxWindowWayland(FlutterDesktopViewProperties view_properties); @@ -161,12 +168,9 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_display* wl_display_; wl_registry* wl_registry_; wl_compositor* wl_compositor_; - wl_seat* wl_seat_; wl_output* wl_output_; wl_shm* wl_shm_; - wl_pointer* wl_pointer_; - wl_touch* wl_touch_; - wl_keyboard* wl_keyboard_; + std::unordered_map seat_inputs_map_; wl_surface* wl_cursor_surface_; xdg_wm_base* xdg_wm_base_; xdg_surface* xdg_surface_; From d73e35a3be61fd20ab82e5ecd3e8bb69fd864196 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93mar=20H=C3=B6gni=20Gu=C3=B0marsson?= Date: Tue, 28 May 2024 14:11:13 +0000 Subject: [PATCH 168/178] wayland: Fix pointer not being drawn on second VNC connect. (#418) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use global_remove event to clean-up seat map. Signed-off-by: Ómar Högni Guðmarsson --- .../window/elinux_window_wayland.cc | 61 +++++++++++++------ .../window/elinux_window_wayland.h | 1 + 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 33848c83..5bd8e0c2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -289,15 +289,18 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { ELINUX_LOG(TRACE) << "wl_seat_listener.capabilities"; auto self = reinterpret_cast(data); - auto [iter_inputs, _] = - self->seat_inputs_map_.emplace(seat, seat_inputs()); - auto& inputs = iter_inputs->second; + auto seat_iter = self->seat_inputs_map_.find(seat); + if (seat_iter == self->seat_inputs_map_.end()) { + ELINUX_LOG(ERROR) << "Failed to find the seat"; + return; + } + auto& inputs = seat_iter->second; if ((caps & WL_SEAT_CAPABILITY_POINTER) && !inputs.pointer) { inputs.pointer = wl_seat_get_pointer(seat); wl_pointer_add_listener(inputs.pointer, &kWlPointerListener, self); } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && inputs.pointer) { - wl_pointer_destroy(inputs.pointer); + wl_pointer_release(inputs.pointer); inputs.pointer = nullptr; } @@ -305,7 +308,7 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { inputs.touch = wl_seat_get_touch(seat); wl_touch_add_listener(inputs.touch, &kWlTouchListener, self); } else if (!(caps & WL_SEAT_CAPABILITY_TOUCH) && inputs.touch) { - wl_touch_destroy(inputs.touch); + wl_touch_release(inputs.touch); inputs.touch = nullptr; } @@ -313,7 +316,7 @@ const wl_seat_listener ELinuxWindowWayland::kWlSeatListener = { inputs.keyboard = wl_seat_get_keyboard(seat); wl_keyboard_add_listener(inputs.keyboard, &kWlKeyboardListener, self); } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && inputs.keyboard) { - wl_keyboard_destroy(inputs.keyboard); + wl_keyboard_release(inputs.keyboard); inputs.keyboard = nullptr; } }, @@ -347,6 +350,11 @@ const wl_pointer_listener ELinuxWindowWayland::kWlPointerListener = { self->pointer_x_ = x_px; self->pointer_y_ = y_px; } + + // Force redraw even though it is the same cursor name + auto copy = self->cursor_info_.cursor_name; + self->cursor_info_.cursor_name.clear(); + self->UpdateFlutterCursor(copy); }, .leave = [](void* data, wl_pointer* pointer, @@ -1513,16 +1521,6 @@ void ELinuxWindowWayland::UpdateVirtualKeyboardStatus(const bool show) { void ELinuxWindowWayland::UpdateFlutterCursor(const std::string& cursor_name) { if (view_properties_.use_mouse_cursor) { - wl_pointer* pointer = nullptr; - for (auto& [_, inputs] : seat_inputs_map_) { - if (inputs.pointer != nullptr) { - pointer = inputs.pointer; - break; - } - } - if (!pointer) { - return; - } if (cursor_name.compare(cursor_info_.cursor_name) == 0) { return; } @@ -1644,6 +1642,7 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, wl_registry, name, &wl_seat_interface, std::min(kMaxVersion, version))), seat_inputs()); + registry_names_to_seat_ptr_.emplace(name, inserted->first); wl_seat_add_listener(inserted->first, &kWlSeatListener, this); return; } @@ -1720,7 +1719,35 @@ void ELinuxWindowWayland::WlRegistryHandler(wl_registry* wl_registry, } void ELinuxWindowWayland::WlUnRegistryHandler(wl_registry* wl_registry, - uint32_t name) {} + uint32_t name) { + // Just remove seats for now, as we don't need to do anything else. + // But there is also no interface name here. + auto seat_iter = registry_names_to_seat_ptr_.find(name); + if (seat_iter != registry_names_to_seat_ptr_.end()) { + auto seat = seat_iter->second; + auto seat_inputs_iter = seat_inputs_map_.find(seat); + if (seat_inputs_iter != seat_inputs_map_.end()) { + auto& inputs = seat_inputs_iter->second; + if (inputs.pointer) { + wl_pointer_release(inputs.pointer); + inputs.pointer = nullptr; + } + if (inputs.touch) { + wl_touch_release(inputs.touch); + inputs.touch = nullptr; + } + if (inputs.keyboard) { + wl_keyboard_release(inputs.keyboard); + inputs.keyboard = nullptr; + } + seat_inputs_map_.erase(seat_inputs_iter); + } + if (seat) { + wl_seat_destroy(seat); + } + registry_names_to_seat_ptr_.erase(name); + } +} bool ELinuxWindowWayland::LoadCursorTheme(uint32_t size) { if (!wl_shm_) { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h index a4e454c4..8ccb84ba 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.h @@ -171,6 +171,7 @@ class ELinuxWindowWayland : public ELinuxWindow, public WindowBindingHandler { wl_output* wl_output_; wl_shm* wl_shm_; std::unordered_map seat_inputs_map_; + std::unordered_map registry_names_to_seat_ptr_; wl_surface* wl_cursor_surface_; xdg_wm_base* xdg_wm_base_; xdg_surface* xdg_surface_; From 595f7f5bb02a32eb09a3ad136a5f9736e0fa7244 Mon Sep 17 00:00:00 2001 From: "Athaariq \"Eric\" Ardhiansyah" Date: Mon, 3 Jun 2024 06:34:17 +0700 Subject: [PATCH 169/178] Add libuv support as a replacement of systemd + some CMake fixes (#420) * git: prevent accidental push on generated files Signed-off-by: Athaariq Ardhiansyah * cmake: fix wrong option usage The option() function only dedicated for boolean type. For enumerated string, better use both set(... CACHE STRING ...) and set_property(CACHE ... PROPERTY STRINGS ...). Signed-off-by: Athaariq Ardhiansyah * cmake: fix wrong string cache syntax in set() For further information, visit the documentation at https://cmake.org/cmake/help/latest/command/set.html#set-cache-entry Signed-off-by: Athaariq Ardhiansyah * cmake: warn if BUILD_ELINUX_SO is OFF but BACKEND_TYPE was modified This commit prevents other new contributors from mistakenly blame CMakeLists.txt. Therefore, I added a warning just in case they forgot to turn on BUILD_ELINUX_SO while modifying BACKEND_TYPE. Signed-off-by: Athaariq Ardhiansyah * cmake: enforce regex exactness for safety Signed-off-by: Athaariq Ardhiansyah * drm: add libuv support as systemd replacement Not all embedded systems can include systemd due to their constrained resource limit. Our requirement from libsystemd is only event loop (sd-event). Therefore, libuv is perfect as drop-in replacement of sd-event. I tested the changes on Raspberry Pi 5 with Buildroot (yes, I am working on it too) and a x86-64 laptop with Arch Linux. Both are working as intended. Interestingly, libuv makes flutter-elinux smoother on my laptop. I have no idea how to benchmark it, but it is a good sign for us. For now, I am assuming users are still relying on libsystemd. Therefore, libuv only be used if the target device has no systemd. If maintainer want to drop the systemd dependency, I suggest to deprecate it gracefully and plan to drop it later. Otherwise, it would be a breaking change. Signed-off-by: Athaariq Ardhiansyah * author: add Athaariq Ardhiansyah Signed-off-by: Athaariq Ardhiansyah * style: overhaul to comply the standard Signed-off-by: Athaariq Ardhiansyah * style: format with clang-format v14.0.6 I realized that clang-format is inconsistent between its versions. So, Arch Linux (clang v17) and Ubuntu Jammy (clang v14) will output different formatting result. For Arch Linux users, the clang14 package has no clang-format included. You need to compile the entire clang on your own until the downstream maintainer include it. Signed-off-by: Athaariq Ardhiansyah * cmake: fix error for CMake before v3.28 On some distributions with non-latest CMake, it will fail on configuration due to its incapability of substition from unset variable to an empty string. To fix this, we need to add double quotes between variables that will be tested by EQUAL, LESS, GREATER, and other related keywords. For better compatibility, use STREQUAL instead of EQUAL if possible. Signed-off-by: Athaariq Ardhiansyah --------- Signed-off-by: Athaariq Ardhiansyah --- .gitignore | 1 + AUTHORS | 1 + CMakeLists.txt | 8 +- cmake/build.cmake | 16 ++- cmake/package.cmake | 13 ++- .../include/flutter/encodable_value.h | 4 +- .../include/flutter/texture_registrar.h | 3 +- .../platform/common/json_method_codec.cc | 3 +- .../common/public/flutter_texture_registrar.h | 15 +-- .../shell/platform/common/text_range.h | 4 +- .../linux_embedded/window/elinux_window_drm.h | 107 ++++++++++++++++-- 11 files changed, 147 insertions(+), 28 deletions(-) diff --git a/.gitignore b/.gitignore index 4b17e1c8..d199025c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .vscode/ /build/ +/src/third_party/wayland/protocols/* \ No newline at end of file diff --git a/AUTHORS b/AUTHORS index 151ed913..368deab2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,3 +15,4 @@ Luke Howard Stanislav Shmarov Sebastian Urban Ómar Högni Guðmarsson +Athaariq Ardhiansyah diff --git a/CMakeLists.txt b/CMakeLists.txt index 0150694c..a467410a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,8 @@ set(CMAKE_CXX_STANDARD 17) project("flutter_elinux" LANGUAGES CXX C) # Build options. -option(BACKEND_TYPE "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type" WAYLAND) +set(BACKEND_TYPE "WAYLAND" CACHE STRING "Select WAYLAND, DRM-GBM, DRM-EGLSTREAM, or X11 as the display backend type") +set_property(CACHE BACKEND_TYPE PROPERTY STRINGS "WAYLAND" "DRM-GBM" "DRM-EGLSTREAM" "X11") # Disabled USE_DIRTY_REGION_MANAGEMENT due flicker issue. # See https://github.com/sony/flutter-embedded-linux/issues/334 option(USE_DIRTY_REGION_MANAGEMENT "Use Flutter dirty region management" OFF) @@ -24,8 +25,11 @@ option(FLUTTER_RELEASE "Build Flutter Engine with release mode" OFF) if(NOT BUILD_ELINUX_SO) # Load the user project. - set(USER_PROJECT_PATH "examples/flutter-wayland-client" CACHE STRING "") + set(USER_PROJECT_PATH "" CACHE STRING "examples/flutter-wayland-client") message("User project: ${USER_PROJECT_PATH}") + if(NOT ${BACKEND_TYPE} STREQUAL "WAYLAND") + message(WARNING "BACKEND_TYPE variable is ignored because BUILD_ELINUX_SO is OFF") + endif() include(${USER_PROJECT_PATH}/cmake/user_config.cmake) else() # Set the filename of elinux .so file diff --git a/cmake/build.cmake b/cmake/build.cmake index 7bd34f7e..ad69502b 100644 --- a/cmake/build.cmake +++ b/cmake/build.cmake @@ -249,6 +249,7 @@ target_link_libraries(${TARGET} ${LIBINPUT_LIBRARIES} ${LIBUDEV_LIBRARIES} ${LIBSYSTEMD_LIBRARIES} + ${LIBUV_LIBRARIES} ${X11_LIBRARIES} ${LIBWESTON_LIBRARIES} ${FLUTTER_EMBEDDER_LIB} @@ -256,11 +257,16 @@ target_link_libraries(${TARGET} ${USER_APP_LIBRARIES} ) -if(${BACKEND_TYPE} MATCHES "DRM-(GBM|EGLSTREAM)") -target_link_libraries(${TARGET} - PRIVATE - Threads::Threads -) +if(${BACKEND_TYPE} MATCHES "^DRM-(GBM|EGLSTREAM)$") + target_link_libraries(${TARGET} + PRIVATE + Threads::Threads + ) + + # Indicate whether libsystemd must replace libuv + if("${LIBSYSTEMD_FOUND}" STREQUAL "1") + add_definitions(-DUSE_LIBSYSTEMD) + endif() endif() set(FLUTTER_EMBEDDER_LIB "${CMAKE_CURRENT_SOURCE_DIR}/build/libflutter_engine.so") diff --git a/cmake/package.cmake b/cmake/package.cmake index 390d8113..7a2ebcaa 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -9,17 +9,26 @@ pkg_check_modules(EGL REQUIRED egl) pkg_check_modules(XKBCOMMON REQUIRED xkbcommon) # depends on backend type. -if(${BACKEND_TYPE} MATCHES "DRM-(GBM|EGLSTREAM)") +if(${BACKEND_TYPE} MATCHES "^DRM-(GBM|EGLSTREAM)$") # DRM backend pkg_check_modules(DRM REQUIRED libdrm) pkg_check_modules(LIBINPUT REQUIRED libinput) pkg_check_modules(LIBUDEV REQUIRED libudev) - pkg_check_modules(LIBSYSTEMD REQUIRED libsystemd) + pkg_check_modules(LIBSYSTEMD libsystemd) + pkg_check_modules(LIBUV libuv) if(${BACKEND_TYPE} STREQUAL "DRM-GBM") pkg_check_modules(GBM REQUIRED gbm) endif() set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) + # Check if either systemd or libuv exist + if((NOT "${LIBSYSTEMD_FOUND}" STREQUAL "1") AND (NOT "${LIBUV_FOUND}" STREQUAL "1")) + message(FATAL_ERROR + "${BACKEND_TYPE} backend requires either libsystemd or libuv, but + they're not exist.") + elseif(("${LIBSYSTEMD_FOUND}" STREQUAL "1") AND ("${LIBUV_FOUND}" STREQUAL "1")) + message("!! NOTICE: libsystemd found, libuv won't be used.") + endif() elseif(${BACKEND_TYPE} STREQUAL "X11") pkg_check_modules(X11 REQUIRED x11) else() diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h index 3a191205..bf243fde 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/encodable_value.h @@ -70,7 +70,9 @@ class CustomEncodableValue { #if defined(FLUTTER_ENABLE_RTTI) && FLUTTER_ENABLE_RTTI // Passthrough to std::any's type(). - const std::type_info& type() const noexcept { return value_.type(); } + const std::type_info& type() const noexcept { + return value_.type(); + } #endif // This operator exists only to provide a stable ordering for use as a diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 4abe19d9..0777e528 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -107,7 +107,8 @@ class GpuSurfaceTexture { // The available texture variants. // Only PixelBufferTexture is currently implemented. // Other variants are expected to be added in the future. -typedef std::variant TextureVariant; +typedef std::variant + TextureVariant; // An object keeping track of external textures. // diff --git a/src/flutter/shell/platform/common/json_method_codec.cc b/src/flutter/shell/platform/common/json_method_codec.cc index cc4ffec6..9ccb79c8 100644 --- a/src/flutter/shell/platform/common/json_method_codec.cc +++ b/src/flutter/shell/platform/common/json_method_codec.cc @@ -104,7 +104,8 @@ JsonMethodCodec::EncodeErrorEnvelopeInternal( rapidjson::Document envelope(rapidjson::kArrayType); auto& allocator = envelope.GetAllocator(); envelope.PushBack(rapidjson::Value(error_code.c_str(), allocator), allocator); - envelope.PushBack(rapidjson::Value(error_message.c_str(), allocator), allocator); + envelope.PushBack(rapidjson::Value(error_message.c_str(), allocator), + allocator); rapidjson::Value details_value; if (error_details) { details_value.CopyFrom(*error_details, allocator); diff --git a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h index cc0dbd2d..fb564382 100644 --- a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h +++ b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h @@ -76,7 +76,8 @@ typedef struct { size_t width; // Height of the EGLImage. size_t height; - // An optional callback that gets invoked when the |egl_image| can be released. + // An optional callback that gets invoked when the |egl_image| can be + // released. void (*release_callback)(void* release_context); // Opaque data passed to |release_callback|. void* release_context; @@ -142,12 +143,12 @@ typedef const FlutterDesktopGpuSurfaceDescriptor* ( size_t height, void* user_data); -typedef const FlutterDesktopEGLImage* ( - *FlutterDesktopEGLImageTextureCallback)(size_t width, - size_t height, - void* egl_display, - void* egl_context, - void* user_data); +typedef const FlutterDesktopEGLImage* (*FlutterDesktopEGLImageTextureCallback)( + size_t width, + size_t height, + void* egl_display, + void* egl_context, + void* user_data); // An object used to configure pixel buffer textures. typedef struct { diff --git a/src/flutter/shell/platform/common/text_range.h b/src/flutter/shell/platform/common/text_range.h index a7b3760b..6a0deff6 100644 --- a/src/flutter/shell/platform/common/text_range.h +++ b/src/flutter/shell/platform/common/text_range.h @@ -7,7 +7,7 @@ #include -//#include "flutter/fml/logging.h" +// #include "flutter/fml/logging.h" namespace flutter { @@ -66,7 +66,7 @@ class TextRange { // // Asserts that the range is of length 0. size_t position() const { - //FML_DCHECK(base_ == extent_); + // FML_DCHECK(base_ == extent_); return extent_; } diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 8b6c0767..0bbb883a 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -8,9 +8,14 @@ #include #include #include -#include #include +#ifdef USE_LIBSYSTEMD +#include +#else +#include +#endif + #include #include #include @@ -61,6 +66,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return; } +#ifdef USE_LIBSYSTEMD ret = sd_event_new(&libinput_event_loop_); if (ret < 0) { ELINUX_LOG(ERROR) << "Failed to create libinput event loop."; @@ -74,20 +80,46 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { libinput_event_loop_ = sd_event_unref(libinput_event_loop_); return; } +#else // #ifdef USE_LIBSYSTEMD + ret = uv_loop_init(&main_loop_); + if (ret) { + ELINUX_LOG(ERROR) << "Failed to create main event loop."; + return; + } + ret = uv_poll_init(&main_loop_, &libinput_event_loop_, + libinput_get_fd(libinput_)); + if (ret) { + ELINUX_LOG(ERROR) << "Failed to create libinput event loop."; + return; + } + libinput_event_loop_.data = this; + ret = uv_poll_start(&libinput_event_loop_, + UV_READABLE | UV_DISCONNECT | UV_PRIORITIZED, + OnLibinputEvent); + if (ret) { + ELINUX_LOG(ERROR) << "Failed to listen for user input."; + return; + } +#endif // #ifdef USE_LIBSYSTEMD } ~ELinuxWindowDrm() { +#ifdef USE_LIBSYSTEMD if (udev_drm_event_loop_) { sd_event_unref(udev_drm_event_loop_); } +#endif if (udev_monitor_) { udev_monitor_unref(udev_monitor_); } +#ifdef USE_LIBSYSTEMD if (libinput_event_loop_) { sd_event_unref(libinput_event_loop_); } +#endif + libinput_unref(libinput_); display_valid_ = false; } @@ -103,9 +135,13 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { // |FlutterWindowBindingHandler| bool DispatchEvent() override { +#ifdef USE_LIBSYSTEMD constexpr uint64_t kMaxWaitTime = 0; sd_event_run(libinput_event_loop_, kMaxWaitTime); sd_event_run(udev_drm_event_loop_, kMaxWaitTime); +#else + uv_run(&main_loop_, UV_RUN_NOWAIT); +#endif return true; } @@ -192,10 +228,14 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - uint16_t GetRotationDegree() const override { return current_rotation_; } + uint16_t GetRotationDegree() const override { + return current_rotation_; + } // |FlutterWindowBindingHandler| - double GetDpiScale() override { return current_scale_; } + double GetDpiScale() override { + return current_scale_; + } // |FlutterWindowBindingHandler| PhysicalWindowBounds GetPhysicalWindowBounds() override { @@ -203,7 +243,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - int32_t GetFrameRate() override { return 60000; } + int32_t GetFrameRate() override { + return 60000; + } // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override { @@ -218,7 +260,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - std::string GetClipboardData() override { return clipboard_data_; } + std::string GetClipboardData() override { + return clipboard_data_; + } // |FlutterWindowBindingHandler| void SetClipboardData(const std::string& data) override { @@ -290,6 +334,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } udev_unref(udev); +#ifdef USE_LIBSYSTEMD if (sd_event_new(&udev_drm_event_loop_) < 0) { ELINUX_LOG(ERROR) << "Failed to create udev drm event loop."; return false; @@ -301,6 +346,22 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { ELINUX_LOG(ERROR) << "Failed to listen for udev drm event."; return false; } +#else // #ifdef USE_LIBSYSTEMD + if (uv_poll_init(&main_loop_, &udev_drm_event_loop_, + udev_monitor_get_fd(udev_monitor_))) { + ELINUX_LOG(ERROR) << "Failed to create udev drm event loop."; + return false; + } + + udev_drm_event_loop_.data = this; + + if (uv_poll_start(&udev_drm_event_loop_, + UV_READABLE | UV_DISCONNECT | UV_PRIORITIZED, + OnUdevDrmEvent)) { + ELINUX_LOG(ERROR) << "Failed to listen for udev drm event."; + return false; + } +#endif // #ifdef USE_LIBSYSTEMD if (udev_monitor_enable_receiving(udev_monitor_) < 0) { ELINUX_LOG(ERROR) << "Failed to enable udev monitor receiving."; @@ -310,6 +371,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return true; } +#ifdef USE_LIBSYSTEMD static int OnUdevDrmEvent(sd_event_source* source, int fd, uint32_t revents, @@ -320,6 +382,15 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { ELINUX_LOG(ERROR) << "Failed to receive udev device."; return -1; } +#else + static void OnUdevDrmEvent(uv_poll_t* handle, int status, int events) { + auto self = reinterpret_cast(handle->data); + auto device = udev_monitor_receive_device(self->udev_monitor_); + if (!device) { + ELINUX_LOG(ERROR) << "Failed to receive udev device."; + return; + } +#endif if (self->IsUdevEventHotplug(*device) && self->native_window_->ConfigureDisplay(self->current_rotation_)) { @@ -343,7 +414,10 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } udev_device_unref(device); + +#ifdef USE_LIBSYSTEMD return 0; +#endif } bool IsUdevEventHotplug(udev_device& device) { @@ -368,6 +442,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { return std::strcmp(value, kPropertyOn) == 0; } +#ifdef USE_LIBSYSTEMD static int OnLibinputEvent(sd_event_source* source, int fd, uint32_t revents, @@ -378,6 +453,15 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { ELINUX_LOG(ERROR) << "Failed to dispatch libinput events."; return -ret; } +#else + static void OnLibinputEvent(uv_poll_t* handle, int uv_status, int uv_events) { + auto self = reinterpret_cast(handle->data); + auto ret = libinput_dispatch(self->libinput_); + if (ret < 0) { + ELINUX_LOG(ERROR) << "Failed to dispatch libinput events."; + return; + } +#endif auto previous_pointer_x = self->pointer_x_; auto previous_pointer_y = self->pointer_y_; @@ -435,7 +519,9 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { self->native_window_->MoveCursor(self->pointer_x_, self->pointer_y_); } +#ifdef USE_LIBSYSTEMD return 0; +#endif } void OnDeviceAdded(libinput_event* event) { @@ -716,15 +802,22 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { bool display_valid_; bool is_pending_cursor_add_event_; - sd_event* libinput_event_loop_; libinput* libinput_; std::unordered_map> libinput_devices_; int libinput_pointer_devices_ = 0; - sd_event* udev_drm_event_loop_ = nullptr; udev_monitor* udev_monitor_ = nullptr; std::optional drm_device_id_; + +#ifdef USE_LIBSYSTEMD + sd_event* libinput_event_loop_; + sd_event* udev_drm_event_loop_ = nullptr; +#else + uv_loop_t main_loop_; + uv_poll_t libinput_event_loop_; + uv_poll_t udev_drm_event_loop_; +#endif }; } // namespace flutter From 30b3d4aa78f5a14714caabf755f69a6afa9602a1 Mon Sep 17 00:00:00 2001 From: Anton Sakhon <58438890+Kofhein@users.noreply.github.com> Date: Fri, 6 Sep 2024 15:35:58 +0300 Subject: [PATCH 170/178] Added marshalling to main thread messages sent from native side (#422) * Added marshalling to main thread messages sent from native side --------- Co-authored-by: Anton Sakhon --- AUTHORS | 1 + .../client_wrapper/core_implementations.cc | 13 ++++--- .../common/public/flutter_messenger.h | 3 +- .../platform/linux_embedded/flutter_elinux.cc | 34 +++++++++++++------ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/AUTHORS b/AUTHORS index 368deab2..85298807 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,3 +16,4 @@ Stanislav Shmarov Sebastian Urban Ómar Högni Guðmarsson Athaariq Ardhiansyah +Anton Sakhon diff --git a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc index 3aae66ca..8110a0c3 100644 --- a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -66,6 +66,11 @@ BinaryMessengerImpl::BinaryMessengerImpl( BinaryMessengerImpl::~BinaryMessengerImpl() = default; +void CaptureCleaner(void* lambda) { + auto& cleanup = *reinterpret_cast*>(lambda); + cleanup(); +} + void BinaryMessengerImpl::Send(const std::string& channel, const uint8_t* message, size_t message_size, @@ -89,10 +94,10 @@ void BinaryMessengerImpl::Send(const std::string& channel, }; bool result = FlutterDesktopMessengerSendWithReply( messenger_, channel.c_str(), message, message_size, message_reply, - captures); - if (!result) { - delete captures; - } + captures, [](void* captures_data) { + auto captures = reinterpret_cast(captures_data); + delete captures; + }); } void BinaryMessengerImpl::SetMessageHandler(const std::string& channel, diff --git a/src/flutter/shell/platform/common/public/flutter_messenger.h b/src/flutter/shell/platform/common/public/flutter_messenger.h index 87c33beb..bb182cdf 100644 --- a/src/flutter/shell/platform/common/public/flutter_messenger.h +++ b/src/flutter/shell/platform/common/public/flutter_messenger.h @@ -63,7 +63,8 @@ FLUTTER_EXPORT bool FlutterDesktopMessengerSendWithReply( const uint8_t* message, const size_t message_size, const FlutterDesktopBinaryReply reply, - void* user_data); + void* user_data, + void (*cleanup)(void* captures_data)); // Sends a reply to a FlutterDesktopMessage for the given response handle. // diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index d3c3dee3..fd3754a4 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -199,22 +199,36 @@ void FlutterDesktopPluginRegistrarSetDestructionHandler( registrar->engine->SetPluginRegistrarDestructionCallback(callback); } -bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger, - const char* channel, - const uint8_t* message, - const size_t message_size, - const FlutterDesktopBinaryReply reply, - void* user_data) { - return messenger->GetEngine()->SendPlatformMessage( - channel, message, message_size, reply, user_data); +bool FlutterDesktopMessengerSendWithReply( + FlutterDesktopMessengerRef messenger, + const char* channel, + const uint8_t* message, + const size_t message_size, + const FlutterDesktopBinaryReply reply, + void* user_data, + void (*cleanup)(void* captures_data)) { + // As we pass data to lambda and it's pointers we need to make sure that we + // send valid data + std::string channel_copy(channel); + std::vector message_copy(message, message + message_size); + + messenger->GetEngine()->task_runner()->PostTask([=]() { + if (!messenger->GetEngine()->SendPlatformMessage( + channel_copy.c_str(), message_copy.data(), message_copy.size(), + reply, user_data) && + user_data) { + cleanup(user_data); + } + }); + return true; } bool FlutterDesktopMessengerSend(FlutterDesktopMessengerRef messenger, const char* channel, const uint8_t* message, const size_t message_size) { - return FlutterDesktopMessengerSendWithReply(messenger, channel, message, - message_size, nullptr, nullptr); + return FlutterDesktopMessengerSendWithReply( + messenger, channel, message, message_size, nullptr, nullptr, nullptr); } void FlutterDesktopMessengerSendResponse( From 63b57ca74991ce6782736a1adb8b63928797272f Mon Sep 17 00:00:00 2001 From: Anton Sakhon <58438890+Kofhein@users.noreply.github.com> Date: Fri, 6 Sep 2024 16:47:21 +0300 Subject: [PATCH 171/178] Removed unused variable (#423) --- .../platform/common/client_wrapper/core_implementations.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc index 8110a0c3..983feb3e 100644 --- a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -92,7 +92,8 @@ void BinaryMessengerImpl::Send(const std::string& channel, captures->reply(data, data_size); delete captures; }; - bool result = FlutterDesktopMessengerSendWithReply( + + FlutterDesktopMessengerSendWithReply( messenger_, channel.c_str(), message, message_size, message_reply, captures, [](void* captures_data) { auto captures = reinterpret_cast(captures_data); From 9dc1156ca709a54ea07ce5873f8d7f6357e98c9c Mon Sep 17 00:00:00 2001 From: barribarrier <98932277+barribarrier@users.noreply.github.com> Date: Fri, 20 Sep 2024 07:17:30 -0400 Subject: [PATCH 172/178] Specify DRM connector with FLUTTER_DRM_CONNECTOR (#425) * Specify DRM connector with FLUTTER_DRM_CONNECTOR * Update AUTHORS --------- Co-authored-by: barri --- AUTHORS | 1 + .../window/native_window_drm.cc | 76 +++++++++++++++++++ .../linux_embedded/window/native_window_drm.h | 4 + 3 files changed, 81 insertions(+) diff --git a/AUTHORS b/AUTHORS index 85298807..6a816263 100644 --- a/AUTHORS +++ b/AUTHORS @@ -17,3 +17,4 @@ Sebastian Urban Ómar Högni Guðmarsson Athaariq Ardhiansyah Anton Sakhon +Bari Rao diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc index 59a29021..73023fd2 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.cc @@ -14,6 +14,31 @@ #include "flutter/shell/platform/linux_embedded/surface/cursor_data.h" namespace flutter { +namespace { +constexpr char kFlutterDrmConnectorEnvironmentKey[] = "FLUTTER_DRM_CONNECTOR"; +static const std::unordered_map connector_names = { + {DRM_MODE_CONNECTOR_Unknown, "Unknown"}, + {DRM_MODE_CONNECTOR_VGA, "VGA"}, + {DRM_MODE_CONNECTOR_DVII, "DVI-I"}, + {DRM_MODE_CONNECTOR_DVID, "DVI-D"}, + {DRM_MODE_CONNECTOR_DVIA, "DVI-A"}, + {DRM_MODE_CONNECTOR_Composite, "Composite"}, + {DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO"}, + {DRM_MODE_CONNECTOR_LVDS, "LVDS"}, + {DRM_MODE_CONNECTOR_Component, "Component"}, + {DRM_MODE_CONNECTOR_9PinDIN, "DIN"}, + {DRM_MODE_CONNECTOR_DisplayPort, "DP"}, + {DRM_MODE_CONNECTOR_HDMIA, "HDMI-A"}, + {DRM_MODE_CONNECTOR_HDMIB, "HDMI-B"}, + {DRM_MODE_CONNECTOR_TV, "TV"}, + {DRM_MODE_CONNECTOR_eDP, "eDP"}, + {DRM_MODE_CONNECTOR_VIRTUAL, "Virtual"}, + {DRM_MODE_CONNECTOR_DSI, "DSI"}, + {DRM_MODE_CONNECTOR_DPI, "DPI"}, + {DRM_MODE_CONNECTOR_WRITEBACK, "Writeback"}, + {DRM_MODE_CONNECTOR_SPI, "SPI"}, + {DRM_MODE_CONNECTOR_USB, "USB"}}; +} // namespace NativeWindowDrm::NativeWindowDrm(const char* device_filename, const uint16_t rotation, @@ -104,11 +129,62 @@ bool NativeWindowDrm::ConfigureDisplay(const uint16_t rotation) { return true; } +std::string NativeWindowDrm::GetConnectorName(uint32_t connector_type, + uint32_t connector_type_id) { + auto it = connector_names.find(connector_type); + std::string name = it != connector_names.end() ? it->second : "Unknown"; + return name + "-" + std::to_string(connector_type_id); +} + +drmModeConnectorPtr NativeWindowDrm::GetConnectorByName( + drmModeResPtr resources, + const char* connector_name) { + for (int i = 0; i < resources->count_connectors; i++) { + auto connector = drmModeGetConnector(drm_device_, resources->connectors[i]); + if (!connector) { + continue; + } + auto other_connector_name = GetConnectorName(connector->connector_type, + connector->connector_type_id); + if (connector_name == other_connector_name) { + return connector; + } + drmModeFreeConnector(connector); + } + return nullptr; +} + drmModeConnectorPtr NativeWindowDrm::FindConnector(drmModeResPtr resources) { + auto connector_name = std::getenv(kFlutterDrmConnectorEnvironmentKey); + if (connector_name && connector_name[0] != '\0') { + auto connector = GetConnectorByName(resources, connector_name); + if (!connector) { + ELINUX_LOG(ERROR) << "Couldn't find connector with name " + << connector_name; + return nullptr; + } + + if (connector->connection == DRM_MODE_CONNECTED) { + ELINUX_LOG(DEBUG) << "Using connector " << connector_name; + return connector; + } else { + ELINUX_LOG(ERROR) << "Connector " << connector_name + << " is not connected."; + drmModeFreeConnector(connector); + return nullptr; + } + } + for (int i = 0; i < resources->count_connectors; i++) { auto connector = drmModeGetConnector(drm_device_, resources->connectors[i]); + if (!connector) { + continue; + } // pick the first connected connector if (connector->connection == DRM_MODE_CONNECTED) { + auto other_connetor_name = GetConnectorName(connector->connector_type, + connector->connector_type_id); + ELINUX_LOG(DEBUG) << "Using connector " << other_connetor_name; return connector; } drmModeFreeConnector(connector); diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h index bae9ec06..3d72f7ac 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window_drm.h @@ -39,6 +39,10 @@ class NativeWindowDrm : public NativeWindow { bool enable_impeller) = 0; protected: + std::string GetConnectorName(uint32_t connector_type, + uint32_t connector_type_id); + drmModeConnectorPtr GetConnectorByName(drmModeResPtr resources, + const char* connector_name); drmModeConnectorPtr FindConnector(drmModeResPtr resources); drmModeEncoder* FindEncoder(drmModeRes* resources, From 9d0ff07b5e1cccbead808ddff0f13f1c5ceeae52 Mon Sep 17 00:00:00 2001 From: barribarrier <98932277+barribarrier@users.noreply.github.com> Date: Mon, 30 Sep 2024 08:06:07 -0400 Subject: [PATCH 173/178] Destroy textures on raster thread (#427) * Destroy textures on raster thread Signed-off-by: Bari Rao * Fix format Signed-off-by: Bari Rao --------- Signed-off-by: Bari Rao --- src/flutter/fml/closure.h | 77 +++++++++++++++++++ src/flutter/fml/macros.h | 44 +++++++++++ .../client_wrapper/core_implementations.cc | 27 ++++++- .../include/flutter/texture_registrar.h | 9 ++- .../client_wrapper/texture_registrar_impl.h | 4 + .../common/public/flutter_texture_registrar.h | 12 +-- .../platform/linux_embedded/flutter_elinux.cc | 15 +++- .../linux_embedded/flutter_elinux_engine.cc | 20 +++++ .../linux_embedded/flutter_elinux_engine.h | 3 + .../flutter_elinux_texture_registrar.cc | 30 +++++--- .../flutter_elinux_texture_registrar.h | 4 +- 11 files changed, 219 insertions(+), 26 deletions(-) create mode 100644 src/flutter/fml/closure.h create mode 100644 src/flutter/fml/macros.h diff --git a/src/flutter/fml/closure.h b/src/flutter/fml/closure.h new file mode 100644 index 00000000..264a95f7 --- /dev/null +++ b/src/flutter/fml/closure.h @@ -0,0 +1,77 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_FML_CLOSURE_H_ +#define FLUTTER_FML_CLOSURE_H_ + +#include + +#include "flutter/fml/macros.h" + +namespace fml { + +using closure = std::function; + +//------------------------------------------------------------------------------ +/// @brief Wraps a closure that is invoked in the destructor unless +/// released by the caller. +/// +/// This is especially useful in dealing with APIs that return a +/// resource by accepting ownership of a sub-resource and a closure +/// that releases that resource. When such APIs are chained, each +/// link in the chain must check that the next member in the chain +/// has accepted the resource. If not, it must invoke the closure +/// eagerly. Not doing this results in a resource leak in the +/// erroneous case. Using this wrapper, the closure can be released +/// once the next call in the chain has successfully accepted +/// ownership of the resource. If not, the closure gets invoked +/// automatically at the end of the scope. This covers the cases +/// where there are early returns as well. +/// +class ScopedCleanupClosure final { + public: + ScopedCleanupClosure() = default; + + ScopedCleanupClosure(ScopedCleanupClosure&& other) { + closure_ = other.Release(); + } + + ScopedCleanupClosure& operator=(ScopedCleanupClosure&& other) { + closure_ = other.Release(); + return *this; + } + + explicit ScopedCleanupClosure(const fml::closure& closure) + : closure_(closure) {} + + ~ScopedCleanupClosure() { Reset(); } + + fml::closure SetClosure(const fml::closure& closure) { + auto old_closure = closure_; + closure_ = closure; + return old_closure; + } + + fml::closure Release() { + fml::closure closure = closure_; + closure_ = nullptr; + return closure; + } + + void Reset() { + if (closure_) { + closure_(); + closure_ = nullptr; + } + } + + private: + fml::closure closure_; + + FML_DISALLOW_COPY_AND_ASSIGN(ScopedCleanupClosure); +}; + +} // namespace fml + +#endif // FLUTTER_FML_CLOSURE_H_ diff --git a/src/flutter/fml/macros.h b/src/flutter/fml/macros.h new file mode 100644 index 00000000..7de4ddf1 --- /dev/null +++ b/src/flutter/fml/macros.h @@ -0,0 +1,44 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_FML_MACROS_H_ +#define FLUTTER_FML_MACROS_H_ + +#ifndef FML_USED_ON_EMBEDDER + +#define FML_EMBEDDER_ONLY [[deprecated]] + +#else // FML_USED_ON_EMBEDDER + +#define FML_EMBEDDER_ONLY + +#endif // FML_USED_ON_EMBEDDER + +#define FML_DISALLOW_COPY(TypeName) TypeName(const TypeName&) = delete + +#define FML_DISALLOW_ASSIGN(TypeName) \ + TypeName& operator=(const TypeName&) = delete + +#define FML_DISALLOW_MOVE(TypeName) \ + TypeName(TypeName&&) = delete; \ + TypeName& operator=(TypeName&&) = delete + +#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName&) = delete; \ + TypeName& operator=(const TypeName&) = delete + +#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) \ + TypeName(const TypeName&) = delete; \ + TypeName(TypeName&&) = delete; \ + TypeName& operator=(const TypeName&) = delete; \ + TypeName& operator=(TypeName&&) = delete + +#define FML_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \ + TypeName() = delete; \ + FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) + +#define FML_FRIEND_TEST(test_case_name, test_name) \ + friend class test_case_name##_##test_name##_Test + +#endif // FLUTTER_FML_MACROS_H_ diff --git a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc index 983feb3e..ec0d6dd9 100644 --- a/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc +++ b/src/flutter/shell/platform/common/client_wrapper/core_implementations.cc @@ -210,9 +210,32 @@ bool TextureRegistrarImpl::MarkTextureFrameAvailable(int64_t texture_id) { texture_registrar_ref_, texture_id); } +void TextureRegistrarImpl::UnregisterTexture(int64_t texture_id, + std::function callback) { + if (callback == nullptr) { + FlutterDesktopTextureRegistrarUnregisterExternalTexture( + texture_registrar_ref_, texture_id, nullptr, nullptr); + return; + } + + struct Captures { + std::function callback; + }; + auto captures = new Captures(); + captures->callback = std::move(callback); + FlutterDesktopTextureRegistrarUnregisterExternalTexture( + texture_registrar_ref_, texture_id, + [](void* opaque) { + auto captures = reinterpret_cast(opaque); + captures->callback(); + delete captures; + }, + captures); +} + bool TextureRegistrarImpl::UnregisterTexture(int64_t texture_id) { - return FlutterDesktopTextureRegistrarUnregisterExternalTexture( - texture_registrar_ref_, texture_id); + UnregisterTexture(texture_id, nullptr); + return true; } } // namespace flutter diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 0777e528..9b13025f 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -128,8 +128,13 @@ class TextureRegistrar { // the callback that was provided upon creating the texture. virtual bool MarkTextureFrameAvailable(int64_t texture_id) = 0; - // Unregisters an existing Texture object. - // Textures must not be unregistered while they're in use. + // Asynchronously unregisters an existing texture object. + // Upon completion, the optional |callback| gets invoked. + virtual void UnregisterTexture(int64_t texture_id, + std::function callback) = 0; + + // Unregisters an existing texture object. + // DEPRECATED: Use UnregisterTexture(texture_id, optional_callback) instead. virtual bool UnregisterTexture(int64_t texture_id) = 0; }; diff --git a/src/flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h b/src/flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h index df51f6dd..bd01839d 100644 --- a/src/flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h +++ b/src/flutter/shell/platform/common/client_wrapper/texture_registrar_impl.h @@ -27,6 +27,10 @@ class TextureRegistrarImpl : public TextureRegistrar { // |flutter::TextureRegistrar| bool MarkTextureFrameAvailable(int64_t texture_id) override; + // |flutter::TextureRegistrar| + void UnregisterTexture(int64_t texture_id, + std::function callback) override; + // |flutter::TextureRegistrar| bool UnregisterTexture(int64_t texture_id) override; diff --git a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h index fb564382..a56c3107 100644 --- a/src/flutter/shell/platform/common/public/flutter_texture_registrar.h +++ b/src/flutter/shell/platform/common/public/flutter_texture_registrar.h @@ -195,13 +195,15 @@ FLUTTER_EXPORT int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( FlutterDesktopTextureRegistrarRef texture_registrar, const FlutterDesktopTextureInfo* info); -// Unregisters an existing texture from the Flutter engine for a |texture_id|. -// Returns true on success or false if the specified texture doesn't exist. +// Asynchronously unregisters the texture identified by |texture_id| from the +// Flutter engine. +// An optional |callback| gets invoked upon completion. // This function can be called from any thread. -// However, textures must not be unregistered while they're in use. -FLUTTER_EXPORT bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( +FLUTTER_EXPORT void FlutterDesktopTextureRegistrarUnregisterExternalTexture( FlutterDesktopTextureRegistrarRef texture_registrar, - int64_t texture_id); + int64_t texture_id, + void (*callback)(void* user_data), + void* user_data); // Marks that a new texture frame is available for a given |texture_id|. // Returns true on success or false if the specified texture doesn't exist. diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc index fd3754a4..2d3587f3 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux.cc @@ -284,11 +284,18 @@ int64_t FlutterDesktopTextureRegistrarRegisterExternalTexture( ->RegisterTexture(texture_info); } -bool FlutterDesktopTextureRegistrarUnregisterExternalTexture( +void FlutterDesktopTextureRegistrarUnregisterExternalTexture( FlutterDesktopTextureRegistrarRef texture_registrar, - int64_t texture_id) { - return TextureRegistrarFromHandle(texture_registrar) - ->UnregisterTexture(texture_id); + int64_t texture_id, + void (*callback)(void* user_data), + void* user_data) { + auto registrar = TextureRegistrarFromHandle(texture_registrar); + if (callback) { + registrar->UnregisterTexture( + texture_id, [callback, user_data]() { callback(user_data); }); + return; + } + registrar->UnregisterTexture(texture_id); } bool FlutterDesktopTextureRegistrarMarkExternalTextureFrameAvailable( diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index 9e49c9e4..c09bca5e 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -425,6 +425,26 @@ bool FlutterELinuxEngine::MarkExternalTextureFrameAvailable( engine_, texture_id) == kSuccess); } +bool FlutterELinuxEngine::PostRasterThreadTask(fml::closure callback) { + struct Captures { + fml::closure callback; + }; + auto captures = new Captures(); + captures->callback = std::move(callback); + if (embedder_api_.PostRenderThreadTask( + engine_, + [](void* opaque) { + auto captures = reinterpret_cast(opaque); + captures->callback(); + delete captures; + }, + captures) == kSuccess) { + return true; + } + delete captures; + return false; +} + void FlutterELinuxEngine::OnVsync(uint64_t last_frame_time_nanos, uint64_t vsync_interval_time_nanos) { uint64_t current_time_nanos = embedder_api_.GetCurrentTime(); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index b705941e..4bcc7f10 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -120,6 +120,9 @@ class FlutterELinuxEngine { // given |texture_id|. bool MarkExternalTextureFrameAvailable(int64_t texture_id); + // Posts the given callback onto the raster thread. + bool PostRasterThreadTask(fml::closure callback); + // Notifies the engine about the vsync event. void OnVsync(uint64_t last_frame_time_nanos, uint64_t vsync_interval_time_nanos); diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc index be4899fe..66a603c3 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.cc @@ -72,20 +72,28 @@ int64_t FlutterELinuxTextureRegistrar::EmplaceTexture( return texture_id; } -bool FlutterELinuxTextureRegistrar::UnregisterTexture(int64_t texture_id) { - { - std::lock_guard lock(map_mutex_); - auto it = textures_.find(texture_id); - if (it == textures_.end()) { - return false; - } - textures_.erase(it); - } - +void FlutterELinuxTextureRegistrar::UnregisterTexture(int64_t texture_id, + fml::closure callback) { engine_->task_runner()->RunNowOrPostTask([engine = engine_, texture_id]() { engine->UnregisterExternalTexture(texture_id); }); - return true; + + bool posted = engine_->PostRasterThreadTask([this, texture_id, callback]() { + { + std::lock_guard lock(map_mutex_); + auto it = textures_.find(texture_id); + if (it != textures_.end()) { + textures_.erase(it); + } + } + if (callback) { + callback(); + } + }); + + if (!posted && callback) { + callback(); + } } bool FlutterELinuxTextureRegistrar::MarkTextureFrameAvailable( diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h index 7ad57a2f..8770ad57 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h @@ -9,6 +9,7 @@ #include #include +#include "flutter/fml/closure.h" #include "flutter/shell/platform/common/public/flutter_texture_registrar.h" #include "flutter/shell/platform/linux_embedded/external_texture.h" @@ -28,8 +29,7 @@ class FlutterELinuxTextureRegistrar { int64_t RegisterTexture(const FlutterDesktopTextureInfo* texture_info); // Attempts to unregister the texture identified by |texture_id|. - // Returns true if the texture was successfully unregistered. - bool UnregisterTexture(int64_t texture_id); + void UnregisterTexture(int64_t texture_id, fml::closure callback = nullptr); // Notifies the engine about a new frame being available. // Returns true on success. From a938f2b2064bb25b58c5207f6f5c3dfb9972fadf Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Wed, 30 Oct 2024 21:35:12 +1100 Subject: [PATCH 174/178] Ensure FlutterDesktopViewControllerState declares default destructor (#428) types containing std::unique_ptr to incomplete types require a destructor to be defined as the size is unavailable, otherwise the following error is raised at compile time: /usr/lib/gcc/aarch64-linux-gnu/13/../../../../include/c++/13/bits/unique_ptr.h:97:16: error: invalid application of 'sizeof' to an incomplete type 'flutter::FlutterELinuxView' 91 | _GLIBCXX23_CONSTEXPR 92 | void 93 | operator()(_Tp* __ptr) const | `- note: in instantiation of member function 'std::default_delete::operator()' requested here 94 | { 95 | static_assert(!is_void<_Tp>::value, 96 | "can't delete pointer to incomplete type"); 97 | static_assert(sizeof(_Tp)>0, | `- error: invalid application of 'sizeof' to an incomplete type 'flutter::FlutterELinuxView' 98 | "can't delete pointer to incomplete type"); 99 | delete __ptr; Signed-off-by: Luke Howard --- .../shell/platform/linux_embedded/flutter_elinux_state.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h index 8248f7e8..aea43c4c 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h @@ -34,6 +34,8 @@ struct FlutterELinuxView; struct FlutterDesktopViewControllerState { // The view that backs this state object. std::unique_ptr view; + + ~FlutterDesktopViewControllerState() = default; }; // Wrapper to distinguish the plugin registrar ref from the engine ref given out From 679d3612e4a6a65ade648a98581a48c4bd5713e4 Mon Sep 17 00:00:00 2001 From: Hidenori Date: Sat, 14 Dec 2024 05:10:34 +0900 Subject: [PATCH 175/178] linux_embedded: fix github actions' failure (#431) This change fixes the CI failure due to code format warnings. Signed-off-by: Hidenori Matsubayashi --- .../linux_embedded/flutter_elinux_engine.cc | 10 ++++------ .../plugins/platform_views_plugin.cc | 5 ++--- .../linux_embedded/surface/context_egl.cc | 20 +++++++++---------- .../linux_embedded/window/elinux_window_drm.h | 16 ++++----------- .../window/elinux_window_wayland.cc | 10 +++++----- .../linux_embedded/window/native_window.h | 2 +- 6 files changed, 26 insertions(+), 37 deletions(-) diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc index c09bca5e..45a922e2 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.cc @@ -371,8 +371,7 @@ void FlutterELinuxEngine::HandlePlatformMessage( auto message = ConvertToDesktopMessage(*engine_message); - message_dispatcher_->HandleMessage( - message, [this] {}, [this] {}); + message_dispatcher_->HandleMessage(message, [this] {}, [this] {}); } void FlutterELinuxEngine::ReloadSystemFonts() { @@ -398,10 +397,9 @@ void FlutterELinuxEngine::SendSystemLocales() { // Convert the locale list to the locale pointer list that must be provided. std::vector flutter_locale_list; flutter_locale_list.reserve(flutter_locales.size()); - std::transform( - flutter_locales.begin(), flutter_locales.end(), - std::back_inserter(flutter_locale_list), - [](const auto& arg) -> const auto* { return &arg; }); + std::transform(flutter_locales.begin(), flutter_locales.end(), + std::back_inserter(flutter_locale_list), + [](const auto& arg) -> const auto* { return &arg; }); auto result = embedder_api_.UpdateLocales(engine_, flutter_locale_list.data(), flutter_locale_list.size()); if (result != kSuccess) { diff --git a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc index 81b29462..fb2a513e 100644 --- a/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc +++ b/src/flutter/shell/platform/linux_embedded/plugins/platform_views_plugin.cc @@ -250,9 +250,8 @@ void PlatformViewsPlugin::PlatformViewsOffset( auto view_id = LookupEncodableMap(arguments, kIdKey); auto view_top = LookupEncodableMap(arguments, kTopKey); auto view_left = LookupEncodableMap(arguments, kLeftKey); - ELINUX_LOG(DEBUG) << "Offset the platform view: " - << "id = " << view_id << ", top = " << view_top - << ", left = " << view_left; + ELINUX_LOG(DEBUG) << "Offset the platform view: " << "id = " << view_id + << ", top = " << view_top << ", left = " << view_left; if (platform_views_.find(view_id) == platform_views_.end()) { result->Error("Couldn't find the view id in the arguments"); return; diff --git a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc index ac87ab10..855687c2 100644 --- a/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc +++ b/src/flutter/shell/platform/linux_embedded/surface/context_egl.cc @@ -15,7 +15,7 @@ ContextEgl::ContextEgl(std::unique_ptr environment, : environment_(std::move(environment)), config_(nullptr) { EGLint config_count = 0; const EGLint attribs[] = { - // clang-format off + // clang-format off EGL_SURFACE_TYPE, egl_surface_type, EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_RED_SIZE, 8, @@ -27,10 +27,10 @@ ContextEgl::ContextEgl(std::unique_ptr environment, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 0, EGL_NONE - // clang-format on + // clang-format on }; const EGLint impeller_config_attributes[] = { - // clang-format off + // clang-format off EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, @@ -42,10 +42,10 @@ ContextEgl::ContextEgl(std::unique_ptr environment, EGL_SAMPLE_BUFFERS, 1, EGL_SAMPLES, 4, EGL_NONE - // clang-format on + // clang-format on }; const EGLint impeller_config_attributes_no_msaa[] = { - // clang-format off + // clang-format off EGL_RED_SIZE, 8, EGL_GREEN_SIZE, 8, EGL_BLUE_SIZE, 8, @@ -55,7 +55,7 @@ ContextEgl::ContextEgl(std::unique_ptr environment, EGL_DEPTH_SIZE, 0, EGL_STENCIL_SIZE, 8, EGL_NONE - // clang-format on + // clang-format on }; if (enable_impeller) { @@ -136,8 +136,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( EGLSurface surface = eglCreatePbufferSurface(environment_->Display(), config_, attribs); if (surface == EGL_NO_SURFACE) { - ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." - << "(" << get_egl_error_cause() << ")"; + ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." << "(" + << get_egl_error_cause() << ")"; } #else // eglCreatePbufferSurface isn't supported on both Wayland and GBM. @@ -146,8 +146,8 @@ std::unique_ptr ContextEgl::CreateOffscreenSurface( EGLSurface surface = eglCreateWindowSurface( environment_->Display(), config_, window->WindowOffscreen(), attribs); if (surface == EGL_NO_SURFACE) { - ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." - << "(" << get_egl_error_cause() << ")"; + ELINUX_LOG(WARNING) << "Failed to create EGL off-screen surface." << "(" + << get_egl_error_cause() << ")"; } #endif return std::make_unique(surface, environment_->Display(), diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h index 0bbb883a..fa1fb9e9 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_drm.h @@ -228,14 +228,10 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - uint16_t GetRotationDegree() const override { - return current_rotation_; - } + uint16_t GetRotationDegree() const override { return current_rotation_; } // |FlutterWindowBindingHandler| - double GetDpiScale() override { - return current_scale_; - } + double GetDpiScale() override { return current_scale_; } // |FlutterWindowBindingHandler| PhysicalWindowBounds GetPhysicalWindowBounds() override { @@ -243,9 +239,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - int32_t GetFrameRate() override { - return 60000; - } + int32_t GetFrameRate() override { return 60000; } // |FlutterWindowBindingHandler| void UpdateFlutterCursor(const std::string& cursor_name) override { @@ -260,9 +254,7 @@ class ELinuxWindowDrm : public ELinuxWindow, public WindowBindingHandler { } // |FlutterWindowBindingHandler| - std::string GetClipboardData() override { - return clipboard_data_; - } + std::string GetClipboardData() override { return clipboard_data_; } // |FlutterWindowBindingHandler| void SetClipboardData(const std::string& data) override { diff --git a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc index 5bd8e0c2..6467bf94 100644 --- a/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc +++ b/src/flutter/shell/platform/linux_embedded/window/elinux_window_wayland.cc @@ -697,11 +697,11 @@ const wl_output_listener ELinuxWindowWayland::kWlOutputListener = { self->request_redraw_ = true; } if (self->view_properties_.height > height) { - ELINUX_LOG(WARNING) << "Requested height size(" - << self->view_properties_.height << ") " - << "is larger than display size(" << height - << ")" - ", clipping"; + ELINUX_LOG(WARNING) + << "Requested height size(" << self->view_properties_.height + << ") " << "is larger than display size(" << height + << ")" + ", clipping"; self->view_properties_.height = height; self->request_redraw_ = true; } diff --git a/src/flutter/shell/platform/linux_embedded/window/native_window.h b/src/flutter/shell/platform/linux_embedded/window/native_window.h index a224b79a..57c40362 100644 --- a/src/flutter/shell/platform/linux_embedded/window/native_window.h +++ b/src/flutter/shell/platform/linux_embedded/window/native_window.h @@ -56,7 +56,7 @@ class NativeWindow { // Swaps frame buffers. This API performs processing only for the DRM-GBM // backend. It is prepared to make the interface common. - virtual void SwapBuffers(){/* do nothing. */}; + virtual void SwapBuffers() { /* do nothing. */ }; protected: EGLNativeWindowType window_; From 61b90d507d68b1db2ec891bf06537def68fc3ab8 Mon Sep 17 00:00:00 2001 From: Hidenori Date: Sat, 14 Dec 2024 05:16:58 +0900 Subject: [PATCH 176/178] embedder: merge embedder.h from flutter/engine (#430) Merged from https://github.com/flutter/engine/commits/3.27.0/shell/platform/embedder/embedder.h Signed-off-by: Hidenori Matsubayashi --- .../shell/platform/embedder/embedder.h | 273 +++++++++++++++--- 1 file changed, 232 insertions(+), 41 deletions(-) diff --git a/src/flutter/shell/platform/embedder/embedder.h b/src/flutter/shell/platform/embedder/embedder.h index d26e2215..9e9b875a 100644 --- a/src/flutter/shell/platform/embedder/embedder.h +++ b/src/flutter/shell/platform/embedder/embedder.h @@ -162,6 +162,8 @@ typedef enum { kFlutterSemanticsActionMoveCursorBackwardByWord = 1 << 20, /// Replace the current text in the text field. kFlutterSemanticsActionSetText = 1 << 21, + /// Request that the respective focusable widget gain input focus. + kFlutterSemanticsActionFocus = 1 << 22, } FlutterSemanticsAction; /// The set of properties that may be associated with a semantics node. @@ -302,6 +304,9 @@ typedef enum { /// Specifies an OpenGL frame-buffer target type. Framebuffers are specified /// using the FlutterOpenGLFramebuffer struct. kFlutterOpenGLTargetTypeFramebuffer, + /// Specifies an OpenGL on-screen surface target type. Surfaces are specified + /// using the FlutterOpenGLSurface struct. + kFlutterOpenGLTargetTypeSurface, } FlutterOpenGLTargetType; /// A pixel format to be used for software rendering. @@ -385,9 +390,14 @@ typedef struct { } FlutterOpenGLTexture; typedef struct { - /// The target of the color attachment of the frame-buffer. For example, - /// GL_TEXTURE_2D or GL_RENDERBUFFER. In case of ambiguity when dealing with - /// Window bound frame-buffers, 0 may be used. + /// The format of the color attachment of the frame-buffer. For example, + /// GL_RGBA8. + /// + /// In case of ambiguity when dealing with Window bound frame-buffers, 0 may + /// be used. + /// + /// @bug This field is incorrectly named as "target" when it actually + /// refers to a format. uint32_t target; /// The name of the framebuffer. @@ -401,6 +411,62 @@ typedef struct { VoidCallback destruction_callback; } FlutterOpenGLFramebuffer; +typedef bool (*FlutterOpenGLSurfaceCallback)(void* /* user data */, + bool* /* opengl state changed */); + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterOpenGLSurface). + size_t struct_size; + + /// User data to be passed to the make_current, clear_current and + /// destruction callbacks. + void* user_data; + + /// Callback invoked (on an engine-managed thread) that asks the embedder to + /// make the surface current. + /// + /// Should return true if the operation succeeded, false if the surface could + /// not be made current and rendering should be cancelled. + /// + /// The second parameter 'opengl state changed' should be set to true if + /// any OpenGL API state is different than before this callback was called. + /// In that case, Flutter will invalidate the internal OpenGL API state cache, + /// which is a somewhat expensive operation. + /// + /// @attention required. (non-null) + FlutterOpenGLSurfaceCallback make_current_callback; + + /// Callback invoked (on an engine-managed thread) when the current surface + /// can be cleared. + /// + /// Should return true if the operation succeeded, false if an error ocurred. + /// That error will be logged but otherwise not handled by the engine. + /// + /// The second parameter 'opengl state changed' is the same as with the + /// @ref make_current_callback. + /// + /// The embedder might clear the surface here after it was previously made + /// current. That's not required however, it's also possible to clear it in + /// the destruction callback. There's no way to signal OpenGL state + /// changes in the destruction callback though. + /// + /// @attention required. (non-null) + FlutterOpenGLSurfaceCallback clear_current_callback; + + /// Callback invoked (on an engine-managed thread) that asks the embedder to + /// collect the surface. + /// + /// @attention required. (non-null) + VoidCallback destruction_callback; + + /// The surface format. + /// + /// Allowed values: + /// - GL_RGBA8 + /// - GL_BGRA8_EXT + uint32_t format; +} FlutterOpenGLSurface; + typedef bool (*BoolCallback)(void* /* user data */); typedef FlutterTransformation (*TransformationCallback)(void* /* user data */); typedef uint32_t (*UIntCallback)(void* /* user data */); @@ -831,6 +897,86 @@ typedef struct { }; } FlutterRendererConfig; +/// Display refers to a graphics hardware system consisting of a framebuffer, +/// typically a monitor or a screen. This ID is unique per display and is +/// stable until the Flutter application restarts. +typedef uint64_t FlutterEngineDisplayId; + +typedef struct { + /// The size of this struct. Must be sizeof(FlutterWindowMetricsEvent). + size_t struct_size; + /// Physical width of the window. + size_t width; + /// Physical height of the window. + size_t height; + /// Scale factor for the physical screen. + double pixel_ratio; + /// Horizontal physical location of the left side of the window on the screen. + size_t left; + /// Vertical physical location of the top of the window on the screen. + size_t top; + /// Top inset of window. + double physical_view_inset_top; + /// Right inset of window. + double physical_view_inset_right; + /// Bottom inset of window. + double physical_view_inset_bottom; + /// Left inset of window. + double physical_view_inset_left; + /// The identifier of the display the view is rendering on. + FlutterEngineDisplayId display_id; + /// The view that this event is describing. + int64_t view_id; +} FlutterWindowMetricsEvent; + +typedef struct { + /// The size of this struct. + /// Must be sizeof(FlutterAddViewResult). + size_t struct_size; + + /// True if the add view operation succeeded. + bool added; + + /// The |FlutterAddViewInfo.user_data|. + void* user_data; +} FlutterAddViewResult; + +/// The callback invoked by the engine when the engine has attempted to add a +/// view. +/// +/// The |FlutterAddViewResult| is only guaranteed to be valid during this +/// callback. +typedef void (*FlutterAddViewCallback)(const FlutterAddViewResult* result); + +typedef struct { + /// The size of this struct. + /// Must be sizeof(FlutterAddViewInfo). + size_t struct_size; + + /// The identifier for the view to add. This must be unique. + FlutterViewId view_id; + + /// The view's properties. + /// + /// The metric's |view_id| must match this struct's |view_id|. + const FlutterWindowMetricsEvent* view_metrics; + + /// A baton that is not interpreted by the engine in any way. It will be given + /// back to the embedder in |add_view_callback|. Embedder resources may be + /// associated with this baton. + void* user_data; + + /// Called once the engine has attempted to add the view. This callback is + /// required. + /// + /// The embedder/app must not use the view until the callback is invoked with + /// an `added` value of `true`. + /// + /// This callback is invoked on an internal engine managed thread. Embedders + /// must re-thread if necessary. + FlutterAddViewCallback add_view_callback; +} FlutterAddViewInfo; + typedef struct { /// The size of this struct. /// Must be sizeof(FlutterRemoveViewResult). @@ -846,7 +992,8 @@ typedef struct { /// The callback invoked by the engine when the engine has attempted to remove /// a view. /// -/// The |FlutterRemoveViewResult| will be deallocated once the callback returns. +/// The |FlutterRemoveViewResult| is only guaranteed to be valid during this +/// callback. typedef void (*FlutterRemoveViewCallback)( const FlutterRemoveViewResult* /* result */); @@ -878,38 +1025,6 @@ typedef struct { FlutterRemoveViewCallback remove_view_callback; } FlutterRemoveViewInfo; -/// Display refers to a graphics hardware system consisting of a framebuffer, -/// typically a monitor or a screen. This ID is unique per display and is -/// stable until the Flutter application restarts. -typedef uint64_t FlutterEngineDisplayId; - -typedef struct { - /// The size of this struct. Must be sizeof(FlutterWindowMetricsEvent). - size_t struct_size; - /// Physical width of the window. - size_t width; - /// Physical height of the window. - size_t height; - /// Scale factor for the physical screen. - double pixel_ratio; - /// Horizontal physical location of the left side of the window on the screen. - size_t left; - /// Vertical physical location of the top of the window on the screen. - size_t top; - /// Top inset of window. - double physical_view_inset_top; - /// Right inset of window. - double physical_view_inset_right; - /// Bottom inset of window. - double physical_view_inset_bottom; - /// Left inset of window. - double physical_view_inset_left; - /// The identifier of the display the view is rendering on. - FlutterEngineDisplayId display_id; - /// The view that this event is describing. - int64_t view_id; -} FlutterWindowMetricsEvent; - /// The phase of the pointer event. typedef enum { kCancel, @@ -1482,7 +1597,7 @@ typedef void (*FlutterUpdateSemanticsCallback2)( /// An update to whether a message channel has a listener set or not. typedef struct { - // The size of the struct. Must be sizeof(FlutterChannelUpdate). + /// The size of the struct. Must be sizeof(FlutterChannelUpdate). size_t struct_size; /// The name of the channel. const char* channel; @@ -1563,6 +1678,9 @@ typedef struct { /// A framebuffer for Flutter to render into. The embedder must ensure that /// the framebuffer is complete. FlutterOpenGLFramebuffer framebuffer; + /// A surface for Flutter to render into. Basically a wrapper around + /// a closure that'll be called when the surface should be made current. + FlutterOpenGLSurface surface; }; } FlutterOpenGLBackingStore; @@ -1584,6 +1702,7 @@ typedef struct { } FlutterSoftwareBackingStore; typedef struct { + /// The size of this struct. Must be sizeof(FlutterSoftwareBackingStore2). size_t struct_size; /// A pointer to the raw bytes of the allocation described by this software /// backing store. @@ -1731,6 +1850,9 @@ typedef struct { size_t struct_size; /// The size of the render target the engine expects to render into. FlutterSize size; + /// The identifier for the view that the engine will use this backing store to + /// render into. + FlutterViewId view_id; } FlutterBackingStoreConfig; typedef enum { @@ -1754,6 +1876,7 @@ typedef struct { /// Contains additional information about the backing store provided /// during presentation to the embedder. typedef struct { + /// The size of this struct. Must be sizeof(FlutterBackingStorePresentInfo). size_t struct_size; /// The area of the backing store that contains Flutter contents. Pixels @@ -1844,18 +1967,26 @@ typedef struct { /// `FlutterBackingStore::struct_size` when specifying a new backing store to /// the engine. This only matters if the embedder expects to be used with /// engines older than the version whose headers it used during compilation. + /// + /// The callback should return true if the operation was successful. FlutterBackingStoreCreateCallback create_backing_store_callback; /// A callback invoked by the engine to release the backing store. The /// embedder may collect any resources associated with the backing store. + /// + /// The callback should return true if the operation was successful. FlutterBackingStoreCollectCallback collect_backing_store_callback; /// Callback invoked by the engine to composite the contents of each layer /// onto the implicit view. /// - /// DEPRECATED: Use |present_view_callback| to support multiple views. + /// DEPRECATED: Use `present_view_callback` to support multiple views. + /// If this callback is provided, `FlutterEngineAddView` and + /// `FlutterEngineRemoveView` should not be used. /// /// Only one of `present_layers_callback` and `present_view_callback` may be /// provided. Providing both is an error and engine initialization will /// terminate. + /// + /// The callback should return true if the operation was successful. FlutterLayersPresentCallback present_layers_callback; /// Avoid caching backing stores provided by this compositor. bool avoid_backing_store_cache; @@ -1865,6 +1996,8 @@ typedef struct { /// Only one of `present_layers_callback` and `present_view_callback` may be /// provided. Providing both is an error and engine initialization will /// terminate. + /// + /// The callback should return true if the operation was successful. FlutterPresentViewCallback present_view_callback; } FlutterCompositor; @@ -1905,7 +2038,7 @@ typedef const FlutterLocale* (*FlutterComputePlatformResolvedLocaleCallback)( size_t /* Number of locales*/); typedef struct { - /// This size of this struct. Must be sizeof(FlutterDisplay). + /// The size of this struct. Must be sizeof(FlutterEngineDisplay). size_t struct_size; FlutterEngineDisplayId display_id; @@ -2175,6 +2308,10 @@ typedef struct { /// `update_semantics_callback`, and /// `update_semantics_callback2` may be provided; the others /// should be set to null. + /// + /// This callback is incompatible with multiple views. If this + /// callback is provided, `FlutterEngineAddView` and + /// `FlutterEngineRemoveView` should not be used. FlutterUpdateSemanticsNodeCallback update_semantics_node_callback; /// The legacy callback invoked by the engine in order to give the embedder /// the chance to respond to updates to semantics custom actions from the Dart @@ -2191,6 +2328,10 @@ typedef struct { /// `update_semantics_callback`, and /// `update_semantics_callback2` may be provided; the others /// should be set to null. + /// + /// This callback is incompatible with multiple views. If this + /// callback is provided, `FlutterEngineAddView` and + /// `FlutterEngineRemoveView` should not be used. FlutterUpdateSemanticsCustomActionCallback update_semantics_custom_action_callback; /// Path to a directory used to store data that is cached across runs of a @@ -2340,6 +2481,10 @@ typedef struct { /// `update_semantics_callback`, and /// `update_semantics_callback2` may be provided; the others /// must be set to null. + /// + /// This callback is incompatible with multiple views. If this + /// callback is provided, `FlutterEngineAddView` and + /// `FlutterEngineRemoveView` should not be used. FlutterUpdateSemanticsCallback update_semantics_callback; /// The callback invoked by the engine in order to give the embedder the @@ -2505,12 +2650,50 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineRunInitialized( FLUTTER_API_SYMBOL(FlutterEngine) engine); +//------------------------------------------------------------------------------ +/// @brief Adds a view. +/// +/// This is an asynchronous operation. The view should not be used +/// until the |info.add_view_callback| is invoked with an |added| +/// value of true. The embedder should prepare resources in advance +/// but be ready to clean up on failure. +/// +/// A frame is scheduled if the operation succeeds. +/// +/// The callback is invoked on a thread managed by the engine. The +/// embedder should re-thread if needed. +/// +/// Attempting to add the implicit view will fail and will return +/// kInvalidArguments. Attempting to add a view with an already +/// existing view ID will fail, and |info.add_view_callback| will be +/// invoked with an |added| value of false. +/// +/// @param[in] engine A running engine instance. +/// @param[in] info The add view arguments. This can be deallocated +/// once |FlutterEngineAddView| returns, before +/// |add_view_callback| is invoked. +/// +/// @return The result of *starting* the asynchronous operation. If +/// `kSuccess`, the |add_view_callback| will be invoked. +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineAddView(FLUTTER_API_SYMBOL(FlutterEngine) + engine, + const FlutterAddViewInfo* info); + //------------------------------------------------------------------------------ /// @brief Removes a view. /// /// This is an asynchronous operation. The view's resources must not -/// be cleaned up until the |remove_view_callback| is invoked with -/// a |removed| value of `true`. +/// be cleaned up until |info.remove_view_callback| is invoked with +/// a |removed| value of true. +/// +/// The callback is invoked on a thread managed by the engine. The +/// embedder should re-thread if needed. +/// +/// Attempting to remove the implicit view will fail and will return +/// kInvalidArguments. Attempting to remove a view with a +/// non-existent view ID will fail, and |info.remove_view_callback| +/// will be invoked with a |removed| value of false. /// /// @param[in] engine A running engine instance. /// @param[in] info The remove view arguments. This can be deallocated @@ -3194,6 +3377,12 @@ typedef FlutterEngineResult (*FlutterEngineSetNextFrameCallbackFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, VoidCallback callback, void* user_data); +typedef FlutterEngineResult (*FlutterEngineAddViewFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterAddViewInfo* info); +typedef FlutterEngineResult (*FlutterEngineRemoveViewFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterRemoveViewInfo* info); /// Function-pointer-based versions of the APIs above. typedef struct { @@ -3240,6 +3429,8 @@ typedef struct { FlutterEngineNotifyDisplayUpdateFnPtr NotifyDisplayUpdate; FlutterEngineScheduleFrameFnPtr ScheduleFrame; FlutterEngineSetNextFrameCallbackFnPtr SetNextFrameCallback; + FlutterEngineAddViewFnPtr AddView; + FlutterEngineRemoveViewFnPtr RemoveView; } FlutterEngineProcTable; //------------------------------------------------------------------------------ From 4e74babc7d46fcd5614b1b4ca7e5a1519c430c06 Mon Sep 17 00:00:00 2001 From: Luke Howard Date: Mon, 10 Feb 2025 20:37:40 +1100 Subject: [PATCH 177/178] Mark FlutterELinuxEngine, FlutterELinuxView and FlutterELinuxTextureRegistrar as unsafe references for importing into Swift, consolidating Swift annotation macro wrappers into flutter_export.h. This patch allows the importing of C++ engine APIs into Swift, using the Swift C++ bridging layer. Signed-off-by: Luke Howard --- .../client_wrapper/include/flutter/texture_registrar.h | 2 +- .../shell/platform/common/public/flutter_export.h | 9 +++++++++ .../shell/platform/common/public/flutter_messenger.h | 8 ++++---- .../platform/common/public/flutter_plugin_registrar.h | 2 +- .../platform/linux_embedded/flutter_elinux_engine.h | 6 ++++-- .../shell/platform/linux_embedded/flutter_elinux_state.h | 6 ------ .../linux_embedded/flutter_elinux_texture_registrar.h | 2 +- .../shell/platform/linux_embedded/flutter_elinux_view.h | 2 +- .../platform/linux_embedded/public/flutter_elinux.h | 4 ++-- 9 files changed, 23 insertions(+), 18 deletions(-) diff --git a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h index 9b13025f..43f1147c 100644 --- a/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h +++ b/src/flutter/shell/platform/common/client_wrapper/include/flutter/texture_registrar.h @@ -136,7 +136,7 @@ class TextureRegistrar { // Unregisters an existing texture object. // DEPRECATED: Use UnregisterTexture(texture_id, optional_callback) instead. virtual bool UnregisterTexture(int64_t texture_id) = 0; -}; +} SWIFT_UNSAFE_REFERENCE; } // namespace flutter diff --git a/src/flutter/shell/platform/common/public/flutter_export.h b/src/flutter/shell/platform/common/public/flutter_export.h index 38cac85b..5fe8c593 100644 --- a/src/flutter/shell/platform/common/public/flutter_export.h +++ b/src/flutter/shell/platform/common/public/flutter_export.h @@ -25,4 +25,13 @@ #endif // FLUTTER_DESKTOP_LIBRARY +#if __has_include() +#include +#else +#define SWIFT_UNSAFE_REFERENCE +#define SWIFT_SHARED_REFERENCE(_retain, _release) +#define SWIFT_RETURNS_RETAINED +#define SWIFT_RETURNS_UNRETAINED +#endif + #endif // FLUTTER_SHELL_PLATFORM_COMMON_PUBLIC_FLUTTER_EXPORT_H_ diff --git a/src/flutter/shell/platform/common/public/flutter_messenger.h b/src/flutter/shell/platform/common/public/flutter_messenger.h index bb182cdf..d06385ca 100644 --- a/src/flutter/shell/platform/common/public/flutter_messenger.h +++ b/src/flutter/shell/platform/common/public/flutter_messenger.h @@ -93,8 +93,8 @@ FLUTTER_EXPORT void FlutterDesktopMessengerSetCallback( // Operation is thread-safe. // // See also: |FlutterDesktopMessengerRelease| -FLUTTER_EXPORT FlutterDesktopMessengerRef -FlutterDesktopMessengerAddRef(FlutterDesktopMessengerRef messenger); +FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopMessengerAddRef( + FlutterDesktopMessengerRef messenger) SWIFT_RETURNS_RETAINED; // Decrements the reference count for the |messenger|. // @@ -124,8 +124,8 @@ FLUTTER_EXPORT bool FlutterDesktopMessengerIsAvailable( // Returns the |messenger| value. // // See also: |FlutterDesktopMessengerUnlock| -FLUTTER_EXPORT FlutterDesktopMessengerRef -FlutterDesktopMessengerLock(FlutterDesktopMessengerRef messenger); +FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopMessengerLock( + FlutterDesktopMessengerRef messenger) SWIFT_RETURNS_UNRETAINED; // Unlocks the `FlutterDesktopMessengerRef`. // diff --git a/src/flutter/shell/platform/common/public/flutter_plugin_registrar.h b/src/flutter/shell/platform/common/public/flutter_plugin_registrar.h index b0847069..23a13b6d 100644 --- a/src/flutter/shell/platform/common/public/flutter_plugin_registrar.h +++ b/src/flutter/shell/platform/common/public/flutter_plugin_registrar.h @@ -26,7 +26,7 @@ typedef void (*FlutterDesktopOnPluginRegistrarDestroyed)( // Returns the engine messenger associated with this registrar. FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopPluginRegistrarGetMessenger( - FlutterDesktopPluginRegistrarRef registrar); + FlutterDesktopPluginRegistrarRef registrar) SWIFT_RETURNS_UNRETAINED; // Returns the texture registrar associated with this registrar. FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h index 4bcc7f10..c7eeee4d 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_engine.h @@ -71,7 +71,9 @@ class FlutterELinuxEngine { // Sets switches member to the given switches. void SetSwitches(const std::vector& switches); - FlutterDesktopMessengerRef messenger() { return messenger_.get(); } + FlutterDesktopMessengerRef messenger() SWIFT_RETURNS_UNRETAINED { + return messenger_.get(); + } IncomingMessageDispatcher* message_dispatcher() { return message_dispatcher_.get(); @@ -195,7 +197,7 @@ class FlutterELinuxEngine { std::unique_ptr vsync_waiter_; bool enable_impeller_ = false; -}; +} SWIFT_UNSAFE_REFERENCE; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h index aea43c4c..061f1e87 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_state.h @@ -9,12 +9,6 @@ #include #include -#if __has_include() -#include -#else -#define SWIFT_SHARED_REFERENCE(_retain, _release) -#endif - #include "flutter/shell/platform/common/client_wrapper/include/flutter/plugin_registrar.h" #include "flutter/shell/platform/common/incoming_message_dispatcher.h" #include "flutter/shell/platform/embedder/embedder.h" diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h index 8770ad57..6e75cb00 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_texture_registrar.h @@ -56,7 +56,7 @@ class FlutterELinuxTextureRegistrar { std::mutex map_mutex_; int64_t EmplaceTexture(std::unique_ptr texture); -}; +} SWIFT_UNSAFE_REFERENCE; }; // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h index 08740eff..0d6ed8d5 100644 --- a/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h +++ b/src/flutter/shell/platform/linux_embedded/flutter_elinux_view.h @@ -318,7 +318,7 @@ class FlutterELinuxView : public WindowBindingHandlerDelegate { // Current view rotation (FlutterTransformation). FlutterTransformation view_rotation_transformation_ = { 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0}; -}; +} SWIFT_UNSAFE_REFERENCE; } // namespace flutter diff --git a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h index 2597aa47..eacb5269 100644 --- a/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h +++ b/src/flutter/shell/platform/linux_embedded/public/flutter_elinux.h @@ -216,8 +216,8 @@ FLUTTER_EXPORT FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView( FlutterDesktopPluginRegistrarRef registrar); // Returns the messenger associated with the engine. -FLUTTER_EXPORT FlutterDesktopMessengerRef -FlutterDesktopEngineGetMessenger(FlutterDesktopEngineRef engine); +FLUTTER_EXPORT FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger( + FlutterDesktopEngineRef engine) SWIFT_RETURNS_UNRETAINED; // Returns the texture registrar associated with the engine. FLUTTER_EXPORT FlutterDesktopTextureRegistrarRef From 846588a8cf1e6708fb3a5f39a21e18e32004de7a Mon Sep 17 00:00:00 2001 From: Takahiro Okayama Date: Tue, 18 Mar 2025 11:19:47 +0900 Subject: [PATCH 178/178] Update contributing policy to be the same as flutter-elinux. --- CONTRIBUTING.md | 2 ++ README.md | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..4f2807de --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,2 @@ +# Contributing to flutter-embedded-linux +Welcome to this project. We welcome all your contribution and feedback. If you've never submitted code before, you must add your (or your organization's) name and contact info to the [AUTHORS](./AUTHORS) file. diff --git a/README.md b/README.md index cd06c6b8..c5c6bd64 100644 --- a/README.md +++ b/README.md @@ -41,10 +41,3 @@ Documentation for this software can be found at [Wiki](https://github.com/sony/f ## Supported platforms This embedder supports x64 and Arm64 (aarch64, ARMv8) architectures on Linux which supports either Wayland backend or DRM backend. See [Support status](https://github.com/sony/flutter-elinux/wiki/Support-status) for details. - -## Contributing -**Now, we cannot accept any Pull Request (PR).** Because We are building a system (e.g. CLA) to accept PRs, so please wait for a while the system is getting ready! However, we are always welcome to report bugs and request new features by creating issues. - -With the assumption, our final goal of this software openly is to be merged this embedder into [Flutter Engine](https://github.com/flutter/engine) after getting feedbacks. And [Google CLA](https://cla.developers.google.com/about/google-corporate) will be required when we do that in the future. Therefore, we cannot easily accept an external PR. However, you can free to create issues for reporting bugs and requesting new features. - -See also: [Contributing to the Flutter engine](https://github.com/flutter/engine/blob/master/CONTRIBUTING.md)