BlastBufferQueue: Add SurfaceView resize tests

If the buffer scaling mode is not set to freeze, the SurfaceView should
resize immediately. Verify behavior with freeze and scale to window
buffer scale modes.

Bug: 174217687
Test: atest SurfaceViewBufferTests:GeometryTests

Change-Id: Idce0ee4e3af0920c1f8d63efe84bae369b7a0cac
This commit is contained in:
Vishnu Nair
2021-01-07 10:04:23 -08:00
parent a3b6beaff1
commit 6d92d0137c
8 changed files with 249 additions and 124 deletions

View File

@@ -0,0 +1 @@
include /services/core/java/com/android/server/wm/OWNERS

View File

@@ -27,12 +27,13 @@ class BufferPresentationTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase
@Test
fun testQueueBuffers() {
val numFrames = 100L
val trace = withTrace {
val trace = withTrace { activity ->
for (i in 1..numFrames) {
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
}
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(numFrames, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(numFrames,
1000 /* ms */))
}
assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
@@ -40,13 +41,13 @@ class BufferPresentationTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase
@Test
fun testSetBufferScalingMode_outOfOrderQueueBuffer() {
val trace = withTrace {
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
val trace = withTrace { activity ->
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
it.mSurfaceProxy.SurfaceQueueBuffer(1)
it.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(2, 5000 /* ms */))
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(2, 5000 /* ms */))
}
assertThat(trace).hasFrameSequence("SurfaceView", 1..2L)
@@ -55,15 +56,16 @@ class BufferPresentationTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase
@Test
fun testSetBufferScalingMode_multipleDequeueBuffer() {
val numFrames = 20L
val trace = withTrace {
val trace = withTrace { activity ->
for (count in 1..(numFrames / 2)) {
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
it.mSurfaceProxy.SurfaceQueueBuffer(0)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
}
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(numFrames, 5000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(numFrames,
5000 /* ms */))
}
assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)
@@ -73,19 +75,20 @@ class BufferPresentationTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase
fun testSetBufferCount_queueMaxBufferCountMinusOne() {
val numBufferCount = 8
val numFrames = numBufferCount * 5L
val trace = withTrace {
assertEquals(0, it.mSurfaceProxy.NativeWindowSetBufferCount(numBufferCount + 1))
val trace = withTrace { activity ->
assertEquals(0, activity.mSurfaceProxy.NativeWindowSetBufferCount(numBufferCount + 1))
for (i in 1..numFrames / numBufferCount) {
for (bufferSlot in 0..numBufferCount - 1) {
assertEquals(0,
it.mSurfaceProxy.SurfaceDequeueBuffer(bufferSlot, 1000 /* ms */))
activity.mSurfaceProxy.SurfaceDequeueBuffer(bufferSlot, 1000 /* ms */))
}
for (bufferSlot in 0..numBufferCount - 1) {
it.mSurfaceProxy.SurfaceQueueBuffer(bufferSlot)
activity.mSurfaceProxy.SurfaceQueueBuffer(bufferSlot)
}
}
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(numFrames, 5000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(numFrames,
5000 /* ms */))
}
assertThat(trace).hasFrameSequence("SurfaceView", 1..numFrames)

View File

@@ -28,20 +28,21 @@ import org.junit.runners.Parameterized
class BufferRejectionTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastAdapter) {
@Test
fun testSetBuffersGeometry_0x0_rejectsBuffer() {
val trace = withTrace {
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, 100, 100,
val trace = withTrace { activity ->
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, 100, 100,
R8G8B8A8_UNORM)
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, 0, 0,
R8G8B8A8_UNORM)
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, 0, 0, R8G8B8A8_UNORM)
// Submit buffer one with a different size which should be rejected
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
// submit a buffer with the default buffer size
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
it.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */)
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */)
}
// Verify we reject buffers since scaling mode == NATIVE_WINDOW_SCALING_MODE_FREEZE
assertThat(trace).layer("SurfaceView", 2).doesNotExist()
@@ -61,22 +62,22 @@ class BufferRejectionTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(us
@Test
fun testSetBufferScalingMode_freeze() {
val bufferSize = Point(300, 200)
val trace = withTrace {
it.drawFrame()
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, bufferSize,
val trace = withTrace { activity ->
activity.drawFrame()
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
R8G8B8A8_UNORM)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
// Change buffer size and set scaling mode to freeze
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, Point(0, 0),
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, Point(0, 0),
R8G8B8A8_UNORM)
// first dequeued buffer does not have the new size so it should be rejected.
it.mSurfaceProxy.SurfaceQueueBuffer(0)
it.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
}
// verify buffer size is reset to default buffer size
@@ -88,23 +89,23 @@ class BufferRejectionTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(us
@Test
fun testSetBufferScalingMode_freeze_withBufferRotation() {
val rotatedBufferSize = Point(defaultBufferSize.y, defaultBufferSize.x)
val trace = withTrace {
it.drawFrame()
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, rotatedBufferSize,
R8G8B8A8_UNORM)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
val trace = withTrace { activity ->
activity.drawFrame()
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!,
rotatedBufferSize, R8G8B8A8_UNORM)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
// Change buffer size and set scaling mode to freeze
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, Point(0, 0),
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, Point(0, 0),
R8G8B8A8_UNORM)
// first dequeued buffer does not have the new size so it should be rejected.
it.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
// add a buffer transform so the buffer size is correct.
it.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.ROT_90)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.ROT_90)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
}
// verify buffer size is reset to default buffer size
@@ -117,24 +118,24 @@ class BufferRejectionTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(us
@Test
fun testRejectedBuffersAreReleased() {
val bufferSize = Point(300, 200)
val trace = withTrace {
val trace = withTrace { activity ->
for (count in 0 until 5) {
it.drawFrame()
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed((count * 3) + 1L,
activity.drawFrame()
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed((count * 3) + 1L,
500 /* ms */), 0)
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, bufferSize,
R8G8B8A8_UNORM)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!,
bufferSize, R8G8B8A8_UNORM)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
// Change buffer size and set scaling mode to freeze
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, Point(0, 0),
R8G8B8A8_UNORM)
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!,
Point(0, 0), R8G8B8A8_UNORM)
// first dequeued buffer does not have the new size so it should be rejected.
it.mSurfaceProxy.SurfaceQueueBuffer(0)
it.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed((count * 3) + 3L,
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed((count * 3) + 3L,
500 /* ms */), 0)
}
}

