Initial Lottie loader impl (Skotty)

Coarse workflow:

* Construction

  1) build a Json tree
  2) collect asset IDs (for preComp/image layer resolution)
  3) "attach" pass
     - traverse the Json tree
     - build an SkSG dom, one fragment at a time
     - attach "animator" objects to the dom, for each animated prop
  4) done, we can throw away the Json tree

* For each animation tick

  1) iterate over active animators and poke their respective dom nodes/attributes
  2) revalidate the SkSG dom
  3) draw the SkSG dom

Note: post construction, things are super-simple - we just poke SkSG DOM attributes
with interpolated values, and everything else is handled by SkSG (invalidation,
revalidation, render).

Change-Id: I96a02be7eb4fb4cb3831f59bf2b3908ea190c0dd
Reviewed-on: https://skia-review.googlesource.com/89420
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Florin Malita <fmalita@chromium.org>
diff --git a/tools/viewer/Viewer.cpp b/tools/viewer/Viewer.cpp
index 1f701e2..55a025c 100644
--- a/tools/viewer/Viewer.cpp
+++ b/tools/viewer/Viewer.cpp
@@ -11,6 +11,7 @@
 #include "ImageSlide.h"
 #include "Resources.h"
 #include "SampleSlide.h"
+#include "SkottySlide.h"
 #include "SKPSlide.h"
 
 #include "GrContext.h"
@@ -68,9 +69,11 @@
 #ifdef SK_BUILD_FOR_ANDROID
 static DEFINE_string(skps, "/data/local/tmp/skps", "Directory to read skps from.");
 static DEFINE_string(jpgs, "/data/local/tmp/resources", "Directory to read jpgs from.");
+static DEFINE_string(jsons, "/data/local/tmp/jsons", "Directory to read (Bodymovin) jsons from.");
 #else
 static DEFINE_string(skps, "skps", "Directory to read skps from.");
 static DEFINE_string(jpgs, "jpgs", "Directory to read jpgs from.");
+static DEFINE_string(jsons, "jsons", "Directory to read (Bodymovin) jsons from.");
 #endif
 
 static DEFINE_string2(backend, b, "sw", "Backend to use. Allowed values are " BACKENDS_STR ".");
@@ -480,6 +483,19 @@
             }
         }
     }
+
+    // JSONs
+    for (const auto& json : FLAGS_jsons) {
+        SkOSFile::Iter it(json.c_str(), ".json");
+        SkString jsonName;
+        while (it.next(&jsonName)) {
+            if (SkCommandLineFlags::ShouldSkip(FLAGS_match, jsonName.c_str())) {
+                continue;
+            }
+            fSlides.push_back(sk_make_sp<SkottySlide>(jsonName, SkOSPath::Join(json.c_str(),
+                                                                               jsonName.c_str())));
+        }
+    }
 }