BLAST: Ensure buffers are submitted before reporting draw finished
If blast sync is not enabled abut we need to report draw finished
for the next frame, call setNextTransaction. Blast buffer queue
will process any queued up buffers and ensure the buffer is
submitted before reporting draw finished.
Test: Test no flickers with blast enabled in splitscreen
Change-Id: If7a36eb0a9a2914dd37adfd20abcbe2b5074b16a
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 5235740..93c2787 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3881,10 +3881,6 @@
}
private void addFrameCallbackIfNeeded() {
- if (!mNextDrawUseBLASTSyncTransaction) {
- return;
- }
-
// Frame callbacks will always occur after submitting draw requests and before
// the draw actually occurs. This will ensure that we set the next transaction
// for the frame that's about to get drawn and not on a previous frame that.
@@ -3892,8 +3888,19 @@
// This is thread safe since mRtNextFrameReportConsumeWithBlast will only be
// modified in onFrameDraw and then again in onFrameComplete. This is to ensure the
// next frame completed should be reported with the blast sync transaction.
- registerRtFrameCallback(createFrameDrawingCallback());
- mNextDrawUseBLASTSyncTransaction = false;
+ if (mNextDrawUseBLASTSyncTransaction) {
+ registerRtFrameCallback(createFrameDrawingCallback());
+ mNextDrawUseBLASTSyncTransaction = false;
+ } else if (mReportNextDraw) {
+ registerRtFrameCallback(frame -> {
+ if (mBlastBufferQueue != null) {
+ // If we need to report next draw, wait for adapter to flush its shadow queue
+ // by processing previously queued buffers so that we can submit the
+ // transaction a timely manner.
+ mBlastBufferQueue.flushShadowQueue();
+ }
+ });
+ }
}
private void performDraw() {
diff --git a/core/jni/android_graphics_BLASTBufferQueue.cpp b/core/jni/android_graphics_BLASTBufferQueue.cpp
index a30c37b..b07c293 100644
--- a/core/jni/android_graphics_BLASTBufferQueue.cpp
+++ b/core/jni/android_graphics_BLASTBufferQueue.cpp
@@ -69,13 +69,19 @@
queue->update(reinterpret_cast<SurfaceControl*>(surfaceControl), width, height);
}
+static void nativeFlushShadowQueue(JNIEnv* env, jclass clazz, jlong ptr) {
+ sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
+ queue->flushShadowQueue();
+}
+
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{"nativeCreate", "(Ljava/lang/String;JJJZ)J", (void*)nativeCreate},
{"nativeGetSurface", "(J)Landroid/view/Surface;", (void*)nativeGetSurface},
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
{"nativeSetNextTransaction", "(JJ)V", (void*)nativeSetNextTransaction},
- {"nativeUpdate", "(JJJJ)V", (void*)nativeUpdate}};
+ {"nativeUpdate", "(JJJJ)V", (void*)nativeUpdate},
+ {"nativeFlushShadowQueue", "(J)V", (void*)nativeFlushShadowQueue}};
int register_android_graphics_BLASTBufferQueue(JNIEnv* env) {
int res = jniRegisterNativeMethods(env, "android/graphics/BLASTBufferQueue",
diff --git a/graphics/java/android/graphics/BLASTBufferQueue.java b/graphics/java/android/graphics/BLASTBufferQueue.java
index 4c0f890..8284042 100644
--- a/graphics/java/android/graphics/BLASTBufferQueue.java
+++ b/graphics/java/android/graphics/BLASTBufferQueue.java
@@ -32,6 +32,7 @@
private static native Surface nativeGetSurface(long ptr);
private static native void nativeSetNextTransaction(long ptr, long transactionPtr);
private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height);
+ private static native void nativeFlushShadowQueue(long ptr);
/** Create a new connection with the surface flinger. */
public BLASTBufferQueue(String name, SurfaceControl sc, int width, int height,
@@ -69,4 +70,8 @@
super.finalize();
}
}
+
+ public void flushShadowQueue() {
+ nativeFlushShadowQueue(mNativeObject);
+ }
}