[benchmarking] Convert shell benchmarks to C++

PT-73 # comment patch

Test: CQ

Change-Id: I0562cc6348806e343aa512d181d9b4190d8ca8b9
diff --git a/tests/benchmarks/BUILD.gn b/tests/benchmarks/BUILD.gn
index 26ea465..cbc212e 100644
--- a/tests/benchmarks/BUILD.gn
+++ b/tests/benchmarks/BUILD.gn
@@ -4,18 +4,38 @@
 
 import("//build/package.gni")
 
+executable("topaz_benchmarks_bin") {
+  output_name = "topaz_benchmarks"
+
+  sources = [
+    "benchmarks.cc",
+    "gfx_benchmarks.cc",
+    "gfx_benchmarks.h",
+  ]
+
+  deps = [
+    "//garnet/testing/benchmarking:benchmarking",
+    "//garnet/testing/benchmarking:is_vulkan_supported",
+  ]
+}
+
 # Builds "benchmarks.sh" into a package that runs all Topaz benchmarks
 # on CI.
 package("topaz_benchmarks") {
   testonly = true
+
+  deps = [
+    ":topaz_benchmarks_bin",
+  ]
+
   binaries = [
     {
-      name = rebase_path("topaz_benchmarks.sh")
+      name = rebase_path("benchmarks.sh")
       dest = "benchmarks.sh"
     },
     {
-      name = rebase_path("topaz_gfx_benchmarks.sh")
-      dest = "gfx_benchmarks.sh"
+      shell = true
+      name = "topaz_benchmarks"
     },
   ]
 }
diff --git a/tests/benchmarks/README.md b/tests/benchmarks/README.md
index 9d9b0d4..d022cb2 100644
--- a/tests/benchmarks/README.md
+++ b/tests/benchmarks/README.md
@@ -1,7 +1,7 @@
 # benchmarks
 
 This is where benchmarks for the Topaz layer are installed.  To run a benchmark
-on CI and upload its results to the performance dashboard, add an entry in benchmarks.sh.
+on CI and upload its results to the performance dashboard, add an entry in benchmarks.cc.
 More detailed instructions can be found the [CI benchmarking guide].
 
 
