mirror tiling
authorMike Klein <mtklein@chromium.org>
Fri, 18 Nov 2016 20:47:22 +0000 (15:47 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 18 Nov 2016 22:11:12 +0000 (22:11 +0000)
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=5064
CQ_INCLUDE_TRYBOTS=master.client.skia:Test-Ubuntu-GCC-GCE-CPU-AVX2-x86_64-Release-SKNX_NO_SIMD-Trybot

Change-Id: I9d48ba73e145701245e5ec4f32c8c360da6baddd
Reviewed-on: https://skia-review.googlesource.com/5064
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>

src/image/SkImageShader.cpp
src/opts/SkNx_sse.h
src/opts/SkRasterPipeline_opts.h

index a791e9c..81b6f76 100644 (file)
@@ -290,11 +290,6 @@ bool SkImageShader::onAppendStages(SkRasterPipeline* p, SkColorSpace* dst, SkFal
         default: return false;
     }
 
-    // TODO: all tile modes
-    if (fTileModeX == kMirror_TileMode || fTileModeY == kMirror_TileMode) {
-        return false;
-    }
-
     // When the matrix is just an integer translate, bilerp == nearest neighbor.
     if (matrix.getType() <= SkMatrix::kTranslate_Mask &&
         matrix.getTranslateX() == (int)matrix.getTranslateX() &&
index c1f4b2c..fa9f4cd 100644 (file)
@@ -610,6 +610,7 @@ public:
         AI SkNx  rsqrt() const { return _mm256_rsqrt_ps(fVec); }
         AI SkNx invert() const { return _mm256_rcp_ps  (fVec); }
 
+        AI SkNx abs() const { return _mm256_andnot_ps(_mm256_set1_ps(-0.0f), fVec); }
         AI SkNx floor() const { return _mm256_floor_ps(fVec); }
 
         AI float operator[](int k) const {
index d9760cb..ee957e1 100644 (file)
@@ -697,21 +697,25 @@ SI SkNf clamp(const SkNf& v, float limit) {
 
 SI SkNf repeat(const SkNf& v, float limit) {
     SkNf result = v - (v/limit).floor()*limit;
-
     // For small negative v, (v/limit).floor()*limit can dominate v in the subtraction,
     // which leaves result == limit.  We want result < limit, so clamp it one ULP.
     result = SkNf::Min(result, nextafterf(limit, 0));
-
     return assert_in_tile(result, limit);
 }
 
+SI SkNf mirror(const SkNf& v, float l/*imit*/) {
+    SkNf result = ((v - l) - ((v - l) / (2*l)).floor()*(2*l) - l).abs();
+    // Same deal as repeat.
+    result = SkNf::Min(result, nextafterf(l, 0));
+    return assert_in_tile(result, l);
+}
+
 STAGE(clamp_x,  true) { r = clamp (r, *(const int*)ctx); }
 STAGE(clamp_y,  true) { g = clamp (g, *(const int*)ctx); }
 STAGE(repeat_x, true) { r = repeat(r, *(const int*)ctx); }
 STAGE(repeat_y, true) { g = repeat(g, *(const int*)ctx); }
-
-STAGE(mirror_x, true) {}  // TODO
-STAGE(mirror_y, true) {}  // TODO
+STAGE(mirror_x, true) { r = mirror(r, *(const int*)ctx); }
+STAGE(mirror_y, true) { g = mirror(g, *(const int*)ctx); }
 
 
 struct NearestCtx {