Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d1f55f63 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Properly run window animations at vsync-sf (1/2)" into oc-dev

parents 713ad88a 34a0cdb9
Loading
Loading
Loading
Loading
+30 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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);
                }
            };

@@ -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());
@@ -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
     */
@@ -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
+22 −3
Original line number Diff line number Diff line
@@ -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();
@@ -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);
@@ -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");
    }
+7 −6
Original line number Diff line number Diff line
@@ -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();

@@ -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);
@@ -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.");
@@ -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;
@@ -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",
+3 −2
Original line number Diff line number Diff line
@@ -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);
}

+2 −1
Original line number Diff line number Diff line
@@ -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