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

Unified Diff: src/effects/gradients/SkLinearGradient.cpp

Issue 2409583003: Apply linear gradient premul in 4f (Closed)
Patch Set: cleanup Created 4 years, 2 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/effects/gradients/SkLinearGradient.cpp
diff --git a/src/effects/gradients/SkLinearGradient.cpp b/src/effects/gradients/SkLinearGradient.cpp
index a249ae4ac82c2195ce2e559978cf057ce0a8377a..d631d942d932363fb28e8dd1d4cc5dcf01bdd2cf 100644
--- a/src/effects/gradients/SkLinearGradient.cpp
+++ b/src/effects/gradients/SkLinearGradient.cpp
@@ -525,25 +525,62 @@ find_backward(const SkLinearGradient::LinearGradientContext::Rec rec[], float ti
return rec;
}
-template <bool apply_alpha> SkPMColor trunc_from_255(const Sk4f& x) {
+// As an optimization, we can apply the dither bias before interpolation -- but only when
+// operating in premul space (apply_alpha == false). When apply_alpha == true, we must
+// defer the bias application until after premul.
+//
+// The following two helpers encapsulate this logic: pre_bias is called before interpolation,
+// and effects the bias when apply_alpha == false, while post_bias is called after premul and
+// effects the bias for the apply_alpha == true case.
+
+template <bool apply_alpha>
+Sk4f pre_bias(const Sk4f& x, const Sk4f& bias) {
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_PREMUL
+ return x + bias;
+#else
+ return apply_alpha ? x : x + bias;
+#endif
+}
+
+template <bool apply_alpha>
+Sk4f post_bias(const Sk4f& x, const Sk4f& bias) {
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_PREMUL
+ return x;
+#else
+ return apply_alpha ? x + bias : x;
+#endif
+}
+
+template <bool apply_alpha> SkPMColor trunc_from_255(const Sk4f& x, const Sk4f& bias) {
SkPMColor c;
+
+#ifdef SK_SUPPORT_LEGACY_GRADIENT_PREMUL
SkNx_cast<uint8_t>(x).store(&c);
if (apply_alpha) {
c = SkPreMultiplyARGB(SkGetPackedA32(c), SkGetPackedR32(c),
SkGetPackedG32(c), SkGetPackedB32(c));
}
+#else
+ Sk4f c4f255 = x;
+ if (apply_alpha) {
+ const float scale = x[SkPM4f::A] * (1 / 255.f);
+ c4f255 *= Sk4f(scale, scale, scale, 1);
+ }
+ SkNx_cast<uint8_t>(post_bias<apply_alpha>(c4f255, bias)).store(&c);
+#endif
return c;
}
template <bool apply_alpha> void fill(SkPMColor dst[], int count,
- const Sk4f& c4, const Sk4f& c4other) {
- sk_memset32_dither(dst, trunc_from_255<apply_alpha>(c4),
- trunc_from_255<apply_alpha>(c4other), count);
+ const Sk4f& c4, const Sk4f& bias0, const Sk4f& bias1) {
+ const SkPMColor c0 = trunc_from_255<apply_alpha>(pre_bias<apply_alpha>(c4, bias0), bias0);
+ const SkPMColor c1 = trunc_from_255<apply_alpha>(pre_bias<apply_alpha>(c4, bias1), bias1);
+ sk_memset32_dither(dst, c0, c1, count);
}
template <bool apply_alpha> void fill(SkPMColor dst[], int count, const Sk4f& c4) {
// Assumes that c4 does not need to be dithered.
- sk_memset32(dst, trunc_from_255<apply_alpha>(c4), count);
+ sk_memset32(dst, trunc_from_255<apply_alpha>(c4, 0), count);
}
/*
@@ -573,8 +610,8 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co
const Sk4f& dither0, const Sk4f& dither1) {
Sk4f dc2 = dc + dc;
Sk4f dc4 = dc2 + dc2;
- Sk4f cd0 = c + dither0;
- Sk4f cd1 = c + dc + dither1;
+ Sk4f cd0 = pre_bias<apply_alpha>(c , dither0);
+ Sk4f cd1 = pre_bias<apply_alpha>(c + dc, dither1);
Sk4f cd2 = cd0 + dc2;
Sk4f cd3 = cd1 + dc2;
while (n >= 4) {
@@ -582,10 +619,10 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co
Sk4f_ToBytes((uint8_t*)dstC, cd0, cd1, cd2, cd3);
dstC += 4;
} else {
- *dstC++ = trunc_from_255<apply_alpha>(cd0);
- *dstC++ = trunc_from_255<apply_alpha>(cd1);
- *dstC++ = trunc_from_255<apply_alpha>(cd2);
- *dstC++ = trunc_from_255<apply_alpha>(cd3);
+ *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0);
+ *dstC++ = trunc_from_255<apply_alpha>(cd1, dither1);
+ *dstC++ = trunc_from_255<apply_alpha>(cd2, dither0);
+ *dstC++ = trunc_from_255<apply_alpha>(cd3, dither1);
}
cd0 = cd0 + dc4;
cd1 = cd1 + dc4;
@@ -594,12 +631,12 @@ template <bool apply_alpha> void ramp(SkPMColor dstC[], int n, const Sk4f& c, co
n -= 4;
}
if (n & 2) {
- *dstC++ = trunc_from_255<apply_alpha>(cd0);
- *dstC++ = trunc_from_255<apply_alpha>(cd1);
+ *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0);
+ *dstC++ = trunc_from_255<apply_alpha>(cd1, dither1);
cd0 = cd0 + dc2;
}
if (n & 1) {
- *dstC++ = trunc_from_255<apply_alpha>(cd0);
+ *dstC++ = trunc_from_255<apply_alpha>(cd0, dither0);
}
}
@@ -746,9 +783,9 @@ void SkLinearGradient::LinearGradientContext::shade4_clamp(int x, int y, SkPMCol
const float pinFx = SkTPin(fx, 0.0f, 1.0f);
Sk4f c = lerp_color(pinFx, find_forward(fRecs.begin(), pinFx));
if (fApplyAlphaAfterInterp) {
- fill<true>(dstC, count, c + dither0, c + dither1);
+ fill<true>(dstC, count, c, dither0, dither1);
} else {
- fill<false>(dstC, count, c + dither0, c + dither1);
+ fill<false>(dstC, count, c, dither0, dither1);
}
return;
}
« 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