diff --git a/tests/benchmarks/benchmarks.cc b/tests/benchmarks/benchmarks.cc
new file mode 100644
index 0000000..81037b2
--- /dev/null
+++ b/tests/benchmarks/benchmarks.cc
@@ -0,0 +1,30 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This target runs all benchmarks for the Topaz layer.
+
+#include "garnet/testing/benchmarking/benchmarking.h"
+#include "garnet/testing/benchmarking/is_vulkan_supported.h"
+#include "src/lib/fxl/logging.h"
+#include "topaz/tests/benchmarks/gfx_benchmarks.h"
+
+int main(int argc, const char** argv) {
+  auto maybe_benchmarks_runner =
+      benchmarking::BenchmarksRunner::Create(argc, argv);
+  if (!maybe_benchmarks_runner) {
+    exit(1);
+  }
+
+  auto& benchmarks_runner = *maybe_benchmarks_runner;
+
+  if (benchmarking::IsVulkanSupported()) {
+    // DISABLED: See SCN-1223
+    // AddGraphicsBenchmarks(&benchmarks_runner);
+    FXL_LOG(INFO) << "Graphics performance tests disabled";
+  } else {
+    FXL_LOG(INFO) << "Vulkan not supported; graphics tests skipped.";
+  }
+
+  benchmarks_runner.Finish();
+}
diff --git a/tests/benchmarks/benchmarks.sh b/tests/benchmarks/benchmarks.sh
new file mode 100644
index 0000000..8010091
--- /dev/null
+++ b/tests/benchmarks/benchmarks.sh
@@ -0,0 +1,10 @@
+#!/boot/bin/sh
+#
+# Copyright 2018 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# This script launches the topaz benchmarks binary, which runs all benchmarks
+# for the Topaz layer.
+
+/pkgfs/packages/topaz_benchmarks/0/bin/topaz_benchmarks "$@"
diff --git a/tests/benchmarks/gfx_benchmarks.cc b/tests/benchmarks/gfx_benchmarks.cc
new file mode 100644
index 0000000..d30c430
--- /dev/null
+++ b/tests/benchmarks/gfx_benchmarks.cc
@@ -0,0 +1,87 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "topaz/tests/benchmarks/gfx_benchmarks.h"
+
+#include "src/lib/fxl/logging.h"
+
+void AddGraphicsBenchmarks(benchmarking::BenchmarksRunner* benchmarks_runner) {
+  FXL_DCHECK(benchmarks_runner != nullptr);
+
+  struct Param {
+    std::string benchmark_name;
+    std::string command;
+    std::optional<std::string> flutter_app_name;
+    std::string renderer_params;
+  };
+
+  constexpr char kImageGridFlutterX3Command[] =
+      "set_root_view fuchsia-pkg://fuchsia.com/tile_view#meta/tile_view.cmx "
+      "image_grid_flutter image_grid_flutter image_grid_flutter";
+  constexpr char kChoreographyCommand[] =
+      "basemgr --test --enable_presenter "
+      "--account_provider=dev_token_manager --base_shell=dev_base_shell "
+      "--base_shell_args=--test_timeout_ms=60000 "
+      "--session_shell=dev_session_shell "
+      "--session_shell_args=--root_module=choreography "
+      "--story_shell=mondrian";
+
+  // clang-format off
+  std::vector<Param> params = {
+    //
+    // image_grid_flutter
+    //
+    {"fuchsia.scenic.image_grid_flutter_noclipping_noshadows", "set_root_view image_grid_flutter", "image_grid_flutter", "--unshadowed --clipping_disabled"},
+    {"fuchsia.scenic.image_grid_flutter_noshadows", "set_root_view image_grid_flutter", "image_grid_flutter", "--unshadowed --clipping_enabled"},
+    {"fuchsia.scenic.image_grid_flutter_ssdo", "set_root_view image_grid_flutter", "image_grid_flutter", "--screen_space_shadows --clipping_enabled"},
+    {"fuchsia.scenic.image_grid_flutter_shadow_map", "set_root_view image_grid_flutter", "image_grid_flutter", "--shadow_map --clipping_enabled"},
+    {"fuchsia.scenic.image_grid_flutter_moment_shadow_map", "set_root_view image_grid_flutter", "image_grid_flutter", "--moment_shadow_map --clipping_enabled"},
+
+    //
+    // image_grid_flutter x3
+    //
+    // TODO: Support tracking multiple flutter apps of the same name in
+    // process_scenic_trace.
+    {"fuchsia.scenic.image_grid_flutter_x3_noclipping_noshadows", kImageGridFlutterX3Command, {}, "--unshadowed --clipping_disabled",},
+    {"fuchsia.scenic.image_grid_flutter_x3_noshadows", kImageGridFlutterX3Command, {}, "--unshadowed --clipping_enabled",},
+    {"fuchsia.scenic.image_grid_flutter_x3_ssdo", kImageGridFlutterX3Command, {}, "--screen_space_shadows --clipping_enabled",},
+    {"fuchsia.scenic.image_grid_flutter_x3_shadow_map", kImageGridFlutterX3Command, {}, "--shadow_map --clipping_enabled",},
+    {"fuchsia.scenic.image_grid_flutter_x3_moment_shadow_map", kImageGridFlutterX3Command, {}, "--moment_shadow_map --clipping_enabled",},
+
+    //
+    // choreography
+    //
+    {"fuchsia.scenic.choreography_noclipping_noshadows", kChoreographyCommand, "dashboard", "--unshadowed --clipping_disabled",},
+    {"fuchsia.scenic.choreography_noshadows", kChoreographyCommand, "dashboard", "--unshadowed --clipping_enabled",},
+    {"fuchsia.scenic.choreography_ssdo", kChoreographyCommand, "dashboard", "--screen_space_shadows --clipping_enabled",},
+    {"fuchsia.scenic.choreography_shadow_map", kChoreographyCommand, "dashboard", "--shadow_map --clipping_enabled",},
+    {"fuchsia.scenic.choreography_moment_shadow_map", kChoreographyCommand, "dashboard", "--moment_shadow_map --clipping_enabled",},
+  };
+  // clang-format on
+
+  for (const auto& param : params) {
+    std::string out_file = benchmarks_runner->MakeTempFile();
+
+    // clang-format off
+    std::vector<std::string> full_command = {
+        "/pkgfs/packages/scenic_benchmarks/0/bin/run_scenic_benchmark.sh",
+        "--out_file", out_file,
+        "--benchmark_label", param.benchmark_name,
+        "--cmd", param.command,
+    };
+    // clang-format on
+
+    if (param.flutter_app_name) {
+      full_command.push_back("--flutter_app_name");
+      full_command.push_back(*param.flutter_app_name);
+      full_command.push_back("--sleep_before_trace");
+      full_command.push_back("5");
+    }
+
+    full_command.push_back(param.renderer_params);
+
+    benchmarks_runner->AddCustomBenchmark(param.benchmark_name, full_command,
+                                          out_file);
+  }
+}
diff --git a/tests/benchmarks/gfx_benchmarks.h b/tests/benchmarks/gfx_benchmarks.h
new file mode 100644
index 0000000..5477ee3
--- /dev/null
+++ b/tests/benchmarks/gfx_benchmarks.h
@@ -0,0 +1,13 @@
+// Copyright 2019 The Fuchsia Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOPAZ_TESTS_BENCHMARKS_GFX_BENCHMARKS_H_
+#define TOPAZ_TESTS_BENCHMARKS_GFX_BENCHMARKS_H_
+
+#include "garnet/testing/benchmarking/benchmarking.h"
+
+// Add all garnet graphics benchmarks to |benchmarks_runner|.
+void AddGraphicsBenchmarks(benchmarking::BenchmarksRunner* benchmarks_runner);
+
+#endif  // TOPAZ_TESTS_BENCHMARKS_GFX_BENCHMARKS_H_
diff --git a/tests/benchmarks/topaz_benchmarks.sh b/tests/benchmarks/topaz_benchmarks.sh
deleted file mode 100644
index 944840d..0000000
--- a/tests/benchmarks/topaz_benchmarks.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/boot/bin/sh
-#
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This script runs all benchmarks for the Topaz layer.
-#
-# For usage, see runbench_read_arguments in runbenchmarks.sh.
-
-# Import the runbenchmarks library.
-. /pkgfs/packages/runbenchmarks/0/data/runbenchmarks.sh
-
-runbench_read_arguments "$@"
-
-# Run benchmarks
-vulkan_is_supported="fuchsia-pkg://fuchsia.com/vulkan_is_supported#meta/vulkan_is_supported.cmx"
-vulkan_is_supported_result="$(/pkgfs/packages/run/0/bin/run $vulkan_is_supported || echo '')"
-if [ "${vulkan_is_supported_result}" = '1' ]; then
-  # Run the gfx benchmarks in the current shell environment, because they write
-  # to (hidden) global state used by runbench_finish.
-
-  # DISABLED: See SCN-1223
-  # . /pkgfs/packages/topaz_benchmarks/0/bin/gfx_benchmarks.sh "$@"
-  echo 'Graphics performance tests disabled'
-elif [ "${vulkan_is_supported_result}" = '0' ]; then
-  echo 'Vulkan not supported; graphics tests skipped.'
-else
-  echo 'Error: Failed to run vulkan_is_supported'
-  exit 1
-fi
-
-# Exit with a code indicating whether any errors occurred.
-runbench_finish "${OUT_DIR}"
diff --git a/tests/benchmarks/topaz_gfx_benchmarks.sh b/tests/benchmarks/topaz_gfx_benchmarks.sh
deleted file mode 100644
index 33eaad8..0000000
--- a/tests/benchmarks/topaz_gfx_benchmarks.sh
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/boot/bin/sh
-#
-# Copyright 2018 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# This script runs all gfx benchmarks for the Garnet layer. It is called by
-# benchmarks.sh.
-
-# Scenic performance tests.
-RUN_SCENIC_BENCHMARK="/pkgfs/packages/scenic_benchmarks/0/bin/run_scenic_benchmark.sh"
-
-
-# Arguments to runbench_exec for Scenic benchmarks:
-#
-# runbench_exec
-#   "${OUT_DIR}/${BENCHMARK}.json"             # Output file path.
-#   "${RUN_SCENIC_BENCHMARK}"                  # Scenic benchmark runner, followed by
-#                                              #   its arguments.
-#   --out_dir "${OUT_DIR}"                     # Output directory.
-#   --out_file "${OUT_DIR}/${BENCHMARK}.json"  # Output file path.
-#   --benchmark_label "${BENCHMARK}"           # Label for benchmark.
-#   --cmd "test_binary"                        # Binary that is being benchmarked.
-#   --unshadowed --clipping_disabled           # Renderer parameters.
-
-
-#
-# image_grid_flutter
-#
-PRESENT_VIEW="fuchsia-pkg://fuchsia.com/present_view#meta/present_view.cmx"
-IMAGE_GRID_FLUTTER="fuchsia-pkg://fuchsia.com/image_grid_flutter#meta/image_grid_flutter.cmx"
-BENCHMARK="fuchsia.scenic.image_grid_flutter_noclipping_noshadows"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "$PRESENT_VIEW $IMAGE_GRID_FLUTTER"  \
-    --flutter_app_name 'image_grid_flutter'   \
-    --sleep_before_trace 5                    \
-    --unshadowed --clipping_disabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_noshadows"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "$PRESENT_VIEW $IMAGE_GRID_FLUTTER"  \
-    --flutter_app_name 'image_grid_flutter'   \
-    --sleep_before_trace 5                    \
-    --unshadowed --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_ssdo"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "$PRESENT_VIEW $IMAGE_GRID_FLUTTER"  \
-    --flutter_app_name 'image_grid_flutter'   \
-    --sleep_before_trace 5                    \
-    --screen_space_shadows --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_shadow_map"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "$PRESENT_VIEW $IMAGE_GRID_FLUTTER"  \
-    --flutter_app_name 'image_grid_flutter'   \
-    --sleep_before_trace 5                    \
-    --shadow_map --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_moment_shadow_map"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "$PRESENT_VIEW $IMAGE_GRID_FLUTTER"  \
-    --flutter_app_name 'image_grid_flutter'   \
-    --sleep_before_trace 5                    \
-    --moment_shadow_map --clipping_enabled
-
-#
-# image_grid_flutter x3
-#
-# TODO: Support tracking multiple flutter apps of the same name in
-# process_scenic_trace.
-IMAGE_GRID_FLUTTER_X3_COMMAND="present_view fuchsia-pkg://fuchsia.com/tile_view#meta/tile_view.cmx $IMAGE_GRID_FLUTTER $IMAGE_GRID_FLUTTER $IMAGE_GRID_FLUTTER"
-BENCHMARK="fuchsia.scenic.image_grid_flutter_x3_noclipping_noshadows"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "${IMAGE_GRID_FLUTTER_X3_COMMAND}"  \
-    --unshadowed --clipping_disabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_x3_noshadows"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "${IMAGE_GRID_FLUTTER_X3_COMMAND}"  \
-    --unshadowed --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_x3_ssdo"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "${IMAGE_GRID_FLUTTER_X3_COMMAND}"  \
-    --screen_space_shadows --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_x3_shadow_map"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "${IMAGE_GRID_FLUTTER_X3_COMMAND}"  \
-    --shadow_map --clipping_enabled
-
-BENCHMARK="fuchsia.scenic.image_grid_flutter_x3_moment_shadow_map"
-runbench_exec "${OUT_DIR}/${BENCHMARK}.json"  \
-    "${RUN_SCENIC_BENCHMARK}"                 \
-    --out_dir "${OUT_DIR}"                    \
-    --out_file "${OUT_DIR}/${BENCHMARK}.json" \
-    --benchmark_label "${BENCHMARK}"          \
-    --cmd "${IMAGE_GRID_FLUTTER_X3_COMMAND}"  \
-    --moment_shadow_map --clipping_enabled