Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(167)

Unified Diff: src/core/SkXfermode4f.cpp

Issue 1653943002: unroll srcover_1 for blending a single color (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: separate src_1 functions Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkXfermode4f.cpp
diff --git a/src/core/SkXfermode4f.cpp b/src/core/SkXfermode4f.cpp
index 0485a5e6edd4c0c65f884eae88b27beb8c9cd637..1bf66a2b6998afed75158e842f3ac6b7445783a3 100644
--- a/src/core/SkXfermode4f.cpp
+++ b/src/core/SkXfermode4f.cpp
@@ -31,10 +31,22 @@ template <DstType D> Sk4f load_dst(SkPMColor dstC) {
return (D == kSRGB_Dst) ? Sk4f_fromS32(dstC) : Sk4f_fromL32(dstC);
}
+static Sk4f srgb_4b_to_linear_unit(SkPMColor dstC) {
+ return Sk4f_fromS32(dstC);
+}
+
template <DstType D> uint32_t store_dst(const Sk4f& x4) {
return (D == kSRGB_Dst) ? Sk4f_toS32(x4) : Sk4f_toL32(x4);
}
+static uint32_t linear_unit_to_srgb_32(const Sk4f& l4) {
+ return Sk4f_toL32(l4);
+}
+
+static Sk4f linear_unit_to_srgb_255f(const Sk4f& l4) {
+ return linear_to_srgb(l4) * Sk4f(255) + Sk4f(0.5f);
+}
+
///////////////////////////////////////////////////////////////////////////////////////////////////
static Sk4f scale_255_round(const SkPM4f& pm4) {
@@ -254,10 +266,53 @@ template <DstType D> void srcover_n(const SkXfermode::PM4fState& state, uint32_t
}
}
-template <DstType D> void srcover_1(const SkXfermode::PM4fState& state, uint32_t dst[],
- const SkPM4f& src, int count, const SkAlpha aa[]) {
+static void srcover_linear_dst_1(const SkXfermode::PM4fState& state, uint32_t dst[],
+ const SkPM4f& src, int count, const SkAlpha aa[]) {
+ Sk4f s4 = Sk4f::Load(src.fVec);
+ Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
+
+ if (aa) {
+ for (int i = 0; i < count; ++i) {
+ unsigned a = aa[i];
+ if (0 == a) {
+ continue;
+ }
+ Sk4f d4 = Sk4f_fromL32(dst[i]);
+ Sk4f r4;
+ if (a != 0xFF) {
+ s4 = scale_by_coverage(s4, a);
+ r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
+ } else {
+ r4 = s4 + d4 * dst_scale;
+ }
+ dst[i] = Sk4f_toL32(r4);
+ }
+ } else {
+ s4 = s4 * Sk4f(255) + Sk4f(0.5f); // +0.5 to pre-bias for rounding
+ while (count >= 4) {
+ Sk4f d0 = to_4f(dst[0]);
+ Sk4f d1 = to_4f(dst[1]);
+ Sk4f d2 = to_4f(dst[2]);
+ Sk4f d3 = to_4f(dst[3]);
+ Sk4f_ToBytes((uint8_t*)dst,
+ s4 + d0 * dst_scale,
+ s4 + d1 * dst_scale,
+ s4 + d2 * dst_scale,
+ s4 + d3 * dst_scale);
+ dst += 4;
+ count -= 4;
+ }
+ for (int i = 0; i < count; ++i) {
+ Sk4f d4 = to_4f(dst[i]);
+ dst[i] = to_4b(s4 + d4 * dst_scale);
+ }
+ }
+}
+
+static void srcover_srgb_dst_1(const SkXfermode::PM4fState& state, uint32_t dst[],
+ const SkPM4f& src, int count, const SkAlpha aa[]) {
Sk4f s4 = Sk4f::Load(src.fVec);
- Sk4f scale = Sk4f(1 - get_alpha(s4));
+ Sk4f dst_scale = Sk4f(1 - get_alpha(s4));
if (aa) {
for (int i = 0; i < count; ++i) {
@@ -265,30 +320,42 @@ template <DstType D> void srcover_1(const SkXfermode::PM4fState& state, uint32_t
if (0 == a) {
continue;
}
- Sk4f d4 = load_dst<D>(dst[i]);
+ Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
Sk4f r4;
if (a != 0xFF) {
s4 = scale_by_coverage(s4, a);
r4 = s4 + d4 * Sk4f(1 - get_alpha(s4));
} else {
- r4 = s4 + d4 * scale;
+ r4 = s4 + d4 * dst_scale;
}
- dst[i] = store_dst<D>(r4);
+ dst[i] = linear_unit_to_srgb_32(r4);
}
} else {
+ while (count >= 4) {
+ Sk4f d0 = srgb_4b_to_linear_unit(dst[0]);
+ Sk4f d1 = srgb_4b_to_linear_unit(dst[1]);
+ Sk4f d2 = srgb_4b_to_linear_unit(dst[2]);
+ Sk4f d3 = srgb_4b_to_linear_unit(dst[3]);
+ Sk4f_ToBytes((uint8_t*)dst,
+ linear_unit_to_srgb_255f(s4 + d0 * dst_scale),
+ linear_unit_to_srgb_255f(s4 + d1 * dst_scale),
+ linear_unit_to_srgb_255f(s4 + d2 * dst_scale),
+ linear_unit_to_srgb_255f(s4 + d3 * dst_scale));
+ dst += 4;
+ count -= 4;
+ }
for (int i = 0; i < count; ++i) {
- Sk4f d4 = load_dst<D>(dst[i]);
- Sk4f r4 = s4 + d4 * scale;
- dst[i] = store_dst<D>(r4);
+ Sk4f d4 = srgb_4b_to_linear_unit(dst[i]);
+ dst[i] = to_4b(linear_unit_to_srgb_255f(s4 + d4 * dst_scale));
}
}
}
const XferProcPair gProcs_SrcOver[] = {
- { srcover_1<kLinear_Dst>, srcover_n<kLinear_Dst> }, // linear alpha
- { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear opaque [ we are src-mode ]
- { srcover_1<kSRGB_Dst>, srcover_n<kSRGB_Dst> }, // srgb alpha
- { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb opaque [ we are src-mode ]
+ { srcover_linear_dst_1, srcover_n<kLinear_Dst> }, // linear alpha
+ { src_1<kLinear_Dst>, src_n<kLinear_Dst> }, // linear opaque [ we are src-mode ]
+ { srcover_srgb_dst_1, srcover_n<kSRGB_Dst> }, // srgb alpha
+ { src_1<kSRGB_Dst>, src_n<kSRGB_Dst> }, // srgb opaque [ we are src-mode ]
};
///////////////////////////////////////////////////////////////////////////////////////////////////
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698