diff --git a/tests/SurfaceViewBufferTests/cpp/SurfaceProxy.cpp b/tests/SurfaceViewBufferTests/cpp/SurfaceProxy.cpp index ce226fdce320..926ff4d5793c 100644 --- a/tests/SurfaceViewBufferTests/cpp/SurfaceProxy.cpp +++ b/tests/SurfaceViewBufferTests/cpp/SurfaceProxy.cpp @@ -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 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 surface = static_cast(sAnw); + return surface->setAsyncMode(async); +} + +JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceSetDequeueTimeout( + JNIEnv* /* env */, jclass /* clazz */, jlong timeoutMs) { + assert(sAnw); + android::sp surface = static_cast(sAnw); + return surface->setDequeueTimeout(timeoutMs); +} + +JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_SurfaceSetMaxDequeuedBufferCount( + JNIEnv* /* env */, jclass /* clazz */, jint maxDequeuedBuffers) { + assert(sAnw); + android::sp surface = static_cast(sAnw); + return surface->setMaxDequeuedBufferCount(maxDequeuedBuffers); +} + JNIEXPORT jint JNICALL Java_com_android_test_SurfaceProxy_NativeWindowSetBufferCount( JNIEnv* /* env */, jclass /* clazz */, jint count) { assert(sAnw); diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt b/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt index 7d278dc8acc0..b67dc380efab 100644 --- a/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt +++ b/tests/SurfaceViewBufferTests/src/com/android/test/BufferPresentationTests.kt @@ -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 diff --git a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceProxy.kt b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceProxy.kt index cfbd3ac11acb..45a70944204c 100644 --- a/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceProxy.kt +++ b/tests/SurfaceViewBufferTests/src/com/android/test/SurfaceProxy.kt @@ -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