summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/view/ViewRootImpl.java20
-rw-r--r--core/jni/android_graphics_BLASTBufferQueue.cpp38
-rw-r--r--graphics/java/android/graphics/BLASTBufferQueue.java22
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.