Switch std::isfinite to SkIsFinite throughout Skia.

On Windows (clang-cl), using std::isfinite appears to be slower
than our old bit-manipulation code. This CL switches to SkIsFinite
roughly everywhere (modulo SkSL and a few other low-level places)
and replaces the SkIsFinite implementation with `(x - x) == 0`,
which appears to generate great code in Clang.

If metrics don't improve, we can go back to the bit masking
approach again.

Change-Id: I61dbf4545ef53031fe5ea492aa8c2f0a8c30c5cf
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/842240
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/include/core/SkM44.h b/include/core/SkM44.h
index 1613662..d8c77ea 100644
--- a/include/core/SkM44.h
+++ b/include/core/SkM44.h
@@ -375,7 +375,7 @@
 
         @return  true if matrix has only finite elements
     */
-    bool isFinite() const { return SkScalarsAreFinite(fMat, 16); }
+    bool isFinite() const { return SkIsFinite(fMat, 16); }
 
     /** If this is invertible, return that in inverse and return true. If it is
      *  not invertible, return false and leave the inverse parameter unchanged.
diff --git a/include/core/SkMatrix.h b/include/core/SkMatrix.h
index 96a12f1..10ee699 100644
--- a/include/core/SkMatrix.h
+++ b/include/core/SkMatrix.h
@@ -12,6 +12,7 @@
 #include "include/core/SkRect.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkMacros.h"
 #include "include/private/base/SkTo.h"
 
@@ -1830,7 +1831,7 @@
 
         @return  true if matrix has only finite elements
     */
-    bool isFinite() const { return SkScalarsAreFinite(fMat, 9); }
+    bool isFinite() const { return SkIsFinite(fMat, 9); }
 
 private:
     /** Set if the matrix will map a rectangle to another rectangle. This
diff --git a/include/core/SkPoint3.h b/include/core/SkPoint3.h
index c20a9a4..af2443e 100644
--- a/include/core/SkPoint3.h
+++ b/include/core/SkPoint3.h
@@ -10,7 +10,7 @@
 
 #include "include/core/SkScalar.h"
 #include "include/private/base/SkAPI.h"
-#include "include/private/base/SkAssert.h"
+#include "include/private/base/SkFloatingPoint.h"
 
 struct SK_API SkPoint3 {
     SkScalar fX, fY, fZ;
@@ -114,17 +114,7 @@
      @return  true for values other than infinities and NaN
      */
     bool isFinite() const {
-        SkScalar accum = 0;
-        accum *= fX;
-        accum *= fY;
-        accum *= fZ;
-
-        // accum is either NaN or it is finite (zero).
-        SkASSERT(0 == accum || SkScalarIsNaN(accum));
-
-        // value==value will be true iff value is not NaN
-        // TODO: is it faster to say !accum or accum==accum?
-        return !SkScalarIsNaN(accum);
+        return SkIsFinite(fX, fY) && SkIsFinite(fZ);
     }
 
     /** Returns the dot product of a and b, treating them as 3D vectors
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index 096c7e1..a07bc50 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -709,18 +709,7 @@
         @return  true if no member is infinite or NaN
     */
     bool isFinite() const {
-        float accum = 0;
-        accum *= fLeft;
-        accum *= fTop;
-        accum *= fRight;
-        accum *= fBottom;
-
-        // accum is either NaN or it is finite (zero).
-        SkASSERT(0 == accum || std::isnan(accum));
-
-        // value==value will be true iff value is not NaN
-        // TODO: is it faster to say !accum or accum==accum?
-        return !std::isnan(accum);
+        return SkIsFinite(fLeft, fTop) && SkIsFinite(fRight, fBottom);
     }
 
     /** Returns left edge of SkRect, if sorted. Call isSorted() to see if SkRect is valid.
diff --git a/include/core/SkScalar.h b/include/core/SkScalar.h
index 6ede6e6..94b1ad6 100644
--- a/include/core/SkScalar.h
+++ b/include/core/SkScalar.h
@@ -63,23 +63,17 @@
 #define SkScalarToDouble(x)     static_cast<double>(x)
 #define SkDoubleToScalar(x)     sk_double_to_float(x)
 
-static inline bool SkScalarIsNaN(SkScalar x) { return x != x; }
+// DEPRECATED: use std::isnan instead.
+static inline bool SkScalarIsNaN(SkScalar x) { return SkIsNaN(x); }
 
-/** Returns true if x is not NaN and not infinite
- */
-static inline bool SkScalarIsFinite(SkScalar x) { return std::isfinite(x); }
+// DEPRECATED: use std::isfinite instead.
+static inline bool SkScalarIsFinite(SkScalar x) { return SkIsFinite(x); }
 
-static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) {
-    // Subtracting a value from itself will result in zero, except for NAN or ±Inf, which make NAN.
-    // A NAN is not equal to any value, so a NAN or ±Inf in either `a` or `b` will cause the
-    // comparison to evaluate as false.
-    // If both `a` and `b` are finite, the comparison will reduce to `0 == 0`, which is true.
-    return (a - a) == (b - b);
-}
+// DEPRECATED: use std::isfinite instead.
+static inline bool SkScalarsAreFinite(SkScalar a, SkScalar b) { return SkIsFinite(a, b); }
 
-static inline bool SkScalarsAreFinite(const SkScalar array[], int count) {
-    return sk_floats_are_finite(array, count);
-}
+// DEPRECATED: use std::isfinite instead.
+static inline bool SkScalarsAreFinite(const SkScalar p[], int n) { return SkIsFinite(p, n); }
 
 /** Returns the fractional part of the scalar. */
 static inline SkScalar SkScalarFraction(SkScalar x) {
diff --git a/include/core/SkStrokeRec.h b/include/core/SkStrokeRec.h
index 7db4c79..8617b25 100644
--- a/include/core/SkStrokeRec.h
+++ b/include/core/SkStrokeRec.h
@@ -13,6 +13,7 @@
 #include "include/core/SkTypes.h"
 #include "include/private/base/SkMacros.h"
 
+#include <cmath>
 #include <cstdint>
 
 class SkPath;
@@ -72,7 +73,7 @@
     }
 
     void setResScale(SkScalar rs) {
-        SkASSERT(rs > 0 && SkScalarIsFinite(rs));
+        SkASSERT(rs > 0 && std::isfinite(rs));
         fResScale = rs;
     }
 
diff --git a/include/private/base/SkFloatingPoint.h b/include/private/base/SkFloatingPoint.h
index 8efa33c..2cdf75c 100644
--- a/include/private/base/SkFloatingPoint.h
+++ b/include/private/base/SkFloatingPoint.h
@@ -36,13 +36,54 @@
 // as floatf(x + .5f), they would be 1 higher than expected.
 #define sk_float_round(x) (float)sk_double_round((double)(x))
 
