Loading core/api/current.txt +12 −2 Original line number Diff line number Diff line Loading @@ -17124,12 +17124,17 @@ package android.hardware { field public static final int MICROPHONE = 1; // 0x1 } public final class SyncFence implements java.io.Closeable android.os.Parcelable { method public void close() throws java.io.IOException; public final class SyncFence implements java.lang.AutoCloseable android.os.Parcelable { method public boolean await(@NonNull java.time.Duration); method public boolean awaitForever(); method public void close(); method public int describeContents(); method public long getSignalTime(); method public boolean isValid(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.hardware.SyncFence> CREATOR; field public static final long SIGNAL_TIME_INVALID = -1L; // 0xffffffffffffffffL field public static final long SIGNAL_TIME_PENDING = 9223372036854775807L; // 0x7fffffffffffffffL } public final class TriggerEvent { Loading Loading @@ -27879,12 +27884,17 @@ package android.opengl { public class EGLExt { ctor public EGLExt(); method @NonNull public static android.hardware.SyncFence eglDupNativeFenceFDANDROID(@NonNull android.opengl.EGLDisplay, @NonNull android.opengl.EGLSync); method public static boolean eglPresentationTimeANDROID(android.opengl.EGLDisplay, android.opengl.EGLSurface, long); field public static final int EGL_CONTEXT_FLAGS_KHR = 12540; // 0x30fc field public static final int EGL_CONTEXT_MAJOR_VERSION_KHR = 12440; // 0x3098 field public static final int EGL_CONTEXT_MINOR_VERSION_KHR = 12539; // 0x30fb field public static final int EGL_NO_NATIVE_FENCE_FD_ANDROID = -1; // 0xffffffff field public static final int EGL_OPENGL_ES3_BIT_KHR = 64; // 0x40 field public static final int EGL_RECORDABLE_ANDROID = 12610; // 0x3142 field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144 field public static final int EGL_SYNC_NATIVE_FENCE_FD_ANDROID = 12613; // 0x3145 field public static final int EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID = 12614; // 0x3146 } public class EGLImage extends android.opengl.EGLObjectHandle { core/java/android/hardware/SyncFence.java +150 −33 Original line number Diff line number Diff line Loading @@ -17,12 +17,17 @@ package android.hardware; import android.annotation.NonNull; import android.opengl.EGLDisplay; import android.opengl.EGLSync; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import java.io.Closeable; import libcore.util.NativeAllocationRegistry; import java.io.FileDescriptor; import java.io.IOException; import java.time.Duration; /** * A SyncFence represents a synchronization primitive which signals when hardware buffers have Loading @@ -34,19 +39,57 @@ import java.io.IOException; * Once the fence signals, then the backing storage for the framebuffer may be safely read from, * such as for display or for media encoding.</p> * * @see <a href="https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateFence.html"> * VkFence</a> * @see android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync) * @see android.media.Image#getFence() */ public final class SyncFence implements AutoCloseable, Parcelable { /** * An invalid signal time. Represents either the signal time for a SyncFence that isn't valid * (that is, {@link #isValid()} is false), or if an error occurred while attempting to retrieve * the signal time. */ public final class SyncFence implements Closeable, Parcelable { private static final String TAG = "SyncFence"; public static final long SIGNAL_TIME_INVALID = -1; /** * Wrapped {@link android.os.ParcelFileDescriptor}. * A pending signal time. This is equivalent to the max value of a long, representing an * infinitely far point in the future. */ private ParcelFileDescriptor mWrapped; public static final long SIGNAL_TIME_PENDING = Long.MAX_VALUE; private static final NativeAllocationRegistry sRegistry = NativeAllocationRegistry.createNonmalloced(SyncFence.class.getClassLoader(), nGetDestructor(), 4); private long mNativePtr; // The destructor for this object // This is also used as our internal lock object. Although SyncFence doesn't claim to be // thread-safe, the cost of doing so to avoid issues around double-close or similar issues // is well worth making. private final Runnable mCloser; private SyncFence(@NonNull ParcelFileDescriptor wrapped) { mWrapped = wrapped; mNativePtr = nCreate(wrapped.detachFd()); mCloser = sRegistry.registerNativeAllocation(this, mNativePtr); } private SyncFence(@NonNull Parcel parcel) { boolean valid = parcel.readBoolean(); FileDescriptor fileDescriptor = null; if (valid) { fileDescriptor = parcel.readRawFileDescriptor(); } if (fileDescriptor != null) { mNativePtr = nCreate(fileDescriptor.getInt$()); mCloser = sRegistry.registerNativeAllocation(this, mNativePtr); } else { mCloser = () -> {}; } } private SyncFence() { mCloser = () -> {}; } /*** Loading @@ -56,7 +99,7 @@ public final class SyncFence implements Closeable, Parcelable { * @hide */ public static @NonNull SyncFence createEmpty() { return new SyncFence(ParcelFileDescriptor.adoptFd(-1)); return new SyncFence(); } /** Loading @@ -75,7 +118,13 @@ public final class SyncFence implements Closeable, Parcelable { * @hide */ public @NonNull ParcelFileDescriptor getFdDup() throws IOException { return mWrapped.dup(); synchronized (mCloser) { final int fd = mNativePtr != 0 ? nGetFd(mNativePtr) : -1; if (fd == -1) { throw new IllegalStateException("Cannot dup the FD of an invalid SyncFence"); } return ParcelFileDescriptor.fromFd(fd); } } /** Loading @@ -85,29 +134,84 @@ public final class SyncFence implements Closeable, Parcelable { * {@code false} otherwise. */ public boolean isValid() { return mWrapped.getFileDescriptor().valid(); synchronized (mCloser) { return mNativePtr != 0 && nIsValid(mNativePtr); } } /** * Waits for a SyncFence to signal for up to the timeout duration. * * An invalid SyncFence, that is if {@link #isValid()} is false, is treated equivalently * to a SyncFence that has already signaled. That is, wait() will immediately return true. * * @param timeout The timeout duration. If the duration is negative, then this waits forever. * @return true if the fence signaled or isn't valid, false otherwise. */ public boolean await(@NonNull Duration timeout) { final long timeoutNanos; if (timeout.isNegative()) { timeoutNanos = -1; } else { timeoutNanos = timeout.toNanos(); } return await(timeoutNanos); } /** * Waits forever for a SyncFence to signal. * * An invalid SyncFence, that is if {@link #isValid()} is false, is treated equivalently * to a SyncFence that has already signaled. That is, wait() will immediately return true. * * @return true if the fence signaled or isn't valid, false otherwise. */ public boolean awaitForever() { return await(-1); } private boolean await(long timeoutNanos) { synchronized (mCloser) { return mNativePtr != 0 && nWait(mNativePtr, timeoutNanos); } } /** * Returns the time that the fence signaled in the CLOCK_MONOTONIC time domain. * * If the fence isn't valid, that is if {@link #isValid()} is false, then this returns * {@link #SIGNAL_TIME_INVALID}. Similarly, if an error occurs while trying to access the * signal time, then {@link #SIGNAL_TIME_INVALID} is also returned. * * If the fence hasn't yet signaled, then {@link #SIGNAL_TIME_PENDING} is returned. * * @return The time the fence signaled, {@link #SIGNAL_TIME_INVALID} if there's an error, * or {@link #SIGNAL_TIME_PENDING} if the fence hasn't signaled yet. */ public long getSignalTime() { synchronized (mCloser) { return mNativePtr != 0 ? nGetSignalTime(mNativePtr) : SIGNAL_TIME_INVALID; } } /** * Close the SyncFence. This implementation closes the underlying OS resources allocated * this stream. * * @throws IOException If an error occurs attempting to close this SyncFence. */ @Override public void close() throws IOException { if (mWrapped != null) { try { mWrapped.close(); } finally { // success public void close() { synchronized (mCloser) { if (mNativePtr == 0) { return; } mNativePtr = 0; mCloser.run(); } } @Override public int describeContents() { return mWrapped.describeContents(); return CONTENTS_FILE_DESCRIPTOR; } /** Loading @@ -119,10 +223,16 @@ public final class SyncFence implements Closeable, Parcelable { */ @Override public void writeToParcel(@NonNull Parcel out, int flags) { try { mWrapped.writeToParcel(out, flags); } finally { // success synchronized (mCloser) { final int fd = mNativePtr != 0 ? nGetFd(mNativePtr) : -1; if (fd == -1) { out.writeBoolean(false); } else { out.writeBoolean(true); FileDescriptor temp = new FileDescriptor(); temp.setInt$(fd); out.writeFileDescriptor(temp); } } } Loading @@ -130,7 +240,7 @@ public final class SyncFence implements Closeable, Parcelable { new Parcelable.Creator<SyncFence>() { @Override public SyncFence createFromParcel(Parcel in) { return new SyncFence(ParcelFileDescriptor.CREATOR.createFromParcel(in)); return new SyncFence(in); } @Override Loading @@ -138,4 +248,11 @@ public final class SyncFence implements Closeable, Parcelable { return new SyncFence[size]; } }; private static native long nGetDestructor(); private static native long nCreate(int fd); private static native boolean nIsValid(long nPtr); private static native int nGetFd(long nPtr); private static native boolean nWait(long nPtr, long timeout); private static native long nGetSignalTime(long nPtr); } core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ cc_library_shared { "android_hardware_HardwareBuffer.cpp", "android_hardware_SensorManager.cpp", "android_hardware_SerialPort.cpp", "android_hardware_SyncFence.cpp", "android_hardware_UsbDevice.cpp", "android_hardware_UsbDeviceConnection.cpp", "android_hardware_UsbRequest.cpp", Loading core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ extern int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env); extern int register_android_hardware_HardwareBuffer(JNIEnv *env); extern int register_android_hardware_SensorManager(JNIEnv *env); extern int register_android_hardware_SerialPort(JNIEnv *env); extern int register_android_hardware_SyncFence(JNIEnv* env); extern int register_android_hardware_UsbDevice(JNIEnv *env); extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env); extern int register_android_hardware_UsbRequest(JNIEnv *env); Loading Loading @@ -1601,6 +1602,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_hardware_HardwareBuffer), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_SerialPort), REG_JNI(register_android_hardware_SyncFence), REG_JNI(register_android_hardware_UsbDevice), REG_JNI(register_android_hardware_UsbDeviceConnection), REG_JNI(register_android_hardware_UsbRequest), Loading core/jni/android_hardware_SyncFence.cpp 0 → 100644 +89 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "SyncFence" #include <nativehelper/JNIHelp.h> #include <ui/Fence.h> #include "core_jni_helpers.h" #include "jni.h" using namespace android; template <typename T> jlong toJlong(T* ptr) { return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr)); } template <typename T> T* fromJlong(jlong jPtr) { return reinterpret_cast<T*>(static_cast<uintptr_t>(jPtr)); } static void destroyFence(Fence* fence) { fence->decStrong(0); } static jlong SyncFence_getDestructor(JNIEnv*, jobject) { return toJlong(&destroyFence); } static jlong SyncFence_create(JNIEnv*, jobject, int fd) { Fence* fence = new Fence(fd); fence->incStrong(0); return toJlong(fence); } static jboolean SyncFence_isValid(JNIEnv*, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->isValid(); } static jint SyncFence_getFd(JNIEnv*, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->get(); } static jboolean SyncFence_wait(JNIEnv* env, jobject, jlong jPtr, jlong timeoutNanos) { Fence* fence = fromJlong<Fence>(jPtr); int err = fence->wait(timeoutNanos); return err == OK; } static jlong SyncFence_getSignalTime(JNIEnv* env, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->getSignalTime(); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- const char* const kClassPathName = "android/hardware/SyncFence"; // clang-format off static const JNINativeMethod gMethods[] = { { "nGetDestructor", "()J", (void*) SyncFence_getDestructor }, { "nCreate", "(I)J", (void*) SyncFence_create }, { "nIsValid", "(J)Z", (void*) SyncFence_isValid }, { "nGetFd", "(J)I", (void*) SyncFence_getFd }, { "nWait", "(JJ)Z", (void*) SyncFence_wait }, { "nGetSignalTime", "(J)J", (void*) SyncFence_getSignalTime }, }; // clang-format on int register_android_hardware_SyncFence(JNIEnv* env) { int err = RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); return err; } No newline at end of file Loading
core/api/current.txt +12 −2 Original line number Diff line number Diff line Loading @@ -17124,12 +17124,17 @@ package android.hardware { field public static final int MICROPHONE = 1; // 0x1 } public final class SyncFence implements java.io.Closeable android.os.Parcelable { method public void close() throws java.io.IOException; public final class SyncFence implements java.lang.AutoCloseable android.os.Parcelable { method public boolean await(@NonNull java.time.Duration); method public boolean awaitForever(); method public void close(); method public int describeContents(); method public long getSignalTime(); method public boolean isValid(); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.hardware.SyncFence> CREATOR; field public static final long SIGNAL_TIME_INVALID = -1L; // 0xffffffffffffffffL field public static final long SIGNAL_TIME_PENDING = 9223372036854775807L; // 0x7fffffffffffffffL } public final class TriggerEvent { Loading Loading @@ -27879,12 +27884,17 @@ package android.opengl { public class EGLExt { ctor public EGLExt(); method @NonNull public static android.hardware.SyncFence eglDupNativeFenceFDANDROID(@NonNull android.opengl.EGLDisplay, @NonNull android.opengl.EGLSync); method public static boolean eglPresentationTimeANDROID(android.opengl.EGLDisplay, android.opengl.EGLSurface, long); field public static final int EGL_CONTEXT_FLAGS_KHR = 12540; // 0x30fc field public static final int EGL_CONTEXT_MAJOR_VERSION_KHR = 12440; // 0x3098 field public static final int EGL_CONTEXT_MINOR_VERSION_KHR = 12539; // 0x30fb field public static final int EGL_NO_NATIVE_FENCE_FD_ANDROID = -1; // 0xffffffff field public static final int EGL_OPENGL_ES3_BIT_KHR = 64; // 0x40 field public static final int EGL_RECORDABLE_ANDROID = 12610; // 0x3142 field public static final int EGL_SYNC_NATIVE_FENCE_ANDROID = 12612; // 0x3144 field public static final int EGL_SYNC_NATIVE_FENCE_FD_ANDROID = 12613; // 0x3145 field public static final int EGL_SYNC_NATIVE_FENCE_SIGNALED_ANDROID = 12614; // 0x3146 } public class EGLImage extends android.opengl.EGLObjectHandle {
core/java/android/hardware/SyncFence.java +150 −33 Original line number Diff line number Diff line Loading @@ -17,12 +17,17 @@ package android.hardware; import android.annotation.NonNull; import android.opengl.EGLDisplay; import android.opengl.EGLSync; import android.os.Parcel; import android.os.ParcelFileDescriptor; import android.os.Parcelable; import java.io.Closeable; import libcore.util.NativeAllocationRegistry; import java.io.FileDescriptor; import java.io.IOException; import java.time.Duration; /** * A SyncFence represents a synchronization primitive which signals when hardware buffers have Loading @@ -34,19 +39,57 @@ import java.io.IOException; * Once the fence signals, then the backing storage for the framebuffer may be safely read from, * such as for display or for media encoding.</p> * * @see <a href="https://www.khronos.org/registry/vulkan/specs/1.3-extensions/man/html/vkCreateFence.html"> * VkFence</a> * @see android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync) * @see android.media.Image#getFence() */ public final class SyncFence implements AutoCloseable, Parcelable { /** * An invalid signal time. Represents either the signal time for a SyncFence that isn't valid * (that is, {@link #isValid()} is false), or if an error occurred while attempting to retrieve * the signal time. */ public final class SyncFence implements Closeable, Parcelable { private static final String TAG = "SyncFence"; public static final long SIGNAL_TIME_INVALID = -1; /** * Wrapped {@link android.os.ParcelFileDescriptor}. * A pending signal time. This is equivalent to the max value of a long, representing an * infinitely far point in the future. */ private ParcelFileDescriptor mWrapped; public static final long SIGNAL_TIME_PENDING = Long.MAX_VALUE; private static final NativeAllocationRegistry sRegistry = NativeAllocationRegistry.createNonmalloced(SyncFence.class.getClassLoader(), nGetDestructor(), 4); private long mNativePtr; // The destructor for this object // This is also used as our internal lock object. Although SyncFence doesn't claim to be // thread-safe, the cost of doing so to avoid issues around double-close or similar issues // is well worth making. private final Runnable mCloser; private SyncFence(@NonNull ParcelFileDescriptor wrapped) { mWrapped = wrapped; mNativePtr = nCreate(wrapped.detachFd()); mCloser = sRegistry.registerNativeAllocation(this, mNativePtr); } private SyncFence(@NonNull Parcel parcel) { boolean valid = parcel.readBoolean(); FileDescriptor fileDescriptor = null; if (valid) { fileDescriptor = parcel.readRawFileDescriptor(); } if (fileDescriptor != null) { mNativePtr = nCreate(fileDescriptor.getInt$()); mCloser = sRegistry.registerNativeAllocation(this, mNativePtr); } else { mCloser = () -> {}; } } private SyncFence() { mCloser = () -> {}; } /*** Loading @@ -56,7 +99,7 @@ public final class SyncFence implements Closeable, Parcelable { * @hide */ public static @NonNull SyncFence createEmpty() { return new SyncFence(ParcelFileDescriptor.adoptFd(-1)); return new SyncFence(); } /** Loading @@ -75,7 +118,13 @@ public final class SyncFence implements Closeable, Parcelable { * @hide */ public @NonNull ParcelFileDescriptor getFdDup() throws IOException { return mWrapped.dup(); synchronized (mCloser) { final int fd = mNativePtr != 0 ? nGetFd(mNativePtr) : -1; if (fd == -1) { throw new IllegalStateException("Cannot dup the FD of an invalid SyncFence"); } return ParcelFileDescriptor.fromFd(fd); } } /** Loading @@ -85,29 +134,84 @@ public final class SyncFence implements Closeable, Parcelable { * {@code false} otherwise. */ public boolean isValid() { return mWrapped.getFileDescriptor().valid(); synchronized (mCloser) { return mNativePtr != 0 && nIsValid(mNativePtr); } } /** * Waits for a SyncFence to signal for up to the timeout duration. * * An invalid SyncFence, that is if {@link #isValid()} is false, is treated equivalently * to a SyncFence that has already signaled. That is, wait() will immediately return true. * * @param timeout The timeout duration. If the duration is negative, then this waits forever. * @return true if the fence signaled or isn't valid, false otherwise. */ public boolean await(@NonNull Duration timeout) { final long timeoutNanos; if (timeout.isNegative()) { timeoutNanos = -1; } else { timeoutNanos = timeout.toNanos(); } return await(timeoutNanos); } /** * Waits forever for a SyncFence to signal. * * An invalid SyncFence, that is if {@link #isValid()} is false, is treated equivalently * to a SyncFence that has already signaled. That is, wait() will immediately return true. * * @return true if the fence signaled or isn't valid, false otherwise. */ public boolean awaitForever() { return await(-1); } private boolean await(long timeoutNanos) { synchronized (mCloser) { return mNativePtr != 0 && nWait(mNativePtr, timeoutNanos); } } /** * Returns the time that the fence signaled in the CLOCK_MONOTONIC time domain. * * If the fence isn't valid, that is if {@link #isValid()} is false, then this returns * {@link #SIGNAL_TIME_INVALID}. Similarly, if an error occurs while trying to access the * signal time, then {@link #SIGNAL_TIME_INVALID} is also returned. * * If the fence hasn't yet signaled, then {@link #SIGNAL_TIME_PENDING} is returned. * * @return The time the fence signaled, {@link #SIGNAL_TIME_INVALID} if there's an error, * or {@link #SIGNAL_TIME_PENDING} if the fence hasn't signaled yet. */ public long getSignalTime() { synchronized (mCloser) { return mNativePtr != 0 ? nGetSignalTime(mNativePtr) : SIGNAL_TIME_INVALID; } } /** * Close the SyncFence. This implementation closes the underlying OS resources allocated * this stream. * * @throws IOException If an error occurs attempting to close this SyncFence. */ @Override public void close() throws IOException { if (mWrapped != null) { try { mWrapped.close(); } finally { // success public void close() { synchronized (mCloser) { if (mNativePtr == 0) { return; } mNativePtr = 0; mCloser.run(); } } @Override public int describeContents() { return mWrapped.describeContents(); return CONTENTS_FILE_DESCRIPTOR; } /** Loading @@ -119,10 +223,16 @@ public final class SyncFence implements Closeable, Parcelable { */ @Override public void writeToParcel(@NonNull Parcel out, int flags) { try { mWrapped.writeToParcel(out, flags); } finally { // success synchronized (mCloser) { final int fd = mNativePtr != 0 ? nGetFd(mNativePtr) : -1; if (fd == -1) { out.writeBoolean(false); } else { out.writeBoolean(true); FileDescriptor temp = new FileDescriptor(); temp.setInt$(fd); out.writeFileDescriptor(temp); } } } Loading @@ -130,7 +240,7 @@ public final class SyncFence implements Closeable, Parcelable { new Parcelable.Creator<SyncFence>() { @Override public SyncFence createFromParcel(Parcel in) { return new SyncFence(ParcelFileDescriptor.CREATOR.createFromParcel(in)); return new SyncFence(in); } @Override Loading @@ -138,4 +248,11 @@ public final class SyncFence implements Closeable, Parcelable { return new SyncFence[size]; } }; private static native long nGetDestructor(); private static native long nCreate(int fd); private static native boolean nIsValid(long nPtr); private static native int nGetFd(long nPtr); private static native boolean nWait(long nPtr, long timeout); private static native long nGetSignalTime(long nPtr); }
core/jni/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -188,6 +188,7 @@ cc_library_shared { "android_hardware_HardwareBuffer.cpp", "android_hardware_SensorManager.cpp", "android_hardware_SerialPort.cpp", "android_hardware_SyncFence.cpp", "android_hardware_UsbDevice.cpp", "android_hardware_UsbDeviceConnection.cpp", "android_hardware_UsbRequest.cpp", Loading
core/jni/AndroidRuntime.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -82,6 +82,7 @@ extern int register_android_hardware_display_DisplayManagerGlobal(JNIEnv* env); extern int register_android_hardware_HardwareBuffer(JNIEnv *env); extern int register_android_hardware_SensorManager(JNIEnv *env); extern int register_android_hardware_SerialPort(JNIEnv *env); extern int register_android_hardware_SyncFence(JNIEnv* env); extern int register_android_hardware_UsbDevice(JNIEnv *env); extern int register_android_hardware_UsbDeviceConnection(JNIEnv *env); extern int register_android_hardware_UsbRequest(JNIEnv *env); Loading Loading @@ -1601,6 +1602,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_hardware_HardwareBuffer), REG_JNI(register_android_hardware_SensorManager), REG_JNI(register_android_hardware_SerialPort), REG_JNI(register_android_hardware_SyncFence), REG_JNI(register_android_hardware_UsbDevice), REG_JNI(register_android_hardware_UsbDeviceConnection), REG_JNI(register_android_hardware_UsbRequest), Loading
core/jni/android_hardware_SyncFence.cpp 0 → 100644 +89 −0 Original line number Diff line number Diff line /* * Copyright (C) 2022 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "SyncFence" #include <nativehelper/JNIHelp.h> #include <ui/Fence.h> #include "core_jni_helpers.h" #include "jni.h" using namespace android; template <typename T> jlong toJlong(T* ptr) { return static_cast<jlong>(reinterpret_cast<uintptr_t>(ptr)); } template <typename T> T* fromJlong(jlong jPtr) { return reinterpret_cast<T*>(static_cast<uintptr_t>(jPtr)); } static void destroyFence(Fence* fence) { fence->decStrong(0); } static jlong SyncFence_getDestructor(JNIEnv*, jobject) { return toJlong(&destroyFence); } static jlong SyncFence_create(JNIEnv*, jobject, int fd) { Fence* fence = new Fence(fd); fence->incStrong(0); return toJlong(fence); } static jboolean SyncFence_isValid(JNIEnv*, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->isValid(); } static jint SyncFence_getFd(JNIEnv*, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->get(); } static jboolean SyncFence_wait(JNIEnv* env, jobject, jlong jPtr, jlong timeoutNanos) { Fence* fence = fromJlong<Fence>(jPtr); int err = fence->wait(timeoutNanos); return err == OK; } static jlong SyncFence_getSignalTime(JNIEnv* env, jobject, jlong jPtr) { return fromJlong<Fence>(jPtr)->getSignalTime(); } // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- const char* const kClassPathName = "android/hardware/SyncFence"; // clang-format off static const JNINativeMethod gMethods[] = { { "nGetDestructor", "()J", (void*) SyncFence_getDestructor }, { "nCreate", "(I)J", (void*) SyncFence_create }, { "nIsValid", "(J)Z", (void*) SyncFence_isValid }, { "nGetFd", "(J)I", (void*) SyncFence_getFd }, { "nWait", "(JJ)Z", (void*) SyncFence_wait }, { "nGetSignalTime", "(J)J", (void*) SyncFence_getSignalTime }, }; // clang-format on int register_android_hardware_SyncFence(JNIEnv* env) { int err = RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods)); return err; } No newline at end of file