Wrap SkNx types in anonymous namespace again.
This should make each compilation unit's SkNx types distinct from each other's as far as C++ cares. This keeps us from violating the One Definition Rule with different implementations for the same function. Here's an example I like. Sk4i SkNx_cast(Sk4b) has at least 4 different sensible implementations: - SSE2: punpcklbw xmm, zero; punpcklbw xmm, zero - SSSE3: load mask; pshufb xmm, mask - SSE4.1: pmovzxbd - AVX2: vpmovzxbd We really want all these to inline, but if for some reason they don't (Debug build, poor inliner) and they're compiled in SkOpts.cpp, SkOpts_ssse3.cpp, SkOpts_sse41.cpp, SkOpts_hsw.cpp... boom! BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=3461 Change-Id: I0088ebfd7640c1b0de989738ed43c81b530dc0d9 Reviewed-on: https://skia-review.googlesource.com/3461 Reviewed-by: Matt Sarett <msarett@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
This commit is contained in:
parent
e5e7eb1478
commit
1e76464f87
@ -10,6 +10,8 @@
|
||||
|
||||
#include "SkNx.h"
|
||||
|
||||
namespace {
|
||||
|
||||
struct Sk4x4f {
|
||||
Sk4f r,g,b,a;
|
||||
|
||||
@ -150,4 +152,6 @@ inline void Sk4x4f::transpose(uint8_t bs[16]) const {
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif//Sk4x4f_DEFINED
|
||||
|
@ -16,6 +16,8 @@
|
||||
#include <math.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace {
|
||||
|
||||
#define SI static inline
|
||||
|
||||
// The default SkNx<N,T> just proxies down to a pair of SkNx<N/2, T>.
|
||||
@ -312,6 +314,8 @@ SI SkNx<N,T> SkNx_fma(const SkNx<N,T>& f, const SkNx<N,T>& m, const SkNx<N,T>& a
|
||||
return f*m+a;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
typedef SkNx<2, float> Sk2f;
|
||||
typedef SkNx<4, float> Sk4f;
|
||||
typedef SkNx<8, float> Sk8f;
|
||||
|
@ -12,6 +12,8 @@
|
||||
|
||||
#define SKNX_IS_FAST
|
||||
|
||||
namespace {
|
||||
|
||||
// ARMv8 has vrndmq_f32 to floor 4 floats. Here we emulate it:
|
||||
// - roundtrip through integers via truncation
|
||||
// - subtract 1 if that's too big (possible for negative values).
|
||||
@ -550,4 +552,6 @@ static inline Sk4i Sk4f_round(const Sk4f& x) {
|
||||
return vcvtq_s32_f32((x + 0.5f).fVec);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif//SkNx_neon_DEFINED
|
||||
|
@ -15,6 +15,8 @@
|
||||
|
||||
#define SKNX_IS_FAST
|
||||
|
||||
namespace {
|
||||
|
||||
template <>
|
||||
class SkNx<2, float> {
|
||||
public:
|
||||
@ -719,4 +721,6 @@ static inline Sk4i Sk4f_round(const Sk4f& x) {
|
||||
return _mm_cvtps_epi32(x.fVec);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif//SkNx_sse_DEFINED
|
||||
|
@ -67,19 +67,28 @@ static inline SkVector evaluateDerivative(const SkPoint pts[4],
|
||||
}
|
||||
/// Used in ArcLengthIntegrator::computeLength
|
||||
static inline Sk8f evaluateDerivativeLength(const Sk8f& ts,
|
||||
const Sk8f (&xCoeff)[3],
|
||||
const Sk8f (&yCoeff)[3],
|
||||
const float (&xCoeff)[3][8],
|
||||
const float (&yCoeff)[3][8],
|
||||
const SkSegType segType) {
|
||||
Sk8f x;
|
||||
Sk8f y;
|
||||
|
||||
Sk8f x0 = Sk8f::Load(&xCoeff[0]),
|
||||
x1 = Sk8f::Load(&xCoeff[1]),
|
||||
x2 = Sk8f::Load(&xCoeff[2]);
|
||||
|
||||
Sk8f y0 = Sk8f::Load(&yCoeff[0]),
|
||||
y1 = Sk8f::Load(&yCoeff[1]),
|
||||
y2 = Sk8f::Load(&yCoeff[2]);
|
||||
|
||||
switch (segType) {
|
||||
case kQuad_SegType:
|
||||
x = xCoeff[0]*ts + xCoeff[1];
|
||||
y = yCoeff[0]*ts + yCoeff[1];
|
||||
x = x0*ts + x1;
|
||||
y = y0*ts + y1;
|
||||
break;
|
||||
case kCubic_SegType:
|
||||
x = (xCoeff[0]*ts + xCoeff[1])*ts + xCoeff[2];
|
||||
y = (yCoeff[0]*ts + yCoeff[1])*ts + yCoeff[2];
|
||||
x = (x0*ts + x1)*ts + x2;
|
||||
y = (y0*ts + y1)*ts + y2;
|
||||
break;
|
||||
case kConic_SegType:
|
||||
UNIMPLEMENTED;
|
||||
@ -106,11 +115,11 @@ ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
|
||||
float Cy = pts[2].y();
|
||||
|
||||
// precompute coefficients for derivative
|
||||
xCoeff[0] = Sk8f(2*(Ax - 2*Bx + Cx));
|
||||
xCoeff[1] = Sk8f(2*(Bx - Ax));
|
||||
Sk8f(2*(Ax - 2*Bx + Cx)).store(&xCoeff[0]);
|
||||
Sk8f(2*(Bx - Ax)).store(&xCoeff[1]);
|
||||
|
||||
yCoeff[0] = Sk8f(2*(Ay - 2*By + Cy));
|
||||
yCoeff[1] = Sk8f(2*(By - Ay));
|
||||
Sk8f(2*(Ay - 2*By + Cy)).store(&yCoeff[0]);
|
||||
Sk8f(2*(By - Ay)).store(&yCoeff[1]);
|
||||
}
|
||||
break;
|
||||
case kCubic_SegType:
|
||||
@ -125,13 +134,13 @@ ArcLengthIntegrator::ArcLengthIntegrator(const SkPoint* pts, SkSegType segType)
|
||||
float Dy = pts[3].y();
|
||||
|
||||
// precompute coefficients for derivative
|
||||
xCoeff[0] = Sk8f(3*(-Ax + 3*(Bx - Cx) + Dx));
|
||||
xCoeff[1] = Sk8f(6*(Ax - 2*Bx + Cx));
|
||||
xCoeff[2] = Sk8f(3*(-Ax + Bx));
|
||||
Sk8f(3*(-Ax + 3*(Bx - Cx) + Dx)).store(&xCoeff[0]);
|
||||
Sk8f(6*(Ax - 2*Bx + Cx)).store(&xCoeff[1]);
|
||||
Sk8f(3*(-Ax + Bx)).store(&xCoeff[2]);
|
||||
|
||||
yCoeff[0] = Sk8f(3*(-Ay + 3*(By - Cy) + Dy));
|
||||
yCoeff[1] = Sk8f(6*(Ay - 2*By + Cy));
|
||||
yCoeff[2] = Sk8f(3*(-Ay + By));
|
||||
Sk8f(3*(-Ay + 3*(By - Cy) + Dy)).store(&yCoeff[0]);
|
||||
Sk8f(6*(Ay - 2*By + Cy)).store(&yCoeff[1]);
|
||||
Sk8f(3*(-Ay + By)).store(&yCoeff[2]);
|
||||
}
|
||||
break;
|
||||
case kConic_SegType:
|
||||
|
@ -37,8 +37,8 @@ private:
|
||||
SkSegType fSegType;
|
||||
|
||||
// precomputed coefficients for derivatives in Horner form
|
||||
Sk8f xCoeff[3];
|
||||
Sk8f yCoeff[3];
|
||||
float xCoeff[3][8];
|
||||
float yCoeff[3][8];
|
||||
};
|
||||
|
||||
class SkCurveMeasure {
|
||||
|
Loading…
Reference in New Issue
Block a user