1 /* 2 * Copyright (C) 2018 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 */ 16 17 package android.text; 18 19 import static android.text.TextDirectionHeuristics.LTR; 20 21 import android.perftests.utils.BenchmarkState; 22 import android.perftests.utils.PerfStatusReporter; 23 24 import android.support.test.filters.LargeTest; 25 import android.support.test.runner.AndroidJUnit4; 26 27 import android.app.Activity; 28 import android.os.Bundle; 29 import android.support.test.InstrumentationRegistry; 30 import android.content.res.ColorStateList; 31 import android.graphics.Canvas; 32 import android.graphics.Typeface; 33 import android.text.Layout; 34 import android.text.style.TextAppearanceSpan; 35 import android.view.DisplayListCanvas; 36 import android.view.RenderNode; 37 38 import org.junit.Before; 39 import org.junit.Rule; 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 import java.nio.CharBuffer; 44 import java.util.Random; 45 46 @LargeTest 47 @RunWith(AndroidJUnit4.class) 48 public class PrecomputedTextMemoryUsageTest { 49 private static final int WORD_LENGTH = 9; // Random word has 9 characters. 50 private static final boolean NO_STYLE_TEXT = false; 51 52 private static TextPaint PAINT = new TextPaint(); 53 54 private static int TRIAL_COUNT = 100; 55 56 public PrecomputedTextMemoryUsageTest() {} 57 58 private TextPerfUtils mTextUtil = new TextPerfUtils(); 59 60 @Before 61 public void setUp() { 62 mTextUtil.resetRandom(0 /* seed */); 63 } 64 65 private void reportMemoryUsage(int memoryUsage, String key) { 66 Bundle status = new Bundle(); 67 status.putInt(key + "_median", memoryUsage); 68 InstrumentationRegistry.getInstrumentation().sendStatus(Activity.RESULT_OK, status); 69 } 70 71 private int median(int[] values) { 72 return values.length % 2 == 0 ? 73 (values[values.length / 2] + values[values.length / 2 - 1]) / 2: 74 values[values.length / 2]; 75 } 76 77 @Test 78 public void testMemoryUsage_NoHyphenation() { 79 int[] memories = new int[TRIAL_COUNT]; 80 final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT) 81 .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) 82 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE) 83 .build(); 84 85 // Report median of randomly generated PrecomputedText. 86 for (int i = 0; i < TRIAL_COUNT; ++i) { 87 memories[i] = PrecomputedText.create( 88 mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param) 89 .getMemoryUsage(); 90 } 91 reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation"); 92 } 93 94 @Test 95 public void testMemoryUsage_Hyphenation() { 96 int[] memories = new int[TRIAL_COUNT]; 97 final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT) 98 .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED) 99 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) 100 .build(); 101 102 // Report median of randomly generated PrecomputedText. 103 for (int i = 0; i < TRIAL_COUNT; ++i) { 104 memories[i] = PrecomputedText.create( 105 mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), param) 106 .getMemoryUsage(); 107 } 108 reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation"); 109 } 110 111 @Test 112 public void testMemoryUsage_NoHyphenation_WidthOnly() { 113 int[] memories = new int[TRIAL_COUNT]; 114 final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT) 115 .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) 116 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE) 117 .build(); 118 119 // Report median of randomly generated PrecomputedText. 120 for (int i = 0; i < TRIAL_COUNT; ++i) { 121 CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); 122 PrecomputedText.ParagraphInfo[] paragraphInfo = 123 PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false); 124 memories[i] = 0; 125 for (PrecomputedText.ParagraphInfo info : paragraphInfo) { 126 memories[i] += info.measured.getMemoryUsage(); 127 } 128 } 129 reportMemoryUsage(median(memories), "MemoryUsage_NoHyphenation_WidthOnly"); 130 } 131 132 @Test 133 public void testMemoryUsage_Hyphenatation_WidthOnly() { 134 int[] memories = new int[TRIAL_COUNT]; 135 final PrecomputedText.Params param = new PrecomputedText.Params.Builder(PAINT) 136 .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED) 137 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL) 138 .build(); 139 140 // Report median of randomly generated PrecomputedText. 141 for (int i = 0; i < TRIAL_COUNT; ++i) { 142 CharSequence cs = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); 143 PrecomputedText.ParagraphInfo[] paragraphInfo = 144 PrecomputedText.createMeasuredParagraphs(cs, param, 0, cs.length(), false); 145 memories[i] = 0; 146 for (PrecomputedText.ParagraphInfo info : paragraphInfo) { 147 memories[i] += info.measured.getMemoryUsage(); 148 } 149 } 150 reportMemoryUsage(median(memories), "MemoryUsage_Hyphenation_WidthOnly"); 151 } 152 } 153