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

Commit ec8e8eb6 authored by Ady Abraham's avatar Ady Abraham Committed by Android (Google) Code Review
Browse files

Merge "Add setDesiredPresentTime/setFrameTimeline to SurfaceControl.Transaction" into main

parents d5203b52 d0d2b1af
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -18617,6 +18617,7 @@ package android.hardware {
  }
  public final class SyncFence implements java.lang.AutoCloseable android.os.Parcelable {
    ctor @FlaggedApi("com.android.window.flags.sdk_desired_present_time") public SyncFence(@NonNull android.hardware.SyncFence);
    method public boolean await(@NonNull java.time.Duration);
    method public boolean awaitForever();
    method public void close();
@@ -51798,6 +51799,7 @@ package android.view {
  public static class SurfaceControl.Transaction implements java.io.Closeable android.os.Parcelable {
    ctor public SurfaceControl.Transaction();
    method @NonNull public android.view.SurfaceControl.Transaction addTransactionCommittedListener(@NonNull java.util.concurrent.Executor, @NonNull android.view.SurfaceControl.TransactionCommittedListener);
    method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") @NonNull public android.view.SurfaceControl.Transaction addTransactionCompletedListener(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.SurfaceControl.TransactionStats>);
    method public void apply();
    method @NonNull public android.view.SurfaceControl.Transaction clearFrameRate(@NonNull android.view.SurfaceControl);
    method @NonNull public android.view.SurfaceControl.Transaction clearTrustedPresentationCallback(@NonNull android.view.SurfaceControl);
@@ -51814,9 +51816,11 @@ package android.view {
    method @NonNull public android.view.SurfaceControl.Transaction setCrop(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect);
    method @NonNull public android.view.SurfaceControl.Transaction setDamageRegion(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Region);
    method @NonNull public android.view.SurfaceControl.Transaction setDataSpace(@NonNull android.view.SurfaceControl, int);
    method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") @NonNull public android.view.SurfaceControl.Transaction setDesiredPresentTime(long);
    method @NonNull public android.view.SurfaceControl.Transaction setExtendedRangeBrightness(@NonNull android.view.SurfaceControl, float, float);
    method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int);
    method @NonNull public android.view.SurfaceControl.Transaction setFrameRate(@NonNull android.view.SurfaceControl, @FloatRange(from=0.0) float, int, int);
    method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") @NonNull public android.view.SurfaceControl.Transaction setFrameTimeline(long);
    method @Deprecated @NonNull public android.view.SurfaceControl.Transaction setGeometry(@NonNull android.view.SurfaceControl, @Nullable android.graphics.Rect, @Nullable android.graphics.Rect, int);
    method @NonNull public android.view.SurfaceControl.Transaction setLayer(@NonNull android.view.SurfaceControl, @IntRange(from=java.lang.Integer.MIN_VALUE, to=java.lang.Integer.MAX_VALUE) int);
    method @NonNull public android.view.SurfaceControl.Transaction setOpaque(@NonNull android.view.SurfaceControl, boolean);
@@ -51832,6 +51836,11 @@ package android.view {
    method public void onTransactionCommitted();
  }
  @FlaggedApi("com.android.window.flags.sdk_desired_present_time") public static final class SurfaceControl.TransactionStats {
    method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") public long getLatchTime();
    method @FlaggedApi("com.android.window.flags.sdk_desired_present_time") @NonNull public android.hardware.SyncFence getPresentFence();
  }
  public static final class SurfaceControl.TrustedPresentationThresholds {
    ctor public SurfaceControl.TrustedPresentationThresholds(@FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @FloatRange(from=0.0f, fromInclusive=false, to=1.0f) float, @IntRange(from=1) int);
  }
+17 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.hardware;

import android.annotation.FlaggedApi;
import android.annotation.NonNull;
import android.media.Image;
import android.media.ImageWriter;
@@ -26,6 +27,8 @@ import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.SystemClock;

import com.android.window.flags.Flags;

import libcore.util.NativeAllocationRegistry;

import java.io.FileDescriptor;
@@ -121,6 +124,19 @@ public final class SyncFence implements AutoCloseable, Parcelable {
        }
    }

    /**
     * Creates a copy of the SyncFence from an existing one.
     * Both fences must be closed() independently.
     */
    @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
    public SyncFence(@NonNull SyncFence other) {
        this(other.mNativePtr);

        if (mNativePtr != 0) {
            nIncRef(mNativePtr);
        }
    }

    private SyncFence() {
        mCloser = () -> {};
    }
@@ -312,4 +328,5 @@ public final class SyncFence implements AutoCloseable, Parcelable {
    private static native int nGetFd(long nPtr);
    private static native boolean nWait(long nPtr, long timeout);
    private static native long nGetSignalTime(long nPtr);
    private static native void nIncRef(long nPtr);
}
+133 −4
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.view.SurfaceControlProto.NAME;

import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.FlaggedApi;
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.IntRange;
@@ -71,6 +72,7 @@ import android.view.Surface.OutOfResourcesException;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
import com.android.internal.util.VirtualRefBasePtr;
import com.android.window.flags.Flags;

import dalvik.system.CloseGuard;

@@ -277,6 +279,8 @@ public final class SurfaceControl implements Parcelable {
    private static native int nativeGetLayerId(long nativeObject);
    private static native void nativeAddTransactionCommittedListener(long nativeObject,
            TransactionCommittedListener listener);
    private static native void nativeAddTransactionCompletedListener(long nativeObject,
            Consumer<TransactionStats> listener);
    private static native void nativeSanitize(long transactionObject, int pid, int uid);
    private static native void nativeSetDestinationFrame(long transactionObj, long nativeObject,
            int l, int t, int r, int b);
@@ -290,6 +294,10 @@ public final class SurfaceControl implements Parcelable {
    private static native void nativeClearTrustedPresentationCallback(long transactionObj,
            long nativeObject);
    private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid);
    private static native void nativeSetDesiredPresentTime(long transactionObj,
                                                           long desiredPresentTime);
    private static native void nativeSetFrameTimeline(long transactionObj,
                                                           long vsyncId);

    /**
     * Transforms that can be applied to buffers as they are displayed to a window.
@@ -2549,6 +2557,50 @@ public final class SurfaceControl implements Parcelable {
        void onTransactionCommitted();
    }

    /**
     * Transaction stats given to the listener registered in
     * {@link SurfaceControl.Transaction#addTransactionCompletedListener}
     */
    @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
    public static final class TransactionStats {
        private long mLatchTime;
        private SyncFence mSyncFence;

        // called from native
        private TransactionStats(long latchTime, long presentFencePtr) {
            mLatchTime = latchTime;
            mSyncFence = new SyncFence(presentFencePtr);
        }

        /**
         * Close the TransactionStats. Called by the framework when the listener returns.
         * @hide
         */
        public void close() {
            mSyncFence.close();
        }

        /**
         * Returns the timestamp of when the frame was latched by the framework and queued for
         * presentation.
         */
        @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
        public long getLatchTime() {
            return mLatchTime;
        }

        /**
         * Returns a new SyncFence that signals when the transaction has been presented.
         * The caller takes ownership of the fence and is responsible for closing
         * it by calling {@link SyncFence#close}.
         * If a device does not support present fences, an empty fence will be returned.
         */
        @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
        public @NonNull SyncFence getPresentFence() {
            return new SyncFence(mSyncFence);
        }
    };

    /**
     * Threshold values that are sent with
     * {@link Transaction#setTrustedPresentationCallback(SurfaceControl,
@@ -4185,12 +4237,35 @@ public final class SurfaceControl implements Parcelable {
        }

        /**
         * Sets the frame timeline vsync id received from choreographer
         * {@link Choreographer#getVsyncId()} that corresponds to the transaction submitted on that
         * surface control.
         * Sets the frame timeline to use in SurfaceFlinger.
         *
         * A frame timeline should be chosen based on the frame deadline the application
         * can meet when rendering the frame and the application's desired presentation time.
         * By setting a frame timeline, SurfaceFlinger tries to present the frame at the
         * corresponding expected presentation time.
         *
         * To receive frame timelines, a callback must be posted to Choreographer using
         * {@link Choreographer#postVsyncCallback} The vsyncId can then be extracted from the
         * {@link Choreographer.FrameTimeline#getVsyncId}.
         *
         * @param vsyncId The vsync ID received from Choreographer, setting the frame's
         *                presentation target to the corresponding expected presentation time
         *                and deadline from the frame to be rendered. A stale or invalid value
         *                will be ignored.
         *
         * @hide
         */
        @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
        @NonNull
        public Transaction setFrameTimeline(long vsyncId) {
            if (!Flags.sdkDesiredPresentTime()) {
                Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
                return this;
            }
            nativeSetFrameTimelineVsync(mNativeObject, vsyncId);
            return this;
        }

        /** @hide */
        @NonNull
        public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) {
            nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId);
@@ -4207,6 +4282,9 @@ public final class SurfaceControl implements Parcelable {
         * to avoid dropping frames (overwriting transactions), and unable to use timestamps (Which
         * provide a more efficient solution), then this method provides a method to pace your
         * transaction application.
         * The listener is invoked once the transaction is applied, and never again. Multiple
         * listeners can be added to the same transaction, however the order the listeners will
         * be called is not guaranteed.
         *
         * @param executor The executor that the callback should be invoked on.
         * @param listener The callback that will be invoked when the transaction has been
@@ -4222,6 +4300,33 @@ public final class SurfaceControl implements Parcelable {
            return this;
        }

        /**
         * Request to add a TransactionCompletedListener.
         *
         * The listener is invoked when transaction is presented, and never again. Multiple
         * listeners can be added to the same transaction, however the order the listeners will
         * be called is not guaranteed.
         *
         * @param executor The executor that the callback should be invoked on.
         * @param listener The callback that will be invoked when the transaction has been
         *                 completed.
         */
        @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
        @NonNull
        public Transaction addTransactionCompletedListener(
                @NonNull @CallbackExecutor Executor executor,
                @NonNull Consumer<TransactionStats> listener) {

            if (!Flags.sdkDesiredPresentTime()) {
                Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
                return this;
            }
            Consumer<TransactionStats> listenerInner = stats -> executor.execute(
                                    () -> listener.andThen(TransactionStats::close).accept(stats));
            nativeAddTransactionCompletedListener(mNativeObject, listenerInner);
            return this;
        }

        /**
         * Sets a callback to receive feedback about the presentation of a {@link SurfaceControl}.
         * When the {@link SurfaceControl} is presented according to the passed in
@@ -4320,6 +4425,30 @@ public final class SurfaceControl implements Parcelable {
            return this;
        }

        /**
         * Specifies a desiredPresentTime for the transaction. The framework will try to present
         * the transaction at or after the time specified.
         *
         * Transactions will not be presented until all of their acquire fences have signaled even
         * if the app requests an earlier present time.
         *
         * If an earlier transaction has a desired present time of x, and a later transaction has
         * a desired present time that is before x, the later transaction will not preempt the
         * earlier transaction.
         *
         * @param desiredPresentTime The desired time (in CLOCK_MONOTONIC) for the transaction.
         * @return This transaction
         */
        @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME)
        @NonNull
        public Transaction setDesiredPresentTime(long desiredPresentTime) {
            if (!Flags.sdkDesiredPresentTime()) {
                Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled");
                return this;
            }
            nativeSetDesiredPresentTime(mNativeObject, desiredPresentTime);
            return this;
        }
        /**
         * Writes the transaction to parcel, clearing the transaction as if it had been applied so
         * it can be used to store future transactions. It's the responsibility of the parcel
+9 −1
Original line number Diff line number Diff line
@@ -64,3 +64,11 @@ flag {
    is_fixed_read_only: true
    bug: "278027319"
}

flag {
    namespace: "window_surfaces"
    name: "sdk_desired_present_time"
    description: "Feature flag for the new SDK API to set desired present time"
    is_fixed_read_only: true
    bug: "295038072"
}
+5 −0
Original line number Diff line number Diff line
@@ -66,6 +66,10 @@ static jlong SyncFence_getSignalTime(JNIEnv* env, jobject, jlong jPtr) {
    return fromJlong<Fence>(jPtr)->getSignalTime();
}

static void SyncFence_incRef(JNIEnv*, jobject, jlong jPtr) {
    fromJlong<Fence>(jPtr)->incStrong((void*)SyncFence_incRef);
}

// ----------------------------------------------------------------------------
// JNI Glue
// ----------------------------------------------------------------------------
@@ -80,6 +84,7 @@ static const JNINativeMethod gMethods[] = {
        { "nGetFd", "(J)I", (void*) SyncFence_getFd },
        { "nWait",  "(JJ)Z", (void*) SyncFence_wait },
        { "nGetSignalTime", "(J)J", (void*) SyncFence_getSignalTime },
        { "nIncRef", "(J)V", (void*) SyncFence_incRef },
};
// clang-format on

Loading