diff options
| author | 2022-07-07 00:23:16 +0000 | |
|---|---|---|
| committer | 2022-08-31 23:07:49 +0000 | |
| commit | 1177f3cfc2040c0da62e752ea3de4ddec977398d (patch) | |
| tree | 0600461927f413112f8fadbe65e4d95d7d3224ea | |
| parent | 1f8fded51211d8c41f79ba4c54454f2093df5434 (diff) | |
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
8 files changed, 580 insertions, 0 deletions
diff --git a/apct-tests/perftests/surfaceflinger/Android.bp b/apct-tests/perftests/surfaceflinger/Android.bp new file mode 100644 index 000000000000..0c28bcef469c --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/Android.bp @@ -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", +} diff --git a/apct-tests/perftests/surfaceflinger/AndroidManifest.xml b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml new file mode 100644 index 000000000000..26f25863f055 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/AndroidManifest.xml @@ -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> diff --git a/apct-tests/perftests/surfaceflinger/AndroidTest.xml b/apct-tests/perftests/surfaceflinger/AndroidTest.xml new file mode 100644 index 000000000000..53e5d99409e2 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/AndroidTest.xml @@ -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> diff --git a/apct-tests/perftests/surfaceflinger/OWNERS b/apct-tests/perftests/surfaceflinger/OWNERS new file mode 100644 index 000000000000..0862c05e0ee4 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/OWNERS @@ -0,0 +1 @@ +include /services/core/java/com/android/server/wm/OWNERS diff --git a/apct-tests/perftests/surfaceflinger/README.md b/apct-tests/perftests/surfaceflinger/README.md new file mode 100644 index 000000000000..0dec70f3cf18 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/README.md @@ -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. diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java new file mode 100644 index 000000000000..52fb8a6023f1 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java @@ -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(); + } + } +} diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java new file mode 100644 index 000000000000..45d164c96cd8 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java @@ -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(); + } + } + +} diff --git a/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java new file mode 100644 index 000000000000..832a0cd1e917 --- /dev/null +++ b/apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java @@ -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(); + } + } +} |