Flutter Engine
vsync_waiter_android.cc
Go to the documentation of this file.
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 #include "flutter/shell/platform/android/vsync_waiter_android.h"
6 
7 #include <cmath>
8 #include <utility>
9 
10 #include "flutter/common/task_runners.h"
11 #include "flutter/fml/logging.h"
12 #include "flutter/fml/platform/android/jni_util.h"
13 #include "flutter/fml/platform/android/scoped_java_ref.h"
14 #include "flutter/fml/size.h"
15 #include "flutter/fml/trace_event.h"
16 
17 namespace flutter {
18 
20 static jmethodID g_async_wait_for_vsync_method_ = nullptr;
21 
23  : VsyncWaiter(std::move(task_runners)) {}
24 
26 
27 // |VsyncWaiter|
28 void VsyncWaiterAndroid::AwaitVSync() {
29  auto* weak_this = new std::weak_ptr<VsyncWaiter>(shared_from_this());
30  jlong java_baton = reinterpret_cast<jlong>(weak_this);
31 
32  task_runners_.GetPlatformTaskRunner()->PostTask([java_baton]() {
33  JNIEnv* env = fml::jni::AttachCurrentThread();
34  env->CallStaticVoidMethod(g_vsync_waiter_class->obj(), //
36  java_baton //
37  );
38  });
39 }
40 
41 // static
42 void VsyncWaiterAndroid::OnNativeVsync(JNIEnv* env,
43  jclass jcaller,
44  jlong frameTimeNanos,
45  jlong frameTargetTimeNanos,
46  jlong java_baton) {
47  TRACE_EVENT0("flutter", "VSYNC");
48 
49  auto frame_time = fml::TimePoint::FromEpochDelta(
50  fml::TimeDelta::FromNanoseconds(frameTimeNanos));
51  auto target_time = fml::TimePoint::FromEpochDelta(
52  fml::TimeDelta::FromNanoseconds(frameTargetTimeNanos));
53 
54  ConsumePendingCallback(java_baton, frame_time, target_time);
55 }
56 
57 // static
58 void VsyncWaiterAndroid::ConsumePendingCallback(
59  jlong java_baton,
60  fml::TimePoint frame_start_time,
61  fml::TimePoint frame_target_time) {
62  auto* weak_this = reinterpret_cast<std::weak_ptr<VsyncWaiter>*>(java_baton);
63  auto shared_this = weak_this->lock();
64  delete weak_this;
65 
66  if (shared_this) {
67  shared_this->FireCallback(frame_start_time, frame_target_time);
68  }
69 }
70 
71 // static
72 bool VsyncWaiterAndroid::Register(JNIEnv* env) {
73  static const JNINativeMethod methods[] = {{
74  .name = "nativeOnVsync",
75  .signature = "(JJJ)V",
76  .fnPtr = reinterpret_cast<void*>(&OnNativeVsync),
77  }};
78 
79  jclass clazz = env->FindClass("io/flutter/embedding/engine/FlutterJNI");
80 
81  if (clazz == nullptr) {
82  return false;
83  }
84 
85  g_vsync_waiter_class = new fml::jni::ScopedJavaGlobalRef<jclass>(env, clazz);
86 
87  FML_CHECK(!g_vsync_waiter_class->is_null());
88 
89  g_async_wait_for_vsync_method_ = env->GetStaticMethodID(
90  g_vsync_waiter_class->obj(), "asyncWaitForVsync", "(J)V");
91 
92  FML_CHECK(g_async_wait_for_vsync_method_ != nullptr);
93 
94  return env->RegisterNatives(clazz, methods, fml::size(methods)) == 0;
95 }
96 
97 } // namespace flutter
static fml::jni::ScopedJavaGlobalRef< jclass > * g_vsync_waiter_class
static jmethodID g_async_wait_for_vsync_method_
#define TRACE_EVENT0(category_group, name)
Definition: trace_event.h:75
static constexpr TimeDelta FromNanoseconds(int64_t nanos)
Definition: time_delta.h:40
Definition: ref_ptr.h:252
fml::RefPtr< fml::TaskRunner > GetPlatformTaskRunner() const
Definition: task_runners.cc:30
virtual void PostTask(const fml::closure &task)
Definition: task_runner.cc:24
constexpr std::size_t size(T(&array)[N])
Definition: size.h:13
static constexpr TimePoint FromEpochDelta(TimeDelta ticks)
Definition: time_point.h:36
VsyncWaiterAndroid(flutter::TaskRunners task_runners)
static bool Register(JNIEnv *env)
#define FML_CHECK(condition)
Definition: logging.h:68
JNIEnv * AttachCurrentThread()
Definition: jni_util.cc:26
const TaskRunners task_runners_
Definition: vsync_waiter.h:39