Home | History | Annotate | Download | only in text
      1 /*
      2  * Copyright (C) 2016 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.content.res.ColorStateList;
     28 import android.graphics.Canvas;
     29 import android.graphics.Typeface;
     30 import android.text.Layout;
     31 import android.text.style.TextAppearanceSpan;
     32 import android.view.DisplayListCanvas;
     33 import android.view.RenderNode;
     34 
     35 import org.junit.Before;
     36 import org.junit.Rule;
     37 import org.junit.Test;
     38 import org.junit.runner.RunWith;
     39 
     40 import java.nio.CharBuffer;
     41 import java.util.Random;
     42 
     43 @LargeTest
     44 @RunWith(AndroidJUnit4.class)
     45 public class StaticLayoutPerfTest {
     46     private static final int WORD_LENGTH = 9;  // Random word has 9 characters.
     47     private static final int WORDS_IN_LINE = 8;  // Roughly, 8 words in a line.
     48     private static final boolean NO_STYLE_TEXT = false;
     49     private static final boolean STYLE_TEXT = true;
     50 
     51     private static TextPaint PAINT = new TextPaint();
     52     private static final int TEXT_WIDTH = WORDS_IN_LINE * WORD_LENGTH * (int) PAINT.getTextSize();
     53 
     54     public StaticLayoutPerfTest() {}
     55 
     56     @Rule
     57     public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
     58 
     59     private TextPerfUtils mTextUtil = new TextPerfUtils();
     60 
     61     @Before
     62     public void setUp() {
     63         mTextUtil.resetRandom(0 /* seed */);
     64     }
     65 
     66     private PrecomputedText makeMeasured(CharSequence text, TextPaint paint) {
     67         PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint).build();
     68         return PrecomputedText.create(text, param);
     69     }
     70 
     71     private PrecomputedText makeMeasured(CharSequence text, TextPaint paint, int strategy,
     72                                       int frequency) {
     73         PrecomputedText.Params param = new PrecomputedText.Params.Builder(paint)
     74                 .setHyphenationFrequency(frequency).setBreakStrategy(strategy).build();
     75         return PrecomputedText.create(text, param);
     76     }
     77 
     78     @Test
     79     public void testCreate_FixedText_NoStyle_Greedy_NoHyphenation() {
     80         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
     81         final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
     82         while (state.keepRunning()) {
     83             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
     84                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
     85                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
     86                     .build();
     87         }
     88     }
     89 
     90     @Test
     91     public void testCreate_RandomText_NoStyled_Greedy_NoHyphenation() {
     92         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
     93         while (state.keepRunning()) {
     94             state.pauseTiming();
     95             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
     96             state.resumeTiming();
     97 
     98             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
     99                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    100                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    101                     .build();
    102         }
    103     }
    104 
    105     @Test
    106     public void testCreate_RandomText_NoStyled_Greedy_Hyphenation() {
    107         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    108         while (state.keepRunning()) {
    109             state.pauseTiming();
    110             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    111             state.resumeTiming();
    112 
    113             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    114                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
    115                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    116                     .build();
    117         }
    118     }
    119 
    120     @Test
    121     public void testCreate_RandomText_NoStyled_Balanced_NoHyphenation() {
    122         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    123         while (state.keepRunning()) {
    124             state.pauseTiming();
    125             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    126             state.resumeTiming();
    127 
    128             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    129                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    130                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
    131                     .build();
    132         }
    133     }
    134 
    135     @Test
    136     public void testCreate_RandomText_NoStyled_Balanced_Hyphenation() {
    137         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    138         while (state.keepRunning()) {
    139             state.pauseTiming();
    140             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    141             state.resumeTiming();
    142 
    143             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    144                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
    145                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
    146                     .build();
    147         }
    148     }
    149 
    150     @Test
    151     public void testCreate_RandomText_Styled_Greedy_NoHyphenation() {
    152         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    153         while (state.keepRunning()) {
    154             state.pauseTiming();
    155             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
    156             state.resumeTiming();
    157 
    158             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    159                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    160                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    161                     .build();
    162         }
    163     }
    164 
    165     @Test
    166     public void testCreate_PrecomputedText_NoStyled_Greedy_NoHyphenation() {
    167         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    168         while (state.keepRunning()) {
    169             state.pauseTiming();
    170             final PrecomputedText text = makeMeasured(
    171                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
    172                     Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE);
    173             state.resumeTiming();
    174 
    175             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    176                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    177                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    178                     .build();
    179         }
    180     }
    181 
    182     @Test
    183     public void testCreate_PrecomputedText_NoStyled_Greedy_Hyphenation() {
    184         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    185         while (state.keepRunning()) {
    186             state.pauseTiming();
    187             final PrecomputedText text = makeMeasured(
    188                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
    189                     Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NORMAL);
    190             state.resumeTiming();
    191 
    192             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    193                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
    194                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    195                     .build();
    196         }
    197     }
    198 
    199     @Test
    200     public void testCreate_PrecomputedText_NoStyled_Balanced_NoHyphenation() {
    201         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    202         while (state.keepRunning()) {
    203             state.pauseTiming();
    204             final PrecomputedText text = makeMeasured(
    205                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
    206                     Layout.BREAK_STRATEGY_BALANCED, Layout.HYPHENATION_FREQUENCY_NONE);
    207             state.resumeTiming();
    208 
    209             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    210                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    211                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
    212                     .build();
    213         }
    214     }
    215 
    216     @Test
    217     public void testCreate_PrecomputedText_NoStyled_Balanced_Hyphenation() {
    218         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    219         while (state.keepRunning()) {
    220             state.pauseTiming();
    221             final PrecomputedText text = makeMeasured(
    222                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT,
    223                     Layout.BREAK_STRATEGY_BALANCED, Layout.HYPHENATION_FREQUENCY_NORMAL);
    224             state.resumeTiming();
    225 
    226             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    227                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NORMAL)
    228                     .setBreakStrategy(Layout.BREAK_STRATEGY_BALANCED)
    229                     .build();
    230         }
    231     }
    232 
    233     @Test
    234     public void testCreate_PrecomputedText_Styled_Greedy_NoHyphenation() {
    235         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    236         while (state.keepRunning()) {
    237             state.pauseTiming();
    238             final PrecomputedText text = makeMeasured(
    239                     mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT,
    240                     Layout.BREAK_STRATEGY_SIMPLE, Layout.HYPHENATION_FREQUENCY_NONE);
    241             state.resumeTiming();
    242 
    243             StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH)
    244                     .setHyphenationFrequency(Layout.HYPHENATION_FREQUENCY_NONE)
    245                     .setBreakStrategy(Layout.BREAK_STRATEGY_SIMPLE)
    246                     .build();
    247         }
    248     }
    249 
    250     @Test
    251     public void testDraw_FixedText_NoStyled() {
    252         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    253         final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    254         final RenderNode node = RenderNode.create("benchmark", null);
    255         while (state.keepRunning()) {
    256             state.pauseTiming();
    257             final StaticLayout layout =
    258                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    259             final DisplayListCanvas c = node.start(1200, 200);
    260             state.resumeTiming();
    261 
    262             layout.draw(c);
    263         }
    264     }
    265 
    266     @Test
    267     public void testDraw_RandomText_Styled() {
    268         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    269         final RenderNode node = RenderNode.create("benchmark", null);
    270         while (state.keepRunning()) {
    271             state.pauseTiming();
    272             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
    273             final StaticLayout layout =
    274                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    275             final DisplayListCanvas c = node.start(1200, 200);
    276             state.resumeTiming();
    277 
    278             layout.draw(c);
    279         }
    280     }
    281 
    282     @Test
    283     public void testDraw_RandomText_NoStyled() {
    284         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    285         final RenderNode node = RenderNode.create("benchmark", null);
    286         while (state.keepRunning()) {
    287             state.pauseTiming();
    288             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    289             final StaticLayout layout =
    290                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    291             final DisplayListCanvas c = node.start(1200, 200);
    292             state.resumeTiming();
    293 
    294             layout.draw(c);
    295         }
    296     }
    297 
    298     @Test
    299     public void testDraw_RandomText_Styled_WithoutCache() {
    300         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    301         final RenderNode node = RenderNode.create("benchmark", null);
    302         while (state.keepRunning()) {
    303             state.pauseTiming();
    304             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT);
    305             final StaticLayout layout =
    306                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    307             final DisplayListCanvas c = node.start(1200, 200);
    308             Canvas.freeTextLayoutCaches();
    309             state.resumeTiming();
    310 
    311             layout.draw(c);
    312         }
    313     }
    314 
    315     @Test
    316     public void testDraw_RandomText_NoStyled_WithoutCache() {
    317         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    318         final RenderNode node = RenderNode.create("benchmark", null);
    319         while (state.keepRunning()) {
    320             state.pauseTiming();
    321             final CharSequence text = mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT);
    322             final StaticLayout layout =
    323                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    324             final DisplayListCanvas c = node.start(1200, 200);
    325             Canvas.freeTextLayoutCaches();
    326             state.resumeTiming();
    327 
    328             layout.draw(c);
    329         }
    330     }
    331 
    332     @Test
    333     public void testDraw_PrecomputedText_Styled() {
    334         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    335         final RenderNode node = RenderNode.create("benchmark", null);
    336         while (state.keepRunning()) {
    337             state.pauseTiming();
    338             final PrecomputedText text = makeMeasured(
    339                     mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
    340             final StaticLayout layout =
    341                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    342             final DisplayListCanvas c = node.start(1200, 200);
    343             state.resumeTiming();
    344 
    345             layout.draw(c);
    346         }
    347     }
    348 
    349     @Test
    350     public void testDraw_PrecomputedText_NoStyled() {
    351         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    352         final RenderNode node = RenderNode.create("benchmark", null);
    353         while (state.keepRunning()) {
    354             state.pauseTiming();
    355             final PrecomputedText text = makeMeasured(
    356                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
    357             final StaticLayout layout =
    358                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    359             final DisplayListCanvas c = node.start(1200, 200);
    360             state.resumeTiming();
    361 
    362             layout.draw(c);
    363         }
    364     }
    365 
    366     @Test
    367     public void testDraw_PrecomputedText_Styled_WithoutCache() {
    368         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    369         final RenderNode node = RenderNode.create("benchmark", null);
    370         while (state.keepRunning()) {
    371             state.pauseTiming();
    372             final PrecomputedText text = makeMeasured(
    373                     mTextUtil.nextRandomParagraph(WORD_LENGTH, STYLE_TEXT), PAINT);
    374             final StaticLayout layout =
    375                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    376             final DisplayListCanvas c = node.start(1200, 200);
    377             Canvas.freeTextLayoutCaches();
    378             state.resumeTiming();
    379 
    380             layout.draw(c);
    381         }
    382     }
    383 
    384     @Test
    385     public void testDraw_PrecomputedText_NoStyled_WithoutCache() {
    386         final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
    387         final RenderNode node = RenderNode.create("benchmark", null);
    388         while (state.keepRunning()) {
    389             state.pauseTiming();
    390             final PrecomputedText text = makeMeasured(
    391                     mTextUtil.nextRandomParagraph(WORD_LENGTH, NO_STYLE_TEXT), PAINT);
    392             final StaticLayout layout =
    393                     StaticLayout.Builder.obtain(text, 0, text.length(), PAINT, TEXT_WIDTH).build();
    394             final DisplayListCanvas c = node.start(1200, 200);
    395             Canvas.freeTextLayoutCaches();
    396             state.resumeTiming();
    397 
    398             layout.draw(c);
    399         }
    400     }
    401 
    402 }
    403