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:
Mike Klein 2016-10-14 17:09:03 -04:00 committed by Skia Commit-Bot
parent e5e7eb1478
commit 1e76464f87
6 changed files with 43 additions and 18 deletions

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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 {