Index: src/core/Sk4px.h |
diff --git a/src/core/Sk4px.h b/src/core/Sk4px.h |
index 3d2a8e336222c893f345d68af2d33557e2dc7640..830e60a156567c2859a382a799926077cd6522ef 100644 |
--- a/src/core/Sk4px.h |
+++ b/src/core/Sk4px.h |
@@ -34,6 +34,12 @@ public: |
// Pack the top byte of each component back down into 4 SkPMColors. |
Sk4px addNarrowHi(const Sk16h&) const; |
+ |
+ Sk4px div255TruncNarrow() const { return this->addNarrowHi(*this >> 8); } |
+ Sk4px div255RoundNarrow() const { |
+ return Sk4px::Wide(*this + Sk16h(128)).div255TruncNarrow(); |
+ } |
+ |
private: |
typedef Sk16h INHERITED; |
}; |
@@ -73,6 +79,72 @@ public: |
} |
} |
+ // As above, but with dst4' = fn(dst4, src4). |
+ template <typename Fn> |
+ static void MapDstSrc(int count, SkPMColor* dst, const SkPMColor* src, Fn fn) { |
+ while (count > 0) { |
+ if (count >= 8) { |
+ Sk4px dst0 = fn(Load4(dst+0), Load4(src+0)), |
+ dst4 = fn(Load4(dst+4), Load4(src+4)); |
+ dst0.store4(dst+0); |
+ dst4.store4(dst+4); |
+ dst += 8; src += 8; count -= 8; |
+ continue; // Keep our stride at 8 pixels as long as possible. |
+ } |
+ SkASSERT(count <= 7); |
+ if (count >= 4) { |
+ fn(Load4(dst), Load4(src)).store4(dst); |
+ dst += 4; src += 4; count -= 4; |
+ } |
+ if (count >= 2) { |
+ fn(Load2(dst), Load2(src)).store2(dst); |
+ dst += 2; src += 2; count -= 2; |
+ } |
+ if (count >= 1) { |
+ fn(Load1(dst), Load1(src)).store1(dst); |
+ } |
+ break; |
+ } |
+ } |
+ |
+ // As above, but with dst4' = fn(dst4, src4, alpha4). |
+ template <typename Fn> |
+ static void MapDstSrcAlpha( |
+ int count, SkPMColor* dst, const SkPMColor* src, const SkAlpha* a, Fn fn) { |
+ // TODO: find a terser / faster way to construct Sk16b alphas. |
+ while (count > 0) { |
+ if (count >= 8) { |
+ Sk16b alpha0(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], |
+ a[2],a[2],a[2],a[2], a[3],a[3],a[3],a[3]), |
+ alpha4(a[4],a[4],a[4],a[4], a[5],a[5],a[5],a[5], |
+ a[6],a[6],a[6],a[6], a[7],a[7],a[7],a[7]); |
+ Sk4px dst0 = fn(Load4(dst+0), Load4(src+0), alpha0), |
+ dst4 = fn(Load4(dst+4), Load4(src+4), alpha4); |
+ dst0.store4(dst+0); |
+ dst4.store4(dst+4); |
+ dst += 8; src += 8; a += 8; count -= 8; |
+ continue; // Keep our stride at 8 pixels as long as possible. |
+ } |
+ SkASSERT(count <= 7); |
+ if (count >= 4) { |
+ Sk16b alpha(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], |
+ a[2],a[2],a[2],a[2], a[3],a[3],a[3],a[3]); |
+ fn(Load4(dst), Load4(src), alpha).store4(dst); |
+ dst += 4; src += 4; a += 4; count -= 4; |
+ } |
+ if (count >= 2) { |
+ Sk16b alpha(a[0],a[0],a[0],a[0], a[1],a[1],a[1],a[1], 0,0,0,0, 0,0,0,0); |
+ fn(Load2(dst), Load2(src), alpha).store2(dst); |
+ dst += 2; src += 2; a += 2; count -= 2; |
+ } |
+ if (count >= 1) { |
+ Sk16b alpha(a[0],a[0],a[0],a[0], 0,0,0,0, 0,0,0,0, 0,0,0,0); |
+ fn(Load1(dst), Load1(src), alpha).store1(dst); |
+ } |
+ break; |
+ } |
+ } |
+ |
private: |
typedef Sk16b INHERITED; |
}; |