Roll external/skia 9661b9822..d23d8d1d9 (2 commits)

https://skia.googlesource.com/skia.git/+log/9661b9822..d23d8d1d9

2018-01-07 reed@google.com remove guarded old malloc code
2018-01-07 fmalita@chromium.org [skotty,sksg] Initial trim path effect

The AutoRoll server is located here: https://android-roll.skia.org

Documentation for the AutoRoller is here:
https://skia.googlesource.com/buildbot/+/master/autoroll/README.md

If the roll is causing failures, please contact the current sheriff, who should
be CC'd on the roll, and stop the roller if necessary.

Test: Presubmit checks will test this change.
Change-Id: Ifc3994064f8dd4210cd1092c5bea126a99bf99c5
Exempt-From-Owner-Approval: The autoroll bot does not require owner approval.
diff --git a/Android.bp b/Android.bp
index 13d9028..e7dbca1 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1061,6 +1061,7 @@
         "experimental/sksg/geometry/SkSGMerge.cpp",
         "experimental/sksg/geometry/SkSGPath.cpp",
         "experimental/sksg/geometry/SkSGRect.cpp",
+        "experimental/sksg/geometry/SkSGTrimEffect.cpp",
         "experimental/sksg/paint/SkSGColor.cpp",
         "experimental/svg/model/SkSVGAttribute.cpp",
         "experimental/svg/model/SkSVGAttributeParser.cpp",
@@ -1971,6 +1972,7 @@
         "experimental/sksg/geometry/SkSGMerge.cpp",
         "experimental/sksg/geometry/SkSGPath.cpp",
         "experimental/sksg/geometry/SkSGRect.cpp",
+        "experimental/sksg/geometry/SkSGTrimEffect.cpp",
         "experimental/sksg/paint/SkSGColor.cpp",
         "experimental/svg/model/SkSVGAttribute.cpp",
         "experimental/svg/model/SkSVGAttributeParser.cpp",
diff --git a/BUILD.gn b/BUILD.gn
index fe58f50..cc1e844 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -1387,6 +1387,7 @@
       "experimental/sksg/geometry/SkSGMerge.cpp",
       "experimental/sksg/geometry/SkSGPath.cpp",
       "experimental/sksg/geometry/SkSGRect.cpp",
+      "experimental/sksg/geometry/SkSGTrimEffect.cpp",
       "experimental/sksg/paint/SkSGColor.cpp",
     ]
     deps = [
diff --git a/experimental/skotty/Skotty.cpp b/experimental/skotty/Skotty.cpp
index 8c48d1f..a13a04c 100644
--- a/experimental/skotty/Skotty.cpp
+++ b/experimental/skotty/Skotty.cpp
@@ -24,6 +24,7 @@
 #include "SkSGPath.h"
 #include "SkSGRect.h"
 #include "SkSGTransform.h"
+#include "SkSGTrimEffect.h"
 #include "SkStream.h"
 #include "SkTArray.h"
 #include "SkTHash.h"
@@ -308,7 +309,8 @@
         sksg::Merge::Mode::kXOR      ,  // "mm": 5
     };
 
-    const auto mode = gModes[SkTPin<int>(ParseInt(jmerge["mm"], 1) - 1, 0, SK_ARRAY_COUNT(gModes))];
+    const auto mode = gModes[SkTPin<int>(ParseInt(jmerge["mm"], 1) - 1,
+                                         0, SK_ARRAY_COUNT(gModes) - 1)];
     merged.push_back(sksg::Merge::Make(std::move(geos), mode));
 
     LOG("** Attached merge path effect, mode: %d\n", mode);
@@ -316,6 +318,47 @@
     return merged;
 }
 
