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