Wire up /batches in skiaserve

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1737323002

Review URL: https://codereview.chromium.org/1737323002
diff --git a/tools/skiaserve/Request.cpp b/tools/skiaserve/Request.cpp
index 33e94fd..3d9e9d3 100644
--- a/tools/skiaserve/Request.cpp
+++ b/tools/skiaserve/Request.cpp
@@ -111,3 +111,41 @@
     return surface;
 }
 
+SkData* Request::getJsonOps(int n) {
+    SkCanvas* canvas = this->getCanvas();
+    Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
+    root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu");
+    SkDynamicMemoryWStream stream;
+    stream.writeText(Json::FastWriter().write(root).c_str());
+
+    return stream.copyToData();
+}
+
+SkData* Request::getJsonBatchList(int n) {
+    SkCanvas* canvas = this->getCanvas();
+    SkASSERT(fGPUEnabled);
+
+    // TODO if this is inefficient we could add a method to GrAuditTrail which takes
+    // a Json::Value and is only compiled in this file
+    Json::Value parsedFromString;
+#if SK_SUPPORT_GPU
+    GrRenderTarget* rt = canvas->internal_private_accessTopLayerRenderTarget();
+    SkASSERT(rt);
+    GrContext* ctx = rt->getContext();
+    SkASSERT(ctx);
+    GrAuditTrail* at = ctx->getAuditTrail();
+    GrAuditTrail::AutoManageBatchList enable(at);
+    
+    fDebugCanvas->drawTo(canvas, n);
+
+    Json::Reader reader;
+    SkDEBUGCODE(bool parsingSuccessful = )reader.parse(at->toJson(true).c_str(),
+                                                       parsedFromString);
+    SkASSERT(parsingSuccessful);
+#endif
+
+    SkDynamicMemoryWStream stream;
+    stream.writeText(Json::FastWriter().write(parsedFromString).c_str());
+
+    return stream.copyToData();
+}