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

Commit 1ba51e8e authored by Rachel Lee's avatar Rachel Lee Committed by Android (Google) Code Review
Browse files

Merge changes from topic "psc1"

* changes:
  Attached choreographer tests
  Attach the Choreographer instance with SurfaceControl
parents f3005b4f 8cfe7622
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -3148,6 +3148,9 @@ package android.view {

  public final class SurfaceControl implements android.os.Parcelable {
    ctor public SurfaceControl(@NonNull android.view.SurfaceControl, @NonNull String);
    method @NonNull public android.view.Choreographer getChoreographer();
    method @NonNull public android.view.Choreographer getChoreographer(@NonNull android.os.Looper);
    method public boolean hasChoreographer();
    method public boolean isSameSurface(@NonNull android.view.SurfaceControl);
  }

+36 −3
Original line number Diff line number Diff line
@@ -270,10 +270,14 @@ public final class Choreographer {
    private static final int CALLBACK_LAST = CALLBACK_COMMIT;

    private Choreographer(Looper looper, int vsyncSource) {
        this(looper, vsyncSource, /* layerHandle */ 0L);
    }

    private Choreographer(Looper looper, int vsyncSource, long layerHandle) {
        mLooper = looper;
        mHandler = new FrameHandler(looper);
        mDisplayEventReceiver = USE_VSYNC
                ? new FrameDisplayEventReceiver(looper, vsyncSource)
                ? new FrameDisplayEventReceiver(looper, vsyncSource, layerHandle)
                : null;
        mLastFrameTimeNanos = Long.MIN_VALUE;

@@ -312,6 +316,26 @@ public final class Choreographer {
        return sSfThreadInstance.get();
    }

    /**
     * Gets the choreographer associated with the SurfaceControl.
     *
     * @param layerHandle to which the choreographer will be attached.
     * @param looper      the choreographer is attached on this looper.
     *
     * @return The choreographer for the looper which is attached
     * to the sourced SurfaceControl::mNativeHandle.
     * @throws IllegalStateException if the looper sourced is null.
     * @hide
     */
    @NonNull
    static Choreographer getInstanceForSurfaceControl(long layerHandle,
            @NonNull Looper looper) {
        if (looper == null) {
            throw new IllegalStateException("The current thread must have a looper!");
        }
        return new Choreographer(looper, VSYNC_SOURCE_APP, layerHandle);
    }

    /**
     * @return The Choreographer of the main thread, if it exists, or {@code null} otherwise.
     * @hide
@@ -333,6 +357,15 @@ public final class Choreographer {
        mDisplayEventReceiver.dispose();
    }

    /**
     * Dispose the DisplayEventReceiver on the Choreographer.
     * @hide
     */
    @UnsupportedAppUsage
    void invalidate() {
        dispose();
    }

    /**
     * The amount of time, in milliseconds, between each frame of the animation.
     * <p>
@@ -1166,8 +1199,8 @@ public final class Choreographer {
        private int mFrame;
        private VsyncEventData mLastVsyncEventData = new VsyncEventData();

        public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
            super(looper, vsyncSource, 0);
        FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
            super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
        }

        // TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
+10 −4
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ public abstract class DisplayEventReceiver {
    private MessageQueue mMessageQueue;

    private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
            MessageQueue messageQueue, int vsyncSource, int eventRegistration);
            MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle);
    private static native void nativeDispose(long receiverPtr);
    @FastNative
    private static native void nativeScheduleVsync(long receiverPtr);
@@ -93,7 +93,11 @@ public abstract class DisplayEventReceiver {
     */
    @UnsupportedAppUsage
    public DisplayEventReceiver(Looper looper) {
        this(looper, VSYNC_SOURCE_APP, 0);
        this(looper, VSYNC_SOURCE_APP, /* eventRegistration */ 0, /* layerHandle */ 0L);
    }

    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
        this(looper, vsyncSource, eventRegistration, /* layerHandle */ 0L);
    }

    /**
@@ -103,15 +107,17 @@ public abstract class DisplayEventReceiver {
     * @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
     * @param eventRegistration Which events to dispatch. Must be a bitfield consist of the
     * EVENT_REGISTRATION_*_FLAG values.
     * @param layerHandle Layer to which the current instance is attached to
     */
    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration) {
    public DisplayEventReceiver(Looper looper, int vsyncSource, int eventRegistration,
            long layerHandle) {
        if (looper == null) {
            throw new IllegalArgumentException("looper must not be null");
        }

        mMessageQueue = looper.getQueue();
        mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
                vsyncSource, eventRegistration);
                vsyncSource, eventRegistration, layerHandle);
    }

    @Override