View File

@@ -15,25 +15,31 @@
*/
package com.android.test
import android.graphics.Color
import android.graphics.Point
import android.graphics.Rect
import android.os.SystemClock
import com.android.server.wm.flicker.traces.layers.LayersTraceSubject.Companion.assertThat
import com.android.test.SurfaceViewBufferTestBase.Companion.ScalingMode
import com.android.test.SurfaceViewBufferTestBase.Companion.Transform
import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
@RunWith(Parameterized::class)
class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastAdapter) {
@Test
fun testSetBuffersGeometry_0x0_resetsBufferSize() {
val trace = withTrace {
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, 0, 0,
val trace = withTrace { activity ->
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, 0, 0,
R8G8B8A8_UNORM)
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
}
// verify buffer size is reset to default buffer size
@@ -43,11 +49,11 @@ class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastA
@Test
fun testSetBuffersGeometry_smallerThanBuffer() {
val bufferSize = Point(300, 200)
val trace = withTrace {
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, bufferSize,
val trace = withTrace { activity ->
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
R8G8B8A8_UNORM)
it.drawFrame()
it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
activity.drawFrame()
activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
}
assertThat(trace).layer("SurfaceView", 1).also {
@@ -60,11 +66,11 @@ class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastA
@Test
fun testSetBuffersGeometry_largerThanBuffer() {
val bufferSize = Point(3000, 2000)
val trace = withTrace {
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, bufferSize,
val trace = withTrace { activity ->
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
R8G8B8A8_UNORM)
it.drawFrame()
it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
activity.drawFrame()
activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
}
assertThat(trace).layer("SurfaceView", 1).also {
@@ -77,22 +83,22 @@ class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastA
@Test
fun testSetBufferScalingMode_freeze() {
val bufferSize = Point(300, 200)
val trace = withTrace {
it.drawFrame()
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, bufferSize,
val trace = withTrace { activity ->
activity.drawFrame()
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, bufferSize,
R8G8B8A8_UNORM)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
// Change buffer size and set scaling mode to freeze
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, Point(0, 0),
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, Point(0, 0),
R8G8B8A8_UNORM)
// first dequeued buffer does not have the new size so it should be rejected.
it.mSurfaceProxy.SurfaceQueueBuffer(0)
it.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
}
// verify buffer size is reset to default buffer size
@@ -105,11 +111,11 @@ class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastA
fun testSetBuffersTransform_FLIP() {
val transforms = arrayOf(Transform.FLIP_H, Transform.FLIP_V, Transform.ROT_180).withIndex()
for ((index, transform) in transforms) {
val trace = withTrace {
it.mSurfaceProxy.ANativeWindowSetBuffersTransform(transform)
it.mSurfaceProxy.ANativeWindowLock()
it.mSurfaceProxy.ANativeWindowUnlockAndPost()
it.mSurfaceProxy.waitUntilBufferDisplayed(index + 1L, 500 /* ms */)
val trace = withTrace { activity ->
activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(transform)
activity.mSurfaceProxy.ANativeWindowLock()
activity.mSurfaceProxy.ANativeWindowUnlockAndPost()
activity.mSurfaceProxy.waitUntilBufferDisplayed(index + 1L, 500 /* ms */)
}
assertThat(trace).layer("SurfaceView", index + 1L).also {
@@ -119,4 +125,100 @@ class GeometryTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(useBlastA
}
}
}
@Test
fun testSurfaceViewResizeImmediatelyWithNonFreezeScaling() {
val surfaceViewPosition = Rect()
var trace = withTrace { activity ->
activity.mSurfaceProxy.SurfaceSetScalingMode(ScalingMode.SCALE_TO_WINDOW)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
activity.mSurfaceProxy.drawBuffer(0, Color.BLUE)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
activity.mSurfaceView!!.getBoundsOnScreen(surfaceViewPosition)
}
runOnUiThread {
val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
checkPixels(svBounds, Color.BLUE)
}
// check that the layer and buffer starts with the default size
assertThat(trace).layer("SurfaceView", 1).also {
it.hasBufferSize(defaultBufferSize)
it.hasLayerSize(defaultBufferSize)
}
val newSize = Point(1280, 960)
lateinit var resizeCountDownLatch: CountDownLatch
runOnUiThread {
resizeCountDownLatch = it.resizeSurfaceView(newSize)
}
assertTrue(resizeCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
// wait for sf to handle the resize transaction request
SystemClock.sleep(500)
trace = withTrace { _ ->
// take a trace with the new size
}
// check that the layer size has changed and the buffer is now streched to the new layer
// size
runOnUiThread {
val svBounds = Rect(0, 0, newSize.x, newSize.y)
svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
checkPixels(svBounds, Color.BLUE)
}
assertThat(trace).layer("SurfaceView", 1).also {
it.hasLayerSize(newSize)
it.hasBufferSize(defaultBufferSize)
}
}
@Test
fun testSurfaceViewDoesNotResizeWithDefaultScaling() {
val surfaceViewPosition = Rect()
var trace = withTrace { activity ->
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
activity.mSurfaceProxy.drawBuffer(0, Color.BLUE)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */)
activity.mSurfaceView!!.getBoundsOnScreen(surfaceViewPosition)
}
runOnUiThread {
val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
checkPixels(svBounds, Color.BLUE)
}
// check that the layer and buffer starts with the default size
assertThat(trace).layer("SurfaceView", 1).also {
it.hasBufferSize(defaultBufferSize)
it.hasLayerSize(defaultBufferSize)
}
val newSize = Point(1280, 960)
lateinit var resizeCountDownLatch: CountDownLatch
runOnUiThread {
resizeCountDownLatch = it.resizeSurfaceView(newSize)
}
assertTrue(resizeCountDownLatch.await(1000, TimeUnit.MILLISECONDS))
// wait for sf to handle the resize transaction request
SystemClock.sleep(500)
trace = withTrace { _ ->
// take a trace after the size change
}
// check the layer and buffer remains the same size
runOnUiThread {
val svBounds = Rect(0, 0, defaultBufferSize.x, defaultBufferSize.y)
svBounds.offsetTo(surfaceViewPosition.left, surfaceViewPosition.top)
checkPixels(svBounds, Color.BLUE)
}
assertThat(trace).layer("SurfaceView", 1).also {
it.hasLayerSize(defaultBufferSize)
it.hasBufferSize(defaultBufferSize)
}
}
}

View File

@@ -44,28 +44,28 @@ class InverseDisplayTransformTests(useBlastAdapter: Boolean) :
"fixed scaling mode.", useBlastAdapter)
val rotatedBufferSize = Point(defaultBufferSize.y, defaultBufferSize.x)
val trace = withTrace {
val trace = withTrace { activity ->
// Inverse display transforms are sticky AND they are only consumed by the sf after
// a valid buffer has been acquired.
it.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.INVERSE_DISPLAY.value)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
it.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.INVERSE_DISPLAY.value)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, rotatedBufferSize,
R8G8B8A8_UNORM)
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(1, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!,
rotatedBufferSize, R8G8B8A8_UNORM)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(1, 1000 /* ms */))
// Change buffer size and set scaling mode to freeze
it.mSurfaceProxy.ANativeWindowSetBuffersGeometry(it.surface!!, Point(0, 0),
activity.mSurfaceProxy.ANativeWindowSetBuffersGeometry(activity.surface!!, Point(0, 0),
R8G8B8A8_UNORM)
// first dequeued buffer does not have the new size so it should be rejected.
it.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.ROT_90.value)
it.mSurfaceProxy.SurfaceQueueBuffer(0)
it.mSurfaceProxy.ANativeWindowSetBuffersTransform(0)
it.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(it.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(Transform.ROT_90.value)
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
activity.mSurfaceProxy.ANativeWindowSetBuffersTransform(0)
activity.mSurfaceProxy.SurfaceQueueBuffer(1)
assertEquals(activity.mSurfaceProxy.waitUntilBufferDisplayed(3, 500 /* ms */), 0)
}
// verify buffer size is reset to default buffer size

View File

@@ -40,12 +40,12 @@ class MainActivity : CapturedActivity() {
private var mSurfaceHolder: SurfaceHolder? = null
private val mDrawLock = ReentrantLock()
var mSurfaceView: SurfaceView? = null
private var mCountDownLatch: CountDownLatch? = null
val surface: Surface? get() = mSurfaceHolder?.surface
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
addSurfaceView(Point(500, 200))
window.decorView.apply {
systemUiVisibility =
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN
@@ -60,13 +60,23 @@ class MainActivity : CapturedActivity() {
val layout = findViewById<FrameLayout>(android.R.id.content)
val surfaceReadyLatch = CountDownLatch(1)
mSurfaceView = createSurfaceView(applicationContext, size, surfaceReadyLatch)
layout.addView(mSurfaceView!!,
layout!!.addView(mSurfaceView!!,
FrameLayout.LayoutParams(size.x, size.y, Gravity.TOP or Gravity.LEFT)
.also { it.setMargins(100, 100, 0, 0) })
return surfaceReadyLatch
}
fun resizeSurfaceView(size: Point): CountDownLatch {
mCountDownLatch = CountDownLatch(1)
mSurfaceView!!.layoutParams.also {
it.width = size.x
it.height = size.y
}
mSurfaceView!!.requestLayout()
return mCountDownLatch!!
}
fun enableSeamlessRotation() {
val p: WindowManager.LayoutParams = window.attributes
p.rotationAnimation = WindowManager.LayoutParams.ROTATION_ANIMATION_SEAMLESS
@@ -88,7 +98,6 @@ class MainActivity : CapturedActivity() {
): SurfaceView {
val surfaceView = SurfaceView(context)
surfaceView.setWillNotDraw(false)
surfaceView.holder.setFixedSize(size.x, size.y)
surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
mDrawLock.withLock {
@@ -104,6 +113,7 @@ class MainActivity : CapturedActivity() {
width: Int,
height: Int
) {
mCountDownLatch?.countDown()
}
override fun surfaceDestroyed(holder: SurfaceHolder) {

View File

@@ -30,12 +30,12 @@ class SharedBufferModeTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(u
@Test
fun testCanPresentBuffers() {
val numFrames = 15L
val trace = withTrace {
assertEquals(0, it.mSurfaceProxy.NativeWindowSetSharedBufferMode(true))
val trace = withTrace { activity ->
assertEquals(0, activity.mSurfaceProxy.NativeWindowSetSharedBufferMode(true))
for (i in 1..numFrames) {
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
it.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(i, 5000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(i, 5000 /* ms */))
}
}
@@ -47,13 +47,14 @@ class SharedBufferModeTests(useBlastAdapter: Boolean) : SurfaceTracingTestBase(u
@Test
fun testFastQueueBuffers() {
val numFrames = 15L
val trace = withTrace {
assertEquals(0, it.mSurfaceProxy.NativeWindowSetSharedBufferMode(true))
val trace = withTrace { activity ->
assertEquals(0, activity.mSurfaceProxy.NativeWindowSetSharedBufferMode(true))
for (i in 1..numFrames) {
assertEquals(0, it.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
it.mSurfaceProxy.SurfaceQueueBuffer(0)
assertEquals(0, activity.mSurfaceProxy.SurfaceDequeueBuffer(0, 1 /* ms */))
activity.mSurfaceProxy.SurfaceQueueBuffer(0)
}
assertEquals(0, it.mSurfaceProxy.waitUntilBufferDisplayed(numFrames, 5000 /* ms */))
assertEquals(0, activity.mSurfaceProxy.waitUntilBufferDisplayed(numFrames,
5000 /* ms */))
}
assertThat(trace).hasFrameSequence("SurfaceView", numFrames..numFrames)

View File

@@ -60,6 +60,13 @@ open class SurfaceTracingTestBase(useBlastAdapter: Boolean) :
}
}
fun withTrace(predicate: () -> Unit): LayersTrace {
return withSFTracing(TRACE_FLAGS,
outputDir = instrumentation.targetContext.dataDir.toPath()) {
predicate()
}
}
fun runOnUiThread(predicate: (it: MainActivity) -> Unit) {
scenarioRule.getScenario().onActivity {
predicate(it)