SurfaceFlingerPerfTests: Scenario builder for SurfaceFlingerPerfTests.

By exposing a SurfaceControl and allocating a specified number
of buffers to it were now able to test various scenarios
utilizing the SurfaceControl.Transaction apis in
SurfaceFlingerPerfTests.

Test: atest SurfaceFlingerPerfTests
Bug: b/230039226
Change-Id: Ic2b49ddbba9d27a8f9ac8015870a1c4aa86014f6
This commit is contained in:
Alexus Allen
2022-08-04 21:38:27 +00:00
parent 0be76567fe
commit e6a0741455
5 changed files with 174 additions and 50 deletions

View File

@@ -18,7 +18,7 @@
<application android:label="SurfaceFlingerPerfTests">
<uses-library android:name="android.test.runner" />
<activity android:name="android.perftests.utils.SurfaceFlingerTestActivity"
<activity android:name="android.surfaceflinger.SurfaceFlingerTestActivity"
android:exported="true">
<intent-filter>

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.surfaceflinger;
import android.annotation.ColorInt;
import android.graphics.Canvas;
import android.graphics.GraphicBuffer;
import android.graphics.PixelFormat;
import android.hardware.HardwareBuffer;
import android.hardware.SyncFence;
import android.view.SurfaceControl;
import java.util.concurrent.ArrayBlockingQueue;
/**
* Allocates n amount of buffers to a SurfaceControl using a Queue implementation. Executes a
* releaseCallback so a buffer can be safely re-used.
*
* @hide
*/
public class BufferFlinger {
ArrayBlockingQueue<GraphicBuffer> mBufferQ;
public BufferFlinger(int numOfBuffers, @ColorInt int color) {
mBufferQ = new ArrayBlockingQueue<>(numOfBuffers);
while (numOfBuffers > 0) {
GraphicBuffer buffer = GraphicBuffer.create(500, 500,
PixelFormat.RGBA_8888,
GraphicBuffer.USAGE_HW_TEXTURE | GraphicBuffer.USAGE_HW_COMPOSER
| GraphicBuffer.USAGE_SW_WRITE_RARELY);
Canvas canvas = buffer.lockCanvas();
canvas.drawColor(color);
buffer.unlockCanvasAndPost(canvas);
mBufferQ.add(buffer);
numOfBuffers--;
}
}
public void addBuffer(SurfaceControl.Transaction t, SurfaceControl surfaceControl)
throws InterruptedException {
GraphicBuffer buffer = mBufferQ.take();
t.setBuffer(surfaceControl,
HardwareBuffer.createFromGraphicBuffer(buffer),
null,
(SyncFence fence) -> {
releaseCallback(fence, buffer);
});
}
public void releaseCallback(SyncFence fence, GraphicBuffer buffer) {
if (fence != null) {
fence.awaitForever();
}
mBufferQ.add(buffer);
}
}

View File

@@ -16,37 +16,50 @@
package android.surfaceflinger;
import android.graphics.Color;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
import android.perftests.utils.SurfaceFlingerTestActivity;
import android.view.SurfaceControl;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.filters.LargeTest;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;
@LargeTest
@RunWith(AndroidJUnit4.class)
public class SurfaceFlingerPerfTest {
protected ActivityScenarioRule<SurfaceFlingerTestActivity> mActivityRule =
new ActivityScenarioRule<>(SurfaceFlingerTestActivity.class);
protected PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
private SurfaceFlingerTestActivity mActivity;
static final int BUFFER_COUNT = 2;
@Rule
public final RuleChain mAllRules = RuleChain
.outerRule(mPerfStatusReporter)
.around(mActivityRule);
@Before
public void setup() {
mActivityRule.getScenario().onActivity(activity -> mActivity = activity);
}
@Test
public void helloWorld() throws Exception {
public void submitSingleBuffer() throws Exception {
SurfaceControl sc = mActivity.getChildSurfaceControl();
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
BufferFlinger bufferflinger = new BufferFlinger(BUFFER_COUNT, Color.GREEN);
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
t.show(sc);
while (state.keepRunning()) {
// Do Something
bufferflinger.addBuffer(t, sc);
t.apply();
}
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.surfaceflinger;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.SurfaceControl;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import java.util.concurrent.CountDownLatch;
/**
* A simple activity used for testing, e.g. performance of activity switching, or as a base
* container of testing view.
*/
public class SurfaceFlingerTestActivity extends Activity {
public TestSurfaceView mTestSurfaceView;
SurfaceControl mSurfaceControl;
CountDownLatch mIsReady = new CountDownLatch(1);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mTestSurfaceView = new TestSurfaceView(this);
setContentView(mTestSurfaceView);
}
public SurfaceControl getChildSurfaceControl() throws InterruptedException {
return mTestSurfaceView.getChildSurfaceControlHelper();
}
public class TestSurfaceView extends SurfaceView {
public TestSurfaceView(Context context) {
super(context);
SurfaceHolder holder = getHolder();
holder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
mIsReady.countDown();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
});
}
public SurfaceControl getChildSurfaceControlHelper() throws InterruptedException {
mIsReady.await();
SurfaceHolder holder = getHolder();
// check to see if surface is valid
if (holder.getSurface().isValid()) {
mSurfaceControl = getSurfaceControl();
}
return new SurfaceControl.Builder()
.setName("ChildSurfaceControl")
.setParent(mSurfaceControl)
.build();
}
}
}

View File

@@ -1,44 +0,0 @@
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.perftests.utils;
import android.app.Activity;
import android.os.Bundle;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.LinearLayout;
/**
* A simple activity used for testing, e.g. performance of activity switching, or as a base
* container of testing view.
*/
public class SurfaceFlingerTestActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
final LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
final SurfaceView surfaceview = new SurfaceView(this);
layout.addView(surfaceview);
setContentView(layout);
}
}