Flutter Engine
The Flutter Engine
VsyncWaiter.java
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
5package io.flutter.view;
6
7import android.hardware.display.DisplayManager;
8import android.view.Choreographer;
9import android.view.Display;
10import androidx.annotation.NonNull;
11import androidx.annotation.VisibleForTesting;
12import io.flutter.embedding.engine.FlutterJNI;
13
14// TODO(mattcarroll): add javadoc.
15public class VsyncWaiter {
16 class DisplayListener implements DisplayManager.DisplayListener {
17 DisplayListener(DisplayManager displayManager) {
18 this.displayManager = displayManager;
19 }
20
21 private DisplayManager displayManager;
22
23 void register() {
24 displayManager.registerDisplayListener(this, null);
25 }
26
27 @Override
28 public void onDisplayAdded(int displayId) {}
29
30 @Override
31 public void onDisplayRemoved(int displayId) {}
32
33 @Override
34 public void onDisplayChanged(int displayId) {
35 if (displayId == Display.DEFAULT_DISPLAY) {
36 final Display primaryDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
37 float fps = primaryDisplay.getRefreshRate();
38 VsyncWaiter.this.refreshPeriodNanos = (long) (1000000000.0 / fps);
39 VsyncWaiter.this.flutterJNI.setRefreshRateFPS(fps);
40 }
41 }
42 }
43
44 private static VsyncWaiter instance;
45 private static DisplayListener listener;
46 private long refreshPeriodNanos = -1;
47 private FlutterJNI flutterJNI;
48 private FrameCallback frameCallback = new FrameCallback(0);
49
50 @NonNull
51 public static VsyncWaiter getInstance(float fps, @NonNull FlutterJNI flutterJNI) {
52 if (instance == null) {
53 instance = new VsyncWaiter(flutterJNI);
54 }
55 flutterJNI.setRefreshRateFPS(fps);
56 instance.refreshPeriodNanos = (long) (1000000000.0 / fps);
57 return instance;
58 }
59
60 @NonNull
61 public static VsyncWaiter getInstance(
62 @NonNull DisplayManager displayManager, @NonNull FlutterJNI flutterJNI) {
63 if (instance == null) {
64 instance = new VsyncWaiter(flutterJNI);
65 }
66 if (listener == null) {
67 listener = instance.new DisplayListener(displayManager);
68 listener.register();
69 }
70 if (instance.refreshPeriodNanos == -1) {
71 final Display primaryDisplay = displayManager.getDisplay(Display.DEFAULT_DISPLAY);
72 float fps = primaryDisplay.getRefreshRate();
73 instance.refreshPeriodNanos = (long) (1000000000.0 / fps);
74 flutterJNI.setRefreshRateFPS(fps);
75 }
76 return instance;
77 }
78
79 // For tests, to reset the singleton between tests.
80 @VisibleForTesting
81 public static void reset() {
82 instance = null;
83 listener = null;
84 }
85
86 private class FrameCallback implements Choreographer.FrameCallback {
87
88 private long cookie;
89
90 FrameCallback(long cookie) {
91 this.cookie = cookie;
92 }
93
94 @Override
95 public void doFrame(long frameTimeNanos) {
96 long delay = System.nanoTime() - frameTimeNanos;
97 if (delay < 0) {
98 delay = 0;
99 }
100 flutterJNI.onVsync(delay, refreshPeriodNanos, cookie);
101 frameCallback = this;
102 }
103 }
104
105 private final FlutterJNI.AsyncWaitForVsyncDelegate asyncWaitForVsyncDelegate =
106 new FlutterJNI.AsyncWaitForVsyncDelegate() {
107
108 private Choreographer.FrameCallback obtainFrameCallback(final long cookie) {
109 if (frameCallback != null) {
110 frameCallback.cookie = cookie;
111 FrameCallback ret = frameCallback;
112 frameCallback = null;
113 return ret;
114 }
115 return new FrameCallback(cookie);
116 }
117
118 @Override
119 public void asyncWaitForVsync(long cookie) {
120 Choreographer.getInstance().postFrameCallback(obtainFrameCallback(cookie));
121 }
122 };
123
124 private VsyncWaiter(@NonNull FlutterJNI flutterJNI) {
125 this.flutterJNI = flutterJNI;
126 }
127
128 public void init() {
129 flutterJNI.setAsyncWaitForVsyncDelegate(asyncWaitForVsyncDelegate);
130 }
131}
void setRefreshRateFPS(float refreshRateFPS)
void setAsyncWaitForVsyncDelegate(@Nullable AsyncWaitForVsyncDelegate delegate)
void onVsync(long frameDelayNanos, long refreshPeriodNanos, long cookie)
DisplayListener(DisplayManager displayManager)
static VsyncWaiter getInstance(float fps, @NonNull FlutterJNI flutterJNI)
static VsyncWaiter getInstance( @NonNull DisplayManager displayManager, @NonNull FlutterJNI flutterJNI)
VkInstance instance
Definition: main.cc:48