xref: /aosp_15_r20/external/harfbuzz_ng/perf/benchmark-shape.cc (revision 2d1272b857b1f7575e6e246373e1cb218663db8a)
1*2d1272b8SAndroid Build Coastguard Worker #include "hb-benchmark.hh"
2*2d1272b8SAndroid Build Coastguard Worker 
3*2d1272b8SAndroid Build Coastguard Worker #define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
4*2d1272b8SAndroid Build Coastguard Worker 
5*2d1272b8SAndroid Build Coastguard Worker struct test_input_t
6*2d1272b8SAndroid Build Coastguard Worker {
7*2d1272b8SAndroid Build Coastguard Worker   const char *font_path;
8*2d1272b8SAndroid Build Coastguard Worker   const char *text_path;
9*2d1272b8SAndroid Build Coastguard Worker   bool is_variable;
10*2d1272b8SAndroid Build Coastguard Worker } default_tests[] =
11*2d1272b8SAndroid Build Coastguard Worker {
12*2d1272b8SAndroid Build Coastguard Worker 
13*2d1272b8SAndroid Build Coastguard Worker   {"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
14*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/fa-thelittleprince.txt",
15*2d1272b8SAndroid Build Coastguard Worker    false},
16*2d1272b8SAndroid Build Coastguard Worker 
17*2d1272b8SAndroid Build Coastguard Worker   {"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
18*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/fa-words.txt",
19*2d1272b8SAndroid Build Coastguard Worker    false},
20*2d1272b8SAndroid Build Coastguard Worker 
21*2d1272b8SAndroid Build Coastguard Worker   {"perf/fonts/Amiri-Regular.ttf",
22*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/fa-thelittleprince.txt",
23*2d1272b8SAndroid Build Coastguard Worker    false},
24*2d1272b8SAndroid Build Coastguard Worker 
25*2d1272b8SAndroid Build Coastguard Worker   {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf",
26*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/hi-words.txt",
27*2d1272b8SAndroid Build Coastguard Worker    false},
28*2d1272b8SAndroid Build Coastguard Worker 
29*2d1272b8SAndroid Build Coastguard Worker   {"perf/fonts/Roboto-Regular.ttf",
30*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/en-thelittleprince.txt",
31*2d1272b8SAndroid Build Coastguard Worker    false},
32*2d1272b8SAndroid Build Coastguard Worker 
33*2d1272b8SAndroid Build Coastguard Worker   {"perf/fonts/Roboto-Regular.ttf",
34*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/en-words.txt",
35*2d1272b8SAndroid Build Coastguard Worker    false},
36*2d1272b8SAndroid Build Coastguard Worker 
37*2d1272b8SAndroid Build Coastguard Worker   {SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf",
38*2d1272b8SAndroid Build Coastguard Worker    "perf/texts/en-thelittleprince.txt",
39*2d1272b8SAndroid Build Coastguard Worker    true},
40*2d1272b8SAndroid Build Coastguard Worker };
41*2d1272b8SAndroid Build Coastguard Worker 
42*2d1272b8SAndroid Build Coastguard Worker static test_input_t *tests = default_tests;
43*2d1272b8SAndroid Build Coastguard Worker static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
44*2d1272b8SAndroid Build Coastguard Worker 
45*2d1272b8SAndroid Build Coastguard Worker enum backend_t { HARFBUZZ, FREETYPE };
46*2d1272b8SAndroid Build Coastguard Worker 
BM_Shape(benchmark::State & state,bool is_var,backend_t backend,const test_input_t & input)47*2d1272b8SAndroid Build Coastguard Worker static void BM_Shape (benchmark::State &state,
48*2d1272b8SAndroid Build Coastguard Worker 		      bool is_var,
49*2d1272b8SAndroid Build Coastguard Worker 		      backend_t backend,
50*2d1272b8SAndroid Build Coastguard Worker 		      const test_input_t &input)
51*2d1272b8SAndroid Build Coastguard Worker {
52*2d1272b8SAndroid Build Coastguard Worker   hb_font_t *font;
53*2d1272b8SAndroid Build Coastguard Worker   {
54*2d1272b8SAndroid Build Coastguard Worker     hb_face_t *face = hb_benchmark_face_create_from_file_or_fail (input.font_path, 0);
55*2d1272b8SAndroid Build Coastguard Worker     assert (face);
56*2d1272b8SAndroid Build Coastguard Worker     font = hb_font_create (face);
57*2d1272b8SAndroid Build Coastguard Worker     hb_face_destroy (face);
58*2d1272b8SAndroid Build Coastguard Worker   }
59*2d1272b8SAndroid Build Coastguard Worker 
60*2d1272b8SAndroid Build Coastguard Worker   if (is_var)
61*2d1272b8SAndroid Build Coastguard Worker   {
62*2d1272b8SAndroid Build Coastguard Worker     hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
63*2d1272b8SAndroid Build Coastguard Worker     hb_font_set_variations (font, &wght, 1);
64*2d1272b8SAndroid Build Coastguard Worker   }
65*2d1272b8SAndroid Build Coastguard Worker 
66*2d1272b8SAndroid Build Coastguard Worker   switch (backend)
67*2d1272b8SAndroid Build Coastguard Worker   {
68*2d1272b8SAndroid Build Coastguard Worker     case HARFBUZZ:
69*2d1272b8SAndroid Build Coastguard Worker       hb_ot_font_set_funcs (font);
70*2d1272b8SAndroid Build Coastguard Worker       break;
71*2d1272b8SAndroid Build Coastguard Worker 
72*2d1272b8SAndroid Build Coastguard Worker     case FREETYPE:
73*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_FREETYPE
74*2d1272b8SAndroid Build Coastguard Worker       hb_ft_font_set_funcs (font);
75*2d1272b8SAndroid Build Coastguard Worker #endif
76*2d1272b8SAndroid Build Coastguard Worker       break;
77*2d1272b8SAndroid Build Coastguard Worker   }
78*2d1272b8SAndroid Build Coastguard Worker 
79*2d1272b8SAndroid Build Coastguard Worker   hb_blob_t *text_blob = hb_blob_create_from_file_or_fail (input.text_path);
80*2d1272b8SAndroid Build Coastguard Worker   assert (text_blob);
81*2d1272b8SAndroid Build Coastguard Worker   unsigned orig_text_length;
82*2d1272b8SAndroid Build Coastguard Worker   const char *orig_text = hb_blob_get_data (text_blob, &orig_text_length);
83*2d1272b8SAndroid Build Coastguard Worker 
84*2d1272b8SAndroid Build Coastguard Worker   hb_buffer_t *buf = hb_buffer_create ();
85*2d1272b8SAndroid Build Coastguard Worker   for (auto _ : state)
86*2d1272b8SAndroid Build Coastguard Worker   {
87*2d1272b8SAndroid Build Coastguard Worker     unsigned text_length = orig_text_length;
88*2d1272b8SAndroid Build Coastguard Worker     const char *text = orig_text;
89*2d1272b8SAndroid Build Coastguard Worker 
90*2d1272b8SAndroid Build Coastguard Worker     const char *end;
91*2d1272b8SAndroid Build Coastguard Worker     while ((end = (const char *) memchr (text, '\n', text_length)))
92*2d1272b8SAndroid Build Coastguard Worker     {
93*2d1272b8SAndroid Build Coastguard Worker       hb_buffer_clear_contents (buf);
94*2d1272b8SAndroid Build Coastguard Worker       hb_buffer_add_utf8 (buf, text, text_length, 0, end - text);
95*2d1272b8SAndroid Build Coastguard Worker       hb_buffer_guess_segment_properties (buf);
96*2d1272b8SAndroid Build Coastguard Worker       hb_shape (font, buf, nullptr, 0);
97*2d1272b8SAndroid Build Coastguard Worker 
98*2d1272b8SAndroid Build Coastguard Worker       unsigned skip = end - text + 1;
99*2d1272b8SAndroid Build Coastguard Worker       text_length -= skip;
100*2d1272b8SAndroid Build Coastguard Worker       text += skip;
101*2d1272b8SAndroid Build Coastguard Worker     }
102*2d1272b8SAndroid Build Coastguard Worker   }
103*2d1272b8SAndroid Build Coastguard Worker   hb_buffer_destroy (buf);
104*2d1272b8SAndroid Build Coastguard Worker 
105*2d1272b8SAndroid Build Coastguard Worker   hb_blob_destroy (text_blob);
106*2d1272b8SAndroid Build Coastguard Worker   hb_font_destroy (font);
107*2d1272b8SAndroid Build Coastguard Worker }
108*2d1272b8SAndroid Build Coastguard Worker 
test_backend(backend_t backend,const char * backend_name,bool variable,const test_input_t & test_input)109*2d1272b8SAndroid Build Coastguard Worker static void test_backend (backend_t backend,
110*2d1272b8SAndroid Build Coastguard Worker 			  const char *backend_name,
111*2d1272b8SAndroid Build Coastguard Worker 			  bool variable,
112*2d1272b8SAndroid Build Coastguard Worker 			  const test_input_t &test_input)
113*2d1272b8SAndroid Build Coastguard Worker {
114*2d1272b8SAndroid Build Coastguard Worker   char name[1024] = "BM_Shape";
115*2d1272b8SAndroid Build Coastguard Worker   const char *p;
116*2d1272b8SAndroid Build Coastguard Worker   strcat (name, "/");
117*2d1272b8SAndroid Build Coastguard Worker   p = strrchr (test_input.font_path, '/');
118*2d1272b8SAndroid Build Coastguard Worker   strcat (name, p ? p + 1 : test_input.font_path);
119*2d1272b8SAndroid Build Coastguard Worker   strcat (name, "/");
120*2d1272b8SAndroid Build Coastguard Worker   p = strrchr (test_input.text_path, '/');
121*2d1272b8SAndroid Build Coastguard Worker   strcat (name, p ? p + 1 : test_input.text_path);
122*2d1272b8SAndroid Build Coastguard Worker   strcat (name, variable ? "/var" : "");
123*2d1272b8SAndroid Build Coastguard Worker   strcat (name, "/");
124*2d1272b8SAndroid Build Coastguard Worker   strcat (name, backend_name);
125*2d1272b8SAndroid Build Coastguard Worker 
126*2d1272b8SAndroid Build Coastguard Worker   benchmark::RegisterBenchmark (name, BM_Shape, variable, backend, test_input)
127*2d1272b8SAndroid Build Coastguard Worker    ->Unit(benchmark::kMillisecond);
128*2d1272b8SAndroid Build Coastguard Worker }
129*2d1272b8SAndroid Build Coastguard Worker 
main(int argc,char ** argv)130*2d1272b8SAndroid Build Coastguard Worker int main(int argc, char** argv)
131*2d1272b8SAndroid Build Coastguard Worker {
132*2d1272b8SAndroid Build Coastguard Worker   benchmark::Initialize(&argc, argv);
133*2d1272b8SAndroid Build Coastguard Worker 
134*2d1272b8SAndroid Build Coastguard Worker   if (argc > 2)
135*2d1272b8SAndroid Build Coastguard Worker   {
136*2d1272b8SAndroid Build Coastguard Worker     num_tests = (argc - 1) / 2;
137*2d1272b8SAndroid Build Coastguard Worker     tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
138*2d1272b8SAndroid Build Coastguard Worker     for (unsigned i = 0; i < num_tests; i++)
139*2d1272b8SAndroid Build Coastguard Worker     {
140*2d1272b8SAndroid Build Coastguard Worker       tests[i].is_variable = true;
141*2d1272b8SAndroid Build Coastguard Worker       tests[i].font_path = argv[1 + i * 2];
142*2d1272b8SAndroid Build Coastguard Worker       tests[i].text_path = argv[2 + i * 2];
143*2d1272b8SAndroid Build Coastguard Worker     }
144*2d1272b8SAndroid Build Coastguard Worker   }
145*2d1272b8SAndroid Build Coastguard Worker 
146*2d1272b8SAndroid Build Coastguard Worker   for (unsigned i = 0; i < num_tests; i++)
147*2d1272b8SAndroid Build Coastguard Worker   {
148*2d1272b8SAndroid Build Coastguard Worker     auto& test_input = tests[i];
149*2d1272b8SAndroid Build Coastguard Worker     for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
150*2d1272b8SAndroid Build Coastguard Worker     {
151*2d1272b8SAndroid Build Coastguard Worker       bool is_var = (bool) variable;
152*2d1272b8SAndroid Build Coastguard Worker 
153*2d1272b8SAndroid Build Coastguard Worker       test_backend (HARFBUZZ, "hb", is_var, test_input);
154*2d1272b8SAndroid Build Coastguard Worker #ifdef HAVE_FREETYPE
155*2d1272b8SAndroid Build Coastguard Worker       test_backend (FREETYPE, "ft", is_var, test_input);
156*2d1272b8SAndroid Build Coastguard Worker #endif
157*2d1272b8SAndroid Build Coastguard Worker     }
158*2d1272b8SAndroid Build Coastguard Worker   }
159*2d1272b8SAndroid Build Coastguard Worker 
160*2d1272b8SAndroid Build Coastguard Worker   benchmark::RunSpecifiedBenchmarks();
161*2d1272b8SAndroid Build Coastguard Worker   benchmark::Shutdown();
162*2d1272b8SAndroid Build Coastguard Worker 
163*2d1272b8SAndroid Build Coastguard Worker   if (tests != default_tests)
164*2d1272b8SAndroid Build Coastguard Worker     free (tests);
165*2d1272b8SAndroid Build Coastguard Worker }
166