perf_tests: Manually serialize JSON and remove dependency on jsoncpp

jsoncpp causes some flaky failures because of inconsistencies in nested
DEPS. We barely use it for JSON serialization so the simplest solution
is to just manually write the serialization for perf test tracing data.

Bug: dawn:208
Change-Id: Ie5e4b5436e2c9e32e6817d64c6e95c774cb8751f
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/14720
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Kai Ninomiya <kainino@chromium.org>
Commit-Queue: Austin Eng <enga@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index e03aa8d..de8f258 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1020,7 +1020,6 @@
     ":dawn_utils",
     ":libdawn_native",
     ":libdawn_wire",
-    "${dawn_jsoncpp_dir}:jsoncpp",
     "${dawn_root}/src/common",
     "${dawn_root}/src/dawn:dawncpp",
     "${dawn_root}/src/dawn:libdawn_proc",
diff --git a/DEPS b/DEPS
index c5913f9..1bc6730 100644
--- a/DEPS
+++ b/DEPS
@@ -73,17 +73,6 @@
     'condition': 'dawn_standalone',
   },
 
-  # jsoncpp for perf tests trace events
-  'third_party/jsoncpp': {
-    'url': '{chromium_git}/chromium/src/third_party/jsoncpp@571788934b5ee8643d53e5d054534abbe6006168',
-    'condition': 'dawn_standalone',
-  },
-
-  'third_party/jsoncpp/source': {
-    'url' : '{chromium_git}/external/github.com/open-source-parsers/jsoncpp@645250b6690785be60ab6780ce4b58698d884d11',
-    'condition': 'dawn_standalone',
-  },
-
   # GLFW for tests and samples
   'third_party/glfw': {
     'url': '{chromium_git}/external/github.com/glfw/glfw@2de2589f910b1a85905f425be4d32f33cec092df',
diff --git a/build_overrides/dawn.gni b/build_overrides/dawn.gni
index 0d44f3b..0378ec1 100644
--- a/build_overrides/dawn.gni
+++ b/build_overrides/dawn.gni
@@ -27,7 +27,6 @@
 dawn_jinja2_dir = "//third_party/jinja2"
 dawn_glfw_dir = "//third_party/glfw"
 dawn_googletest_dir = "//third_party/googletest"
-dawn_jsoncpp_dir = "//third_party/jsoncpp"
 dawn_shaderc_dir = "//third_party/shaderc"
 dawn_spirv_tools_dir = "//third_party/SPIRV-Tools"
 dawn_spirv_cross_dir = "//third_party/spirv-cross"
diff --git a/scripts/dawn_overrides_with_defaults.gni b/scripts/dawn_overrides_with_defaults.gni
index b7eaee1..0886e03 100644
--- a/scripts/dawn_overrides_with_defaults.gni
+++ b/scripts/dawn_overrides_with_defaults.gni
@@ -41,10 +41,6 @@
   dawn_googletest_dir = "//third_party/googletest"
 }
 
-if (!defined(dawn_jsoncpp_dir)) {
-  dawn_jsoncpp_dir = "//third_party/jsoncpp"
-}
-
 if (!defined(dawn_shaderc_dir)) {
   dawn_shaderc_dir = "//third_party/shaderc"
 }
diff --git a/src/tests/perf_tests/DawnPerfTest.cpp b/src/tests/perf_tests/DawnPerfTest.cpp
index 3bd641b..64b4d70 100644
--- a/src/tests/perf_tests/DawnPerfTest.cpp
+++ b/src/tests/perf_tests/DawnPerfTest.cpp
@@ -20,9 +20,6 @@
 #include "tests/perf_tests/DawnPerfTestPlatform.h"
 #include "utils/Timer.h"
 
-#include <json/value.h>
-#include <json/writer.h>
-
 #include <fstream>
 #include <limits>
 
@@ -36,45 +33,37 @@
         std::ofstream outFile;
         outFile.open(traceFile, std::ios_base::app);
 
-        Json::StreamWriterBuilder builder;
-        std::unique_ptr<Json::StreamWriter> writer(builder.newStreamWriter());
-
         for (const DawnPerfTestPlatform::TraceEvent& traceEvent : traceEventBuffer) {
-            Json::Value value(Json::objectValue);
-
-            const Json::LargestInt microseconds =
-                static_cast<Json::LargestInt>(traceEvent.timestamp * 1000.0 * 1000.0);
-
-            char phase[2] = {traceEvent.phase, '\0'};
-
-            value["name"] = traceEvent.name;
+            const char* category = nullptr;
             switch (traceEvent.category) {
                 case dawn_platform::TraceCategory::General:
-                    value["cat"] = "general";
+                    category = "general";
                     break;
                 case dawn_platform::TraceCategory::Validation:
-                    value["cat"] = "validation";
+                    category = "validation";
                     break;
                 case dawn_platform::TraceCategory::Recording:
-                    value["cat"] = "recording";
+                    category = "recording";
                     break;
                 case dawn_platform::TraceCategory::GPUWork:
-                    value["cat"] = "gpu";
+                    category = "gpu";
                     break;
                 default:
                     UNREACHABLE();
             }
-            value["ph"] = &phase[0];
-            value["id"] = traceEvent.id;
-            value["tid"] = traceEvent.threadId;
-            value["ts"] = microseconds;
-            value["pid"] = "Dawn";
 
-            outFile << ", ";
-            writer->write(value, &outFile);
-            outFile.flush();
+            uint64_t microseconds = static_cast<uint64_t>(traceEvent.timestamp * 1000.0 * 1000.0);
+
+            outFile << ", { "
+                    << "\"name\": \"" << traceEvent.name << "\", "
+                    << "\"cat\": \"" << category << "\", "
+                    << "\"ph\": \"" << traceEvent.phase << "\", "
+                    << "\"id\": " << traceEvent.id << ", "
+                    << "\"tid\": " << traceEvent.threadId << ", "
+                    << "\"ts\": " << microseconds << ", "
+                    << "\"pid\": \"Dawn\""
+                    << " }";
         }
-
         outFile.close();
     }
 
@@ -115,7 +104,7 @@
         if (strcmp("-h", argv[i]) == 0 || strcmp("--help", argv[i]) == 0) {
             dawn::InfoLog()
                 << "Additional flags:"
-                << " [--calibration] [--override-steps=x] [--enable-tracing] [--trace-file=file]\n"
+                << " [--calibration] [--override-steps=x] [--trace-file=file]\n"
                 << "  --calibration: Only run calibration. Calibration allows the perf test"
                    " runner script to save some time.\n"
                 << " --override-steps: Set a fixed number of steps to run for each test\n"