#ifndef GrWangsFormula_DEFINED
#define GrWangsFormula_DEFINED
#include "include/core/SkPoint.h"
#include "src/gpu/GrVx.h"
#include "src/gpu/tessellate/GrVectorXform.h"
namespace pk {
namespace GrWangsFormula {
template <int Degree> constexpr float length_term_pow2(float precision) {
return ((Degree * Degree) * ((Degree - 1) * (Degree - 1)) / 64.f) * (precision * precision);
}
PK_ALWAYS_INLINE static int nextlog16(float x) { return (pk_float_nextlog2(x) + 3) >> 2; }
PK_ALWAYS_INLINE static float cubic_pow4(float precision,
const SkPoint pts[],
const GrVectorXform& vectorXform = GrVectorXform()) {
using grvx::float4;
float4 p01 = float4::Load(pts);
float4 p12 = float4::Load(pts + 1);
float4 p23 = float4::Load(pts + 2);
float4 v = grvx::fast_madd<4>(-2, p12, p01) + p23;
v = vectorXform(v);
float4 vv = v * v;
return std::max(vv[0] + vv[1], vv[2] + vv[3]) * length_term_pow2<3>(precision);
}
PK_ALWAYS_INLINE static int cubic_log2(float precision,
const SkPoint pts[],
const GrVectorXform& vectorXform = GrVectorXform()) {
return nextlog16(cubic_pow4(precision, pts, vectorXform));
}
} }
#endif