benchmark-shape.cc 3.9 KB

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