1af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir/* 2af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Copyright (C) 2017 The Android Open Source Project 3af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * 4af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * use this file except in compliance with the License. You may obtain a copy of 6af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * the License at 7af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * 8af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * http://www.apache.org/licenses/LICENSE-2.0 9af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * 10af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Unless required by applicable law or agreed to in writing, software 11af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * License for the specific language governing permissions and limitations under 14af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * the License. 15af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir */ 16af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirpackage android.text; 17af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 18af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.graphics.Canvas; 19af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.graphics.Paint; 20af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.perftests.utils.BenchmarkState; 21af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.perftests.utils.PerfStatusReporter; 22af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.support.test.filters.LargeTest; 23af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.view.DisplayListCanvas; 24af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport android.view.RenderNode; 25af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 26af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport org.junit.Rule; 27af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport org.junit.Test; 28af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport org.junit.runner.RunWith; 29af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport org.junit.runners.Parameterized; 30af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 31af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport java.util.ArrayList; 32af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport java.util.Collection; 33af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport java.util.List; 34af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirimport java.util.Random; 35af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 36af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir/** 37af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Performance test for single line measure and draw using {@link Paint} and {@link Canvas}. 38af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir */ 39af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir@LargeTest 40af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir@RunWith(Parameterized.class) 41af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinirpublic class PaintMeasureDrawPerfTest { 42af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 43af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir private static final boolean[] BOOLEANS = new boolean[]{false, true}; 44af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 451f84ea9f2d9b5df63460e88216f618ae5d1a8e1bSiyamed Sinir @Parameterized.Parameters(name = "cached={1},{0}chars") 46af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir public static Collection cases() { 47af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final List<Object[]> params = new ArrayList<>(); 48d0a5206dd8130611567acab92206eeecc222a65eSiyamed Sinir for (int length : new int[]{128}) { 49af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir for (boolean cached : BOOLEANS) { 50af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir params.add(new Object[]{length, cached}); 51af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 52af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 53af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir return params; 54af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 55af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 56af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir @Rule 57af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); 58af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 59af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir private final int mLength; 60af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir private final boolean mCached; 61af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir private final TextPaint mTextPaint; 62af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 63af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 64af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir public PaintMeasureDrawPerfTest(int length, boolean cached) { 65af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir mLength = length; 66af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir mCached = cached; 67af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir mTextPaint = new TextPaint(); 68af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir mTextPaint.setTextSize(10); 69af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 70af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 71af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir /** 72af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Measure the time for {@link Paint#measureText(String)} 73af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir */ 74af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir @Test 75af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir public void timeMeasure() throws Exception { 76af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 77af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 78af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.pauseTiming(); 79af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir Canvas.freeTextLayoutCaches(); 80af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final String text = createRandomText(); 81af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir if (mCached) mTextPaint.measureText(text); 82af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.resumeTiming(); 83af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 84af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir while (state.keepRunning()) { 85af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.pauseTiming(); 86af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir if (!mCached) Canvas.freeTextLayoutCaches(); 87af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.resumeTiming(); 88af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 89af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir mTextPaint.measureText(text); 90af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 91af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 92af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 93af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir /** 94af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir * Measures the time for {@link Canvas#drawText(String, float, float, Paint)} 95af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir */ 96af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir @Test 97af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir public void timeDraw() throws Throwable { 98af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 99af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 100af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.pauseTiming(); 101af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir Canvas.freeTextLayoutCaches(); 102af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final RenderNode node = RenderNode.create("benchmark", null); 103af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final String text = createRandomText(); 104af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir if (mCached) mTextPaint.measureText(text); 105af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.resumeTiming(); 106af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 107af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir while (state.keepRunning()) { 108af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 109af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.pauseTiming(); 110af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final DisplayListCanvas canvas = node.start(1200, 200); 111af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir final int save = canvas.save(); 112af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir if (!mCached) Canvas.freeTextLayoutCaches(); 113af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.resumeTiming(); 114af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 115af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir canvas.drawText(text, 0 /*x*/, 100 /*y*/, mTextPaint); 116af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 117af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.pauseTiming(); 118af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir canvas.restoreToCount(save); 119af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir node.end(canvas); 120af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir state.resumeTiming(); 121af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 122af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 123af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir 124af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir private String createRandomText() { 125af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir return (String) new NonEditableTextGenerator(new Random(0)) 126af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir .setSequenceLength(mLength) 127af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir .setCreateBoring(true) 128af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir .setTextType(NonEditableTextGenerator.TextType.STRING) 129af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir .build(); 130af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir } 131af479b8c9743a1536d46f0985294c8bc0823a338Siyamed Sinir} 132