+std::vector<sk_sp<sksg::GeometryNode>> AttachTrimGeometryEffect(
+    const Json::Value& jtrim, AttachContext* ctx, std::vector<sk_sp<sksg::GeometryNode>>&& geos) {
+
+    enum class Mode {
+        kMerged,   // "m": 1
+        kSeparate, // "m": 2
+    } gModes[] = { Mode::kMerged, Mode::kSeparate };
+
+    const auto mode = gModes[SkTPin<int>(ParseInt(jtrim["m"], 1) - 1,
+                                         0, SK_ARRAY_COUNT(gModes) - 1)];
+
+    std::vector<sk_sp<sksg::GeometryNode>> inputs;
+    if (mode == Mode::kMerged) {
+        inputs.push_back(sksg::Merge::Make(std::move(geos), sksg::Merge::Mode::kMerge));
+    } else {
+        inputs = std::move(geos);
+    }
+
+    std::vector<sk_sp<sksg::GeometryNode>> trimmed;
+    trimmed.reserve(inputs.size());
+    for (const auto& i : inputs) {
+        const auto trim = sksg::TrimEffect::Make(i);
+        trimmed.push_back(trim);
+        AttachProperty<ScalarValue, SkScalar>(jtrim["s"], ctx, trim,
+            [](const sk_sp<sksg::TrimEffect>& node, const SkScalar& s) {
+                node->setStart(s * 0.01f);
+            });
+        AttachProperty<ScalarValue, SkScalar>(jtrim["e"], ctx, trim,
+            [](const sk_sp<sksg::TrimEffect>& node, const SkScalar& e) {
+                node->setEnd(e * 0.01f);
+            });
+        // TODO: "offset" doesn't currently work the same as BM - figure out what's going on.
+        AttachProperty<ScalarValue, SkScalar>(jtrim["o"], ctx, trim,
+            [](const sk_sp<sksg::TrimEffect>& node, const SkScalar& o) {
+                node->setOffset(o * 0.01f);
+            });
+    }
+
+    return trimmed;
+}
+
 using GeometryAttacherT = sk_sp<sksg::GeometryNode> (*)(const Json::Value&, AttachContext*);
 static constexpr GeometryAttacherT gGeometryAttachers[] = {
     AttachPathGeometry,
@@ -341,6 +384,7 @@
                                                std::vector<sk_sp<sksg::GeometryNode>>&&);
 static constexpr GeometryEffectAttacherT gGeometryEffectAttachers[] = {
     AttachMergeGeometryEffect,
+    AttachTrimGeometryEffect,
 };
 
 enum class ShapeType {
@@ -367,6 +411,7 @@
         { "sh", ShapeType::kGeometry      , 0 }, // shape     -> AttachPathGeometry
         { "sr", ShapeType::kGeometry      , 3 }, // polystar  -> AttachPolyStarGeometry
         { "st", ShapeType::kPaint         , 1 }, // stroke    -> AttachStrokePaint
+        { "tm", ShapeType::kGeometryEffect, 1 }, // trim      -> AttachTrimGeometryEffect
         { "tr", ShapeType::kTransform     , 0 }, // transform -> In-place handler
     };
 
diff --git a/experimental/sksg/SkSGNode.h b/experimental/sksg/SkSGNode.h
index 769e2a4..4e1e7b0 100644
--- a/experimental/sksg/SkSGNode.h
+++ b/experimental/sksg/SkSGNode.h
@@ -70,6 +70,7 @@
     friend class Merge;
     friend class Stroke;
     friend class Transform;
+    friend class TrimEffect;
 
     template <typename Func>
     void forEachInvalReceiver(Func&&) const;
