Move SkCubicSolver out of opts
This was only specialized to get fma, and only on Haswell. The code is
only used in skottie, and the net speedup to a cubic-map microbench was
very small (~20%). Overall, it hardly seems worth the trouble.
Change-Id: I82de38be05186747e8ccdeb2d6215a0c21bcf5fe
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/664580
Reviewed-by: Florin Malita <fmalita@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/gn/core.gni b/gn/core.gni
index cc187d7..e61b77b 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -316,7 +316,6 @@
"$_src/core/SkCubicClipper.cpp",
"$_src/core/SkCubicClipper.h",
"$_src/core/SkCubicMap.cpp",
- "$_src/core/SkCubicSolver.h",
"$_src/core/SkData.cpp",
"$_src/core/SkDataTable.cpp",
"$_src/core/SkDebug.cpp",
diff --git a/public.bzl b/public.bzl
index 53c2a03..e63ab64 100644
--- a/public.bzl
+++ b/public.bzl
@@ -427,7 +427,6 @@
"src/core/SkCubicClipper.cpp",
"src/core/SkCubicClipper.h",
"src/core/SkCubicMap.cpp",
- "src/core/SkCubicSolver.h",
"src/core/SkData.cpp",
"src/core/SkDataTable.cpp",
"src/core/SkDebug.cpp",
diff --git a/src/core/BUILD.bazel b/src/core/BUILD.bazel
index dc8989d..b380da3b 100644
--- a/src/core/BUILD.bazel
+++ b/src/core/BUILD.bazel
@@ -97,7 +97,6 @@
"SkCubicClipper.cpp",
"SkCubicClipper.h",
"SkCubicMap.cpp",
- "SkCubicSolver.h",
"SkDataTable.cpp",
"SkDebug.cpp",
"SkDebugUtils.h",
diff --git a/src/core/SkCubicMap.cpp b/src/core/SkCubicMap.cpp
index a767126..f394e16 100644
--- a/src/core/SkCubicMap.cpp
+++ b/src/core/SkCubicMap.cpp
@@ -10,17 +10,52 @@
#include "include/private/base/SkFloatingPoint.h"
#include "include/private/base/SkTPin.h"
#include "src/base/SkVx.h"
-#include "src/core/SkOpts.h"
#include <algorithm>
+static float eval_poly(float t, float b) { return b; }
+
+template <typename... Rest>
+static float eval_poly(float t, float m, float b, Rest... rest) {
+ return eval_poly(t, sk_fmaf(m, t, b), rest...);
+}
+
+static float cubic_solver(float A, float B, float C, float D) {
+#ifdef SK_DEBUG
+ auto valid = [](float t) { return t >= 0 && t <= 1; };
+#endif
+
+ auto guess_nice_cubic_root = [](float a, float b, float c, float d) { return -d; };
+ float t = guess_nice_cubic_root(A, B, C, D);
+
+ int iters = 0;
+ const int MAX_ITERS = 8;
+ for (; iters < MAX_ITERS; ++iters) {
+ SkASSERT(valid(t));
+ float f = eval_poly(t, A, B, C, D); // f = At^3 + Bt^2 + Ct + D
+ if (sk_float_abs(f) <= 0.00005f) {
+ break;
+ }
+ float fp = eval_poly(t, 3*A, 2*B, C); // f' = 3At^2 + 2Bt + C
+ float fpp = eval_poly(t, 3*A + 3*A, 2*B); // f'' = 6At + 2B
+
+ float numer = 2 * fp * f;
+ float denom = sk_fmaf(2 * fp, fp, -(f * fpp));
+
+ t -= numer / denom;
+ }
+
+ SkASSERT(valid(t));
+ return t;
+}
+
static inline bool nearly_zero(SkScalar x) {
SkASSERT(x >= 0);
return x <= 0.0000000001f;
}
static float compute_t_from_x(float A, float B, float C, float x) {
- return SkOpts::cubic_solver(A, B, C, -x);
+ return cubic_solver(A, B, C, -x);
}
float SkCubicMap::computeYFromX(float x) const {
diff --git a/src/core/SkCubicSolver.h b/src/core/SkCubicSolver.h
deleted file mode 100644
index e65f3cc..0000000
--- a/src/core/SkCubicSolver.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkCubicSolver_DEFINED
-#define SkCubicSolver_DEFINED
-
-#include "include/core/SkTypes.h"
-#include "include/private/base/SkFloatingPoint.h"
-
-namespace SK_OPTS_NS {
-
- static float eval_poly(float t, float b) {
- return b;
- }
-
- template <typename... Rest>
- static float eval_poly(float t, float m, float b, Rest... rest) {
- return eval_poly(t, sk_fmaf(m,t,b), rest...);
- }
-
- inline float cubic_solver(float A, float B, float C, float D) {
-
- #ifdef SK_DEBUG
- auto valid = [](float t) {
- return t >= 0 && t <= 1;
- };
- #endif
-
- auto guess_nice_cubic_root = [](float a, float b, float c, float d) {
- return -d;
- };
- float t = guess_nice_cubic_root(A, B, C, D);
-
- int iters = 0;
- const int MAX_ITERS = 8;
- for (; iters < MAX_ITERS; ++iters) {
- SkASSERT(valid(t));
- float f = eval_poly(t, A,B,C,D); // f = At^3 + Bt^2 + Ct + D
- if (sk_float_abs(f) <= 0.00005f) {
- break;
- }
- float fp = eval_poly(t, 3*A, 2*B, C); // f' = 3At^2 + 2Bt + C
- float fpp = eval_poly(t, 3*A+3*A, 2*B); // f'' = 6At + 2B
-
- float numer = 2 * fp * f;
- float denom = sk_fmaf(2*fp, fp, -(f*fpp));
-
- t -= numer / denom;
- }
-
- SkASSERT(valid(t));
- return t;
- }
-
-} // namespace SK_OPTS_NS
-#endif
diff --git a/src/core/SkOpts.cpp b/src/core/SkOpts.cpp
index 1c329ca..b0aa726 100644
--- a/src/core/SkOpts.cpp
+++ b/src/core/SkOpts.cpp
@@ -38,7 +38,6 @@
#define SK_OPTS_NS portable
#endif
-#include "src/core/SkCubicSolver.h"
#include "src/opts/SkBitmapProcState_opts.h"
#include "src/opts/SkBlitMask_opts.h"
#include "src/opts/SkBlitRow_opts.h"
@@ -81,8 +80,6 @@
DEFINE_DEFAULT(rect_memset32);
DEFINE_DEFAULT(rect_memset64);
- DEFINE_DEFAULT(cubic_solver);
-
DEFINE_DEFAULT(hash_fn);
DEFINE_DEFAULT(S32_alpha_D32_filter_DX);
diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h
index 4df2a4f..6ffde77 100644
--- a/src/core/SkOpts.h
+++ b/src/core/SkOpts.h
@@ -105,8 +105,6 @@
extern void (*rect_memset32)(uint32_t[], uint32_t, int, size_t, int);
extern void (*rect_memset64)(uint64_t[], uint64_t, int, size_t, int);
- extern float (*cubic_solver)(float, float, float, float);
-
static inline uint32_t hash(const void* data, size_t bytes, uint32_t seed=0) {
// hash_fn is defined in SkOpts_spi.h so it can be used by //modules
return hash_fn(data, bytes, seed);
diff --git a/src/opts/SkOpts_hsw.cpp b/src/opts/SkOpts_hsw.cpp
index 34f2ccd..cfa2a25 100644
--- a/src/opts/SkOpts_hsw.cpp
+++ b/src/opts/SkOpts_hsw.cpp
@@ -10,7 +10,6 @@
#if !defined(SK_ENABLE_OPTIMIZE_SIZE)
#define SK_OPTS_NS hsw
-#include "src/core/SkCubicSolver.h"
#include "src/opts/SkBitmapProcState_opts.h"
#include "src/opts/SkBlitRow_opts.h"
#include "src/opts/SkRasterPipeline_opts.h"
@@ -25,8 +24,6 @@
S32_alpha_D32_filter_DX = hsw::S32_alpha_D32_filter_DX;
- cubic_solver = SK_OPTS_NS::cubic_solver;
-
RGBA_to_BGRA = SK_OPTS_NS::RGBA_to_BGRA;
RGBA_to_rgbA = SK_OPTS_NS::RGBA_to_rgbA;
RGBA_to_bgrA = SK_OPTS_NS::RGBA_to_bgrA;