Skip to content

Commit

Permalink
Add vsync wayland support (#140)
Browse files Browse the repository at this point in the history
Closed #68
  • Loading branch information
Hidenori Matsubayashi committed May 26, 2021
1 parent 89b6a49 commit 09458fc
Show file tree
Hide file tree
Showing 25 changed files with 352 additions and 52 deletions.
7 changes: 7 additions & 0 deletions cmake/build.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-drm-eglstream-backend/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-drm-gbm-backend/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-external-texture-plugin/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-wayland-client/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-weston-desktop-shell/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
14 changes: 9 additions & 5 deletions examples/flutter-x11-client/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "flutter_window.h"

#include <chrono>
#include <cmath>
#include <iostream>
#include <thread>

#include "generated_plugin_registrant.h"
Expand Down Expand Up @@ -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<int>(std::trunc(1000000.0 / frame_rate))));
}
next_flutter_event_time =
std::max(next_flutter_event_time, next_event_time);
Expand Down
3 changes: 3 additions & 0 deletions src/client_wrapper/include/flutter/flutter_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 4 additions & 0 deletions src/flutter/shell/platform/linux_embedded/flutter_linuxes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ FlutterLinuxesEngine::FlutterLinuxesEngine(const FlutterProjectBundle& project)
std::make_unique<BasicMessageChannel<rapidjson::Document>>(
messenger_wrapper_.get(), "flutter/settings",
&JsonMessageCodec::GetInstance());

vsync_waiter_ = std::make_unique<VsyncWaiter>();
}

FlutterLinuxesEngine::~FlutterLinuxesEngine() { Stop(); }
Expand Down Expand Up @@ -204,7 +206,15 @@ bool FlutterLinuxesEngine::RunWithEntrypoint(const char* entrypoint) {
auto host = static_cast<FlutterLinuxesEngine*>(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<FlutterLinuxesEngine*>(user_data);
host->vsync_waiter_->NotifyWaitForVsync(baton);
};
#endif
args.custom_task_runners = &custom_task_runners;

if (aot_data_) {
Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -158,6 +163,9 @@ class FlutterLinuxesEngine {
// is being destroyed.
FlutterDesktopOnPluginRegistrarDestroyed
plugin_registrar_destruction_callback_ = nullptr;

// The vsync waiter.
std::unique_ptr<VsyncWaiter> vsync_waiter_;
};

} // namespace flutter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -381,4 +386,8 @@ LinuxesRenderSurfaceTarget* FlutterLinuxesView::GetRenderSurfaceTarget() const {

FlutterLinuxesEngine* FlutterLinuxesView::GetEngine() { return engine_.get(); }

int32_t FlutterLinuxesView::GetFrameRate() {
return binding_handler_->GetFrameRate();
}

} // namespace flutter
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Loading

0 comments on commit 09458fc

Please sign in to comment.