diff --git a/experimental/sksg/geometry/SkSGTrimEffect.cpp b/experimental/sksg/geometry/SkSGTrimEffect.cpp
new file mode 100644
index 0000000..4c30389
--- /dev/null
+++ b/experimental/sksg/geometry/SkSGTrimEffect.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkSGTrimEffect.h"
+
+#include "SkCanvas.h"
+#include "SkDashPathEffect.h"
+#include "SkPathMeasure.h"
+
+namespace sksg {
+
+TrimEffect::TrimEffect(sk_sp<GeometryNode> child)
+    : fChild(std::move(child)) {
+    fChild->addInvalReceiver(this);
+}
+
+TrimEffect::~TrimEffect() {
+    fChild->removeInvalReceiver(this);
+}
+
+// TODO
+//   This is a quick hack to get something on the screen.  What we really want here is to apply
+//   the geometry transformation and cache the result on revalidation. Or an SkTrimPathEffect.
+void TrimEffect::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
+    SkASSERT(!this->hasInval());
+
+    SkASSERT(!paint.getPathEffect());
+
+    const auto path = fChild->asPath();
+    SkScalar pathLen = 0;
+    SkPathMeasure measure(path, false);
+    do {
+        pathLen += measure.getLength();
+    } while (measure.nextContour());
+
+    const auto start  = SkScalarPin(fStart , 0, 1) * pathLen,
+               end    = SkScalarPin(fEnd   , 0, 1) * pathLen,
+               offset = SkScalarPin(fOffset, 0, 1) * pathLen,
+               len    = SkTMax<SkScalar>(end - start, 0);
+
+    const SkScalar dashes[4] = { 0, start, len, pathLen - end };
+    SkPaint dashedPaint(paint);
+    dashedPaint.setPathEffect(SkDashPathEffect::Make(dashes, 4, -offset));
+
+    canvas->drawPath(path, dashedPaint);
+}
+
+SkPath TrimEffect::onAsPath() const {
+    return fChild->asPath();
+}
+
+SkRect TrimEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
+    SkASSERT(this->hasInval());
+    return fChild->revalidate(ic, ctm);
+}
+
+} // namespace sksg
diff --git a/experimental/sksg/geometry/SkSGTrimEffect.h b/experimental/sksg/geometry/SkSGTrimEffect.h
new file mode 100644
index 0000000..77da3ab
--- /dev/null
+++ b/experimental/sksg/geometry/SkSGTrimEffect.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2017 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkSGTrimEffect_DEFINED
+#define SkSGTrimEffect_DEFINED
+
+#include "SkSGGeometryNode.h"
+
+#include "SkPath.h"
+
+class SkCanvas;
+class SkPaint;
+
+namespace sksg {
+
+/**
+ * Concrete Geometry node, applying a trim effect to its child.
+ */
+class TrimEffect final : public GeometryNode {
+public:
+    static sk_sp<TrimEffect> Make(sk_sp<GeometryNode> child) {
+        return child ? sk_sp<TrimEffect>(new TrimEffect(std::move(child))) : nullptr;
+    }
+
+    ~TrimEffect() override;
+
+    SG_ATTRIBUTE(Start , SkScalar, fStart )
+    SG_ATTRIBUTE(End   , SkScalar, fEnd   )
+    SG_ATTRIBUTE(Offset, SkScalar, fOffset)
+
+protected:
+    void onDraw(SkCanvas*, const SkPaint&) const override;
+
+    SkRect onRevalidate(InvalidationController*, const SkMatrix&) override;
+    SkPath onAsPath() const override;
+
+private:
+    explicit TrimEffect(sk_sp<GeometryNode>);
+
+    const sk_sp<GeometryNode> fChild;
+
+    SkScalar                  fStart  = 0, // starting t
+                              fEnd    = 1, // ending t
+                              fOffset = 0; // t offset
+};
+
+} // namespace sksg
+
+#endif // SkSGTrimEffect_DEFINED
diff --git a/include/private/SkMalloc.h b/include/private/SkMalloc.h
index 53c3d99..178e1b8 100644
--- a/include/private/SkMalloc.h
+++ b/include/private/SkMalloc.h
@@ -28,15 +28,11 @@
 SK_API extern void sk_out_of_memory(void);
 
 enum {
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-    SK_MALLOC_TEMP = 1,
-#else
     /**
      *  If this bit is set, the returned buffer must be zero-initialized. If this bit is not set
      *  the buffer can be uninitialized.
      */
     SK_MALLOC_ZERO_INITIALIZE   = 1 << 0,
-#endif
 
     /**
      *  If this bit is set, the implementation must throw/crash/quit if the request cannot
@@ -59,20 +55,6 @@
  */
 SK_API extern void* sk_realloc_throw(void* buffer, size_t size);
 
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-
-/** Same as sk_malloc_flags(), but hard coded to pass SK_MALLOC_THROW as the flag */
-SK_API extern void* sk_malloc_throw(size_t size);
-
-/** Much like calloc: returns a pointer to at least size zero bytes, or NULL on failure.
- */
-SK_API extern void* sk_calloc(size_t size);
-
-/** Same as sk_calloc, but throws an exception instead of returning NULL on failure.
- */
-SK_API extern void* sk_calloc_throw(size_t size);
-
-#else
 static inline void* sk_malloc_throw(size_t size) {
     return sk_malloc_flags(size, SK_MALLOC_THROW);
 }
@@ -80,14 +62,9 @@
 static inline void* sk_calloc_throw(size_t size) {
     return sk_malloc_flags(size, SK_MALLOC_THROW | SK_MALLOC_ZERO_INITIALIZE);
 }
-#endif
 
 static inline void* sk_calloc_canfail(size_t size) {
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-    return sk_calloc(size);
-#else
     return sk_malloc_flags(size, SK_MALLOC_ZERO_INITIALIZE);
-#endif
 }
 
 // Performs a safe multiply count * elemSize, checking for overflow
diff --git a/src/ports/SkMemory_malloc.cpp b/src/ports/SkMemory_malloc.cpp
index aa1cfac..206ee4f 100644
--- a/src/ports/SkMemory_malloc.cpp
+++ b/src/ports/SkMemory_malloc.cpp
@@ -66,31 +66,14 @@
 
 void* sk_malloc_flags(size_t size, unsigned flags) {
     void* p;
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-    p = malloc(size);
-#else
     if (flags & SK_MALLOC_ZERO_INITIALIZE) {
         p = calloc(size, 1);
     } else {
         p = malloc(size);
     }
-#endif
     if (flags & SK_MALLOC_THROW) {
         return throw_on_failure(size, p);
     } else {
         return p;
     }
 }
-
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-void* sk_malloc_throw(size_t size) {
-    return sk_malloc_flags(size, SK_MALLOC_THROW);
-}
-void* sk_calloc(size_t size) {
-    return calloc(size, 1);
-}
-void* sk_calloc_throw(size_t size) {
-    return throw_on_failure(size, sk_calloc(size));
-}
-#endif
-
diff --git a/src/ports/SkMemory_mozalloc.cpp b/src/ports/SkMemory_mozalloc.cpp
index e13b946..35b94de 100644
--- a/src/ports/SkMemory_mozalloc.cpp
+++ b/src/ports/SkMemory_mozalloc.cpp
@@ -31,25 +31,8 @@
 }
 
 void* sk_malloc_flags(size_t size, unsigned flags) {
-#ifndef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
     if (flags & SK_MALLOC_ZERO_INITIALIZE) {
         return (flags & SK_MALLOC_THROW) ? moz_xcalloc(size, 1) : calloc(size, 1);
     }
-#endif
     return (flags & SK_MALLOC_THROW) ? moz_xmalloc(size) : malloc(size);
 }
-
-#ifdef SK_SUPPORT_LEGACY_MALLOC_PORTING_LAYER
-void* sk_malloc_throw(size_t size) {
-    return sk_malloc_flags(size, SK_MALLOC_THROW);
-}
-
-void* sk_calloc(size_t size) {
-    return calloc(size, 1);
-}
-
-void* sk_calloc_throw(size_t size) {
-    return moz_xcalloc(size, 1);
-}
-#endif
-