From 63f96344f7c32590681e9761590753582ef0f306 Mon Sep 17 00:00:00 2001 From: Hidenori Matsubayashi Date: Mon, 7 Aug 2023 13:23:00 +0000 Subject: [PATCH] egl: add async buffer swapping command option 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 | 4 +- .../window/native_window_drm_eglstream.h | 3 +- .../window/native_window_drm_gbm.cc | 4 +- .../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, 327 insertions(+), 102 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..f13dc8f4 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) + const uint16_t rotation, + bool enable_vsync) : NativeWindowDrm(device_filename, rotation) { 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..c6c0f44a 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) + const uint16_t rotation, + bool enable_vsync) : NativeWindowDrm(device_filename, rotation) { 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();