diff options
| -rw-r--r-- | core/java/android/view/ViewRootImpl.java | 20 | ||||
| -rw-r--r-- | core/jni/android_graphics_BLASTBufferQueue.cpp | 38 | ||||
| -rw-r--r-- | graphics/java/android/graphics/BLASTBufferQueue.java | 22 |
3 files changed, 50 insertions, 30 deletions
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java index 055b5cb70562..86e7fb09c5ea 100644 --- a/core/java/android/view/ViewRootImpl.java +++ b/core/java/android/view/ViewRootImpl.java @@ -11263,13 +11263,19 @@ public final class ViewRootImpl implements ViewParent, } if (syncBuffer) { - mBlastBufferQueue.syncNextTransaction(new Consumer<Transaction>() { - @Override - public void accept(Transaction transaction) { - surfaceSyncGroup.addTransaction(transaction); - surfaceSyncGroup.markSyncReady(); - } + boolean result = mBlastBufferQueue.syncNextTransaction(transaction -> { + surfaceSyncGroup.addTransaction(transaction); + surfaceSyncGroup.markSyncReady(); }); + if (!result) { + // syncNextTransaction can only return false if something is already trying + // to sync the same frame in the same BBQ. That shouldn't be possible, but + // if it did happen, invoke markSyncReady so the active SSG doesn't get + // stuck. + Log.e(mTag, "Unable to syncNextTransaction. Possibly something else is" + + " trying to sync?"); + surfaceSyncGroup.markSyncReady(); + } } return didProduceBuffer -> { @@ -11283,7 +11289,7 @@ public final class ViewRootImpl implements ViewParent, // the next draw attempt. The next transaction and transaction complete callback // were only set for the current draw attempt. if (!didProduceBuffer) { - mBlastBufferQueue.syncNextTransaction(null); + mBlastBufferQueue.clearSyncTransaction(); // Gather the transactions that were sent to mergeWithNextTransaction // since the frame didn't draw on this vsync. It's possible the frame will diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp index 03815108f6dd..55aa7117221e 100644 --- a/core/jni/android_graphics_BLASTBufferQueue.cpp +++ b/core/jni/android_graphics_BLASTBufferQueue.cpp @@ -125,26 +125,24 @@ private: jobject mObject; }; -static void nativeSyncNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jobject callback, +static bool nativeSyncNextTransaction(JNIEnv* env, jclass clazz, jlong ptr, jobject callback, jboolean acquireSingleBuffer) { + LOG_ALWAYS_FATAL_IF(!callback, "callback passed in to syncNextTransaction must not be NULL"); + sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr); JavaVM* vm = nullptr; LOG_ALWAYS_FATAL_IF(env->GetJavaVM(&vm) != JNI_OK, "Unable to get Java VM"); - if (!callback) { - queue->syncNextTransaction(nullptr, acquireSingleBuffer); - } else { - auto globalCallbackRef = - std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); - queue->syncNextTransaction( - [globalCallbackRef](SurfaceComposerClient::Transaction* t) { - JNIEnv* env = getenv(globalCallbackRef->vm()); - env->CallVoidMethod(globalCallbackRef->object(), gTransactionConsumer.accept, - env->NewObject(gTransactionClassInfo.clazz, - gTransactionClassInfo.ctor, - reinterpret_cast<jlong>(t))); - }, - acquireSingleBuffer); - } + + auto globalCallbackRef = std::make_shared<JGlobalRefHolder>(vm, env->NewGlobalRef(callback)); + return queue->syncNextTransaction( + [globalCallbackRef](SurfaceComposerClient::Transaction* t) { + JNIEnv* env = getenv(globalCallbackRef->vm()); + env->CallVoidMethod(globalCallbackRef->object(), gTransactionConsumer.accept, + env->NewObject(gTransactionClassInfo.clazz, + gTransactionClassInfo.ctor, + reinterpret_cast<jlong>(t))); + }, + acquireSingleBuffer); } static void nativeStopContinuousSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr) { @@ -152,6 +150,11 @@ static void nativeStopContinuousSyncTransaction(JNIEnv* env, jclass clazz, jlong queue->stopContinuousSyncTransaction(); } +static void nativeClearSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr) { + sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr); + queue->clearSyncTransaction(); +} + static void nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width, jlong height, jint format) { sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr); @@ -207,8 +210,9 @@ static const JNINativeMethod gMethods[] = { {"nativeCreate", "(Ljava/lang/String;Z)J", (void*)nativeCreate}, {"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface}, {"nativeDestroy", "(J)V", (void*)nativeDestroy}, - {"nativeSyncNextTransaction", "(JLjava/util/function/Consumer;Z)V", (void*)nativeSyncNextTransaction}, + {"nativeSyncNextTransaction", "(JLjava/util/function/Consumer;Z)Z", (void*)nativeSyncNextTransaction}, {"nativeStopContinuousSyncTransaction", "(J)V", (void*)nativeStopContinuousSyncTransaction}, + {"nativeClearSyncTransaction", "(J)V", (void*)nativeClearSyncTransaction}, {"nativeUpdate", "(JJJJI)V", (void*)nativeUpdate}, {"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction}, {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum}, diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java index 9940ca3933c8..c52f700ef4f6 100644 --- a/graphics/java/android/graphics/BLASTBufferQueue.java +++ b/graphics/java/android/graphics/BLASTBufferQueue.java @@ -16,6 +16,7 @@ package android.graphics; +import android.annotation.NonNull; import android.view.Surface; import android.view.SurfaceControl; @@ -31,9 +32,10 @@ public final class BLASTBufferQueue { private static native long nativeCreate(String name, boolean updateDestinationFrame); private static native void nativeDestroy(long ptr); private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle); - private static native void nativeSyncNextTransaction(long ptr, + private static native boolean nativeSyncNextTransaction(long ptr, Consumer<SurfaceControl.Transaction> callback, boolean acquireSingleBuffer); private static native void nativeStopContinuousSyncTransaction(long ptr); + private static native void nativeClearSyncTransaction(long ptr); private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height, int format); private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr, @@ -92,9 +94,9 @@ public final class BLASTBufferQueue { * acquired. If false, continue to acquire all buffers into the * transaction until stopContinuousSyncTransaction is called. */ - public void syncNextTransaction(boolean acquireSingleBuffer, - Consumer<SurfaceControl.Transaction> callback) { - nativeSyncNextTransaction(mNativeObject, callback, acquireSingleBuffer); + public boolean syncNextTransaction(boolean acquireSingleBuffer, + @NonNull Consumer<SurfaceControl.Transaction> callback) { + return nativeSyncNextTransaction(mNativeObject, callback, acquireSingleBuffer); } /** @@ -104,8 +106,8 @@ public final class BLASTBufferQueue { * @param callback The callback invoked when the buffer has been added to the transaction. The * callback will contain the transaction with the buffer. */ - public void syncNextTransaction(Consumer<SurfaceControl.Transaction> callback) { - syncNextTransaction(true /* acquireSingleBuffer */, callback); + public boolean syncNextTransaction(@NonNull Consumer<SurfaceControl.Transaction> callback) { + return syncNextTransaction(true /* acquireSingleBuffer */, callback); } /** @@ -118,6 +120,14 @@ public final class BLASTBufferQueue { } /** + * Tell BBQ to clear the sync transaction that was previously set. The callback will not be + * invoked when the next frame is acquired. + */ + public void clearSyncTransaction() { + nativeClearSyncTransaction(mNativeObject); + } + + /** * Updates {@link SurfaceControl}, size, and format for a particular BLASTBufferQueue * @param sc The new SurfaceControl that this BLASTBufferQueue will update * @param width The new width for the buffer. |