1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#define FML_USED_ON_EMBEDDER
6
7#include "flutter/shell/common/shell_test.h"
8
9#include "flutter/flow/layers/layer_tree.h"
10#include "flutter/flow/layers/transform_layer.h"
11#include "flutter/fml/make_copyable.h"
12#include "flutter/fml/mapping.h"
13#include "flutter/runtime/dart_vm.h"
14#include "flutter/testing/testing.h"
15
16namespace flutter {
17namespace testing {
18
19void ShellTestVsyncClock::SimulateVSync() {
20 std::scoped_lock lock(mutex_);
21 if (vsync_issued_ >= vsync_promised_.size()) {
22 vsync_promised_.emplace_back();
23 }
24 FML_CHECK(vsync_issued_ < vsync_promised_.size());
25 vsync_promised_[vsync_issued_].set_value(vsync_issued_);
26 vsync_issued_ += 1;
27}
28
29std::future<int> ShellTestVsyncClock::NextVSync() {
30 std::scoped_lock lock(mutex_);
31 vsync_promised_.emplace_back();
32 return vsync_promised_.back().get_future();
33}
34
35void ShellTestVsyncWaiter::AwaitVSync() {
36 FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
37 auto vsync_future = clock_->NextVSync();
38
39 auto async_wait = std::async([&vsync_future, this]() {
40 vsync_future.wait();
41
42 // Post the `FireCallback` to the Platform thread so earlier Platform tasks
43 // (specifically, the `VSyncFlush` call) will be finished before
44 // `FireCallback` is executed. This is only needed for our unit tests.
45 //
46 // Without this, the repeated VSYNC signals in `VSyncFlush` may start both
47 // the current frame in the UI thread and the next frame in the secondary
48 // callback (both of them are waiting for VSYNCs). That breaks the unit
49 // test's assumption that each frame's VSYNC must be issued by different
50 // `VSyncFlush` call (which resets the `will_draw_new_frame` bit).
51 //
52 // For example, HandlesActualIphoneXsInputEvents will fail without this.
53 task_runners_.GetPlatformTaskRunner()->PostTask([this]() {
54 FireCallback(fml::TimePoint::Now(), fml::TimePoint::Now());
55 });
56 });
57}
58
59void ConstantFiringVsyncWaiter::AwaitVSync() {
60 FML_DCHECK(task_runners_.GetUITaskRunner()->RunsTasksOnCurrentThread());
61 auto async_wait = std::async([this]() {
62 task_runners_.GetPlatformTaskRunner()->PostTask(
63 [this]() { FireCallback(frame_begin_time, frame_target_time); });
64 });
65}
66
67} // namespace testing
68} // namespace flutter
69