Merge "Synchronize SV buffers with main window when config changes"

This commit is contained in:
Chavi Weingarten
2021-12-01 17:20:44 +00:00
committed by Android (Google) Code Review
4 changed files with 82 additions and 18 deletions

View File

@@ -227,6 +227,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
*/
private final SurfaceControl.Transaction mRtTransaction = new SurfaceControl.Transaction();
/**
* Used on the main thread to set the transaction that will be synced with the main window.
*/
private final Transaction mSyncTransaction = new Transaction();
/**
* Transaction that should be used whe
* {@link HardwareRenderer.FrameDrawingCallback#onFrameDraw} is invoked. All
@@ -496,7 +501,8 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
}
private void performDrawFinished() {
private void performDrawFinished(Transaction t) {
mSyncTransaction.merge(t);
if (mDeferredDestroySurfaceControl != null) {
synchronized (mSurfaceControlLock) {
mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
@@ -521,7 +527,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
void notifyDrawFinished() {
ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
viewRoot.pendingDrawFinished();
viewRoot.pendingDrawFinished(mSyncTransaction);
}
mPendingReportDraws--;
}
@@ -1202,10 +1208,17 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
callbacks = getSurfaceCallbacks();
}
final Transaction t = new Transaction();
if (viewRoot.wasRelayoutRequested()) {
mBlastBufferQueue.setSyncTransaction(t,
false /* acquireSingleBuffer */);
}
mPendingReportDraws++;
viewRoot.drawPending();
SurfaceCallbackHelper sch =
new SurfaceCallbackHelper(this::onDrawFinished);
SurfaceCallbackHelper sch = new SurfaceCallbackHelper(() -> {
mBlastBufferQueue.setSyncTransaction(null);
onDrawFinished(t);
});
sch.dispatchSurfaceRedrawNeededAsync(mSurfaceHolder, callbacks);
}
}
@@ -1367,13 +1380,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
mSurfaceHeight, mFormat);
}
private void onDrawFinished() {
private void onDrawFinished(Transaction t) {
if (DEBUG) {
Log.i(TAG, System.identityHashCode(this) + " "
+ "finishedDrawing");
}
runOnUiThread(this::performDrawFinished);
runOnUiThread(() -> performDrawFinished(t));
}
/**

View File

@@ -532,6 +532,11 @@ public final class ViewRootImpl implements ViewParent,
boolean mPerformContentCapture;
boolean mReportNextDraw;
/**
* Set if the reportDraw was requested from WM. If just a local report draw was invoked, there's
* no need to report back to system server and can just apply immediately on the client.
*/
boolean mReportDrawToWm;
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
boolean mForceNextWindowRelayout;
@@ -754,6 +759,8 @@ public final class ViewRootImpl implements ViewParent,
*/
private int mSurfaceSequenceId = 0;
private boolean mRelayoutRequested;
private String mTag = TAG;
public ViewRootImpl(Context context, Display display) {
@@ -3311,6 +3318,7 @@ public final class ViewRootImpl implements ViewParent,
}
mIsInTraversal = false;
mRelayoutRequested = false;
}
private void notifyContentCatpureEvents() {
@@ -3941,10 +3949,18 @@ public final class ViewRootImpl implements ViewParent,
mDrawsNeededToReport++;
}
void pendingDrawFinished() {
void pendingDrawFinished(Transaction t) {
if (mDrawsNeededToReport == 0) {
throw new RuntimeException("Unbalanced drawPending/pendingDrawFinished calls");
}
if (t != null) {
if (DEBUG_BLAST) {
Log.d(mTag, "Merging transaction into main window transaction");
}
mSurfaceChangedTransaction.merge(t);
}
mDrawsNeededToReport--;
if (mDrawsNeededToReport == 0) {
reportDrawFinished();
@@ -3954,17 +3970,31 @@ public final class ViewRootImpl implements ViewParent,
}
}
void pendingDrawFinished() {
pendingDrawFinished(null);
}
private void postDrawFinished() {
mHandler.sendEmptyMessage(MSG_DRAW_FINISHED);
}
private void reportDrawFinished() {
try {
if (DEBUG_BLAST) {
Log.d(mTag, "reportDrawFinished");
}
mDrawsNeededToReport = 0;
if (!mReportDrawToWm) {
if (DEBUG_BLAST) {
Log.d(mTag, "reportDrawFinished");
Log.d(mTag, "No need to report finishDrawing. Apply immediately");
}
mDrawsNeededToReport = 0;
mSurfaceChangedTransaction.apply();
return;
}
try {
mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction);
mReportDrawToWm = false;
} catch (RemoteException e) {
Log.e(mTag, "Unable to report draw finished", e);
mSurfaceChangedTransaction.apply();
@@ -7756,6 +7786,7 @@ public final class ViewRootImpl implements ViewParent,
private int relayoutWindow(WindowManager.LayoutParams params, int viewVisibility,
boolean insetsPending) throws RemoteException {
mRelayoutRequested = true;
float appScale = mAttachInfo.mApplicationScale;
boolean restore = false;
if (params != null && mTranslator != null) {
@@ -9573,6 +9604,7 @@ public final class ViewRootImpl implements ViewParent,
if (mReportNextDraw == false) {
drawPending();
}
mReportDrawToWm = true;
mReportNextDraw = true;
}
@@ -10501,4 +10533,8 @@ public final class ViewRootImpl implements ViewParent,
mBLASTDrawConsumer = consume;
return true;
}
boolean wasRelayoutRequested() {
return mRelayoutRequested;
}
}

View File

@@ -61,10 +61,11 @@ static jobject nativeGetSurface(JNIEnv* env, jclass clazz, jlong ptr,
queue->getSurface(includeSurfaceControlHandle));
}
static void nativeSetSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr) {
static void nativeSetSyncTransaction(JNIEnv* env, jclass clazz, jlong ptr, jlong transactionPtr,
jboolean acquireSingleBuffer) {
sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionPtr);
queue->setSyncTransaction(transaction);
queue->setSyncTransaction(transaction, acquireSingleBuffer);
}
static void nativeUpdate(JNIEnv* env, jclass clazz, jlong ptr, jlong surfaceControl, jlong width,
@@ -98,7 +99,7 @@ static const JNINativeMethod gMethods[] = {
{"nativeCreate", "(Ljava/lang/String;JJJI)J", (void*)nativeCreate},
{"nativeGetSurface", "(JZ)Landroid/view/Surface;", (void*)nativeGetSurface},
{"nativeDestroy", "(J)V", (void*)nativeDestroy},
{"nativeSetSyncTransaction", "(JJ)V", (void*)nativeSetSyncTransaction},
{"nativeSetSyncTransaction", "(JJZ)V", (void*)nativeSetSyncTransaction},
{"nativeUpdate", "(JJJJIJ)V", (void*)nativeUpdate},
{"nativeMergeWithNextTransaction", "(JJJ)V", (void*)nativeMergeWithNextTransaction},
{"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},

View File

@@ -31,7 +31,8 @@ public final class BLASTBufferQueue {
long height, int format);
private static native void nativeDestroy(long ptr);
private static native Surface nativeGetSurface(long ptr, boolean includeSurfaceControlHandle);
private static native void nativeSetSyncTransaction(long ptr, long transactionPtr);
private static native void nativeSetSyncTransaction(long ptr, long transactionPtr,
boolean acquireSingleBuffer);
private static native void nativeUpdate(long ptr, long surfaceControl, long width, long height,
int format, long transactionPtr);
private static native void nativeMergeWithNextTransaction(long ptr, long transactionPtr,
@@ -66,12 +67,25 @@ public final class BLASTBufferQueue {
}
/**
* Send the transaction to BBQ so the next frame can be added and not applied immediately.
* This gives the caller a chance to apply the transaction when it's ready.
* @param t The transaction to add the frame to. This can be null to clear the transaction.
* Send the transaction to BBQ so the next frame can be added and not applied immediately. This
* gives the caller a chance to apply the transaction when it's ready.
*
* @param t The transaction to add the frame to. This can be null to clear the
* transaction.
* @param acquireSingleBuffer If true, only acquire a single buffer when processing frames. The
* transaction will be cleared once a single buffer has been
* acquired. If false, continue to acquire all buffers into the
* transaction until setSyncTransaction is called again with a null
* transaction.
*/
public void setSyncTransaction(@Nullable SurfaceControl.Transaction t,
boolean acquireSingleBuffer) {
nativeSetSyncTransaction(mNativeObject, t == null ? 0 : t.mNativeObject,
acquireSingleBuffer);
}
public void setSyncTransaction(@Nullable SurfaceControl.Transaction t) {
nativeSetSyncTransaction(mNativeObject, t == null ? 0 : t.mNativeObject);
setSyncTransaction(t, true /* acquireSingleBuffer */);
}
/**