Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9f19b5d1 authored by chaviw's avatar chaviw
Browse files

Call applyPendingTransactions when frame didn't draw

It's possible for a caller to requested mergeWithNextTransaction, but
the main frame had nothing new to draw. If that's the case, the
mergeWithNextTransactions will be stuck and never applied (or applied
much later). Since this could end up blocking Transactions, it's better
to force apply these when we know a frame wasn't going to draw this
vsync.

Test: Existing tests pass
Bug: 195262673
Change-Id: Ic0919ba6446d6a12d824185f6b3e540c2d5319d7
parent 31142f49
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -4031,6 +4031,10 @@ public final class ViewRootImpl implements ViewParent,
                mBlastBufferQueue.setNextTransaction(null);
                mBlastBufferQueue.setTransactionCompleteCallback(mRtLastAttemptedDrawFrameNum,
                        null);
                // Apply the transactions that were sent to mergeWithNextTransaction since the
                // frame didn't draw on this vsync. It's possible the frame will draw later, but
                // it's better to not be sync than to block on a frame that may never come.
                mBlastBufferQueue.applyPendingTransactions(mRtLastAttemptedDrawFrameNum);
            }

            mHandler.postAtFrontOfQueue(() -> {
+6 −0
Original line number Diff line number Diff line
@@ -144,6 +144,11 @@ static jlong nativeGetLastAcquiredFrameNum(JNIEnv* env, jclass clazz, jlong ptr)
    return queue->getLastAcquiredFrameNum();
}

static void nativeApplyPendingTransactions(JNIEnv* env, jclass clazz, jlong ptr, jlong frameNum) {
    sp<BLASTBufferQueue> queue = reinterpret_cast<BLASTBufferQueue*>(ptr);
    queue->applyPendingTransactions(frameNum);
}

static const JNINativeMethod gMethods[] = {
        /* name, signature, funcPtr */
        // clang-format off
@@ -158,6 +163,7 @@ static const JNINativeMethod gMethods[] = {
                "(JJLandroid/graphics/BLASTBufferQueue$TransactionCompleteCallback;)V",
                (void*)nativeSetTransactionCompleteCallback},
        {"nativeGetLastAcquiredFrameNum", "(J)J", (void*)nativeGetLastAcquiredFrameNum},
        {"nativeApplyPendingTransactions", "(JJ)V", (void*)nativeApplyPendingTransactions},
        // clang-format on
};

+12 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@ public final class BLASTBufferQueue {
    private static native void nativeSetTransactionCompleteCallback(long ptr, long frameNumber,
            TransactionCompleteCallback callback);
    private static native long nativeGetLastAcquiredFrameNum(long ptr);
    private static native void nativeApplyPendingTransactions(long ptr, long frameNumber);

    /**
     * Callback sent to {@link #setTransactionCompleteCallback(long, TransactionCompleteCallback)}
@@ -146,6 +147,17 @@ public final class BLASTBufferQueue {
        nativeMergeWithNextTransaction(mNativeObject, nativeTransaction, frameNumber);
    }

    /**
     * Apply any transactions that were passed to {@link #mergeWithNextTransaction} with the
     * specified frameNumber. This is intended to ensure transactions don't get stuck as pending
     * if the specified frameNumber is never drawn.
     *
     * @param frameNumber The frameNumber used to determine which transactions to apply.
     */
    public void applyPendingTransactions(long frameNumber) {
        nativeApplyPendingTransactions(mNativeObject, frameNumber);
    }

    public long getLastAcquiredFrameNum() {
        return nativeGetLastAcquiredFrameNum(mNativeObject);
    }