Merge "Synchronize SV buffers with main window when config changes"
This commit is contained in:
committed by
Android (Google) Code Review
commit
354d65eec7
@@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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},
|
||||
|
||||
@@ -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 */);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user