+65 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ import android.opengl.EGLDisplay;
import android.opengl.EGLSync;
import android.os.Build;
import android.os.IBinder;
import android.os.Looper;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.RemoteException;
@@ -463,6 +464,10 @@ public final class SurfaceControl implements Parcelable {
    public long mNativeObject;
    private long mNativeHandle;

    private final Object mChoreographerLock = new Object();
    @GuardedBy("mChoreographerLock")
    private Choreographer mChoreographer;

    // TODO: Move width/height to native and fix locking through out.
    private final Object mLock = new Object();
    @GuardedBy("mLock")
@@ -1268,6 +1273,59 @@ public final class SurfaceControl implements Parcelable {
        return other.mNativeHandle == mNativeHandle;
    }

    /**
     * Returns the associated {@link Choreographer} instance with the
     * current instance of the SurfaceControl.
     * Must be called from a thread that already has a {@link android.os.Looper}
     * associated with it.
     * If there is no {@link Choreographer} associated with the SurfaceControl then a new instance
     * of the {@link Choreographer} is created.
     *
     * @hide
     */
    @TestApi
    public @NonNull Choreographer getChoreographer() {
        return getChoreographer(Looper.myLooper());
    }

    /**
     * Returns the associated {@link Choreographer} instance with the
     * current instance of the SurfaceControl.
     * If there is no {@link Choreographer} associated with the SurfaceControl then a new instance
     * of the {@link Choreographer} is created.
     *
     * @param looper the choreographer is attached on this looper
     *
     * @hide
     */
    @TestApi
    public @NonNull Choreographer getChoreographer(@NonNull Looper looper) {
        checkNotReleased();
        synchronized (mChoreographerLock) {
            if (mChoreographer != null) {
                return mChoreographer;
            }

            mChoreographer = Choreographer.getInstanceForSurfaceControl(mNativeHandle, looper);
            return mChoreographer;
        }
    }

    /**
     * Returns true if {@link Choreographer} is present otherwise false.
     * To check the validity use {@link #isValid} on the SurfaceControl, a valid SurfaceControl with
     * choreographer will have the valid Choreographer.
     *
     * @hide
     */
    @TestApi
    @UnsupportedAppUsage
    public boolean hasChoreographer() {
        synchronized (mChoreographerLock) {
            return mChoreographer != null;
        }
    }

    /**
     * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link
     * android.view.SurfaceControlProto}.
@@ -1325,6 +1383,13 @@ public final class SurfaceControl implements Parcelable {
            mNativeObject = 0;
            mNativeHandle = 0;
            mCloseGuard.close();
            synchronized (mChoreographerLock) {
                if (mChoreographer != null) {
                    mChoreographer.invalidate();
                    // TODO(b/266121235): Use NativeAllocationRegistry to clean up Choreographer.
                    mChoreographer = null;
                }
            }
        }
    }

+10 −6
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ class NativeDisplayEventReceiver : public DisplayEventDispatcher {
public:
    NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                               const sp<MessageQueue>& messageQueue, jint vsyncSource,
                               jint eventRegistration);
                               jint eventRegistration, jlong layerHandle);

    void dispose();

@@ -88,11 +88,15 @@ private:

NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                                                       const sp<MessageQueue>& messageQueue,
                                                       jint vsyncSource, jint eventRegistration)
                                                       jint vsyncSource, jint eventRegistration,
                                                       jlong layerHandle)
      : DisplayEventDispatcher(messageQueue->getLooper(),
                               static_cast<gui::ISurfaceComposer::VsyncSource>(vsyncSource),
                               static_cast<gui::ISurfaceComposer::EventRegistration>(
                                       eventRegistration)),
                                       eventRegistration),
                               layerHandle != 0 ? sp<IBinder>::fromExisting(
                                                          reinterpret_cast<IBinder*>(layerHandle))
                                                : nullptr),
        mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
        mMessageQueue(messageQueue) {
    ALOGV("receiver %p ~ Initializing display event receiver.", this);
@@ -214,7 +218,7 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides(
}

static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj,
                        jint vsyncSource, jint eventRegistration) {
                        jint vsyncSource, jint eventRegistration, jlong layerHandle) {
    sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
    if (messageQueue == NULL) {
        jniThrowRuntimeException(env, "MessageQueue is not initialized.");
@@ -223,7 +227,7 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject

    sp<NativeDisplayEventReceiver> receiver =
            new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource,
                                           eventRegistration);
                                           eventRegistration, layerHandle);
    status_t status = receiver->initialize();
    if (status) {
        String8 message;
@@ -268,7 +272,7 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re

static const JNINativeMethod gMethods[] = {
        /* name, signature, funcPtr */
        {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
        {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J",
         (void*)nativeInit},
        {"nativeDispose", "(J)V", (void*)nativeDispose},
        // @FastNative
Loading