-static inline bool sk_floats_are_finite(const float array[], int count) {
-    float prod = 0;
+static inline bool SkIsNaN(float x) {
+    return x != x;
+}
+
+static inline bool SkIsNaN(double x) {
+    return x != x;
+}
+
+// Subtracting a value from itself will result in zero, except for NAN or ±Inf, which make NAN.
+// This generates better code than `std::isfinite` when building with clang-cl (April 2024).
+static inline bool SkIsFinite(float x) {
+    return (x - x) == 0;
+}
+
+static inline bool SkIsFinite(double x) {
+    return (x - x) == 0;
+}
+
+// Subtracting a value from itself will result in zero, except for NAN or ±Inf, which make NAN.
+// A NAN is not equal to any value, so a NAN or ±Inf in either `a` or `b` will cause the
+// comparison to evaluate as false.
+// If both `a` and `b` are finite, the comparison will reduce to `0 == 0`, which is true.
+static inline bool SkIsFinite(float a, float b) {
+    return (a - a) == (b - b);
+}
+
+static inline bool SkIsFinite(double a, double b) {
+    return (a - a) == (b - b);
+}
+
+// Multiplying a group of values against zero will result in zero at each iteration, except for
+// NAN or ±Inf, which will result in NAN and continue resulting in NAN for the rest of the loop.
+static inline bool SkIsFinite(const float array[], int count) {
+    float prod = 0.0f;
     for (int i = 0; i < count; ++i) {
         prod *= array[i];
     }
-    // At this point, prod will either be NaN or 0
-    return prod == 0;   // if prod is NaN, this check will return false
+    // At this point, prod will either be NaN or 0.
+    return prod == 0.0f;
+}
+
+static inline bool SkIsFinite(const double array[], int count) {
+    double prod = 0.0;
+    for (int i = 0; i < count; ++i) {
+        prod *= array[i];
+    }
+    // At this point, prod will either be NaN or 0.
+    return prod == 0.0;
 }
 
 inline constexpr int SK_MaxS32FitsInFloat = 2147483520;
diff --git a/include/private/base/SkPoint_impl.h b/include/private/base/SkPoint_impl.h
index 6385bbe..e3843b2 100644
--- a/include/private/base/SkPoint_impl.h
+++ b/include/private/base/SkPoint_impl.h
@@ -9,7 +9,7 @@
 #define SkPoint_DEFINED
 
 #include "include/private/base/SkAPI.h"
-#include "include/private/base/SkAssert.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSafe32.h"
 
 #include <cmath>
@@ -410,16 +410,7 @@
         @return  true for values other than infinities and NaN
     */
     bool isFinite() const {
-        float accum = 0;
-        accum *= fX;
-        accum *= fY;
-
-        // accum is either NaN or it is finite (zero).
-        SkASSERT(0 == accum || std::isnan(accum));
-
-        // value==value will be true iff value is not NaN
-        // TODO: is it faster to say !accum or accum==accum?
-        return !std::isnan(accum);
+        return SkIsFinite(fX, fY);
     }
 
     /** Returns true if SkPoint is equivalent to SkPoint constructed from (x, y).
diff --git a/modules/skottie/src/Skottie.cpp b/modules/skottie/src/Skottie.cpp
index b35d3d1..a33ff42 100644
--- a/modules/skottie/src/Skottie.cpp
+++ b/modules/skottie/src/Skottie.cpp
@@ -403,7 +403,7 @@
                duration = sk_ieee_float_divide(outPoint - inPoint, fps);
 
     if (size.isEmpty() || version.isEmpty() || fps <= 0 ||
-        !SkScalarIsFinite(inPoint) || !SkScalarIsFinite(outPoint) || !SkScalarIsFinite(duration)) {
+        !SkIsFinite(inPoint, outPoint) || !SkIsFinite(duration)) {
         if (fLogger) {
             const auto msg = SkStringPrintf(
                          "Invalid animation params (version: %s, size: [%f %f], frame rate: %f, "
diff --git a/modules/skottie/src/effects/LevelsEffect.cpp b/modules/skottie/src/effects/LevelsEffect.cpp
index 57f3d90..9b7a4a0 100644
--- a/modules/skottie/src/effects/LevelsEffect.cpp
+++ b/modules/skottie/src/effects/LevelsEffect.cpp
@@ -97,7 +97,7 @@
 
         for (size_t i = 0; i < 256; ++i) {
             const auto out = out_0 + dOut * std::pow(std::max(t, 0.0f), g);
-            SkASSERT(!SkScalarIsNaN(out));
+            SkASSERT(!SkIsNaN(out));
 
             lut_storage[i] = static_cast<uint8_t>(std::round(SkTPin(out, clip[0], clip[1]) * 255));
 
diff --git a/modules/skparagraph/include/TextStyle.h b/modules/skparagraph/include/TextStyle.h
index 607ac7c..4bc2fb9 100644
--- a/modules/skparagraph/include/TextStyle.h
+++ b/modules/skparagraph/include/TextStyle.h
@@ -22,14 +22,14 @@
 namespace textlayout {
 
 static inline bool nearlyZero(SkScalar x, SkScalar tolerance = SK_ScalarNearlyZero) {
-    if (SkScalarIsFinite(x)) {
+    if (SkIsFinite(x)) {
         return SkScalarNearlyZero(x, tolerance);
     }
     return false;
 }
 
 static inline bool nearlyEqual(SkScalar x, SkScalar y, SkScalar tolerance = SK_ScalarNearlyZero) {
-    if (SkScalarIsFinite(x) && SkScalarIsFinite(x)) {
+    if (SkIsFinite(x, y)) {
         return SkScalarNearlyEqual(x, y, tolerance);
     }
     // Inf == Inf, anything else is false
diff --git a/modules/skparagraph/src/ParagraphCache.cpp b/modules/skparagraph/src/ParagraphCache.cpp
index f9a3b84..f0ad958 100644
--- a/modules/skparagraph/src/ParagraphCache.cpp
+++ b/modules/skparagraph/src/ParagraphCache.cpp
@@ -14,7 +14,7 @@
 namespace {
     int32_t relax(SkScalar a) {
         // This rounding is done to match Flutter tests. Must be removed..
-        if (SkScalarIsFinite(a)) {
+        if (SkIsFinite(a)) {
           auto threshold = SkIntToScalar(1 << 12);
           return SkFloat2Bits(SkScalarRoundToScalar(a * threshold)/threshold);
         } else {
diff --git a/modules/skparagraph/src/ParagraphImpl.cpp b/modules/skparagraph/src/ParagraphImpl.cpp
index f394e8a..eec5557 100644
--- a/modules/skparagraph/src/ParagraphImpl.cpp
+++ b/modules/skparagraph/src/ParagraphImpl.cpp
@@ -141,7 +141,7 @@
         floorWidth = SkScalarFloorToScalar(floorWidth);
     }
 
-    if ((!SkScalarIsFinite(rawWidth) || fLongestLine <= floorWidth) &&
+    if ((!SkIsFinite(rawWidth) || fLongestLine <= floorWidth) &&
         fState >= kLineBroken &&
          fLines.size() == 1 && fLines.front().ellipsis() == nullptr) {
         // Most common case: one line of text (and one line is never justified, so no cluster shifts)
@@ -672,7 +672,7 @@
     const bool isLeftAligned = effectiveAlign == TextAlign::kLeft
         || (effectiveAlign == TextAlign::kJustify && fParagraphStyle.getTextDirection() == TextDirection::kLtr);
 
-    if (!SkScalarIsFinite(maxWidth) && !isLeftAligned) {
+    if (!SkIsFinite(maxWidth) && !isLeftAligned) {
         // Special case: clean all text in case of maxWidth == INF & align != left
         // We had to go through shaping though because we need all the measurement numbers
         fLines.clear();
diff --git a/modules/skparagraph/src/TextLine.cpp b/modules/skparagraph/src/TextLine.cpp
index 1052607..fc7e6d4 100644
--- a/modules/skparagraph/src/TextLine.cpp
+++ b/modules/skparagraph/src/TextLine.cpp
@@ -783,7 +783,7 @@
         return result;
     } else if (run->isPlaceholder()) {
         result.fTextShift = runOffsetInLine;
-        if (SkScalarIsFinite(run->fFontMetrics.fAscent)) {
+        if (SkIsFinite(run->fFontMetrics.fAscent)) {
           result.clip = SkRect::MakeXYWH(runOffsetInLine,
                                          sizes().runTop(run, this->fAscentStyle),
                                          run->advance().fX,
diff --git a/modules/skparagraph/src/TextWrapper.cpp b/modules/skparagraph/src/TextWrapper.cpp
index f3ce9cd..ca4d7dc 100644
--- a/modules/skparagraph/src/TextWrapper.cpp
+++ b/modules/skparagraph/src/TextWrapper.cpp
@@ -288,7 +288,7 @@
     auto maxLines = parent->paragraphStyle().getMaxLines();
     auto align = parent->paragraphStyle().effective_align();
     auto unlimitedLines = maxLines == std::numeric_limits<size_t>::max();
-    auto endlessLine = !SkScalarIsFinite(maxWidth);
+    auto endlessLine = !SkIsFinite(maxWidth);
     auto hasEllipsis = parent->paragraphStyle().ellipsized();
 
     auto disableFirstAscent = parent->paragraphStyle().getTextHeightBehavior() & TextHeightBehavior::kDisableFirstAscent;
diff --git a/modules/skparagraph/tests/SkParagraphTest.cpp b/modules/skparagraph/tests/SkParagraphTest.cpp
index 5be79bd..62d6c9e 100644
--- a/modules/skparagraph/tests/SkParagraphTest.cpp
+++ b/modules/skparagraph/tests/SkParagraphTest.cpp
@@ -6001,8 +6001,8 @@
     paragraph->paint(canvas.get(), 0, 0);
 
     auto impl = static_cast<ParagraphImpl*>(paragraph.get());
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(impl->getPicture()->cullRect().height()));
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(impl->getPicture()->cullRect().width()));
+    REPORTER_ASSERT(reporter, SkIsFinite(impl->getPicture()->cullRect().height()));
+    REPORTER_ASSERT(reporter, SkIsFinite(impl->getPicture()->cullRect().width()));
 }
 
 UNIX_ONLY_TEST(SkParagraph_LineMetricsTextAlign, reporter) {
diff --git a/src/base/SkCubics.cpp b/src/base/SkCubics.cpp
index 64a4beb..4fba299 100644
--- a/src/base/SkCubics.cpp
+++ b/src/base/SkCubics.cpp
@@ -78,7 +78,7 @@
     // If one of R2 Q3 is infinite or nan, subtracting them will also be infinite/nan.
     // If both are infinite or nan, the subtraction will be nan.
     // In either case, we have no finite roots.
-    if (!std::isfinite(R2MinusQ3)) {
+    if (!SkIsFinite(R2MinusQ3)) {
         return 0;
     }
     double adiv3 = a / 3;
@@ -180,7 +180,7 @@
         return start;
     }
     double right = SkCubics::EvalAt(A, B, C, D, stop);
-    if (!std::isfinite(left) || !std::isfinite(right)) {
+    if (!SkIsFinite(left, right)) {
         return -1; // Not going to deal with one or more endpoints being non-finite.
     }
     if ((left > 0 && right > 0) || (left < 0 && right < 0)) {
@@ -207,7 +207,7 @@
 
 int SkCubics::BinarySearchRootsValidT(double A, double B, double C, double D,
                                       double solution[3]) {
-    if (!std::isfinite(A) || !std::isfinite(B) || !std::isfinite(C) || !std::isfinite(D)) {
+    if (!SkIsFinite(A, B) || !SkIsFinite(C, D)) {
         return 0;
     }
     double regions[4] = {0, 0, 0, 1};
diff --git a/src/base/SkVx.h b/src/base/SkVx.h
index b40a8fb..33999ff 100644
--- a/src/base/SkVx.h
+++ b/src/base/SkVx.h
@@ -1003,7 +1003,7 @@
 SINT bool isfinite(const Vec<N, T>& v) {
     // Multiply all values together with 0. If they were all finite, the output is
     // 0 (also finite). If any were not, we'll get nan.
-    return std::isfinite(dot(v, Vec<N, T>(0)));
+    return SkIsFinite(dot(v, Vec<N, T>(0)));
 }
 
 // De-interleaving load of 4 vectors.
diff --git a/src/core/SkBlurMaskFilterImpl.cpp b/src/core/SkBlurMaskFilterImpl.cpp
index aa3d1de..045ae82 100644
--- a/src/core/SkBlurMaskFilterImpl.cpp
+++ b/src/core/SkBlurMaskFilterImpl.cpp
@@ -27,6 +27,7 @@
 #include "include/effects/SkImageFilters.h"
 #include "include/private/base/SkAlign.h"
 #include "include/private/base/SkAssert.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTemplates.h"
 #include "src/base/SkTLazy.h"
 #include "src/core/SkBlitter_A8.h"
@@ -532,7 +533,7 @@
 void sk_register_blur_maskfilter_createproc() { SK_REGISTER_FLATTENABLE(SkBlurMaskFilterImpl); }
 
 sk_sp<SkMaskFilter> SkMaskFilter::MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM) {
-    if (SkScalarIsFinite(sigma) && sigma > 0) {
+    if (SkIsFinite(sigma) && sigma > 0) {
         return sk_sp<SkMaskFilter>(new SkBlurMaskFilterImpl(sigma, style, respectCTM));
     }
     return nullptr;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 7f9ad01..d39ef07 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -35,6 +35,7 @@
 #include "include/core/SkTypes.h"
 #include "include/core/SkVertices.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSafe32.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTemplates.h"
@@ -2076,7 +2077,7 @@
 static bool fillable(const SkRect& r) {
     SkScalar w = r.width();
     SkScalar h = r.height();
-    return SkScalarIsFinite(w) && w > 0 && SkScalarIsFinite(h) && h > 0;
+    return SkIsFinite(w, h) && w > 0 && h > 0;
 }
 
 static SkPaint clean_paint_for_lattice(const SkPaint* paint) {
diff --git a/src/core/SkContourMeasure.cpp b/src/core/SkContourMeasure.cpp
index 1f1bf9c..8c88119 100644
--- a/src/core/SkContourMeasure.cpp
+++ b/src/core/SkContourMeasure.cpp
@@ -437,7 +437,7 @@
 
     }
 
-    if (!SkScalarIsFinite(distance)) {
+    if (!SkIsFinite(distance)) {
         return nullptr;
     }
     if (fSegments.empty()) {
@@ -605,7 +605,7 @@
 }
 
 bool SkContourMeasure::getPosTan(SkScalar distance, SkPoint* pos, SkVector* tangent) const {
-    if (SkScalarIsNaN(distance)) {
+    if (SkIsNaN(distance)) {
         return false;
     }
 
@@ -621,7 +621,7 @@
 
     SkScalar        t;
     const Segment*  seg = this->distanceToSegment(distance, &t);
-    if (SkScalarIsNaN(t)) {
+    if (SkIsNaN(t)) {
         return false;
     }
 
@@ -672,11 +672,11 @@
     SkPoint  p;
     SkScalar startT, stopT;
     const Segment* seg = this->distanceToSegment(startD, &startT);
-    if (!SkScalarIsFinite(startT)) {
+    if (!SkIsFinite(startT)) {
         return false;
     }
     const Segment* stopSeg = this->distanceToSegment(stopD, &stopT);
-    if (!SkScalarIsFinite(stopT)) {
+    if (!SkIsFinite(stopT)) {
         return false;
     }
     SkASSERT(seg <= stopSeg);
diff --git a/src/core/SkDraw.cpp b/src/core/SkDraw.cpp
index f0ba91e..78ba942 100644
--- a/src/core/SkDraw.cpp
+++ b/src/core/SkDraw.cpp
@@ -18,6 +18,7 @@
 #include "include/private/base/SkAssert.h"
 #include "include/private/base/SkDebug.h"
 #include "include/private/base/SkFixed.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTemplates.h"
 #include "include/private/base/SkTo.h"
 #include "src/base/SkArenaAlloc.h"
@@ -265,7 +266,7 @@
                 n = MAX_DEV_PTS;
             }
             fCTM->mapPoints(devPts, pts, n);
-            if (!SkScalarsAreFinite(&devPts[0].fX, n * 2)) {
+            if (!SkIsFinite(&devPts[0].fX, n * 2)) {
                 return;
             }
             proc(rec, devPts, n, bltr);
diff --git a/src/core/SkDrawBase.cpp b/src/core/SkDrawBase.cpp
index 2c4a70a..4dce30d 100644
--- a/src/core/SkDrawBase.cpp
+++ b/src/core/SkDrawBase.cpp
@@ -20,6 +20,7 @@
 #include "include/private/base/SkAssert.h"
 #include "include/private/base/SkCPUTypes.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTemplates.h"
 #include "src/base/SkTLazy.h"
 #include "src/base/SkZip.h"
@@ -610,7 +611,7 @@
     }
 
     // needed?
-    if (!SkScalarsAreFinite(&pts[0].fX, count * 2)) {
+    if (!SkIsFinite(&pts[0].fX, count * 2)) {
         return;
     }
 
diff --git a/src/core/SkDraw_vertices.cpp b/src/core/SkDraw_vertices.cpp
index 48bb030..132988f 100644
--- a/src/core/SkDraw_vertices.cpp
+++ b/src/core/SkDraw_vertices.cpp
@@ -335,7 +335,7 @@
         dev3 = outerAlloc.makeArray<SkPoint3>(vertexCount);
         fCTM->mapHomogeneousPoints(dev3, info.positions(), vertexCount);
         // similar to the bounds check for 2d points (below)
-        if (!SkScalarsAreFinite((const SkScalar*)dev3, vertexCount * 3)) {
+        if (!SkIsFinite((const SkScalar*)dev3, vertexCount * 3)) {
             return;
         }
     } else {
diff --git a/src/core/SkEdgeBuilder.cpp b/src/core/SkEdgeBuilder.cpp
index 4cc560a..0be077b 100644
--- a/src/core/SkEdgeBuilder.cpp
+++ b/src/core/SkEdgeBuilder.cpp
@@ -13,6 +13,7 @@
 #include "include/core/SkTypes.h"
 #include "include/private/base/SkDebug.h"
 #include "include/private/base/SkFixed.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSafe32.h"
 #include "include/private/base/SkTo.h"
 #include "src/base/SkSafeMath.h"
@@ -320,7 +321,7 @@
 
             while ((verb = clipper->next(pts)) != SkPath::kDone_Verb) {
                 const int count = SkPathPriv::PtsInIter(verb);
-                if (!SkScalarsAreFinite(&pts[0].fX, count*2)) {
+                if (!SkIsFinite(&pts[0].fX, count*2)) {
                     rec->fIsFinite = false;
                     return;
                 }
diff --git a/src/core/SkFont.cpp b/src/core/SkFont.cpp
index b079a53..7bb8235 100644
--- a/src/core/SkFont.cpp
+++ b/src/core/SkFont.cpp
@@ -19,6 +19,7 @@
 #include "include/core/SkTypeface.h"
 #include "include/core/SkTypes.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkPoint_impl.h"
 #include "include/private/base/SkSpan_impl.h"
 #include "include/private/base/SkTemplates.h"
@@ -369,7 +370,7 @@
     } else {
         // approximate the scale since we can't get it directly from the matrix
         SkScalar maxScaleSq = SkMatrixPriv::DifferentialAreaScale(matrix, textLocation);
-        if (SkScalarIsFinite(maxScaleSq) && !SkScalarNearlyZero(maxScaleSq)) {
+        if (SkIsFinite(maxScaleSq) && !SkScalarNearlyZero(maxScaleSq)) {
             return font.getSize() * SkScalarSqrt(maxScaleSq);
         } else {
             return -font.getSize();
diff --git a/src/core/SkFontPriv.h b/src/core/SkFontPriv.h
index 03a6e50..7c2808f 100644
--- a/src/core/SkFontPriv.h
+++ b/src/core/SkFontPriv.h
@@ -76,9 +76,9 @@
                                                    const SkPoint& textLocation);
 
     static bool IsFinite(const SkFont& font) {
-        return SkScalarIsFinite(font.getSize()) &&
-               SkScalarIsFinite(font.getScaleX()) &&
-               SkScalarIsFinite(font.getSkewX());
+        return SkIsFinite(font.getSize()) &&
+               SkIsFinite(font.getScaleX()) &&
+               SkIsFinite(font.getSkewX());
     }
 
     // Returns the number of elements (characters or glyphs) in the array.
diff --git a/src/core/SkGeometry.cpp b/src/core/SkGeometry.cpp
index 70976a6..b935310 100644
--- a/src/core/SkGeometry.cpp
+++ b/src/core/SkGeometry.cpp
@@ -64,7 +64,7 @@
     }
 
     SkScalar r = numer / denom;
-    if (SkScalarIsNaN(r)) {
+    if (SkIsNaN(r)) {
         return 0;
     }
     SkASSERTF(r >= 0 && r < SK_Scalar1, "numer %f, denom %f, r %f", numer, denom, r);
@@ -108,7 +108,7 @@
     }
     dr = sqrt(dr);
     SkScalar R = SkDoubleToScalar(dr);
-    if (!SkScalarIsFinite(R)) {
+    if (!SkIsFinite(R)) {
         return return_check_zero(0);
     }
 
@@ -360,7 +360,7 @@
         return 1;
     }
     SkScalar t = numer / denom;
-    SkASSERT((0 <= t && t < 1) || SkScalarIsNaN(t));
+    SkASSERT((0 <= t && t < 1) || SkIsNaN(t));
     return t;
 }
 
@@ -1322,7 +1322,7 @@
     dst[1].fW = tmp2[2].fZ / root;
     SkASSERT(sizeof(dst[0]) == sizeof(SkScalar) * 7);
     SkASSERT(0 == offsetof(SkConic, fPts[0].fX));
-    return SkScalarsAreFinite(&dst[0].fPts[0].fX, 7 * 2);
+    return SkIsFinite(&dst[0].fPts[0].fX, 7 * 2);
 }
 
 void SkConic::chopAt(SkScalar t1, SkScalar t2, SkConic* dst) const {
@@ -1486,7 +1486,7 @@
 #define kMaxConicToQuadPOW2     5
 
 int SkConic::computeQuadPOW2(SkScalar tol) const {
-    if (tol < 0 || !SkScalarIsFinite(tol) || !SkPointPriv::AreFinite(fPts, 3)) {
+    if (tol < 0 || !SkIsFinite(tol) || !SkPointPriv::AreFinite(fPts, 3)) {
         return 0;
     }
 
@@ -1782,7 +1782,7 @@
     const SkPoint finalP = { x, y };
     const SkPoint& lastQ = quadrantPts[quadrant * 2];  // will already be a unit-vector
     const SkScalar dot = SkVector::DotProduct(lastQ, finalP);
-    if (SkScalarIsNaN(dot)) {
+    if (SkIsNaN(dot)) {
         return 0;
     }
     SkASSERT(0 <= dot && dot <= SK_Scalar1 + SK_ScalarNearlyZero);
diff --git a/src/core/SkGeometry.h b/src/core/SkGeometry.h
index 5a84035..f597aad 100644
--- a/src/core/SkGeometry.h
+++ b/src/core/SkGeometry.h
@@ -11,6 +11,7 @@
 #include "include/core/SkPoint.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/base/SkVx.h"
 
 #include <cstring>
@@ -348,12 +349,12 @@
     }
 
     void setW(SkScalar w) {
-        if (SkScalarIsFinite(w)) {
+        if (SkIsFinite(w)) {
             SkASSERT(w > 0);
         }
 
         // Guard against bad weights by forcing them to 1.
-        fW = w > 0 && SkScalarIsFinite(w) ? w : 1;
+        fW = w > 0 && SkIsFinite(w) ? w : 1;
     }
 
     /**
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index 14481dc..806e8b3 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -22,6 +22,7 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSpan_impl.h"
 #include "include/private/base/SkTArray.h"
 #include "src/core/SkGlyph.h"
@@ -64,7 +65,7 @@
     int rejectedSize = 0;
     strike->lock();
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
         const SkPackedGlyphID packedID{glyphID};
@@ -95,7 +96,7 @@
     int rejectedSize = 0;
     strike->lock();
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
         const SkPackedGlyphID packedID{glyphID};
@@ -133,7 +134,7 @@
     int rejectedSize = 0;
     strike->lock();
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
diff --git a/src/core/SkImageFilterTypes.cpp b/src/core/SkImageFilterTypes.cpp
index 55251b4..da41408 100644
--- a/src/core/SkImageFilterTypes.cpp
+++ b/src/core/SkImageFilterTypes.cpp
@@ -98,7 +98,7 @@
         // Perspective, which has a non-uniform scaling effect on the filter. Pick a single scale
         // factor that best matches where the filter will be evaluated.
         SkScalar approxScale = SkMatrixPriv::DifferentialAreaScale(transform, representativePoint);
-        if (SkScalarIsFinite(approxScale) && !SkScalarNearlyZero(approxScale)) {
+        if (SkIsFinite(approxScale) && !SkScalarNearlyZero(approxScale)) {
             // Now take the sqrt to go from an area scale factor to a scaling per X and Y
             approxScale = SkScalarSqrt(approxScale);
         } else {
diff --git a/src/core/SkImageFilterTypes.h b/src/core/SkImageFilterTypes.h
index 43b2116..f86af4c 100644
--- a/src/core/SkImageFilterTypes.h
+++ b/src/core/SkImageFilterTypes.h
@@ -21,6 +21,7 @@
 #include "include/core/SkSurfaceProps.h"
 #include "include/core/SkTileMode.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTArray.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTo.h"
@@ -75,7 +76,7 @@
     Vector(SkScalar x, SkScalar y) : fX(x), fY(y) {}
     explicit Vector(const SkVector& v) : fX(v.fX), fY(v.fY) {}
 
-    bool isFinite() const { return SkScalarsAreFinite(fX, fY); }
+    bool isFinite() const { return SkIsFinite(fX, fY); }
 };
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkM44.cpp b/src/core/SkM44.cpp
index 7d7f6e4..9e9dd53 100644
--- a/src/core/SkM44.cpp
+++ b/src/core/SkM44.cpp
@@ -278,7 +278,7 @@
 
 SkM44& SkM44::setRotate(SkV3 axis, SkScalar radians) {
     SkScalar len = axis.length();
-    if (len > 0 && SkScalarIsFinite(len)) {
+    if (len > 0 && SkIsFinite(len)) {
         this->setRotateUnit(axis * (SK_Scalar1 / len), radians);
     } else {
         this->setIdentity();
diff --git a/src/core/SkMatrix.cpp b/src/core/SkMatrix.cpp
index 245a0ab..bfaf915 100644
--- a/src/core/SkMatrix.cpp
+++ b/src/core/SkMatrix.cpp
@@ -823,7 +823,7 @@
                 SkScalar invY = sk_ieee_float_divide(1.f, fMat[kMScaleY]);
                 // Denormalized (non-zero) scale factors will overflow when inverted, in which case
                 // the inverse matrix would not be finite, so return false.
-                if (!SkScalarsAreFinite(invX, invY)) {
+                if (!SkIsFinite(invX, invY)) {
                     return false;
                 }
 
@@ -1497,7 +1497,7 @@
             results[1] = apluscdiv2 + x;
         }
     }
-    if (!SkScalarIsFinite(results[0])) {
+    if (!SkIsFinite(results[0])) {
         return false;
     }
     // Due to the floating point inaccuracy, there might be an error in a, b, c
@@ -1508,7 +1508,7 @@
     }
     results[0] = SkScalarSqrt(results[0]);
     if (kBoth_MinMaxOrBoth == MIN_MAX_OR_BOTH) {
-        if (!SkScalarIsFinite(results[1])) {
+        if (!SkIsFinite(results[1])) {
             return false;
         }
         if (results[1] < 0) {
@@ -1563,7 +1563,7 @@
 
     const SkScalar sx = SkVector::Length(this->getScaleX(), this->getSkewY());
     const SkScalar sy = SkVector::Length(this->getSkewX(), this->getScaleY());
-    if (!SkScalarIsFinite(sx) || !SkScalarIsFinite(sy) ||
+    if (!SkIsFinite(sx) || !SkIsFinite(sy) ||
         SkScalarNearlyZero(sx) || SkScalarNearlyZero(sy)) {
         return false;
     }
@@ -1878,7 +1878,7 @@
     // Not sure how to handle perspective differently, so we just don't try (yet)
     SkScalar sx = SkPoint::Length(matrix[SkMatrix::kMScaleX], matrix[SkMatrix::kMSkewY]);
     SkScalar sy = SkPoint::Length(matrix[SkMatrix::kMSkewX],  matrix[SkMatrix::kMScaleY]);
-    if (SkScalarsAreFinite(sx, sy)) {
+    if (SkIsFinite(sx, sy)) {
         SkScalar scale = std::max(sx, sy);
         if (scale > 0) {
             return scale;
diff --git a/src/core/SkMatrixInvert.cpp b/src/core/SkMatrixInvert.cpp
index ea8d367..7fe20b1 100644
--- a/src/core/SkMatrixInvert.cpp
+++ b/src/core/SkMatrixInvert.cpp
@@ -25,7 +25,7 @@
         outMatrix[3] =  a00 * invdet;
         // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
         // values is non-finite, return zero to indicate a non-invertible matrix.
-        if (!SkScalarsAreFinite(outMatrix, 4)) {
+        if (!SkIsFinite(outMatrix, 4)) {
             determinant = 0.0f;
         }
     }
@@ -62,7 +62,7 @@
         outMatrix[8] = ( a11 * a00 - a01 * a10) * invdet;
         // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
         // values is non-finite, return zero to indicate a non-invertible matrix.
-        if (!SkScalarsAreFinite(outMatrix, 9)) {
+        if (!SkIsFinite(outMatrix, 9)) {
             determinant = 0.0f;
         }
     }
@@ -136,7 +136,7 @@
 
         // If 1/det overflows to infinity (i.e. det is denormalized) or any of the inverted matrix
         // values is non-finite, return zero to indicate a non-invertible matrix.
-        if (!SkScalarsAreFinite(outMatrix, 16)) {
+        if (!SkIsFinite(outMatrix, 16)) {
             determinant = 0.0f;
         }
     }
diff --git a/src/core/SkMipmap.cpp b/src/core/SkMipmap.cpp
index ba2d548..5a46c53 100644
--- a/src/core/SkMipmap.cpp
+++ b/src/core/SkMipmap.cpp
@@ -205,13 +205,13 @@
     const float scale = std::sqrt(scaleSize.width() * scaleSize.height());
 #endif
 
-    if (scale >= SK_Scalar1 || scale <= 0 || !SkScalarIsFinite(scale)) {
+    if (scale >= SK_Scalar1 || scale <= 0 || !SkIsFinite(scale)) {
         return -1;
     }
 
     // The -0.5 bias here is to emulate GPU's sharpen mipmap option.
     float L = std::max(-SkScalarLog2(scale) - 0.5f, 0.f);
-    if (!SkScalarIsFinite(L)) {
+    if (!SkIsFinite(L)) {
         return -1;
     }
     return L;
diff --git a/src/core/SkPath.cpp b/src/core/SkPath.cpp
index 3ca857a..bd21fc8 100644
--- a/src/core/SkPath.cpp
+++ b/src/core/SkPath.cpp
@@ -754,7 +754,7 @@
     // check for <= 0 or NaN with this test
     if (!(w > 0)) {
         this->lineTo(x2, y2);
-    } else if (!SkScalarIsFinite(w)) {
+    } else if (!SkIsFinite(w)) {
         this->lineTo(x1, y1);
         this->lineTo(x2, y2);
     } else if (SK_Scalar1 == w) {
@@ -1309,7 +1309,7 @@
     int segments = SkScalarCeilToInt(SkScalarAbs(thetaArc / (2 * SK_ScalarPI / 3)));
     SkScalar thetaWidth = thetaArc / segments;
     SkScalar t = SkScalarTan(0.5f * thetaWidth);
-    if (!SkScalarIsFinite(t)) {
+    if (!SkIsFinite(t)) {
         return *this;
     }
     SkScalar startTheta = theta1;
@@ -1807,8 +1807,8 @@
         // A special case: if both points are NaN, SkPoint::operation== returns
         // false, but the iterator expects that they are treated as the same.
         // (consider SkPoint is a 2-dimension float point).
-        if (SkScalarIsNaN(fLastPt.fX) || SkScalarIsNaN(fLastPt.fY) ||
-            SkScalarIsNaN(fMoveTo.fX) || SkScalarIsNaN(fMoveTo.fY)) {
+        if (SkIsNaN(fLastPt.fX) || SkIsNaN(fLastPt.fY) ||
+            SkIsNaN(fMoveTo.fX) || SkIsNaN(fMoveTo.fY)) {
             return kClose_Verb;
         }
 
@@ -2225,7 +2225,7 @@
 private:
     DirChange directionChange(const SkVector& curVec) {
         SkScalar cross = SkPoint::CrossProduct(fLastVec, curVec);
-        if (!SkScalarIsFinite(cross)) {
+        if (!SkIsFinite(cross)) {
                 return kUnknown_DirChange;
         }
         if (cross == 0) {
@@ -3760,7 +3760,7 @@
         b *= dscale;
         c *= dscale;
         // check if we're not finite, or normal is zero-length
-        if (!std::isfinite(a) || !std::isfinite(b) || !std::isfinite(c) ||
+        if (!SkIsFinite(a, b) || !SkIsFinite(c) ||
             (a == 0 && b == 0)) {
             fA = fB = 0;
             fC = SK_Scalar1;
diff --git a/src/core/SkPathBuilder.cpp b/src/core/SkPathBuilder.cpp
index 4a2ef01..c0b7899 100644
--- a/src/core/SkPathBuilder.cpp
+++ b/src/core/SkPathBuilder.cpp
@@ -10,6 +10,7 @@
 #include "include/core/SkMatrix.h"
 #include "include/core/SkRRect.h"
 #include "include/private/SkPathRef.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSafe32.h"
 #include "src/base/SkVx.h"
 #include "src/core/SkGeometry.h"
@@ -541,7 +542,7 @@
     int segments = SkScalarCeilToInt(SkScalarAbs(thetaArc / (2 * SK_ScalarPI / 3)));
     SkScalar thetaWidth = thetaArc / segments;
     SkScalar t = SkScalarTan(0.5f * thetaWidth);
-    if (!SkScalarIsFinite(t)) {
+    if (!SkIsFinite(t)) {
         return *this;
     }
     SkScalar startTheta = theta1;
diff --git a/src/core/SkPoint.cpp b/src/core/SkPoint.cpp
index 9409f36..6538320 100644
--- a/src/core/SkPoint.cpp
+++ b/src/core/SkPoint.cpp
@@ -53,7 +53,7 @@
     x *= dscale;
     y *= dscale;
     // check if we're not finite, or we're zero-length
-    if (!std::isfinite(x) || !std::isfinite(y) || (x == 0 && y == 0)) {
+    if (!SkIsFinite(x, y) || (x == 0 && y == 0)) {
         pt->set(0, 0);
         return false;
     }
@@ -78,7 +78,7 @@
 
 float SkPoint::Length(float dx, float dy) {
     float mag2 = dx * dx + dy * dy;
-    if (std::isfinite(mag2)) {
+    if (SkIsFinite(mag2)) {
         return std::sqrt(mag2);
     } else {
         double xx = dx;
@@ -117,7 +117,7 @@
     temp *= det;
     // It's possible we have a degenerate line vector, or we're so far away it looks degenerate
     // In this case, return squared distance to point A.
-    if (!std::isfinite(temp)) {
+    if (!SkIsFinite(temp)) {
         return LengthSqd(v);
     }
     return temp;
@@ -160,7 +160,7 @@
         temp *= det;
         // It's possible we have a degenerate segment, or we're so far away it looks degenerate
         // In this case, return squared distance to point A.
-        if (!std::isfinite(temp)) {
+        if (!SkIsFinite(temp)) {
             return LengthSqd(v);
         }
         return temp;
diff --git a/src/core/SkPoint3.cpp b/src/core/SkPoint3.cpp
index c5e5b6d..bb573a5 100644
--- a/src/core/SkPoint3.cpp
+++ b/src/core/SkPoint3.cpp
@@ -6,6 +6,7 @@
  */
 
 #include "include/core/SkPoint3.h"
+#include "include/private/base/SkFloatingPoint.h"
 
 #include <cmath>
 
@@ -27,7 +28,7 @@
 
 SkScalar SkPoint3::Length(SkScalar x, SkScalar y, SkScalar z) {
     float magSq = get_length_squared(x, y, z);
-    if (SkScalarIsFinite(magSq)) {
+    if (SkIsFinite(magSq)) {
         return std::sqrt(magSq);
     } else {
         double xx = x;
@@ -54,7 +55,7 @@
     // sqrtf does not provide enough precision; since sqrt takes a double,
     // there's no additional penalty to storing invScale in a double
     double invScale;
-    if (std::isfinite(magSq)) {
+    if (SkIsFinite(magSq)) {
         invScale = magSq;
     } else {
         // our magSq step overflowed to infinity, so use doubles instead.
@@ -70,7 +71,7 @@
     fX *= scale;
     fY *= scale;
     fZ *= scale;
-    if (!std::isfinite(fX) || !std::isfinite(fY) || !std::isfinite(fZ)) {
+    if (!SkIsFinite(fX, fY) || !SkIsFinite(fZ)) {
         this->set(0, 0, 0);
         return false;
     }
diff --git a/src/core/SkPointPriv.h b/src/core/SkPointPriv.h
index c8a6d52..b607f67 100644
--- a/src/core/SkPointPriv.h
+++ b/src/core/SkPointPriv.h
@@ -20,13 +20,13 @@
     };
 
     static bool AreFinite(const SkPoint array[], int count) {
-        return SkScalarsAreFinite(&array[0].fX, count << 1);
+        return SkIsFinite(&array[0].fX, count << 1);
     }
 
     static const SkScalar* AsScalars(const SkPoint& pt) { return &pt.fX; }
 
     static bool CanNormalize(SkScalar dx, SkScalar dy) {
-        return SkScalarsAreFinite(dx, dy) && (dx || dy);
+        return SkIsFinite(dx, dy) && (dx || dy);
     }
 
     static SkScalar DistanceToLineBetweenSqd(const SkPoint& pt, const SkPoint& a,
diff --git a/src/core/SkRRect.cpp b/src/core/SkRRect.cpp
index 57991b7..2b4d76f 100644
--- a/src/core/SkRRect.cpp
+++ b/src/core/SkRRect.cpp
@@ -54,7 +54,7 @@
         return;
     }
 
-    if (!SkScalarsAreFinite(xRad, yRad)) {
+    if (!SkIsFinite(xRad, yRad)) {
         xRad = yRad = 0;    // devolve into a simple rect
     }
 
@@ -118,8 +118,7 @@
         return;
     }
 
-    const SkScalar array[4] = { leftRad, topRad, rightRad, bottomRad };
-    if (!SkScalarsAreFinite(array, 4)) {
+    if (!SkIsFinite(leftRad, topRad) || !SkIsFinite(rightRad, bottomRad)) {
         this->setRect(rect);    // devolve into a simple rect
         return;
     }
@@ -192,7 +191,7 @@
         return;
     }
 
-    if (!SkScalarsAreFinite(&radii[0].fX, 8)) {
+    if (!SkIsFinite(&radii[0].fX, 8)) {
         this->setRect(rect);    // devolve into a simple rect
         return;
     }
diff --git a/src/core/SkScan_Hairline.cpp b/src/core/SkScan_Hairline.cpp
index 7b5473e..d389a5d 100644
--- a/src/core/SkScan_Hairline.cpp
+++ b/src/core/SkScan_Hairline.cpp
@@ -13,6 +13,7 @@
 #include "include/core/SkScalar.h"
 #include "include/private/base/SkAssert.h"
 #include "include/private/base/SkFixed.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkMath.h"
 #include "include/private/base/SkSafe32.h"
 #include "src/base/SkMathPriv.h"
@@ -278,7 +279,7 @@
 }
 
 static SkRect compute_nocheck_quad_bounds(const SkPoint pts[3]) {
-    SkASSERT(SkScalarsAreFinite(&pts[0].fX, 6));
+    SkASSERT(SkIsFinite(&pts[0].fX, 6));
 
     float2 min = float2::Load(pts);
     float2 max = min;
@@ -411,7 +412,7 @@
 }
 
 static SkRect compute_nocheck_cubic_bounds(const SkPoint pts[4]) {
-    SkASSERT(SkScalarsAreFinite(&pts[0].fX, 8));
+    SkASSERT(SkIsFinite(&pts[0].fX, 8));
 
     float2 min = float2::Load(pts);
     float2 max = min;
diff --git a/src/core/SkString.cpp b/src/core/SkString.cpp
index 08aac66..53c1d9a 100644
--- a/src/core/SkString.cpp
+++ b/src/core/SkString.cpp
@@ -8,6 +8,7 @@
 #include "include/core/SkString.h"
 
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkMalloc.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTo.h"
@@ -163,11 +164,11 @@
 char* SkStrAppendScalar(char string[], SkScalar value) {
     // Handle infinity and NaN ourselves to ensure consistent cross-platform results.
     // (e.g.: `inf` versus `1.#INF00`, `nan` versus `-nan` for high-bit-set NaNs)
-    if (SkScalarIsNaN(value)) {
+    if (SkIsNaN(value)) {
         strcpy(string, "nan");
         return string + 3;
     }
-    if (!SkScalarIsFinite(value)) {
+    if (!SkIsFinite(value)) {
         if (value > 0) {
             strcpy(string, "inf");
             return string + 3;
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index 4d607f7..b442ca3 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -697,7 +697,7 @@
     // SkFindConicMaxCurvature would be a better solution, once we know how to
     // implement it. Quad curvature is a reasonable substitute
     SkScalar t = SkFindQuadMaxCurvature(conic.fPts);
-    if (0 == t || SkScalarIsNaN(t)) {
+    if (0 == t || SkIsNaN(t)) {
         return kLine_ReductionType;
     }
     conic.evalAt(t, reduction, nullptr);
@@ -925,7 +925,7 @@
              byLen  * axLen         -   ayLen          * bxLen         ( == denom )
      */
     SkScalar denom = aLen.cross(bLen);
-    if (denom == 0 || !SkScalarIsFinite(denom)) {
+    if (denom == 0 || !SkIsFinite(denom)) {
         quadPts->fOppositeTangents = aLen.dot(bLen) < 0;
         return STROKER_RESULT(kDegenerate_ResultType, depth, quadPts, "denom == 0");
     }
@@ -1183,7 +1183,7 @@
             }
         }
     }
-    if (!SkScalarIsFinite(quadPts->fQuad[2].fX) || !SkScalarIsFinite(quadPts->fQuad[2].fY)) {
+    if (!SkIsFinite(quadPts->fQuad[2].fX) || !SkIsFinite(quadPts->fQuad[2].fY)) {
         DEBUG_CUBIC_RECURSION_TRACK_DEPTH(fRecursionDepth);
         return false;  // just abort if projected quad isn't representable
     }
diff --git a/src/core/SkStroke.h b/src/core/SkStroke.h
index ff98784..3587348 100644
--- a/src/core/SkStroke.h
+++ b/src/core/SkStroke.h
@@ -14,6 +14,7 @@
 #include "include/private/base/SkAssert.h"
 #include "include/private/base/SkTo.h"
 
+#include <cmath>
 #include <cstdint>
 
 class SkPath;
@@ -37,11 +38,11 @@
     SkStroke(const SkPaint&);
     SkStroke(const SkPaint&, SkScalar width);   // width overrides paint.getStrokeWidth()
 
-    SkPaint::Cap    getCap() const { return (SkPaint::Cap)fCap; }
-    void        setCap(SkPaint::Cap);
+    SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; }
+    void         setCap(SkPaint::Cap);
 
-    SkPaint::Join   getJoin() const { return (SkPaint::Join)fJoin; }
-    void        setJoin(SkPaint::Join);
+    SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; }
+    void          setJoin(SkPaint::Join);
 
     void    setMiterLimit(SkScalar);
     void    setWidth(SkScalar);
@@ -59,7 +60,7 @@
      */
     SkScalar getResScale() const { return fResScale; }
     void setResScale(SkScalar rs) {
-        SkASSERT(rs > 0 && SkScalarIsFinite(rs));
+        SkASSERT(rs > 0 && std::isfinite(rs));
         fResScale = rs;
     }
 
diff --git a/src/core/SkValidationUtils.h b/src/core/SkValidationUtils.h
index 491f202..5acb286 100644
--- a/src/core/SkValidationUtils.h
+++ b/src/core/SkValidationUtils.h
@@ -28,8 +28,7 @@
 static inline bool SkIsValidRect(const SkRect& rect) {
     return (rect.fLeft <= rect.fRight) &&
            (rect.fTop <= rect.fBottom) &&
-           SkScalarIsFinite(rect.width()) &&
-           SkScalarIsFinite(rect.height());
+           SkIsFinite(rect.width(), rect.height());
 }
 
 #endif
diff --git a/src/effects/Sk1DPathEffect.cpp b/src/effects/Sk1DPathEffect.cpp
index 98da0d4..969f162 100644
--- a/src/effects/Sk1DPathEffect.cpp
+++ b/src/effects/Sk1DPathEffect.cpp
@@ -17,6 +17,7 @@
 #include "include/core/SkScalar.h"
 #include "include/core/SkStrokeRec.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkPathEffectBase.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
@@ -248,7 +249,7 @@
 
 sk_sp<SkPathEffect> SkPath1DPathEffect::Make(const SkPath& path, SkScalar advance, SkScalar phase,
                                              Style style) {
-    if (advance <= 0 || !SkScalarIsFinite(advance) || !SkScalarIsFinite(phase) || path.isEmpty()) {
+    if (advance <= 0 || !SkIsFinite(advance, phase) || path.isEmpty()) {
         return nullptr;
     }
     return sk_sp<SkPathEffect>(new SkPath1DPathEffectImpl(path, advance, phase, style));
diff --git a/src/effects/SkBlenders.cpp b/src/effects/SkBlenders.cpp
index b3680b1..d82da2b 100644
--- a/src/effects/SkBlenders.cpp
+++ b/src/effects/SkBlenders.cpp
@@ -14,16 +14,14 @@
 #include "include/core/SkData.h"
 #include "include/core/SkScalar.h"
 #include "include/effects/SkRuntimeEffect.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkKnownRuntimeEffects.h"
 
 sk_sp<SkBlender> SkBlenders::Arithmetic(float k1, float k2, float k3, float k4,
                                         bool enforcePremul) {
     using namespace SkKnownRuntimeEffects;
 
-    if (!SkScalarIsFinite(k1) ||
-        !SkScalarIsFinite(k2) ||
-        !SkScalarIsFinite(k3) ||
-        !SkScalarIsFinite(k4)) {
+    if (!SkIsFinite(k1, k2) || !SkIsFinite(k3, k4)) {
         return nullptr;
     }
 
diff --git a/src/effects/SkCornerPathEffect.cpp b/src/effects/SkCornerPathEffect.cpp
index e19c6c6..a301072 100644
--- a/src/effects/SkCornerPathEffect.cpp
+++ b/src/effects/SkCornerPathEffect.cpp
@@ -14,6 +14,7 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkPathEffectBase.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
@@ -178,7 +179,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 sk_sp<SkPathEffect> SkCornerPathEffect::Make(SkScalar radius) {
-    return SkScalarIsFinite(radius) && (radius > 0) ?
+    return SkIsFinite(radius) && (radius > 0) ?
             sk_sp<SkPathEffect>(new SkCornerPathEffectImpl(radius)) : nullptr;
 }
 
diff --git a/src/effects/SkDashPathEffect.cpp b/src/effects/SkDashPathEffect.cpp
index 49ed5fe..e5755c9 100644
--- a/src/effects/SkDashPathEffect.cpp
+++ b/src/effects/SkDashPathEffect.cpp
@@ -16,6 +16,7 @@
 #include "include/core/SkRect.h"
 #include "include/core/SkStrokeRec.h"
 #include "include/private/base/SkAlign.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkMalloc.h"
 #include "include/private/base/SkTemplates.h"
 #include "include/private/base/SkTo.h"
@@ -272,7 +273,7 @@
         // otherwise cause the results->fPoints allocation below to OOM.
         // Cap it to a sane value.
         SkScalar numIntervals = len2 / fIntervalLength;
-        if (!SkScalarIsFinite(numIntervals) || numIntervals > SkDashPath::kMaxDashCount) {
+        if (!SkIsFinite(numIntervals) || numIntervals > SkDashPath::kMaxDashCount) {
             return false;
         }
         int numMidPoints = SkScalarFloorToInt(numIntervals);
diff --git a/src/effects/SkDiscretePathEffect.cpp b/src/effects/SkDiscretePathEffect.cpp
index 727ca4ae..a019791 100644
--- a/src/effects/SkDiscretePathEffect.cpp
+++ b/src/effects/SkDiscretePathEffect.cpp
@@ -17,6 +17,7 @@
 #include "include/core/SkTypes.h"
 #include "include/effects/SkDiscretePathEffect.h"
 #include "include/private/base/SkFixed.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkPathEffectBase.h"
 #include "src/core/SkPointPriv.h"
 #include "src/core/SkReadBuffer.h"
@@ -80,8 +81,8 @@
     SkDiscretePathEffectImpl(SkScalar segLength, SkScalar deviation, uint32_t seedAssist)
         : fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
     {
-        SkASSERT(SkScalarIsFinite(segLength));
-        SkASSERT(SkScalarIsFinite(deviation));
+        SkASSERT(SkIsFinite(segLength));
+        SkASSERT(SkIsFinite(deviation));
         SkASSERT(segLength > SK_ScalarNearlyZero);
     }
 
@@ -177,7 +178,7 @@
 
 sk_sp<SkPathEffect> SkDiscretePathEffect::Make(SkScalar segLength, SkScalar deviation,
                                                uint32_t seedAssist) {
-    if (!SkScalarIsFinite(segLength) || !SkScalarIsFinite(deviation)) {
+    if (!SkIsFinite(segLength, deviation)) {
         return nullptr;
     }
     if (segLength <= SK_ScalarNearlyZero) {
diff --git a/src/effects/SkEmbossMaskFilter.cpp b/src/effects/SkEmbossMaskFilter.cpp
index febd715..3d431f8 100644
--- a/src/effects/SkEmbossMaskFilter.cpp
+++ b/src/effects/SkEmbossMaskFilter.cpp
@@ -12,6 +12,7 @@
 #include "include/core/SkPoint.h"
 #include "include/core/SkPoint3.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkBlurMask.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
@@ -24,7 +25,7 @@
 #include <cstring>
 
 sk_sp<SkMaskFilter> SkEmbossMaskFilter::Make(SkScalar blurSigma, const Light& light) {
-    if (!SkScalarIsFinite(blurSigma) || blurSigma <= 0) {
+    if (!SkIsFinite(blurSigma) || blurSigma <= 0) {
         return nullptr;
     }
 
@@ -66,7 +67,7 @@
     : fLight(light), fBlurSigma(blurSigma)
 {
     SkASSERT(fBlurSigma > 0);
-    SkASSERT(SkScalarsAreFinite(fLight.fDirection, 3));
+    SkASSERT(SkIsFinite(fLight.fDirection, 3));
 }
 
 SkMask::Format SkEmbossMaskFilter::getFormat() const {
diff --git a/src/effects/SkTrimPathEffect.cpp b/src/effects/SkTrimPathEffect.cpp
index abd2522..b5e1e16 100644
--- a/src/effects/SkTrimPathEffect.cpp
+++ b/src/effects/SkTrimPathEffect.cpp
@@ -14,6 +14,7 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkScalar.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTPin.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
@@ -130,7 +131,7 @@
 //////////////////////////////////////////////////////////////////////////////////////////////////
 
 sk_sp<SkPathEffect> SkTrimPathEffect::Make(SkScalar startT, SkScalar stopT, Mode mode) {
-    if (!SkScalarsAreFinite(startT, stopT)) {
+    if (!SkIsFinite(startT, stopT)) {
         return nullptr;
     }
 
diff --git a/src/effects/colorfilters/SkMatrixColorFilter.cpp b/src/effects/colorfilters/SkMatrixColorFilter.cpp
index 18a2187..2bad15c 100644
--- a/src/effects/colorfilters/SkMatrixColorFilter.cpp
+++ b/src/effects/colorfilters/SkMatrixColorFilter.cpp
@@ -90,7 +90,7 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 static sk_sp<SkColorFilter> MakeMatrix(const float array[20], SkMatrixColorFilter::Domain domain) {
-    if (!sk_floats_are_finite(array, 20)) {
+    if (!SkIsFinite(array, 20)) {
         return nullptr;
     }
     return sk_make_sp<SkMatrixColorFilter>(array, domain);
diff --git a/src/effects/colorfilters/SkRuntimeColorFilter.cpp b/src/effects/colorfilters/SkRuntimeColorFilter.cpp
index 2d8693d..687e23d 100644
--- a/src/effects/colorfilters/SkRuntimeColorFilter.cpp
+++ b/src/effects/colorfilters/SkRuntimeColorFilter.cpp
@@ -13,7 +13,6 @@
 #include "include/core/SkColorFilter.h"
 #include "include/core/SkData.h"
 #include "include/core/SkMatrix.h"
-#include "include/core/SkScalar.h"
 #include "include/core/SkString.h"
 #include "include/effects/SkLumaColorFilter.h"
 #include "include/effects/SkOverdrawColorFilter.h"
@@ -21,6 +20,7 @@
 #include "include/private/SkColorData.h"
 #include "include/private/SkSLSampleUsage.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTArray.h"
 #include "src/core/SkEffectPriv.h"
 #include "src/core/SkKnownRuntimeEffects.h"
@@ -120,7 +120,7 @@
     if (!cf0 && !cf1) {
         return nullptr;
     }
-    if (SkScalarIsNaN(weight)) {
+    if (SkIsNaN(weight)) {
         return nullptr;
     }
 
diff --git a/src/effects/imagefilters/SkBlurImageFilter.cpp b/src/effects/imagefilters/SkBlurImageFilter.cpp
index 291c33c..7a0550b 100644
--- a/src/effects/imagefilters/SkBlurImageFilter.cpp
+++ b/src/effects/imagefilters/SkBlurImageFilter.cpp
@@ -107,7 +107,7 @@
 sk_sp<SkImageFilter> SkImageFilters::Blur(
         SkScalar sigmaX, SkScalar sigmaY, SkTileMode tileMode, sk_sp<SkImageFilter> input,
         const CropRect& cropRect) {
-    if (!SkScalarsAreFinite(sigmaX, sigmaY) || sigmaX < 0.f || sigmaY < 0.f) {
+    if (!SkIsFinite(sigmaX, sigmaY) || sigmaX < 0.f || sigmaY < 0.f) {
         // Non-finite or negative sigmas are error conditions. We allow 0 sigma for X and/or Y
         // for 1D blurs; onFilterImage() will detect when no visible blurring would occur based on
         // the Context mapping.
@@ -987,7 +987,7 @@
 
     // Disable bluring on axes that are not finite, or that are small enough that the blur is
     // effectively an identity.
-    if (!SkScalarIsFinite(sigma.width()) || (!gpuBacked && calculate_window(sigma.width()) <= 1)
+    if (!SkIsFinite(sigma.width()) || (!gpuBacked && calculate_window(sigma.width()) <= 1)
 #if defined(SK_GANESH) || defined(SK_GRAPHITE)
         || (gpuBacked && skgpu::BlurIsEffectivelyIdentity(sigma.width()))
 #endif
@@ -995,7 +995,7 @@
         sigma = skif::LayerSpace<SkSize>({0.f, sigma.height()});
     }
 
-    if (!SkScalarIsFinite(sigma.height()) || (!gpuBacked && calculate_window(sigma.height()) <= 1)
+    if (!SkIsFinite(sigma.height()) || (!gpuBacked && calculate_window(sigma.height()) <= 1)
 #if defined(SK_GANESH) || defined(SK_GRAPHITE)
         || (gpuBacked && skgpu::BlurIsEffectivelyIdentity(sigma.height()))
 #endif
diff --git a/src/effects/imagefilters/SkLightingImageFilter.cpp b/src/effects/imagefilters/SkLightingImageFilter.cpp
index 08f05a7..38fde08 100644
--- a/src/effects/imagefilters/SkLightingImageFilter.cpp
+++ b/src/effects/imagefilters/SkLightingImageFilter.cpp
@@ -20,6 +20,7 @@
 #include "include/core/SkTypes.h"
 #include "include/effects/SkRuntimeEffect.h"
 #include "include/private/base/SkCPUTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkSpan_impl.h"
 #include "src/core/SkImageFilterTypes.h"
 #include "src/core/SkImageFilter_Base.h"
@@ -281,19 +282,16 @@
                                    const SkImageFilters::CropRect& cropRect) {
     // According to the spec, ks and kd can be any non-negative number:
     // http://www.w3.org/TR/SVG/filters.html#feSpecularLightingElement
-    if (!SkScalarIsFinite(material.fK) || material.fK < 0.f ||
-        !SkScalarIsFinite(material.fShininess) ||
-        !SkScalarIsFinite(ZValue(material.fSurfaceDepth))) {
+    if (!SkIsFinite(material.fK) || material.fK < 0.f ||
+        !SkIsFinite(material.fShininess, ZValue(material.fSurfaceDepth))) {
         return nullptr;
     }
 
     // Ensure light values are finite, and the cosine should be between -1 and 1
     if (!SkPoint(light.fLocationXY).isFinite() ||
-        !SkScalarIsFinite(ZValue(light.fLocationZ)) ||
         !skif::Vector(light.fDirectionXY).isFinite() ||
-        !SkScalarIsFinite(ZValue(light.fDirectionZ)) ||
-        !SkScalarIsFinite(light.fFalloffExponent) ||
-        !SkScalarIsFinite(light.fCosCutoffAngle) ||
+        !SkIsFinite(ZValue(light.fLocationZ), ZValue(light.fDirectionZ)) ||
+        !SkIsFinite(light.fFalloffExponent, light.fCosCutoffAngle) ||
         light.fCosCutoffAngle < -1.f || light.fCosCutoffAngle > 1.f) {
         return nullptr;
     }
diff --git a/src/effects/imagefilters/SkMagnifierImageFilter.cpp b/src/effects/imagefilters/SkMagnifierImageFilter.cpp
index 399e36e..9d85d03 100644
--- a/src/effects/imagefilters/SkMagnifierImageFilter.cpp
+++ b/src/effects/imagefilters/SkMagnifierImageFilter.cpp
@@ -21,6 +21,7 @@
 #include "include/core/SkSpan.h"
 #include "include/core/SkTypes.h"
 #include "include/effects/SkRuntimeEffect.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/core/SkImageFilterTypes.h"
 #include "src/core/SkImageFilter_Base.h"
 #include "src/core/SkKnownRuntimeEffects.h"
@@ -85,8 +86,8 @@
                                                sk_sp<SkImageFilter> input,
                                                const CropRect& cropRect) {
     if (lensBounds.isEmpty() || !lensBounds.isFinite() ||
-        zoomAmount <= 0.f || !SkScalarIsFinite(zoomAmount) ||
-        inset < 0.f || !SkScalarIsFinite(inset)) {
+        zoomAmount <= 0.f || inset < 0.f ||
+        !SkIsFinite(zoomAmount, inset)) {
         return nullptr; // invalid
     }
     // The magnifier automatically restricts its output based on the size of the image it receives
diff --git a/src/gpu/BlurUtils.cpp b/src/gpu/BlurUtils.cpp
index afbac5f..f8773d4 100644
--- a/src/gpu/BlurUtils.cpp
+++ b/src/gpu/BlurUtils.cpp
@@ -274,8 +274,8 @@
 }
 
 int ComputeIntegralTableWidth(float sixSigma) {
-    // Check for NaN
-    if (std::isnan(sixSigma)) {
+    // Check for NaN/infinity
+    if (!SkIsFinite(sixSigma)) {
         return 0;
     }
     // Avoid overflow, covers both multiplying by 2 and finding next power of 2:
diff --git a/src/gpu/ganesh/GrBlurUtils.cpp b/src/gpu/ganesh/GrBlurUtils.cpp
index e2d6c24..4e987b2 100644
--- a/src/gpu/ganesh/GrBlurUtils.cpp
+++ b/src/gpu/ganesh/GrBlurUtils.cpp
@@ -424,7 +424,7 @@
                                                                   float* solidRadius,
                                                                   float* textureRadius) {
     float circleR = circle.width() / 2.0f;
-    if (!std::isfinite(circleR) || circleR < SK_ScalarNearlyZero) {
+    if (!SkIsFinite(circleR) || circleR < SK_ScalarNearlyZero) {
         return nullptr;
     }
 
diff --git a/src/gpu/ganesh/geometry/GrAAConvexTessellator.cpp b/src/gpu/ganesh/geometry/GrAAConvexTessellator.cpp
index 606508b..20cfbde 100644
--- a/src/gpu/ganesh/geometry/GrAAConvexTessellator.cpp
+++ b/src/gpu/ganesh/geometry/GrAAConvexTessellator.cpp
@@ -50,7 +50,7 @@
         return false;
     }
     *t = (v.fX * n1.fY - v.fY * n1.fX) / perpDot;
-    return SkScalarIsFinite(*t);
+    return SkIsFinite(*t);
 }
 
 // This is a special case version of intersect where we have the vector
@@ -64,7 +64,7 @@
         return false;
     }
     *t = v.dot(perp) / perpDot;
-    return SkScalarIsFinite(*t);
+    return SkIsFinite(*t);
 }
 
 static bool duplicate_pt(const SkPoint& p0, const SkPoint& p1) {
diff --git a/src/gpu/ganesh/geometry/GrPathUtils.cpp b/src/gpu/ganesh/geometry/GrPathUtils.cpp
index 937a90b..9e8307a 100644
--- a/src/gpu/ganesh/geometry/GrPathUtils.cpp
+++ b/src/gpu/ganesh/geometry/GrPathUtils.cpp
@@ -17,7 +17,6 @@
 #include "src/gpu/tessellate/WangsFormula.h"
 
 #include <algorithm>
-#include <cmath>
 
 using namespace skia_private;
 
@@ -161,7 +160,7 @@
     double a8 = x0*y1-x1*y0;
     double det = a2 + a5 + a8;
 
-    if (!std::isfinite(det)
+    if (!SkIsFinite(det)
         || SkScalarNearlyZero((float)det, SK_ScalarNearlyZero * SK_ScalarNearlyZero)) {
         // The quad is degenerate. Hopefully this is rare. Find the pts that are
         // farthest apart to compute a line (unless it is really a pt).
@@ -498,7 +497,7 @@
     if (!p[0].isFinite() || !p[1].isFinite() || !p[2].isFinite() || !p[3].isFinite()) {
         return;
     }
-    if (!SkScalarIsFinite(tolScale)) {
+    if (!SkIsFinite(tolScale)) {
         return;
     }
     SkPoint chopped[10];
@@ -519,7 +518,7 @@
     if (!p[0].isFinite() || !p[1].isFinite() || !p[2].isFinite() || !p[3].isFinite()) {
         return;
     }
-    if (!SkScalarIsFinite(tolScale)) {
+    if (!SkIsFinite(tolScale)) {
         return;
     }
     SkPoint chopped[10];
diff --git a/src/gpu/ganesh/geometry/GrQuad.h b/src/gpu/ganesh/geometry/GrQuad.h
index 97a5a40..8048f8b 100644
--- a/src/gpu/ganesh/geometry/GrQuad.h
+++ b/src/gpu/ganesh/geometry/GrQuad.h
@@ -100,8 +100,9 @@
             accum *= fY[i];
             accum *= fW[i];
         }
-        SkASSERT(0 == accum || SkScalarIsNaN(accum));
-        return !SkScalarIsNaN(accum);
+        SkASSERT(0 == accum || SkIsNaN(accum));
+
+        return accum == 0.0f;
     }
 
     float x(int i) const { return fX[i]; }
diff --git a/src/gpu/ganesh/geometry/GrTriangulator.cpp b/src/gpu/ganesh/geometry/GrTriangulator.cpp
index dd215bb..6e5ffdd 100644
--- a/src/gpu/ganesh/geometry/GrTriangulator.cpp
+++ b/src/gpu/ganesh/geometry/GrTriangulator.cpp
@@ -10,6 +10,7 @@
 #include "include/core/SkPathTypes.h"
 #include "include/core/SkRect.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkMath.h"
 #include "include/private/base/SkTPin.h"
 #include "src/base/SkVx.h"
@@ -519,8 +520,7 @@
                                          int pointsLeft) const {
     SkScalar d1 = SkPointPriv::DistanceToLineSegmentBetweenSqd(p1, p0, p3);
     SkScalar d2 = SkPointPriv::DistanceToLineSegmentBetweenSqd(p2, p0, p3);
-    if (pointsLeft < 2 || (d1 < tolSqd && d2 < tolSqd) ||
-        !SkScalarIsFinite(d1) || !SkScalarIsFinite(d2)) {
+    if (pointsLeft < 2 || (d1 < tolSqd && d2 < tolSqd) || !SkIsFinite(d1, d2)) {
         this->appendPointToContour(p3, contour);
         return;
     }
diff --git a/src/gpu/ganesh/ops/AAConvexPathRenderer.cpp b/src/gpu/ganesh/ops/AAConvexPathRenderer.cpp
index 32c7d0f..300dddd 100644
--- a/src/gpu/ganesh/ops/AAConvexPathRenderer.cpp
+++ b/src/gpu/ganesh/ops/AAConvexPathRenderer.cpp
@@ -120,7 +120,7 @@
         // undo the translate of p0 to the origin.
         *c = center + p0;
     }
-    return !SkScalarIsNaN(c->fX) && !SkScalarIsNaN(c->fY) && c->isFinite();
+    return !SkIsNaN(c->fX) && !SkIsNaN(c->fY) && c->isFinite();
 }
 
 bool compute_vectors(SegmentArray* segments,
diff --git a/src/gpu/ganesh/ops/AAHairLinePathRenderer.cpp b/src/gpu/ganesh/ops/AAHairLinePathRenderer.cpp
index 360c5ec..5769931 100644
--- a/src/gpu/ganesh/ops/AAHairLinePathRenderer.cpp
+++ b/src/gpu/ganesh/ops/AAHairLinePathRenderer.cpp
@@ -514,7 +514,7 @@
 
     SkScalar wInv = normA.fX * normB.fY - normA.fY * normB.fX;
     wInv = sk_ieee_float_divide(1.0f, wInv);
-    if (!SkScalarIsFinite(wInv)) {
+    if (!SkIsFinite(wInv)) {
         // lines are parallel, pick the point in between
         *result = (ptA + ptB)*SK_ScalarHalf;
         *result += normA;
diff --git a/src/gpu/graphite/ClipStack_graphite.cpp b/src/gpu/graphite/ClipStack_graphite.cpp
index 0a0ac6f..8eceb55 100644
--- a/src/gpu/graphite/ClipStack_graphite.cpp
+++ b/src/gpu/graphite/ClipStack_graphite.cpp
@@ -1114,7 +1114,7 @@
     }
 
     auto origSize = geometry.bounds().size();
-    if (!std::isfinite(origSize.x()) || !std::isfinite(origSize.y())) {
+    if (!SkIsFinite(origSize.x(), origSize.y())) {
         // Discard all non-finite geometry as if it were clipped out
         return kClippedOut;
     }
@@ -1141,7 +1141,7 @@
     // Some renderers make the drawn area larger than the geometry for anti-aliasing
     float rendererOutset = outsetBoundsForAA ? localToDevice.localAARadius(styledShape->bounds())
                                              : 0.f;
-    if (!SkScalarIsFinite(rendererOutset)) {
+    if (!SkIsFinite(rendererOutset)) {
         transformedShapeBounds = deviceBounds;
         infiniteBounds = true;
     } else {
diff --git a/src/gpu/graphite/geom/Transform.cpp b/src/gpu/graphite/geom/Transform.cpp
index 128f2db..a4abbcb 100644
--- a/src/gpu/graphite/geom/Transform.cpp
+++ b/src/gpu/graphite/geom/Transform.cpp
@@ -231,7 +231,7 @@
     // transformation moves between [1,max/min] so using 1/min as the local AA radius ensures that
     // the post-transformed point is at least 1px away from the original.
     float aaRadius = sk_ieee_float_divide(1.f, min);
-    if (std::isfinite(aaRadius)) {
+    if (SkIsFinite(aaRadius)) {
         return aaRadius;
     } else {
         return SK_FloatInfinity;
diff --git a/src/gpu/graphite/geom/Transform_graphite.h b/src/gpu/graphite/geom/Transform_graphite.h
index ed35300..f9b8cea 100644
--- a/src/gpu/graphite/geom/Transform_graphite.h
+++ b/src/gpu/graphite/geom/Transform_graphite.h
@@ -56,7 +56,7 @@
     static inline Transform Translate(float x, float y) {
         if (x == 0.f && y == 0.f) {
             return Identity();
-        } else if (SkScalarsAreFinite(x, y)) {
+        } else if (SkIsFinite(x, y)) {
             return Transform(SkM44::Translate(x, y), SkM44::Translate(-x, -y),
                              Type::kSimpleRectStaysRect, 1.f, 1.f);
         } else {
diff --git a/src/pathops/SkOpEdgeBuilder.cpp b/src/pathops/SkOpEdgeBuilder.cpp
index 7078f2d..ffdd07c 100644
--- a/src/pathops/SkOpEdgeBuilder.cpp
+++ b/src/pathops/SkOpEdgeBuilder.cpp
@@ -9,6 +9,7 @@
 #include "include/core/SkPath.h"
 #include "include/core/SkPoint.h"
 #include "include/core/SkTypes.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/base/SkTSort.h"
 #include "src/core/SkGeometry.h"
 #include "src/core/SkPathPriv.h"
@@ -217,7 +218,7 @@
                         if (SkChopQuadAtMaxCurvature(pointsPtr, pair) == 1) {
                             goto addOneQuad;
                         }
-                        if (!SkScalarsAreFinite(&pair[0].fX, std::size(pair) * 2)) {
+                        if (!SkIsFinite(&pair[0].fX, std::size(pair) * 2)) {
                             return false;
                         }
                         for (unsigned index = 0; index < std::size(pair); ++index) {
diff --git a/src/pathops/SkPathOpsCubic.cpp b/src/pathops/SkPathOpsCubic.cpp
index 138072d..64e0ad6 100644
--- a/src/pathops/SkPathOpsCubic.cpp
+++ b/src/pathops/SkPathOpsCubic.cpp
@@ -6,6 +6,7 @@
  */
 #include "src/pathops/SkPathOpsCubic.h"
 
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTo.h"
 #include "src/base/SkTSort.h"
@@ -728,7 +729,7 @@
             cubic[index] = 0;
         }
     }
-    return SkScalarsAreFinite(&pts->fX, kPointCount * 2);
+    return SkIsFinite(&pts->fX, kPointCount * 2);
 }
 
 double SkDCubic::top(const SkDCubic& dCurve, double startT, double endT, SkDPoint*topPt) const {
diff --git a/src/pathops/SkPathOpsDebug.cpp b/src/pathops/SkPathOpsDebug.cpp
index 1e686ac..ef00cac 100644
--- a/src/pathops/SkPathOpsDebug.cpp
+++ b/src/pathops/SkPathOpsDebug.cpp
@@ -415,22 +415,22 @@
         if (glitch.fOppEndSpan) {
             SkDebugf(" oppEndSpan=%d", glitch.fOppEndSpan->debugID());
         }
-        if (!SkScalarIsNaN(glitch.fStartT)) {
+        if (!SkIsNaN(glitch.fStartT)) {
             SkDebugf(" startT=%g", glitch.fStartT);
         }
-        if (!SkScalarIsNaN(glitch.fEndT)) {
+        if (!SkIsNaN(glitch.fEndT)) {
             SkDebugf(" endT=%g", glitch.fEndT);
         }
         if (glitch.fOppSegment) {
             SkDebugf(" segment=%d", glitch.fOppSegment->debugID());
         }
-        if (!SkScalarIsNaN(glitch.fOppStartT)) {
+        if (!SkIsNaN(glitch.fOppStartT)) {
             SkDebugf(" oppStartT=%g", glitch.fOppStartT);
         }
-        if (!SkScalarIsNaN(glitch.fOppEndT)) {
+        if (!SkIsNaN(glitch.fOppEndT)) {
             SkDebugf(" oppEndT=%g", glitch.fOppEndT);
         }
-        if (!SkScalarIsNaN(glitch.fPt.fX) || !SkScalarIsNaN(glitch.fPt.fY)) {
+        if (!SkIsNaN(glitch.fPt.fX) || !SkIsNaN(glitch.fPt.fY)) {
             SkDebugf(" pt=%g,%g", glitch.fPt.fX, glitch.fPt.fY);
         }
         DumpGlitchType(glitch.fType);
diff --git a/src/pathops/SkPathOpsPoint.h b/src/pathops/SkPathOpsPoint.h
index 9d70df0..053192b 100644
--- a/src/pathops/SkPathOpsPoint.h
+++ b/src/pathops/SkPathOpsPoint.h
@@ -95,7 +95,7 @@
     }
 
     bool isFinite() const {
-        return std::isfinite(fX) && std::isfinite(fY);
+        return SkIsFinite(fX, fY);
     }
 };
 
diff --git a/src/pathops/SkPathOpsTypes.cpp b/src/pathops/SkPathOpsTypes.cpp
index e516b1d..76147dc 100644
--- a/src/pathops/SkPathOpsTypes.cpp
+++ b/src/pathops/SkPathOpsTypes.cpp
@@ -40,7 +40,7 @@
 }
 
 static bool equal_ulps_pin(float a, float b, int epsilon, int depsilon) {
-    if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
+    if (!SkIsFinite(a, b)) {
         return false;
     }
     if (arguments_denormalized(a, b, depsilon)) {
@@ -70,7 +70,7 @@
 }
 
 static bool not_equal_ulps_pin(float a, float b, int epsilon) {
-    if (!SkScalarIsFinite(a) || !SkScalarIsFinite(b)) {
+    if (!SkIsFinite(a, b)) {
         return false;
     }
     if (arguments_denormalized(a, b, epsilon)) {
diff --git a/src/shaders/SkColorShader.cpp b/src/shaders/SkColorShader.cpp
index 1ade7ca..90b5754 100644
--- a/src/shaders/SkColorShader.cpp
+++ b/src/shaders/SkColorShader.cpp
@@ -11,8 +11,8 @@
 #include "include/core/SkColorSpace.h"
 #include "include/core/SkData.h"
 #include "include/core/SkFlattenable.h"
-#include "include/core/SkScalar.h"
 #include "include/core/SkShader.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTPin.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "src/core/SkColorSpaceXformSteps.h"
@@ -103,7 +103,7 @@
 sk_sp<SkShader> Color(SkColor color) { return sk_make_sp<SkColorShader>(color); }
 
 sk_sp<SkShader> Color(const SkColor4f& color, sk_sp<SkColorSpace> space) {
-    if (!SkScalarsAreFinite(color.vec(), 4)) {
+    if (!SkIsFinite(color.vec(), 4)) {
         return nullptr;
     }
     return sk_make_sp<SkColor4Shader>(color, std::move(space));
diff --git a/src/shaders/SkPerlinNoiseShaderImpl.cpp b/src/shaders/SkPerlinNoiseShaderImpl.cpp
index d4780b6..e843763 100644
--- a/src/shaders/SkPerlinNoiseShaderImpl.cpp
+++ b/src/shaders/SkPerlinNoiseShaderImpl.cpp
@@ -119,7 +119,7 @@
     if (tileSize && !(tileSize->width() >= 0 && tileSize->height() >= 0)) {
         return false;
     }
-    if (!SkScalarIsFinite(seed)) {
+    if (!SkIsFinite(seed)) {
         return false;
     }
     return true;
diff --git a/src/shaders/SkPictureShader.cpp b/src/shaders/SkPictureShader.cpp
index b776dfc..924e536 100644
--- a/src/shaders/SkPictureShader.cpp
+++ b/src/shaders/SkPictureShader.cpp
@@ -19,6 +19,7 @@
 #include "include/core/SkSurface.h"
 #include "include/core/SkTileMode.h"
 #include "include/private/base/SkDebug.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "src/base/SkArenaAlloc.h"
 #include "src/core/SkEffectPriv.h"
 #include "src/core/SkImageInfoPriv.h"
@@ -191,7 +192,7 @@
         if (!totalM.decomposeScale(&size, nullptr)) {
             SkPoint center = {bounds.centerX(), bounds.centerY()};
             SkScalar area = SkMatrixPriv::DifferentialAreaScale(totalM, center);
-            if (!SkScalarIsFinite(area) || SkScalarNearlyZero(area)) {
+            if (!SkIsFinite(area) || SkScalarNearlyZero(area)) {
                 size = {1, 1};  // ill-conditioned matrix
             } else {
                 size.fWidth = size.fHeight = SkScalarSqrt(area);
diff --git a/src/shaders/gradients/SkGradientBaseShader.cpp b/src/shaders/gradients/SkGradientBaseShader.cpp
index 6cbdf02..d45d691 100644
--- a/src/shaders/gradients/SkGradientBaseShader.cpp
+++ b/src/shaders/gradients/SkGradientBaseShader.cpp
@@ -391,7 +391,7 @@
                 SkASSERT(t_l <= t_r);
                 if (t_l < t_r) {
                     float c_scale = sk_ieee_float_divide(1, t_r - t_l);
-                    if (std::isfinite(c_scale)) {
+                    if (SkIsFinite(c_scale)) {
                         init_stop_pos(ctx, stopCount, t_l, c_scale, c_l, c_r);
                         stopCount += 1;
                     }
diff --git a/src/shaders/gradients/SkLinearGradient.cpp b/src/shaders/gradients/SkLinearGradient.cpp
index b63c519..6126147 100644
--- a/src/shaders/gradients/SkLinearGradient.cpp
+++ b/src/shaders/gradients/SkLinearGradient.cpp
@@ -14,6 +14,7 @@
 #include "include/core/SkScalar.h"
 #include "include/core/SkShader.h"
 #include "include/effects/SkGradientShader.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTArray.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkWriteBuffer.h"
@@ -96,7 +97,7 @@
                                              SkTileMode mode,
                                              const Interpolation& interpolation,
                                              const SkMatrix* localMatrix) {
-    if (!pts || !SkScalarIsFinite((pts[1] - pts[0]).length())) {
+    if (!pts || !SkIsFinite((pts[1] - pts[0]).length())) {
         return nullptr;
     }
     if (!SkGradientBaseShader::ValidGradient(colors, colorCount, mode, interpolation)) {
diff --git a/src/shaders/gradients/SkSweepGradient.cpp b/src/shaders/gradients/SkSweepGradient.cpp
index 9efb733..cded4ca 100644
--- a/src/shaders/gradients/SkSweepGradient.cpp
+++ b/src/shaders/gradients/SkSweepGradient.cpp
@@ -111,7 +111,7 @@
     if (1 == colorCount) {
         return SkShaders::Color(colors[0], std::move(colorSpace));
     }
-    if (!SkScalarIsFinite(startAngle) || !SkScalarIsFinite(endAngle) || startAngle > endAngle) {
+    if (!SkIsFinite(startAngle, endAngle) || startAngle > endAngle) {
         return nullptr;
     }
     if (localMatrix && !localMatrix->invert(nullptr)) {
diff --git a/src/text/gpu/SubRunContainer.cpp b/src/text/gpu/SubRunContainer.cpp
index 0fe6e82..bb21c02 100644
--- a/src/text/gpu/SubRunContainer.cpp
+++ b/src/text/gpu/SubRunContainer.cpp
@@ -24,6 +24,7 @@
 #include "include/core/SkTypes.h"
 #include "include/effects/SkDashPathEffect.h"
 #include "include/private/SkColorData.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkOnce.h"
 #include "include/private/base/SkTArray.h"
 #include "include/private/base/SkTLogic.h"
@@ -1449,7 +1450,7 @@
     SkGlyphRect boundingRect = skglyph::empty_rect();
     StrikeMutationMonitor m{strike};
     for (const auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
@@ -1503,7 +1504,7 @@
     SkGlyphRect boundingRect = skglyph::empty_rect();
     StrikeMutationMonitor m{strike};
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
@@ -1546,7 +1547,7 @@
     SkGlyphRect boundingRect = skglyph::empty_rect();
     StrikeMutationMonitor m{strike};
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
@@ -1583,7 +1584,7 @@
     int rejectedSize = 0;
     StrikeMutationMonitor m{strike};
     for (const auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
@@ -1611,7 +1612,7 @@
     int rejectedSize = 0;
     StrikeMutationMonitor m{strike};
     for (const auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
 
@@ -1888,7 +1889,7 @@
                 SkPoint center = glyphRunList.sourceBounds().center();
                 SkScalar maxAreaScale = SkMatrixPriv::DifferentialAreaScale(creationMatrix, center);
                 SkScalar perspectiveFactor = 1;
-                if (SkScalarIsFinite(maxAreaScale) && !SkScalarNearlyZero(maxAreaScale)) {
+                if (SkIsFinite(maxAreaScale) && !SkScalarNearlyZero(maxAreaScale)) {
                     perspectiveFactor = SkScalarSqrt(maxAreaScale);
                 }
 
diff --git a/src/utils/SkDashPath.cpp b/src/utils/SkDashPath.cpp
index b704b09..5a5c34d 100644
--- a/src/utils/SkDashPath.cpp
+++ b/src/utils/SkDashPath.cpp
@@ -254,7 +254,7 @@
 
         fPathLength = pathLength;
         fTangent.scale(sk_ieee_float_divide(1.0f, pathLength));
-        if (!SkScalarsAreFinite(fTangent.fX, fTangent.fY)) {
+        if (!SkIsFinite(fTangent.fX, fTangent.fY)) {
             return false;
         }
         SkPointPriv::RotateCCW(fTangent, &fNormal);
@@ -266,7 +266,7 @@
 
         SkScalar ptCount = pathLength * intervalCount / (float)intervalLength;
         ptCount = std::min(ptCount, SkDashPath::kMaxDashCount);
-        if (SkScalarIsNaN(ptCount)) {
+        if (SkIsNaN(ptCount)) {
             return false;
         }
         int n = SkScalarCeilToInt(ptCount) << 2;
@@ -485,5 +485,5 @@
         length += intervals[i];
     }
     // watch out for values that might make us go out of bounds
-    return length > 0 && SkScalarIsFinite(phase) && SkScalarIsFinite(length);
+    return length > 0 && SkIsFinite(phase, length);
 }
diff --git a/src/utils/SkPatchUtils.cpp b/src/utils/SkPatchUtils.cpp
index eee7bae..efc2d44 100644
--- a/src/utils/SkPatchUtils.cpp
+++ b/src/utils/SkPatchUtils.cpp
@@ -159,7 +159,7 @@
     for (int i = 0; i < count - 1; i++) {
         arcLength += SkPoint::Distance(points[i], points[i + 1]);
     }
-    return SkScalarIsFinite(arcLength) ? arcLength : -1;
+    return SkIsFinite(arcLength) ? arcLength : -1;
 }
 
 static SkScalar bilerp(SkScalar tx, SkScalar ty, SkScalar c00, SkScalar c10, SkScalar c01,
diff --git a/src/utils/SkPolyUtils.cpp b/src/utils/SkPolyUtils.cpp
index 2135208..c122bb7 100644
--- a/src/utils/SkPolyUtils.cpp
+++ b/src/utils/SkPolyUtils.cpp
@@ -95,7 +95,7 @@
 
 // special zero-length test when we're using vdotv as a denominator
 static inline bool zero_length(const SkPoint& v, SkScalar vdotv) {
-    return !(SkScalarsAreFinite(v.fX, v.fY) && vdotv);
+    return !(SkIsFinite(v.fX, v.fY) && vdotv);
 }
 
 // Compute the intersection 'p' between segments s0 and s1, if any.
@@ -348,7 +348,7 @@
     }
 
     // can't inset by a negative or non-finite amount
-    if (inset < -SK_ScalarNearlyZero || !SkScalarIsFinite(inset)) {
+    if (inset < -SK_ScalarNearlyZero || !SkIsFinite(inset)) {
         return false;
     }
 
@@ -492,11 +492,11 @@
     const SkScalar kRecipPixelsPerArcSegment = 0.25f;
 
     SkScalar rCos = v1.dot(v2);
-    if (!SkScalarIsFinite(rCos)) {
+    if (!SkIsFinite(rCos)) {
         return false;
     }
     SkScalar rSin = v1.cross(v2);
-    if (!SkScalarIsFinite(rSin)) {
+    if (!SkIsFinite(rSin)) {
         return false;
     }
     SkScalar theta = SkScalarATan2(rSin, rCos);
@@ -1204,7 +1204,7 @@
         return false;
     }
 
-    if (!SkScalarIsFinite(offset)) {
+    if (!SkIsFinite(offset)) {
         return false;
     }
 
@@ -1527,13 +1527,13 @@
         fNumVerts = 0;
         SkScalar width = bounds.width();
         SkScalar height = bounds.height();
-        if (!SkScalarIsFinite(width) || !SkScalarIsFinite(height)) {
+        if (!SkIsFinite(width, height)) {
             return false;
         }
 
         // We want vertexCount grid cells, roughly distributed to match the bounds ratio
         SkScalar hCount = SkScalarSqrt(sk_ieee_float_divide(vertexCount*width, height));
-        if (!SkScalarIsFinite(hCount)) {
+        if (!SkIsFinite(hCount)) {
             return false;
         }
         fHCount = std::max(std::min(SkScalarRoundToInt(hCount), vertexCount), 1);
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index 095a357..26bb874 100644
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -293,7 +293,7 @@
             // if the umbra would collapse, we back off a bit on inner blur and adjust the alpha
             auto newInset = SkScalarSqrt(minDistSq) - kTolerance;
             auto ratio = 128 * (newInset / inset + 1);
-            SkASSERT(SkScalarIsFinite(ratio));
+            SkASSERT(SkIsFinite(ratio));
             // they aren't PMColors, but the interpolation algorithm is the same
             umbraColor = SkPMLerp(kUmbraColor, kPenumbraColor, (unsigned)ratio);
             inset = newInset;
@@ -936,7 +936,7 @@
     if (!this->computePathPolygon(path, ctm)) {
         return;
     }
-    if (fPathPolygon.size() < 3 || !SkScalarIsFinite(fArea)) {
+    if (fPathPolygon.size() < 3 || !SkIsFinite(fArea)) {
         fSucceeded = true; // We don't want to try to blur these cases, so we will
                            // return an empty SkVertices instead.
         return;
@@ -1037,7 +1037,7 @@
     if (!this->computeClipAndPathPolygons(path, ctm, shadowTransform)) {
         return;
     }
-    if (fClipPolygon.size() < 3 || fPathPolygon.size() < 3 || !SkScalarIsFinite(fArea)) {
+    if (fClipPolygon.size() < 3 || fPathPolygon.size() < 3 || !SkIsFinite(fArea)) {
         fSucceeded = true; // We don't want to try to blur these cases, so we will
                            // return an empty SkVertices instead.
         return;
@@ -1179,7 +1179,7 @@
                                                 bool directional) {
     if (!ctm.mapRect(path.getBounds()).isFinite() || !zPlane.isFinite() ||
         !lightPos.isFinite() || !(lightPos.fZ >= SK_ScalarNearlyZero) ||
-        !SkScalarIsFinite(lightRadius) || !(lightRadius >= SK_ScalarNearlyZero)) {
+        !SkIsFinite(lightRadius) || !(lightRadius >= SK_ScalarNearlyZero)) {
         return nullptr;
     }
     SkSpotShadowTessellator spotTess(path, ctm, zPlane, lightPos, lightRadius, transparent,
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index 21d917d..53ce311 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -22,6 +22,7 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkVertices.h"
 #include "include/private/SkIDChangeListener.h"
+#include "include/private/base/SkFloatingPoint.h"
 #include "include/private/base/SkTPin.h"
 #include "include/private/base/SkTemplates.h"
 #include "include/private/base/SkTo.h"
@@ -586,7 +587,7 @@
 
 static bool validate_rec(const SkDrawShadowRec& rec) {
     return rec.fLightPos.isFinite() && rec.fZPlaneParams.isFinite() &&
-           SkScalarIsFinite(rec.fLightRadius);
+           SkIsFinite(rec.fLightRadius);
 }
 
 void SkDevice::drawShadow(const SkPath& path, const SkDrawShadowRec& rec) {
diff --git a/tests/Float16Test.cpp b/tests/Float16Test.cpp
index d40be06..e1c21d2 100644
--- a/tests/Float16Test.cpp
+++ b/tests/Float16Test.cpp
@@ -49,7 +49,7 @@
 #endif
 
         float f = SkBits2Float(bits);
-        if (SkScalarIsNaN(f)) {
+        if (SkIsNaN(f)) {
 #ifndef SK_DEBUG
             // We want float->half and half->float to play well with infinities and max
             // representable values in the 16-bit precision, but NaNs should have been caught ahead
@@ -146,8 +146,8 @@
         } else if (e16 == kF16_Exp) {
             if (m16 != 0) {
                 // A NaN stays NaN
-                REPORTER_ASSERT(r, SkScalarIsNaN(actual2));
-                REPORTER_ASSERT(r, SkScalarIsNaN(actual4));
+                REPORTER_ASSERT(r, SkIsNaN(actual2));
+                REPORTER_ASSERT(r, SkIsNaN(actual4));
             } else {
                 // +/- infinity stays infinite
                 if (s16) {
diff --git a/tests/FloatingPointTest.cpp b/tests/FloatingPointTest.cpp
index f284256..9546765 100644
--- a/tests/FloatingPointTest.cpp
+++ b/tests/FloatingPointTest.cpp
@@ -126,7 +126,7 @@
     {
         uint64_t bits = sk_bit_cast<uint64_t>((double) INFINITY);
         double output = sk_bit_cast<double>(bits);
-        REPORTER_ASSERT(reporter, !std::isfinite(output), "%.16f is not infinity", output);
+        REPORTER_ASSERT(reporter, !SkIsFinite(output), "%.16f is not infinity", output);
     }
 }
 
diff --git a/tests/GLBackendSurfaceTest.cpp b/tests/GLBackendSurfaceTest.cpp
index 433c6c1..a11e8b3 100644
--- a/tests/GLBackendSurfaceTest.cpp
+++ b/tests/GLBackendSurfaceTest.cpp
@@ -38,7 +38,7 @@
 struct GrContextOptions;
 
 static bool sampler_params_invalid(const GrGLTextureParameters& parameters) {
-    return SkScalarIsNaN(parameters.samplerOverriddenState().fMaxLOD);
+    return SkIsNaN(parameters.samplerOverriddenState().fMaxLOD);
 }
 
 static bool nonsampler_params_invalid(const GrGLTextureParameters& parameters) {
diff --git a/tests/GeometryTest.cpp b/tests/GeometryTest.cpp
index 653e069..c99c365 100644
--- a/tests/GeometryTest.cpp
+++ b/tests/GeometryTest.cpp
@@ -267,7 +267,7 @@
         do {
             w *= 2;
             test_this_conic_to_quad(reporter, pts, w);
-        } while (SkScalarIsFinite(w));
+        } while (SkIsFinite(w));
         test_this_conic_to_quad(reporter, pts, SK_ScalarNaN);
     }
 }
diff --git a/tests/MathTest.cpp b/tests/MathTest.cpp
index 0b057be..809e9f5 100644
--- a/tests/MathTest.cpp
+++ b/tests/MathTest.cpp
@@ -180,25 +180,27 @@
     REPORTER_ASSERT(reporter, len > 0.999f && len < 1.001f);
 }
 
+template <typename T>
 static void unittest_isfinite(skiatest::Reporter* reporter) {
-    float nan = std::asin(2);
-    float inf = SK_ScalarInfinity;
-    float big = 3.40282e+038f;
+    const T inf = std::numeric_limits<T>::infinity();
+    const T big = std::numeric_limits<T>::max();
+    const T nan = inf * 0;
+    const T zero = 0;
 
-    REPORTER_ASSERT(reporter, !SkScalarIsNaN(inf));
-    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-inf));
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(inf));
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(-inf));
+    REPORTER_ASSERT(reporter, !SkIsNaN(inf));
+    REPORTER_ASSERT(reporter, !SkIsNaN(-inf));
+    REPORTER_ASSERT(reporter, !SkIsFinite(inf));
+    REPORTER_ASSERT(reporter, !SkIsFinite(-inf));
 
-    REPORTER_ASSERT(reporter,  SkScalarIsNaN(nan));
-    REPORTER_ASSERT(reporter, !SkScalarIsNaN(big));
-    REPORTER_ASSERT(reporter, !SkScalarIsNaN(-big));
-    REPORTER_ASSERT(reporter, !SkScalarIsNaN(0));
+    REPORTER_ASSERT(reporter,  SkIsNaN(nan));
+    REPORTER_ASSERT(reporter, !SkIsNaN(big));
+    REPORTER_ASSERT(reporter, !SkIsNaN(-big));
+    REPORTER_ASSERT(reporter, !SkIsNaN(zero));
 
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(nan));
-    REPORTER_ASSERT(reporter,  SkScalarIsFinite(big));
-    REPORTER_ASSERT(reporter,  SkScalarIsFinite(-big));
-    REPORTER_ASSERT(reporter,  SkScalarIsFinite(0));
+    REPORTER_ASSERT(reporter, !SkIsFinite(nan));
+    REPORTER_ASSERT(reporter,  SkIsFinite(big));
+    REPORTER_ASSERT(reporter,  SkIsFinite(-big));
+    REPORTER_ASSERT(reporter,  SkIsFinite(zero));
 }
 
 static void unittest_half(skiatest::Reporter* reporter) {
@@ -237,7 +239,7 @@
     static const FloatUnion overflowHalf = { ((143 << 23) | (1023 << 13)) };
     h = SkFloatToHalf(overflowHalf.fF);
     f = SkHalfToFloat(h);
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(f) );
+    REPORTER_ASSERT(reporter, !SkIsFinite(f) );
 
     static const FloatUnion underflowHalf = { 101 << 23 };
     h = SkFloatToHalf(underflowHalf.fF);
@@ -247,12 +249,12 @@
     static const FloatUnion inf32 = { 255 << 23 };
     h = SkFloatToHalf(inf32.fF);
     f = SkHalfToFloat(h);
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(f) );
+    REPORTER_ASSERT(reporter, !SkIsFinite(f) );
 
     static const FloatUnion nan32 = { 255 << 23 | 1 };
     h = SkFloatToHalf(nan32.fF);
     f = SkHalfToFloat(h);
-    REPORTER_ASSERT(reporter, SkScalarIsNaN(f) );
+    REPORTER_ASSERT(reporter, SkIsNaN(f) );
 
 }
 
@@ -505,7 +507,7 @@
 
     {
         SkScalar x = SK_ScalarNaN;
-        REPORTER_ASSERT(reporter, SkScalarIsNaN(x));
+        REPORTER_ASSERT(reporter, SkIsNaN(x));
     }
 
     for (i = 0; i < 10000; i++) {
@@ -539,7 +541,8 @@
     }
 
     huge_vector_normalize(reporter);
-    unittest_isfinite(reporter);
+    unittest_isfinite<float>(reporter);
+    unittest_isfinite<double>(reporter);
     unittest_half(reporter);
     test_rsqrt(reporter, sk_float_rsqrt);
     test_rsqrt(reporter, sk_float_rsqrt_portable);
diff --git a/tests/PDFPrimitivesTest.cpp b/tests/PDFPrimitivesTest.cpp
index 70e832a..3eb0c3f 100644
--- a/tests/PDFPrimitivesTest.cpp
+++ b/tests/PDFPrimitivesTest.cpp
@@ -370,7 +370,7 @@
         ERRORF(reporter, "unscannable result: %s", floatString);
         return;
     }
-    if (std::isfinite(inputFloat) && roundTripFloat != inputFloat) {
+    if (SkIsFinite(inputFloat) && roundTripFloat != inputFloat) {
         ERRORF(reporter, "roundTripFloat (%.9g) != inputFloat (%.9g)",
                roundTripFloat, inputFloat);
     }
diff --git a/tests/PathOpsTestCommon.cpp b/tests/PathOpsTestCommon.cpp
index 5f7c96a..7c04939 100644
--- a/tests/PathOpsTestCommon.cpp
+++ b/tests/PathOpsTestCommon.cpp
@@ -259,16 +259,16 @@
 }
 
 bool ValidBounds(const SkPathOpsBounds& bounds) {
-    if (SkScalarIsNaN(bounds.fLeft)) {
+    if (SkIsNaN(bounds.fLeft)) {
         return false;
     }
-    if (SkScalarIsNaN(bounds.fTop)) {
+    if (SkIsNaN(bounds.fTop)) {
         return false;
     }
-    if (SkScalarIsNaN(bounds.fRight)) {
+    if (SkIsNaN(bounds.fRight)) {
         return false;
     }
-    return !SkScalarIsNaN(bounds.fBottom);
+    return !SkIsNaN(bounds.fBottom);
 }
 
 bool ValidConic(const SkDConic& conic) {
@@ -310,10 +310,10 @@
 
 bool ValidPoints(const SkPoint* pts, int count) {
     for (int index = 0; index < count; ++index) {
-        if (SkScalarIsNaN(pts[index].fX)) {
+        if (SkIsNaN(pts[index].fX)) {
             return false;
         }
-        if (SkScalarIsNaN(pts[index].fY)) {
+        if (SkIsNaN(pts[index].fY)) {
             return false;
         }
     }
diff --git a/tests/PointTest.cpp b/tests/PointTest.cpp
index 73e653f..a605d80 100644
--- a/tests/PointTest.cpp
+++ b/tests/PointTest.cpp
@@ -116,9 +116,9 @@
     length = force_as_float(reporter, length);
 
     // expect this to be non-finite, but dump the results if not.
-    if (SkScalarIsFinite(length)) {
+    if (SkIsFinite(length)) {
         SkDebugf("length(%g, %g) == %g\n", pt.fX, pt.fY, length);
-        REPORTER_ASSERT(reporter, !SkScalarIsFinite(length));
+        REPORTER_ASSERT(reporter, !SkIsFinite(length));
     }
 
     // this should succeed, even though we can't represent length
diff --git a/tests/QuadRootsTest.cpp b/tests/QuadRootsTest.cpp
index 5af7449..3f13ee6 100644
--- a/tests/QuadRootsTest.cpp
+++ b/tests/QuadRootsTest.cpp
@@ -364,7 +364,7 @@
                C = testCase.C,
                answerLo = testCase.answerLo,
                answerHi = testCase.answerHi;
-        if (std::isfinite(answerLo) && std::isfinite(answerHi)) {
+        if (SkIsFinite(answerLo, answerHi)) {
             SkASSERT(answerLo <= answerHi);
         }
         auto [discriminate, r0, r1] = SkQuads::Roots(A, -0.5*B, C);
diff --git a/tests/RectTest.cpp b/tests/RectTest.cpp
index 6bb0ccc..6b309f4 100644
--- a/tests/RectTest.cpp
+++ b/tests/RectTest.cpp
@@ -167,18 +167,18 @@
     const SkRect r = { -big, -big, big, big };
 
     REPORTER_ASSERT(reporter, r.isFinite());
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(r.width()));
-    REPORTER_ASSERT(reporter, !SkScalarIsFinite(r.height()));
+    REPORTER_ASSERT(reporter, !SkIsFinite(r.width()));
+    REPORTER_ASSERT(reporter, !SkIsFinite(r.height()));
 
     // ensure we can compute center even when the width/height might overflow
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(r.centerX()));
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(r.centerY()));
+    REPORTER_ASSERT(reporter, SkIsFinite(r.centerX()));
+    REPORTER_ASSERT(reporter, SkIsFinite(r.centerY()));
 
 
     // ensure we can compute halfWidth and halfHeight even when width/height might overflow,
     // i.e. for use computing the radii filling a rectangle.
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(SkRectPriv::HalfWidth(r)));
-    REPORTER_ASSERT(reporter, SkScalarIsFinite(SkRectPriv::HalfHeight(r)));
+    REPORTER_ASSERT(reporter, SkIsFinite(SkRectPriv::HalfWidth(r)));
+    REPORTER_ASSERT(reporter, SkIsFinite(SkRectPriv::HalfHeight(r)));
 }
 
 DEF_TEST(Rect_subtract, reporter) {
diff --git a/tests/ScalarTest.cpp b/tests/ScalarTest.cpp
index 382b86c..8b8fb1d 100644
--- a/tests/ScalarTest.cpp
+++ b/tests/ScalarTest.cpp
@@ -97,7 +97,7 @@
 }
 
 static bool isFinite_float(float x) {
-    return SkToBool(std::isfinite(x));
+    return SkToBool(SkIsFinite(x));
 }
 
 static bool isFinite_mulzero(float x) {
@@ -128,16 +128,16 @@
 static void test_floatclass(skiatest::Reporter* reporter, float value, FloatClass fc) {
     // our sk_float_is... function may return int instead of bool,
     // hence the double ! to turn it into a bool
-    REPORTER_ASSERT(reporter, !!std::isfinite(value) == (fc == kFinite));
-    REPORTER_ASSERT(reporter, !!std::isinf(value)    == (fc == kInfinite));
-    REPORTER_ASSERT(reporter, !!std::isnan(value)    == (fc == kNaN));
+    REPORTER_ASSERT(reporter, !!SkIsFinite(value) == (fc == kFinite));
+    REPORTER_ASSERT(reporter, !!std::isinf(value) == (fc == kInfinite));
+    REPORTER_ASSERT(reporter, !!SkIsNaN(value)    == (fc == kNaN));
 }
 
 #if defined _WIN32
-#pragma warning ( push )
+#pragma warning(push)
 // we are intentionally causing an overflow here
 //      (warning C4756: overflow in constant arithmetic)
-#pragma warning ( disable : 4756 )
+#pragma warning(disable : 4756)
 #endif
 
 static void test_isfinite(skiatest::Reporter* reporter) {
diff --git a/tests/SkRasterPipelineTest.cpp b/tests/SkRasterPipelineTest.cpp
index b2795bc..c161ae0 100644
--- a/tests/SkRasterPipelineTest.cpp
+++ b/tests/SkRasterPipelineTest.cpp
@@ -2971,7 +2971,7 @@
             }
             for (int j = i; j < 4; j++) {
                 for (auto f : buffer[j]) {
-                    REPORTER_ASSERT(r, SkScalarIsNaN(f));
+                    REPORTER_ASSERT(r, SkIsNaN(f));
                 }
             }
         }
diff --git a/tests/SkStrikeTest.cpp b/tests/SkStrikeTest.cpp
index 4e6a912..c16d3a9 100644
--- a/tests/SkStrikeTest.cpp
+++ b/tests/SkStrikeTest.cpp
@@ -81,7 +81,7 @@
         rejectedSize = 0;
     StrikeMutationMonitor m{strike};
     for (auto [glyphID, pos] : source) {
-        if (!SkScalarsAreFinite(pos.x(), pos.y())) {
+        if (!SkIsFinite(pos.x(), pos.y())) {
             continue;
         }
         const SkPackedGlyphID packedID{glyphID};
diff --git a/tools/testrunners/benchmark/BazelBenchmarkTestRunner.cpp b/tools/testrunners/benchmark/BazelBenchmarkTestRunner.cpp
index ff138db..8e2dba3 100644
--- a/tools/testrunners/benchmark/BazelBenchmarkTestRunner.cpp
+++ b/tools/testrunners/benchmark/BazelBenchmarkTestRunner.cpp
@@ -274,7 +274,7 @@
                 // https://skia.googlesource.com/skia/+/a063eaeaf1e09e4d6f42e0f44a5723622a46d21c/bench/ResultsWriter.h#51.
                 //
                 // Don't record if NaN or Inf.
-                if (std::isfinite(singleMeasurement.measurement)) {
+                if (SkIsFinite(singleMeasurement.measurement)) {
                     fJson.beginObject();
                     fJson.appendCString("value", singleMeasurement.value.c_str());
                     fJson.appendDoubleDigits("measurement", singleMeasurement.measurement, 16);
diff --git a/tools/viewer/FilterBoundsSlide.cpp b/tools/viewer/FilterBoundsSlide.cpp
index 24858c5..abab955 100644
--- a/tools/viewer/FilterBoundsSlide.cpp
+++ b/tools/viewer/FilterBoundsSlide.cpp
@@ -143,7 +143,7 @@
                 SkPoint(mapping.paramToLayer(skif::ParameterSpace<SkPoint>(testPoints[i]))));
         SkColor4f color = {0.f, 0.f, 0.f, 1.f};
 
-        if (SkScalarIsFinite(scale)) {
+        if (SkIsFinite(scale)) {
             float logScale = SkScalarLog2(scale);
             for (int j = 0; j <= kStopCount; ++j) {
                 if (j == kStopCount) {