Loading core/java/android/view/Choreographer.java +30 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.view; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; import android.hardware.display.DisplayManagerGlobal; import android.os.Handler; import android.os.Looper; Loading Loading @@ -102,7 +105,20 @@ public final class Choreographer { if (looper == null) { throw new IllegalStateException("The current thread must have a looper!"); } return new Choreographer(looper); return new Choreographer(looper, VSYNC_SOURCE_APP); } }; // Thread local storage for the SF choreographer. private static final ThreadLocal<Choreographer> sSfThreadInstance = new ThreadLocal<Choreographer>() { @Override protected Choreographer initialValue() { Looper looper = Looper.myLooper(); if (looper == null) { throw new IllegalStateException("The current thread must have a looper!"); } return new Choreographer(looper, VSYNC_SOURCE_SURFACE_FLINGER); } }; Loading Loading @@ -202,10 +218,12 @@ public final class Choreographer { private static final int CALLBACK_LAST = CALLBACK_COMMIT; private Choreographer(Looper looper) { private Choreographer(Looper looper, int vsyncSource) { mLooper = looper; mHandler = new FrameHandler(looper); mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null; mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper, vsyncSource) : null; mLastFrameTimeNanos = Long.MIN_VALUE; mFrameIntervalNanos = (long)(1000000000 / getRefreshRate()); Loading Loading @@ -233,6 +251,13 @@ public final class Choreographer { return sThreadInstance.get(); } /** * @hide */ public static Choreographer getSfInstance() { return sSfThreadInstance.get(); } /** Destroys the calling thread's choreographer * @hide */ Loading Loading @@ -816,8 +841,8 @@ public final class Choreographer { private long mTimestampNanos; private int mFrame; public FrameDisplayEventReceiver(Looper looper) { super(looper); public FrameDisplayEventReceiver(Looper looper, int vsyncSource) { super(looper, vsyncSource); } @Override Loading core/java/android/view/DisplayEventReceiver.java +22 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,23 @@ import java.lang.ref.WeakReference; * @hide */ public abstract class DisplayEventReceiver { /** * When retrieving vsync events, this specifies that the vsync event should happen at the normal * vsync-app tick. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ public static final int VSYNC_SOURCE_APP = 0; /** * When retrieving vsync events, this specifies that the vsync event should happen whenever * Surface Flinger is processing a frame. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1; private static final String TAG = "DisplayEventReceiver"; private final CloseGuard mCloseGuard = CloseGuard.get(); Loading @@ -46,7 +63,7 @@ public abstract class DisplayEventReceiver { private MessageQueue mMessageQueue; private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, MessageQueue messageQueue); MessageQueue messageQueue, int vsyncSource); private static native void nativeDispose(long receiverPtr); @FastNative private static native void nativeScheduleVsync(long receiverPtr); Loading @@ -55,14 +72,16 @@ public abstract class DisplayEventReceiver { * Creates a display event receiver. * * @param looper The looper to use when invoking callbacks. * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values. */ public DisplayEventReceiver(Looper looper) { public DisplayEventReceiver(Looper looper, int vsyncSource) { if (looper == null) { throw new IllegalArgumentException("looper must not be null"); } mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue, vsyncSource); mCloseGuard.open("dispose"); } Loading core/jni/android_view_DisplayEventReceiver.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ static struct { class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue); jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource); void dispose(); Loading @@ -65,8 +65,9 @@ private: NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue) : DisplayEventDispatcher(messageQueue->getLooper()), jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) : DisplayEventDispatcher(messageQueue->getLooper(), static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); Loading Loading @@ -113,7 +114,7 @@ void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) { jobject messageQueueObj, jint vsyncSource) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); Loading @@ -121,7 +122,7 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue); receiverWeak, messageQueue, vsyncSource); status_t status = receiver->initialize(); if (status) { String8 message; Loading Loading @@ -156,7 +157,7 @@ static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) { static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;)J", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;I)J", (void*)nativeInit }, { "nativeDispose", "(J)V", Loading libs/androidfw/DisplayEventDispatcher.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -33,8 +33,9 @@ namespace android { // using just a few large reads. static const size_t EVENT_BUFFER_SIZE = 100; DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper) : mLooper(looper), mWaitingForVsync(false) { DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource) : mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) { ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this); } Loading libs/androidfw/include/androidfw/DisplayEventDispatcher.h +2 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ namespace android { class DisplayEventDispatcher : public LooperCallback { public: DisplayEventDispatcher(const sp<Looper>& looper); DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp); status_t initialize(); void dispose(); Loading Loading
core/java/android/view/Choreographer.java +30 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package android.view; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP; import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER; import android.hardware.display.DisplayManagerGlobal; import android.os.Handler; import android.os.Looper; Loading Loading @@ -102,7 +105,20 @@ public final class Choreographer { if (looper == null) { throw new IllegalStateException("The current thread must have a looper!"); } return new Choreographer(looper); return new Choreographer(looper, VSYNC_SOURCE_APP); } }; // Thread local storage for the SF choreographer. private static final ThreadLocal<Choreographer> sSfThreadInstance = new ThreadLocal<Choreographer>() { @Override protected Choreographer initialValue() { Looper looper = Looper.myLooper(); if (looper == null) { throw new IllegalStateException("The current thread must have a looper!"); } return new Choreographer(looper, VSYNC_SOURCE_SURFACE_FLINGER); } }; Loading Loading @@ -202,10 +218,12 @@ public final class Choreographer { private static final int CALLBACK_LAST = CALLBACK_COMMIT; private Choreographer(Looper looper) { private Choreographer(Looper looper, int vsyncSource) { mLooper = looper; mHandler = new FrameHandler(looper); mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper) : null; mDisplayEventReceiver = USE_VSYNC ? new FrameDisplayEventReceiver(looper, vsyncSource) : null; mLastFrameTimeNanos = Long.MIN_VALUE; mFrameIntervalNanos = (long)(1000000000 / getRefreshRate()); Loading Loading @@ -233,6 +251,13 @@ public final class Choreographer { return sThreadInstance.get(); } /** * @hide */ public static Choreographer getSfInstance() { return sSfThreadInstance.get(); } /** Destroys the calling thread's choreographer * @hide */ Loading Loading @@ -816,8 +841,8 @@ public final class Choreographer { private long mTimestampNanos; private int mFrame; public FrameDisplayEventReceiver(Looper looper) { super(looper); public FrameDisplayEventReceiver(Looper looper, int vsyncSource) { super(looper, vsyncSource); } @Override Loading
core/java/android/view/DisplayEventReceiver.java +22 −3 Original line number Diff line number Diff line Loading @@ -35,6 +35,23 @@ import java.lang.ref.WeakReference; * @hide */ public abstract class DisplayEventReceiver { /** * When retrieving vsync events, this specifies that the vsync event should happen at the normal * vsync-app tick. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ public static final int VSYNC_SOURCE_APP = 0; /** * When retrieving vsync events, this specifies that the vsync event should happen whenever * Surface Flinger is processing a frame. * <p> * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h */ public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1; private static final String TAG = "DisplayEventReceiver"; private final CloseGuard mCloseGuard = CloseGuard.get(); Loading @@ -46,7 +63,7 @@ public abstract class DisplayEventReceiver { private MessageQueue mMessageQueue; private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, MessageQueue messageQueue); MessageQueue messageQueue, int vsyncSource); private static native void nativeDispose(long receiverPtr); @FastNative private static native void nativeScheduleVsync(long receiverPtr); Loading @@ -55,14 +72,16 @@ public abstract class DisplayEventReceiver { * Creates a display event receiver. * * @param looper The looper to use when invoking callbacks. * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values. */ public DisplayEventReceiver(Looper looper) { public DisplayEventReceiver(Looper looper, int vsyncSource) { if (looper == null) { throw new IllegalArgumentException("looper must not be null"); } mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue, vsyncSource); mCloseGuard.open("dispose"); } Loading
core/jni/android_view_DisplayEventReceiver.cpp +7 −6 Original line number Diff line number Diff line Loading @@ -47,7 +47,7 @@ static struct { class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue); jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource); void dispose(); Loading @@ -65,8 +65,9 @@ private: NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp<MessageQueue>& messageQueue) : DisplayEventDispatcher(messageQueue->getLooper()), jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) : DisplayEventDispatcher(messageQueue->getLooper(), static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); Loading Loading @@ -113,7 +114,7 @@ void NativeDisplayEventReceiver::dispatchHotplug(nsecs_t timestamp, int32_t id, static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj) { jobject messageQueueObj, jint vsyncSource) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); Loading @@ -121,7 +122,7 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue); receiverWeak, messageQueue, vsyncSource); status_t status = receiver->initialize(); if (status) { String8 message; Loading Loading @@ -156,7 +157,7 @@ static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) { static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;)J", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;I)J", (void*)nativeInit }, { "nativeDispose", "(J)V", Loading
libs/androidfw/DisplayEventDispatcher.cpp +3 −2 Original line number Diff line number Diff line Loading @@ -33,8 +33,9 @@ namespace android { // using just a few large reads. static const size_t EVENT_BUFFER_SIZE = 100; DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper) : mLooper(looper), mWaitingForVsync(false) { DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource) : mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) { ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this); } Loading
libs/androidfw/include/androidfw/DisplayEventDispatcher.h +2 −1 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ namespace android { class DisplayEventDispatcher : public LooperCallback { public: DisplayEventDispatcher(const sp<Looper>& looper); DisplayEventDispatcher(const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp); status_t initialize(); void dispose(); Loading