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

Commit 3afbfad1 authored by Vishnu Nair's avatar Vishnu Nair
Browse files

Add async mode tests for BLAST

Add some tests to validate dequeue blocking behavior when the IGBP
is configured in async mode. We want to validate that in this mode,
with or without blast, the client will not be blocked when dequeuing
a buffer. Instead, when the client tries to queue a buffer, the
bufferqueue will drop the queued buffer if it exists.

In async mode, the bufferqueue in the will have an additional buffer
so for blast: one buffer will be acquired and presented, one buffer
will be acquired in the queue, and the client will have two buffers
left for non blocking dequeue. When queuing a buffer, the BQ in the
adapter will drop the last queued buffer if available.

Test: atest BufferPresentationTests
Bug: 176916466

Change-Id: I6ff45c24d6529cc7cd4169f962eb2ca9cbc09943
parent cebc5661
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -130,6 +130,9 @@ JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceDequeueBuffer(J
        return result;
    }
    sBuffers[slot] = anb;
    if (timeoutMs == 0) {
        return android::OK;
    }
    android::sp<android::Fence> fence(new android::Fence(fenceFd));
    int waitResult = fence->wait(timeoutMs);
    if (waitResult != android::OK) {
@@ -197,6 +200,28 @@ JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceQueueBuffer(JNI
    return result;
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceSetAsyncMode(JNIEnv* /* env */,
                                                                              jclass /* clazz */,
                                                                              jboolean async) {
    assert(sAnw);
    android::sp<android::Surface> surface = static_cast<android::Surface*>(sAnw);
    return surface->setAsyncMode(async);
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceSetDequeueTimeout(
        JNIEnv* /* env */, jclass /* clazz */, jlong timeoutMs) {
    assert(sAnw);
    android::sp<android::Surface> surface = static_cast<android::Surface*>(sAnw);
    return surface->setDequeueTimeout(timeoutMs);
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceSetMaxDequeuedBufferCount(
        JNIEnv* /* env */, jclass /* clazz */, jint maxDequeuedBuffers) {
    assert(sAnw);
    android::sp<android::Surface> surface = static_cast<android::Surface*>(sAnw);
    return surface->setMaxDequeuedBufferCount(maxDequeuedBuffers);
}

JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_NativeWindowSetBufferCount(
        JNIEnv* /* env */, jclass /* clazz */, jint count) {
    assert(sAnw);
+77 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@ package com.android.test

import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -93,4 +94,80 @@ class BufferPresentationTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase

        assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
    }

    @Test
    // Leave IGBP in sync mode, try to dequeue and queue as fast as possible. Check that we
    // occasionally get timeout errors.
    fun testSyncMode_dequeueWithoutBlockingFails() {
        val numFrames = 1000L
        runOnUiThread { activity ->
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetDequeueTimeout(3L))
            var failures = false
            for (i in 1..numFrames) {
                if (activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 0 /* ms */) != 0) {
                    failures = true
                    break
                }
                activity.mSurfaceProxy.SurfaceQueueBuffer(0)
            }
            assertTrue(failures)
        }
    }

    @Test
    // Set IGBP to be in async mode, try to dequeue and queue as fast as possible. Client should be
    // able to dequeue and queue buffers without being blocked.
    fun testAsyncMode_dequeueWithoutBlocking() {
        val numFrames = 1000L
        runOnUiThread { activity ->
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetDequeueTimeout(3L))
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetAsyncMode(async = true))
            for (i in 1..numFrames) {
                assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 0 /* ms */))
                activity.mSurfaceProxy.SurfaceQueueBuffer(0)
            }
        }
    }

    @Test
    // Disable triple buffering in the system and leave IGBP in sync mode. Check that we
    // occasionally get timeout errors.
    fun testSyncModeWithDisabledTripleBuffering_dequeueWithoutBlockingFails() {
        val numFrames = 1000L
        runOnUiThread { activity ->
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetMaxDequeuedBufferCount(1))
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetDequeueTimeout(3L))
            var failures = false
            for (i in 1..numFrames) {
                if (activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 0 /* ms */) != 0) {
                    failures = true
                    break
                }
                activity.mSurfaceProxy.SurfaceQueueBuffer(0)
            }
            assertTrue(failures)
        }
    }

    @Test
    // Disable triple buffering in the system and set IGBP to be in async mode. Try to dequeue and
    // queue as fast as possible. Without triple buffering, the client does not have an extra buffer
    // to dequeue and will not be able to dequeue and queue buffers without being blocked.
    fun testAsyncModeWithDisabledTripleBuffering_dequeueWithoutBlockingFails() {
        val numFrames = 1000L
        runOnUiThread { activity ->
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetMaxDequeuedBufferCount(1))
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetDequeueTimeout(3L))
            assertEquals(0, activity.mSurfaceProxy.SurfaceSetAsyncMode(async = true))
            var failures = false
            for (i in 1..numFrames) {
                if (activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 0 /* ms */) != 0) {
                    failures = true
                    break
                }
                activity.mSurfaceProxy.SurfaceQueueBuffer(0)
            }
            assertTrue(failures)
        }
    }
}
 No newline at end of file
+7 −1
Original line number Diff line number Diff line
@@ -54,7 +54,13 @@ class SurfaceProxy {
    external fun SurfaceSetScalingMode(scalingMode: Int)
    external fun SurfaceDequeueBuffer(slot: Int, timeoutMs: Int): Int
    external fun SurfaceCancelBuffer(slot: Int)
    external fun SurfaceQueueBuffer(slot: Int, freeSlot: Boolean = true)
    external fun SurfaceQueueBuffer(slot: Int, freeSlot: Boolean = true): Int
    external fun SurfaceSetAsyncMode(async: Boolean): Int
    external fun SurfaceSetDequeueTimeout(timeout: Long): Int
    external fun SurfaceQuery(what: Int): Int
    external fun SurfaceSetMaxDequeuedBufferCount(maxDequeuedBuffers: Int): Int

    // system/native_window.h functions
    external fun NativeWindowSetBufferCount(count: Int): Int
    external fun NativeWindowSetSharedBufferMode(shared: Boolean): Int
    external fun NativeWindowSetAutoRefresh(autoRefresh: Boolean): Int