SkQP: make report.html smaller

Change-Id: Ie43bf83fbd94fdf7edc79cfe403b01474894199d
Reviewed-on: https://skia-review.googlesource.com/99280
Reviewed-by: Hal Canary <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
diff --git a/tools/skqp/gm_knowledge.cpp b/tools/skqp/gm_knowledge.cpp
index 8bbac6e..51f0d8f 100644
--- a/tools/skqp/gm_knowledge.cpp
+++ b/tools/skqp/gm_knowledge.cpp
@@ -31,6 +31,7 @@
 #define PATH_IMG_PNG "image.png"
 #define PATH_ERR_PNG "errors.png"
 #define PATH_REPORT  "report.html"
+#define PATH_CSV      "out.csv"
 
 ////////////////////////////////////////////////////////////////////////////////
 
@@ -199,71 +200,93 @@
     return (float)badness;
 }
 
+static constexpr char kDocHead[] =
+    "<!doctype html>\n"
+    "<html lang=\"en\">\n"
+    "<head>\n"
+    "<meta charset=\"UTF-8\">\n"
+    "<title>SkQP Report</title>\n"
+    "<style>\n"
+    "img { max-width:48%; border:1px green solid; }\n"
+    "img.i { background-image:url('data:image/png;base64,iVBORw0KGgoA"
+    "AAANSUhEUgAAABAAAAAQCAAAAAA6mKC9AAAAAXNSR0IArs4c6QAAAAJiS0dEAP+H"
+    "j8y/AAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gUBEi4DGRAQYgAAAB1J"
+    "REFUGNNjfMoAAVJQmokBDdBHgPE/lPFsYN0BABdaAwN6tehMAAAAAElFTkSuQmCC"
+    "'); }\n"
+    "</style>\n"
+    "<script>\n"
+    "function ce(t) { return document.createElement(t); }\n"
+    "function ct(n) { return document.createTextNode(n); }\n"
+    "function ac(u,v) { return u.appendChild(v); }\n"
+    "function br(u) { ac(u, ce(\"br\")); }\n"
+    "function ma(s, c) { var a = ce(\"a\"); a.href = s; ac(a, c); return a; }\n"
+    "function f(backend, gm, e1, e2) {\n"
+    "  var b = ce(\"div\");\n"
+    "  var x = ce(\"h2\");\n"
+    "  var t = backend + \"/\" + gm;\n"
+    "  ac(x, ct(t));\n"
+    "  ac(b, x);\n"
+    "  ac(b, ct(\"backend: \" + backend));\n"
+    "  br(b);\n"
+    "  ac(b, ct(\"gm name: \" + gm));\n"
+    "  br(b);\n"
+    "  ac(b, ct(\"maximum error: \" + e1));\n"
+    "  br(b);\n"
+    "  ac(b, ct(\"bad pixel counts: \" + e2));\n"
+    "  br(b);\n"
+    "  var i = ce(\"img\");\n"
+    "  i.src = t + \"/image.png\";\n"
+    "  i.alt = \"img\";\n"
+    "  i.classList.add(\"i\");\n"
+    "  ac(b, ma(i.src, i));\n"
+    "  i = ce(\"img\");\n"
+    "  i.src = t + \"/errors.png\";\n"
+    "  i.alt = \"img\";\n"
+    "  ac(b, ma(i.src, i));\n"
+    "  br(b);\n"
+    "  ac(b, ma(t + \"/max.png\", ct(\"max\")));\n"
+    "  ac(b, ma(t + \"/min.png\", ct(\"min\")));\n"
+    "  ac(b, ce(\"hr\"));\n"
+    "  ac(document.body, b);\n"
+    "}\n"
+    "function bar() {\n";
+
+static constexpr char kDocTail[] =
+    "}\n"
+    "</script>\n"
+    "</head>\n"
+    "<body onload=\"bar()\">\n"
+    "<h1>SkQP Report</h1>\n"
+    "<hr>\n"
+    "</body>\n"
+    "</html>\n";
+
+static void write(SkWStream* wStream, const SkString& text) {
+    wStream->write(text.c_str(), text.size());
+}
+
 bool MakeReport(const char* report_directory_path) {
     SkASSERT_RELEASE(sk_isdir(report_directory_path));
     std::lock_guard<std::mutex> lock(gMutex);
-    {
-        SkFILEWStream csvOut(SkOSPath::Join(report_directory_path, "out.csv").c_str());
-        SkASSERT_RELEASE(csvOut.isValid());
-        if (!csvOut.isValid()) {
-            return false;
-        }
-        for (const Run& run : gErrors) {
-            SkString line = SkStringPrintf("\"%s\",\"%s\",%d,%d\n",
-                                           run.fBackend.c_str(), run.fGM.c_str(),
-                                           run.fMaxerror, run.fBadpixels);
-            csvOut.write(line.c_str(), line.size());
-        }
-    }
-
-    SkFILEWStream out(SkOSPath::Join(report_directory_path, PATH_REPORT).c_str());
-    if (!out.isValid()) {
+    SkFILEWStream csvOut(SkOSPath::Join(report_directory_path, PATH_CSV).c_str());
+    SkFILEWStream htmOut(SkOSPath::Join(report_directory_path, PATH_REPORT).c_str());
+    SkASSERT_RELEASE(csvOut.isValid());
+    if (!csvOut.isValid() || !htmOut.isValid()) {
         return false;
     }
-    out.writeText(
-        "<!doctype html>\n"
-        "<html lang=\"en\">\n"
-        "<head>\n"
-        "<meta charset=\"UTF-8\">\n"
-        "<title>SkQP Report</title>\n"
-        "<style>\n"
-        "img { max-width:48%; border:1px green solid; }\n"
-        "img.i { background-image:url('data:image/png;base64,iVBORw0KGgoAAAANSU"
-        "hEUgAAABAAAAAQCAAAAAA6mKC9AAAAAXNSR0IArs4c6QAAAAJiS0dEAP+Hj8y/AAAACXBI"
-        "WXMAAA7DAAAOwwHHb6hkAAAAB3RJTUUH3gUBEi4DGRAQYgAAAB1JREFUGNNjfMoAAVJQmo"
-        "kBDdBHgPE/lPFsYN0BABdaAwN6tehMAAAAAElFTkSuQmCC'); }\n"
-        "</style>\n"
-        "</head>\n"
-        "<body>\n"
-        "<h1>SkQP Report</h1>\n"
-        "<hr>\n");
+    htmOut.writeText(kDocHead);
     for (const Run& run : gErrors) {
-        const SkString& backend = run.fBackend;
-        const SkString& gm = run.fGM;
-        int maxerror = run.fMaxerror;
-        int badpixels = run.fBadpixels;
-        if (maxerror == 0 && badpixels == 0) {
+        write(&csvOut, SkStringPrintf("\"%s\",\"%s\",%d,%d\n",
+                                      run.fBackend.c_str(), run.fGM.c_str(),
+                                      run.fMaxerror, run.fBadpixels));
+        if (run.fMaxerror == 0 && run.fBadpixels == 0) {
             continue;
         }
-        SkString rdir = SkOSPath::Join(backend.c_str(), gm.c_str());
-        SkString text = SkStringPrintf(
-            "<h2>%s</h2>\n"
-            "backend: %s\n<br>\n"
-            "gm name: %s\n<br>\n"
-            "maximum error: %d\n<br>\n"
-            "bad pixel counts: %d\n<br>\n"
-            "<a  href=\"%s/" PATH_IMG_PNG "\">"
-            "<img src=\"%s/" PATH_IMG_PNG "\" alt='img' class=\"i\"></a>\n"
-            "<a  href=\"%s/" PATH_ERR_PNG "\">"
-            "<img src=\"%s/" PATH_ERR_PNG "\" alt='err'></a>\n<br>\n"
-            "<a  href=\"%s/" PATH_MAX_PNG "\">max</a>\n<br>\n"
-            "<a  href=\"%s/" PATH_MIN_PNG "\">min</a>\n<hr>\n\n",
-            rdir.c_str(), backend.c_str(), gm.c_str(), maxerror, badpixels,
-            rdir.c_str(), rdir.c_str(), rdir.c_str(),
-            rdir.c_str(), rdir.c_str(), rdir.c_str());
-        out.write(text.c_str(), text.size());
+        write(&htmOut, SkStringPrintf("  f(\"%s\", \"%s\", %d, %d);\n",
+                                      run.fBackend.c_str(), run.fGM.c_str(),
+                                      run.fMaxerror, run.fBadpixels));
     }
-    out.writeText("</body>\n</html>\n");
+    htmOut.writeText(kDocTail);
     return true;
 }
 }  // namespace gmkb