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 17package android.text; 18 19import android.perftests.utils.BenchmarkState; 20import android.perftests.utils.PerfStatusReporter; 21 22import android.support.test.filters.LargeTest; 23import android.support.test.runner.AndroidJUnit4; 24 25import org.junit.Rule; 26import org.junit.Test; 27import org.junit.runner.RunWith; 28 29import java.util.Random; 30import java.util.concurrent.CountDownLatch; 31import java.util.concurrent.atomic.AtomicBoolean; 32import java.util.concurrent.TimeUnit; 33 34@LargeTest 35@RunWith(AndroidJUnit4.class) 36public class StaticLayoutMultithreadPerfTest { 37 private static final int WORD_LENGTH = 9; // Random word has 9 characters. 38 private static final int WORDS_IN_LINE = 8; // Roughly, 8 words in a line. 39 private static final boolean NO_STYLE_TEXT = false; 40 41 private static TextPaint PAINT = new TextPaint(); 42 private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize(); 43 44 public StaticLayoutMultithreadPerfTest() {} 45 46 @Rule 47 public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter(); 48 49 private CountDownLatch mStartLatch; 50 private AtomicBoolean mThreadState; // True for running, False for stopped. 51 52 private static final long TIMEOUT_MS = 5000; 53 54 private Thread[] startBackgroundThread(int numOfThreads) { 55 mStartLatch = new CountDownLatch(numOfThreads); 56 mThreadState = new AtomicBoolean(true); 57 58 Thread[] threads = new Thread[numOfThreads]; 59 for (int i = 0; i < numOfThreads; ++i) { 60 final int seed = i + 1; 61 threads[i] = new Thread(new Runnable() { 62 @Override 63 public void run() { 64 final TextPerfUtils util = new TextPerfUtils(); 65 util.resetRandom(seed); 66 67 mStartLatch.countDown(); 68 while (mThreadState.get()) { 69 final CharSequence text = util.nextRandomParagraph( 70 WORD_LENGTH, NO_STYLE_TEXT); 71 StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) 72 .build(); 73 } 74 } 75 }); 76 } 77 78 for (int i = 0; i < numOfThreads; ++i) { 79 threads[i].start(); 80 } 81 82 try { 83 mStartLatch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS); 84 } catch (InterruptedException e) { 85 throw new RuntimeException(e); 86 } 87 return threads; 88 } 89 90 private void finishThreads(Thread[] threads) { 91 mThreadState.set(false); 92 for (Thread thread : threads) { 93 try { 94 thread.join(); 95 } catch (InterruptedException e) { 96 throw new RuntimeException(e); 97 } 98 } 99 mStartLatch = null; 100 mThreadState = null; 101 } 102 103 private void runRandomTest(int numOfTotalThreads) { 104 final BenchmarkState state = mPerfStatusReporter.getBenchmarkState(); 105 final TextPerfUtils util = new TextPerfUtils(); 106 Thread[] threads = startBackgroundThread(numOfTotalThreads - 1); 107 while (state.keepRunning()) { 108 state.pauseTiming(); 109 final CharSequence text = util.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT); 110 state.resumeTiming(); 111 112 StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH) 113 .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE) 114 .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE) 115 .build(); 116 } 117 finishThreads(threads); 118 } 119 120 @Test 121 public void testCreate_RandomText_Thread_1() { 122 runRandomTest(1); 123 } 124 125 @Test 126 public void testCreate_RandomText_Thread_2() { 127 runRandomTest(2); 128 } 129 130 @Test 131 public void testCreate_RandomText_Thread_4() { 132 runRandomTest(4); 133 } 134} 135