Loading apct-tests/perftests/surfaceflinger/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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> Loading apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * 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); } } apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java +18 −5 Original line number Diff line number Diff line Loading @@ -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(); } } } apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java→apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java +82 −0 Original line number Diff line number Diff line Loading @@ -14,31 +14,69 @@ * limitations under the License. */ package android.perftests.utils; 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 android.widget.LinearLayout; 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(); } final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); 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) { } }); } final SurfaceView surfaceview = new SurfaceView(this); layout.addView(surfaceview); setContentView(layout); 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(); } } } Loading
apct-tests/perftests/surfaceflinger/AndroidManifest.xml +1 −1 Original line number Diff line number Diff line Loading @@ -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> Loading
apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/BufferFlinger.java 0 → 100644 +73 −0 Original line number Diff line number Diff line /* * 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); } }
apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerPerfTest.java +18 −5 Original line number Diff line number Diff line Loading @@ -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(); } } }
apct-tests/perftests/utils/src/android/perftests/utils/SurfaceFlingerTestActivity.java→apct-tests/perftests/surfaceflinger/src/android/surfaceflinger/SurfaceFlingerTestActivity.java +82 −0 Original line number Diff line number Diff line Loading @@ -14,31 +14,69 @@ * limitations under the License. */ package android.perftests.utils; 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 android.widget.LinearLayout; 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(); } final LinearLayout layout = new LinearLayout(this); layout.setOrientation(LinearLayout.VERTICAL); 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) { } }); } final SurfaceView surfaceview = new SurfaceView(this); layout.addView(surfaceview); setContentView(layout); 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(); } } }