Loading core/api/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); } core/java/android/hardware/SyncFence.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.hardware; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.media.Image; import android.media.ImageWriter; Loading @@ -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; Loading Loading @@ -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 = () -> {}; } Loading Loading @@ -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); } core/java/android/view/SurfaceControl.java +133 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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, Loading Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading core/java/android/window/flags/window_surfaces.aconfig +9 −1 Original line number Diff line number Diff line Loading @@ -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" } core/jni/android_hardware_SyncFence.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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 // ---------------------------------------------------------------------------- Loading @@ -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 Loading
core/api/current.txt +9 −0 Original line number Diff line number Diff line Loading @@ -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(); Loading Loading @@ -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); Loading @@ -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); Loading @@ -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); }
core/java/android/hardware/SyncFence.java +17 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ package android.hardware; import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.media.Image; import android.media.ImageWriter; Loading @@ -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; Loading Loading @@ -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 = () -> {}; } Loading Loading @@ -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); }
core/java/android/view/SurfaceControl.java +133 −4 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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); Loading @@ -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. Loading Loading @@ -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, Loading Loading @@ -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); Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading
core/java/android/window/flags/window_surfaces.aconfig +9 −1 Original line number Diff line number Diff line Loading @@ -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" }
core/jni/android_hardware_SyncFence.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -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 // ---------------------------------------------------------------------------- Loading @@ -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