blob: edd3f1a8de9802af73587de6780ddd27993e1a81 [file] [log] [blame]
Jeff Brown0a0a1242011-12-02 02:25:22 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.view;
18
Mathew Inwoode5ad5982018-08-17 15:07:52 +010019import android.annotation.UnsupportedAppUsage;
Jeff Brown0a0a1242011-12-02 02:25:22 -080020import android.os.Looper;
21import android.os.MessageQueue;
22import android.util.Log;
23
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070024import dalvik.annotation.optimization.FastNative;
25import dalvik.system.CloseGuard;
26
Jeff Brown3b4049e2015-04-17 15:22:27 -070027import java.lang.ref.WeakReference;
28
Jeff Brown0a0a1242011-12-02 02:25:22 -080029/**
30 * Provides a low-level mechanism for an application to receive display events
31 * such as vertical sync.
Jeff Brown58aedbc2012-02-13 20:15:01 -080032 *
33 * The display event receive is NOT thread safe. Moreover, its methods must only
34 * be called on the Looper thread to which it is attached.
35 *
Jeff Brown0a0a1242011-12-02 02:25:22 -080036 * @hide
37 */
38public abstract class DisplayEventReceiver {
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -070039
40 /**
41 * When retrieving vsync events, this specifies that the vsync event should happen at the normal
42 * vsync-app tick.
43 * <p>
44 * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
45 */
46 public static final int VSYNC_SOURCE_APP = 0;
47
48 /**
49 * When retrieving vsync events, this specifies that the vsync event should happen whenever
50 * Surface Flinger is processing a frame.
51 * <p>
52 * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
53 */
54 public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1;
55
Jeff Brown0a0a1242011-12-02 02:25:22 -080056 private static final String TAG = "DisplayEventReceiver";
57
58 private final CloseGuard mCloseGuard = CloseGuard.get();
59
Mathew Inwoode5ad5982018-08-17 15:07:52 +010060 @UnsupportedAppUsage
Ashok Bhat27285822013-12-18 18:00:05 +000061 private long mReceiverPtr;
Jeff Brown0a0a1242011-12-02 02:25:22 -080062
63 // We keep a reference message queue object here so that it is not
64 // GC'd while the native peer of the receiver is using them.
65 private MessageQueue mMessageQueue;
66
Jeff Brown3b4049e2015-04-17 15:22:27 -070067 private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -070068 MessageQueue messageQueue, int vsyncSource);
Ashok Bhat27285822013-12-18 18:00:05 +000069 private static native void nativeDispose(long receiverPtr);
John Recke46af372016-10-03 16:21:30 -070070 @FastNative
Ashok Bhat27285822013-12-18 18:00:05 +000071 private static native void nativeScheduleVsync(long receiverPtr);
Jeff Brown0a0a1242011-12-02 02:25:22 -080072
73 /**
74 * Creates a display event receiver.
75 *
76 * @param looper The looper to use when invoking callbacks.
Wale Ogunwale71f30992017-06-19 13:53:32 -070077 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +010078 @UnsupportedAppUsage
Wale Ogunwale71f30992017-06-19 13:53:32 -070079 public DisplayEventReceiver(Looper looper) {
80 this(looper, VSYNC_SOURCE_APP);
81 }
82
83 /**
84 * Creates a display event receiver.
85 *
86 * @param looper The looper to use when invoking callbacks.
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -070087 * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
Jeff Brown0a0a1242011-12-02 02:25:22 -080088 */
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -070089 public DisplayEventReceiver(Looper looper, int vsyncSource) {
Jeff Brown0a0a1242011-12-02 02:25:22 -080090 if (looper == null) {
91 throw new IllegalArgumentException("looper must not be null");
92 }
93
94 mMessageQueue = looper.getQueue();
Jorim Jaggi34a0cdb2017-06-08 15:40:38 -070095 mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
96 vsyncSource);
Jeff Brown0a0a1242011-12-02 02:25:22 -080097
98 mCloseGuard.open("dispose");
99 }
100
101 @Override
102 protected void finalize() throws Throwable {
103 try {
Jeff Brown3e7e7f02012-08-27 14:33:53 -0700104 dispose(true);
Jeff Brown0a0a1242011-12-02 02:25:22 -0800105 } finally {
106 super.finalize();
107 }
108 }
109
110 /**
111 * Disposes the receiver.
112 */
113 public void dispose() {
Jeff Brown3e7e7f02012-08-27 14:33:53 -0700114 dispose(false);
115 }
116
117 private void dispose(boolean finalized) {
Jeff Brown0a0a1242011-12-02 02:25:22 -0800118 if (mCloseGuard != null) {
Jeff Brown3e7e7f02012-08-27 14:33:53 -0700119 if (finalized) {
120 mCloseGuard.warnIfOpen();
121 }
Jeff Brown0a0a1242011-12-02 02:25:22 -0800122 mCloseGuard.close();
123 }
Jeff Brown3e7e7f02012-08-27 14:33:53 -0700124
Jeff Brown0a0a1242011-12-02 02:25:22 -0800125 if (mReceiverPtr != 0) {
126 nativeDispose(mReceiverPtr);
127 mReceiverPtr = 0;
128 }
129 mMessageQueue = null;
130 }
131
132 /**
133 * Called when a vertical sync pulse is received.
134 * The recipient should render a frame and then call {@link #scheduleVsync}
135 * to schedule the next vertical sync pulse.
136 *
137 * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
138 * timebase.
Jeff Browne87bf032012-09-20 18:30:13 -0700139 * @param builtInDisplayId The surface flinger built-in display id such as
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800140 * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
Jeff Brown0a0a1242011-12-02 02:25:22 -0800141 * @param frame The frame number. Increases by one for each vertical sync interval.
142 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100143 @UnsupportedAppUsage
Jeff Browne87bf032012-09-20 18:30:13 -0700144 public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
145 }
146
147 /**
148 * Called when a display hotplug event is received.
149 *
150 * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
151 * timebase.
152 * @param builtInDisplayId The surface flinger built-in display id such as
Mathias Agopian3866f0d2013-02-11 22:08:48 -0800153 * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
Jeff Browne87bf032012-09-20 18:30:13 -0700154 * @param connected True if the display is connected, false if it disconnected.
155 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100156 @UnsupportedAppUsage
Jeff Browne87bf032012-09-20 18:30:13 -0700157 public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
Jeff Brown0a0a1242011-12-02 02:25:22 -0800158 }
159
160 /**
161 * Schedules a single vertical sync pulse to be delivered when the next
162 * display frame begins.
163 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100164 @UnsupportedAppUsage
Jeff Brown0a0a1242011-12-02 02:25:22 -0800165 public void scheduleVsync() {
166 if (mReceiverPtr == 0) {
167 Log.w(TAG, "Attempted to schedule a vertical sync pulse but the display event "
168 + "receiver has already been disposed.");
169 } else {
170 nativeScheduleVsync(mReceiverPtr);
171 }
172 }
173
174 // Called from native code.
175 @SuppressWarnings("unused")
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100176 @UnsupportedAppUsage
Jeff Browne87bf032012-09-20 18:30:13 -0700177 private void dispatchVsync(long timestampNanos, int builtInDisplayId, int frame) {
178 onVsync(timestampNanos, builtInDisplayId, frame);
179 }
180
181 // Called from native code.
182 @SuppressWarnings("unused")
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100183 @UnsupportedAppUsage
Jeff Browne87bf032012-09-20 18:30:13 -0700184 private void dispatchHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
185 onHotplug(timestampNanos, builtInDisplayId, connected);
Jeff Brown0a0a1242011-12-02 02:25:22 -0800186 }
187}