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