DO NOT MERGE: Add SurfaceFlingerPerfTests
cherry-pick following change ids from U so we can get a performance baseline in t-qpr I4577987a8c06243b58f3982b379540104ca19a10 Ic8f07222c8307223c030dab08f4acd3eb18e18aa Ic2b49ddbba9d27a8f9ac8015870a1c4aa86014f6 I28e280b8df2d7140fb51fb05fd4e897e23478143 I89c75c956d6aa644367a834453e80c550d351fc2 I3c273a71ed29d5011848517b2bff81c1f3b5b80d Test: atest SurfaceFlingerPerfTests Bug: b/230039226 Ignore-AOSP-First: New folder that does not exist within AOSP. Change-Id: If31b1b573faeed269cf2cc8c7e483e4c5a351dba
This commit is contained in:
committed by
Vishnu Nair
parent
1f8fded512
commit
1177f3cfc2
40
apct-tests/perftests/surfaceflinger/Android.bp
Normal file
40
apct-tests/perftests/surfaceflinger/Android.bp
Normal file
@@ -0,0 +1,40 @@
|
||||
// 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 {
|
||||
// See: http://go/android-license-faq
|
||||
// A large-scale-change added 'default_applicable_licenses' to import
|
||||
// all of the 'license_kinds' from "frameworks_base_license"
|
||||
// to get the below license kinds:
|
||||
// SPDX-license-identifier-Apache-2.0
|
||||
default_applicable_licenses: ["frameworks_base_license"],
|
||||
}
|
||||
|
||||
android_test {
|
||||
name: "SurfaceFlingerPerfTests",
|
||||
srcs: ["src/**/*.java"],
|
||||
libs: ["android.test.runner.stubs"],
|
||||
static_libs: [
|
||||
"androidx.test.rules",
|
||||
"androidx.test.ext.junit",
|
||||
"androidx.annotation_annotation",
|
||||
"apct-perftests-utils",
|
||||
"collector-device-lib",
|
||||
"platform-test-annotations",
|
||||
],
|
||||
test_suites: ["device-tests"],
|
||||
data: [":perfetto_artifacts"],
|
||||
platform_apis: true,
|
||||
certificate: "platform",
|
||||
}
|
||||
37
apct-tests/perftests/surfaceflinger/AndroidManifest.xml
Normal file
37
apct-tests/perftests/surfaceflinger/AndroidManifest.xml
Normal file
@@ -0,0 +1,37 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="android.perftests.surfaceflinger">
|
||||
|
||||
<!-- permission needed to write perfetto trace and read/write simpleperf report -->
|
||||
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<application android:label="SurfaceFlingerPerfTests">
|
||||
<uses-library android:name="android.test.runner" />
|
||||
<activity android:name="android.surfaceflinger.SurfaceFlingerTestActivity"
|
||||
android:exported="true">
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="com.android.perftests.core.PERFTEST" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
<instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
|
||||
android:targetPackage="android.perftests.surfaceflinger">
|
||||
</instrumentation>
|
||||
</manifest>
|
||||
79
apct-tests/perftests/surfaceflinger/AndroidTest.xml
Normal file
79
apct-tests/perftests/surfaceflinger/AndroidTest.xml
Normal file
@@ -0,0 +1,79 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- 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.
|
||||
-->
|
||||
<configuration description="Runs SurfaceFlingerPerfTests metric instrumentation.">
|
||||
<option name="test-suite-tag" value="apct" />
|
||||
<option name="test-suite-tag" value="apct-metric-instrumentation" />
|
||||
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
|
||||
<option name="cleanup-apks" value="true" />
|
||||
<option name="install-arg" value="-t" />
|
||||
<option name="test-file-name" value="SurfaceFlingerPerfTests.apk" />
|
||||
</target_preparer>
|
||||
|
||||
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
|
||||
<option name="force-skip-system-props" value="true" />
|
||||
<option name="run-command" value="input keyevent KEYCODE_WAKEUP" />
|
||||
<option name="run-command" value="cmd window dismiss-keyguard" />
|
||||
<option name="run-command" value="cmd package compile -m speed android.perftests.surfaceflinger" />
|
||||
</target_preparer>
|
||||
|
||||
<!-- Needed for pushing the trace config file -->
|
||||
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
|
||||
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
|
||||
<option name="push-file" key="trace_config_detailed.textproto" value="/data/misc/perfetto-traces/trace_config.textproto" />
|
||||
</target_preparer>
|
||||
|
||||
<!-- Needed for storing the perfetto trace files in the sdcard/test_results-->
|
||||
<option name="isolated-storage" value="false" />
|
||||
|
||||
<test class="com.android.tradefed.testtype.AndroidJUnitTest" >
|
||||
<option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
|
||||
<option name="package" value="android.perftests.surfaceflinger" />
|
||||
<option name="hidden-api-checks" value="false"/>
|
||||
|
||||
<!-- Listener related args for collecting the traces and waiting for the device to stabilize. -->
|
||||
<option name="device-listeners" value="android.device.collectors.ProcLoadListener,android.device.collectors.PerfettoListener,android.device.collectors.SimpleperfListener" />
|
||||
|
||||
<!-- Guarantee that user defined RunListeners will be running before any of the default listeners defined in this runner. -->
|
||||
<option name="instrumentation-arg" key="newRunListenerMode" value="true" />
|
||||
|
||||
<!-- PerfettoListener related arguments -->
|
||||
<option name="instrumentation-arg" key="perfetto_config_text_proto" value="true" />
|
||||
<option name="instrumentation-arg" key="perfetto_config_file" value="trace_config.textproto" />
|
||||
|
||||
<!-- SimpleperfListener related arguments -->
|
||||
<option name="instrumentation-arg" key="report" value="true" />
|
||||
<option name="instrumentation-arg" key="arguments" value="""" />
|
||||
<option name="instrumentation-arg" key="events_to_record" value="instructions,cpu-cycles,raw-l3d-cache-refill,sched:sched_waking" />
|
||||
<option name="instrumentation-arg" key="processes_to_record" value="surfaceflinger" />
|
||||
<option name="instrumentation-arg" key="symbols_to_report" value=""android::SurfaceFlinger::commit(;android::SurfaceFlinger::composite("" />
|
||||
|
||||
<!-- ProcLoadListener related arguments -->
|
||||
<!-- Wait for device last minute threshold to reach 3 with 2 minute timeout before starting the test run -->
|
||||
<option name="instrumentation-arg" key="procload-collector:per_run" value="true" />
|
||||
<option name="instrumentation-arg" key="proc-loadavg-threshold" value="3" />
|
||||
<option name="instrumentation-arg" key="proc-loadavg-timeout" value="120000" />
|
||||
<option name="instrumentation-arg" key="proc-loadavg-interval" value="10000" />
|
||||
|
||||
</test>
|
||||
|
||||
<metrics_collector class="com.android.tradefed.device.metric.FilePullerLogCollector">
|
||||
<option name="directory-keys" value="/data/local/tmp/SurfaceFlingerPerfTests" />
|
||||
<!-- Needed for pulling the collected trace config on to the host -->
|
||||
<option name="pull-pattern-keys" value="perfetto_file_path" />
|
||||
<option name="pull-pattern-keys" value="simpleperf_file_path" />
|
||||
</metrics_collector>
|
||||
|
||||
</configuration>
|
||||
1
apct-tests/perftests/surfaceflinger/OWNERS
Normal file
1
apct-tests/perftests/surfaceflinger/OWNERS
Normal file
@@ -0,0 +1 @@
|
||||
include /services/core/java/com/android/server/wm/OWNERS
|
||||
34
apct-tests/perftests/surfaceflinger/README.md
Normal file
34
apct-tests/perftests/surfaceflinger/README.md
Normal file
@@ -0,0 +1,34 @@
|
||||
## SurfaceFlinger performance tests
|
||||
|
||||
### Precondition
|
||||
To reduce the variance of the test, if `perf-setup.sh` (platform_testing/scripts/perf-setup)
|
||||
is available, it is better to use the following instructions to lock CPU and GPU frequencies.
|
||||
```
|
||||
m perf-setup
|
||||
PERF_SETUP_PATH=/data/local/tmp/perf-setup.sh
|
||||
adb push $OUT/$PERF_SETUP_PATH $PERF_SETUP_PATH
|
||||
adb shell chmod +x $PERF_SETUP_PATH
|
||||
adb shell $PERF_SETUP_PATH
|
||||
```
|
||||
|
||||
### Example to run
|
||||
Use `atest`
|
||||
```
|
||||
atest SurfaceFlingerPerfTests:SurfaceFlingerPerfTest -- \
|
||||
--module-arg SurfaceFlingerPerfTests:instrumentation-arg:kill-bg:=true
|
||||
```
|
||||
Use `am instrument`
|
||||
```
|
||||
adb shell am instrument -w -r -e class android.surfaceflinger.SurfaceFlingerPerfTest \
|
||||
-e kill-bg true \
|
||||
com.android.perftests.surfaceflinger/androidx.test.runner.AndroidJUnitRunner
|
||||
```
|
||||
* `kill-bg` is optional.
|
||||
|
||||
Test arguments
|
||||
- kill-bg
|
||||
* boolean: Kill background process before running test.
|
||||
- profiling-iterations
|
||||
* int: Run the extra iterations with enabling method profiling.
|
||||
- profiling-sampling
|
||||
* int: The interval (0=trace each method, default is 10) of sample profiling in microseconds.
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
|
||||
public void freeBuffers() {
|
||||
for (GraphicBuffer buffer : mBufferQ) {
|
||||
buffer.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,228 @@
|
||||
/*
|
||||
* 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.graphics.Bitmap;
|
||||
import android.graphics.Color;
|
||||
import android.perftests.utils.BenchmarkState;
|
||||
import android.perftests.utils.PerfStatusReporter;
|
||||
import android.view.SurfaceControl;
|
||||
|
||||
import androidx.test.ext.junit.rules.ActivityScenarioRule;
|
||||
import androidx.test.filters.LargeTest;
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.runner.AndroidJUnit4;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.RuleChain;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Random;
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
@After
|
||||
public void teardown() {
|
||||
mSurfaceControls.forEach(SurfaceControl::release);
|
||||
mByfferTrackers.forEach(BufferFlinger::freeBuffers);
|
||||
}
|
||||
|
||||
|
||||
private ArrayList<BufferFlinger> mByfferTrackers = new ArrayList<>();
|
||||
private BufferFlinger createBufferTracker(int color) {
|
||||
BufferFlinger bufferTracker = new BufferFlinger(BUFFER_COUNT, color);
|
||||
mByfferTrackers.add(bufferTracker);
|
||||
return bufferTracker;
|
||||
}
|
||||
|
||||
private ArrayList<SurfaceControl> mSurfaceControls = new ArrayList<>();
|
||||
private SurfaceControl createSurfaceControl() throws InterruptedException {
|
||||
SurfaceControl sc = mActivity.createChildSurfaceControl();
|
||||
mSurfaceControls.add(sc);
|
||||
return sc;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleBuffer() throws Exception {
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.show(sc);
|
||||
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
static int getRandomColorComponent() {
|
||||
return new Random().nextInt(155) + 100;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleBuffers() throws Exception {
|
||||
final int MAX_BUFFERS = 10;
|
||||
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
for (int i = 0; i < MAX_BUFFERS; i++) {
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.argb(getRandomColorComponent(),
|
||||
getRandomColorComponent(), getRandomColorComponent(),
|
||||
getRandomColorComponent()));
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.setPosition(sc, i * 10, i * 10);
|
||||
t.show(sc);
|
||||
}
|
||||
t.apply(true);
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
for (int i = 0; i < MAX_BUFFERS; i++) {
|
||||
mByfferTrackers.get(i).addBuffer(t, mSurfaceControls.get(i));
|
||||
}
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleOpaqueBuffers() throws Exception {
|
||||
final int MAX_BUFFERS = 10;
|
||||
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
for (int i = 0; i < MAX_BUFFERS; i++) {
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.rgb(getRandomColorComponent(),
|
||||
getRandomColorComponent(), getRandomColorComponent()));
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.setOpaque(sc, true);
|
||||
t.setPosition(sc, i * 10, i * 10);
|
||||
t.show(sc);
|
||||
}
|
||||
t.apply(true);
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
for (int i = 0; i < MAX_BUFFERS; i++) {
|
||||
mByfferTrackers.get(i).addBuffer(t, mSurfaceControls.get(i));
|
||||
}
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void geometryChanges() throws Exception {
|
||||
final int MAX_POSITION = 10;
|
||||
final float MAX_SCALE = 2.0f;
|
||||
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.show(sc).apply(true);
|
||||
|
||||
int step = 0;
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
step = ++step % MAX_POSITION;
|
||||
t.setPosition(sc, step, step);
|
||||
float scale = ((step * MAX_SCALE) / MAX_POSITION) + 0.5f;
|
||||
t.setScale(sc, scale, scale);
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void geometryWithBufferChanges() throws Exception {
|
||||
final int MAX_POSITION = 10;
|
||||
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.show(sc).apply(true);
|
||||
|
||||
int step = 0;
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
step = ++step % MAX_POSITION;
|
||||
t.setPosition(sc, step, step);
|
||||
float scale = ((step * 2.0f) / MAX_POSITION) + 0.5f;
|
||||
t.setScale(sc, scale, scale);
|
||||
bufferTracker.addBuffer(t, sc);
|
||||
t.apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addRemoveLayers() throws Exception {
|
||||
SurfaceControl sc = createSurfaceControl();
|
||||
BufferFlinger bufferTracker = createBufferTracker(Color.GREEN);
|
||||
SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
SurfaceControl childSurfaceControl = new SurfaceControl.Builder()
|
||||
.setName("childLayer").setBLASTLayer().build();
|
||||
bufferTracker.addBuffer(t, childSurfaceControl);
|
||||
t.reparent(childSurfaceControl, sc);
|
||||
t.apply();
|
||||
t.remove(childSurfaceControl).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void displayScreenshot() throws Exception {
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
Bitmap screenshot =
|
||||
InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot();
|
||||
screenshot.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void layerScreenshot() throws Exception {
|
||||
BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
|
||||
while (state.keepRunning()) {
|
||||
Bitmap screenshot =
|
||||
InstrumentationRegistry.getInstrumentation().getUiAutomation().takeScreenshot(
|
||||
mActivity.getWindow());
|
||||
screenshot.recycle();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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 createChildSurfaceControl() 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user