aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/core/SkBlendMode.cpp28
-rw-r--r--src/core/SkBlendModePriv.h6
-rw-r--r--src/core/SkOpts.h2
-rw-r--r--src/core/SkXfermode.cpp416
-rw-r--r--src/core/SkXfermodePriv.h1
-rw-r--r--src/core/SkXfermode_proccoeff.h9
-rw-r--r--src/effects/SkXfermodeImageFilter.cpp5
-rw-r--r--src/gpu/effects/GrXfermodeFragmentProcessor.cpp8
-rw-r--r--src/opts/SkXfermode_opts.h14
9 files changed, 86 insertions, 403 deletions
diff --git a/src/core/SkBlendMode.cpp b/src/core/SkBlendMode.cpp
index d7ebfb8f8e..81ba69ad26 100644
--- a/src/core/SkBlendMode.cpp
+++ b/src/core/SkBlendMode.cpp
@@ -102,3 +102,31 @@ void SkBlendMode_AppendStages(SkBlendMode mode, SkRasterPipeline* p) {
}
p->append(stage);
}
+
+SkPM4f SkBlendMode_Apply(SkBlendMode mode, SkPM4f src, SkPM4f dst) {
+ // special-case simple/common modes...
+ switch (mode) {
+ case SkBlendMode::kClear: return {{ 0, 0, 0, 0 }};
+ case SkBlendMode::kSrc: return src;
+ case SkBlendMode::kDst: return dst;
+ case SkBlendMode::kSrcOver:
+ return SkPM4f::From4f(src.to4f() + dst.to4f() * Sk4f(1 - src.a()));
+ default:
+ break;
+ }
+
+ SkRasterPipeline_<256> p;
+ SkPM4f *src_ctx = &src,
+ *dst_ctx = &dst;
+
+ p.append(SkRasterPipeline::load_f32, &dst_ctx);
+ p.append(SkRasterPipeline::move_src_dst);
+ p.append(SkRasterPipeline::load_f32, &src_ctx);
+ SkBlendMode_AppendStages(mode, &p);
+ if (SkBlendMode_CanOverflow(mode)) {
+ p.append(SkRasterPipeline::clamp_1);
+ }
+ p.append(SkRasterPipeline::store_f32, &dst_ctx);
+ p.run(0, 0, 1);
+ return dst;
+}
diff --git a/src/core/SkBlendModePriv.h b/src/core/SkBlendModePriv.h
index c965fe2cb9..406076b2d3 100644
--- a/src/core/SkBlendModePriv.h
+++ b/src/core/SkBlendModePriv.h
@@ -9,7 +9,9 @@
#define SkBlendModePriv_DEFINED
#include "SkBlendMode.h"
-#include "SkRasterPipeline.h"
+#include "SkPM4f.h"
+
+class SkRasterPipeline;
bool SkBlendMode_SupportsCoverageAsAlpha(SkBlendMode);
bool SkBlendMode_CanOverflow(SkBlendMode);
@@ -37,4 +39,6 @@ enum class SkBlendModeCoeff {
bool SkBlendMode_AsCoeff(SkBlendMode mode, SkBlendModeCoeff* src, SkBlendModeCoeff* dst);
+SkPM4f SkBlendMode_Apply(SkBlendMode, SkPM4f src, SkPM4f dst);
+
#endif
diff --git a/src/core/SkOpts.h b/src/core/SkOpts.h
index 31153f929a..4c744e8d67 100644
--- a/src/core/SkOpts.h
+++ b/src/core/SkOpts.h
@@ -24,7 +24,7 @@ namespace SkOpts {
// Declare function pointers here...
// May return nullptr if we haven't specialized the given Mode.
- extern SkXfermode* (*create_xfermode)(const ProcCoeff&, SkBlendMode);
+ extern SkXfermode* (*create_xfermode)(SkXfermodeProc, SkBlendMode);
typedef void (*BoxBlur)(const SkPMColor*, int, const SkIRect& srcBounds, SkPMColor*, int, int, int, int, int);
extern BoxBlur box_blur_xx, box_blur_xy, box_blur_yx;
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp
index 02abe55f74..e6c10e7c4b 100644
--- a/src/core/SkXfermode.cpp
+++ b/src/core/SkXfermode.cpp
@@ -56,308 +56,6 @@ static inline int clamp_div255round(int prod) {
}
///////////////////////////////////////////////////////////////////////////////
-#include "SkNx.h"
-
-static Sk4f alpha(const Sk4f& color) { return Sk4f(color[3]); }
-static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color[3]); }
-static Sk4f pin_1(const Sk4f& value) { return Sk4f::Min(value, Sk4f(1)); }
-
-static Sk4f color_alpha(const Sk4f& color, float newAlpha) {
- return Sk4f(color[0], color[1], color[2], newAlpha);
-}
-static Sk4f color_alpha(const Sk4f& color, const Sk4f& newAlpha) {
- return color_alpha(color, newAlpha[3]);
-}
-
-static Sk4f set_argb(float a, float r, float g, float b) {
- if (0 == SkPM4f::R) {
- return Sk4f(r, g, b, a);
- } else {
- return Sk4f(b, g, r, a);
- }
-}
-
-static Sk4f clear_4f(const Sk4f& s, const Sk4f& d) { return Sk4f(0); }
-static Sk4f src_4f(const Sk4f& s, const Sk4f& d) { return s; }
-static Sk4f dst_4f(const Sk4f& s, const Sk4f& d) { return d; }
-static Sk4f srcover_4f(const Sk4f& s, const Sk4f& d) { return s + inv_alpha(s) * d; }
-static Sk4f dstover_4f(const Sk4f& s, const Sk4f& d) { return d + inv_alpha(d) * s; }
-static Sk4f srcin_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d); }
-static Sk4f dstin_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s); }
-static Sk4f srcout_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d); }
-static Sk4f dstout_4f(const Sk4f& s, const Sk4f& d) { return d * inv_alpha(s); }
-static Sk4f srcatop_4f(const Sk4f& s, const Sk4f& d) { return s * alpha(d) + d * inv_alpha(s); }
-static Sk4f dstatop_4f(const Sk4f& s, const Sk4f& d) { return d * alpha(s) + s * inv_alpha(d); }
-static Sk4f xor_4f(const Sk4f& s, const Sk4f& d) { return s * inv_alpha(d) + d * inv_alpha(s);}
-static Sk4f plus_4f(const Sk4f& s, const Sk4f& d) { return pin_1(s + d); }
-static Sk4f modulate_4f(const Sk4f& s, const Sk4f& d) { return s * d; }
-static Sk4f screen_4f(const Sk4f& s, const Sk4f& d) { return s + d - s * d; }
-
-static Sk4f multiply_4f(const Sk4f& s, const Sk4f& d) {
- return s * inv_alpha(d) + d * inv_alpha(s) + s * d;
-}
-
-static Sk4f overlay_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- Sk4f two = Sk4f(2);
- Sk4f rc = (two * d <= da).thenElse(two * s * d,
- sa * da - two * (da - d) * (sa - s));
- return pin_1(s + d - s * da + color_alpha(rc - d * sa, 0));
-}
-
-static Sk4f hardlight_4f(const Sk4f& s, const Sk4f& d) {
- return overlay_4f(d, s);
-}
-
-static Sk4f darken_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- return s + d - Sk4f::Max(s * da, d * sa);
-}
-
-static Sk4f lighten_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- return s + d - Sk4f::Min(s * da, d * sa);
-}
-
-static Sk4f colordodge_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- Sk4f isa = Sk4f(1) - sa;
- Sk4f ida = Sk4f(1) - da;
-
- Sk4f srcover = s + d * isa;
- Sk4f dstover = d + s * ida;
- Sk4f otherwise = sa * Sk4f::Min(da, (d * sa) / (sa - s)) + s * ida + d * isa;
-
- // Order matters here, preferring d==0 over s==sa.
- auto colors = (d == Sk4f(0)).thenElse(dstover,
- (s == sa).thenElse(srcover,
- otherwise));
- return color_alpha(colors, srcover);
-}
-
-static Sk4f colorburn_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- Sk4f isa = Sk4f(1) - sa;
- Sk4f ida = Sk4f(1) - da;
-
- Sk4f srcover = s + d * isa;
- Sk4f dstover = d + s * ida;
- Sk4f otherwise = sa * (da - Sk4f::Min(da, (da - d) * sa / s)) + s * ida + d * isa;
-
- // Order matters here, preferring d==da over s==0.
- auto colors = (d == da).thenElse(dstover,
- (s == Sk4f(0)).thenElse(srcover,
- otherwise));
- return color_alpha(colors, srcover);
-}
-
-static Sk4f softlight_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f sa = alpha(s);
- Sk4f da = alpha(d);
- Sk4f isa = Sk4f(1) - sa;
- Sk4f ida = Sk4f(1) - da;
-
- // Some common terms.
- Sk4f m = (da > Sk4f(0)).thenElse(d / da, Sk4f(0));
- Sk4f s2 = Sk4f(2) * s;
- Sk4f m4 = Sk4f(4) * m;
-
- // The logic forks three ways:
- // 1. dark src?
- // 2. light src, dark dst?
- // 3. light src, light dst?
- Sk4f darkSrc = d * (sa + (s2 - sa) * (Sk4f(1) - m)); // Used in case 1.
- Sk4f darkDst = (m4 * m4 + m4) * (m - Sk4f(1)) + Sk4f(7) * m; // Used in case 2.
- Sk4f liteDst = m.sqrt() - m; // Used in case 3.
- Sk4f liteSrc = d * sa + da * (s2 - sa) * (Sk4f(4) * d <= da).thenElse(darkDst,
- liteDst); // Case 2 or 3?
-
- return color_alpha(s * ida + d * isa + (s2 <= sa).thenElse(darkSrc, liteSrc), // Case 1 or 2/3?
- s + d * isa);
-}
-
-static Sk4f difference_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f min = Sk4f::Min(s * alpha(d), d * alpha(s));
- return s + d - min - color_alpha(min, 0);
-}
-
-static Sk4f exclusion_4f(const Sk4f& s, const Sk4f& d) {
- Sk4f product = s * d;
- return s + d - product - color_alpha(product, 0);
-}
-
-////////////////////////////////////////////////////
-
-// The CSS compositing spec introduces the following formulas:
-// (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable)
-// SkComputeLuminance is similar to this formula but it uses the new definition from Rec. 709
-// while PDF and CG uses the one from Rec. Rec. 601
-// See http://www.glennchan.info/articles/technical/hd-versus-sd-color-space/hd-versus-sd-color-space.htm
-static inline float Lum(float r, float g, float b) {
- return r * 0.2126f + g * 0.7152f + b * 0.0722f;
-}
-
-static inline float max(float a, float b, float c) {
- return SkTMax(a, SkTMax(b, c));
-}
-
-static inline float min(float a, float b, float c) {
- return SkTMin(a, SkTMin(b, c));
-}
-
-static inline float Sat(float r, float g, float b) {
- return max(r, g, b) - min(r, g, b);
-}
-
-static inline void setSaturationComponents(float* Cmin, float* Cmid, float* Cmax, float s) {
- if(*Cmax > *Cmin) {
- *Cmid = (*Cmid - *Cmin) * s / (*Cmax - *Cmin);
- *Cmax = s;
- } else {
- *Cmax = 0;
- *Cmid = 0;
- }
- *Cmin = 0;
-}
-
-static inline void SetSat(float* r, float* g, float* b, float s) {
- if(*r <= *g) {
- if(*g <= *b) {
- setSaturationComponents(r, g, b, s);
- } else if(*r <= *b) {
- setSaturationComponents(r, b, g, s);
- } else {
- setSaturationComponents(b, r, g, s);
- }
- } else if(*r <= *b) {
- setSaturationComponents(g, r, b, s);
- } else if(*g <= *b) {
- setSaturationComponents(g, b, r, s);
- } else {
- setSaturationComponents(b, g, r, s);
- }
-}
-
-static inline void clipColor(float* r, float* g, float* b, float a) {
- float L = Lum(*r, *g, *b);
- float n = min(*r, *g, *b);
- float x = max(*r, *g, *b);
- float denom;
- if ((n < 0) && (denom = L - n)) { // Compute denom and make sure it's non zero
- float scale = L / denom;
- *r = L + (*r - L) * scale;
- *g = L + (*g - L) * scale;
- *b = L + (*b - L) * scale;
- }
-
- if ((x > a) && (denom = x - L)) { // Compute denom and make sure it's non zero
- float scale = (a - L) / denom;
- *r = L + (*r - L) * scale;
- *g = L + (*g - L) * scale;
- *b = L + (*b - L) * scale;
- }
-}
-
-static inline void SetLum(float* r, float* g, float* b, float a, float l) {
- float d = l - Lum(*r, *g, *b);
- *r += d;
- *g += d;
- *b += d;
- clipColor(r, g, b, a);
-}
-
-static Sk4f hue_4f(const Sk4f& s, const Sk4f& d) {
- float sa = s[SkPM4f::A];
- float sr = s[SkPM4f::R];
- float sg = s[SkPM4f::G];
- float sb = s[SkPM4f::B];
-
- float da = d[SkPM4f::A];
- float dr = d[SkPM4f::R];
- float dg = d[SkPM4f::G];
- float db = d[SkPM4f::B];
-
- float Sr = sr;
- float Sg = sg;
- float Sb = sb;
- SetSat(&Sr, &Sg, &Sb, Sat(dr, dg, db) * sa);
- SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
-
- return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb),
- sa + da - sa * da);
-}
-
-static Sk4f saturation_4f(const Sk4f& s, const Sk4f& d) {
- float sa = s[SkPM4f::A];
- float sr = s[SkPM4f::R];
- float sg = s[SkPM4f::G];
- float sb = s[SkPM4f::B];
-
- float da = d[SkPM4f::A];
- float dr = d[SkPM4f::R];
- float dg = d[SkPM4f::G];
- float db = d[SkPM4f::B];
-
- float Dr = dr;
- float Dg = dg;
- float Db = db;
- SetSat(&Dr, &Dg, &Db, Sat(sr, sg, sb) * da);
- SetLum(&Dr, &Dg, &Db, sa * da, Lum(dr, dg, db) * sa);
-
- return color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db),
- sa + da - sa * da);
-}
-
-static Sk4f color_4f(const Sk4f& s, const Sk4f& d) {
- float sa = s[SkPM4f::A];
- float sr = s[SkPM4f::R];
- float sg = s[SkPM4f::G];
- float sb = s[SkPM4f::B];
-
- float da = d[SkPM4f::A];
- float dr = d[SkPM4f::R];
- float dg = d[SkPM4f::G];
- float db = d[SkPM4f::B];
-
- float Sr = sr;
- float Sg = sg;
- float Sb = sb;
- SetLum(&Sr, &Sg, &Sb, sa * da, Lum(dr, dg, db) * sa);
-
- Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Sr, Sg, Sb),
- sa + da - sa * da);
- // Can return tiny negative values ...
- return Sk4f::Max(res, Sk4f(0));
-}
-
-static Sk4f luminosity_4f(const Sk4f& s, const Sk4f& d) {
- float sa = s[SkPM4f::A];
- float sr = s[SkPM4f::R];
- float sg = s[SkPM4f::G];
- float sb = s[SkPM4f::B];
-
- float da = d[SkPM4f::A];
- float dr = d[SkPM4f::R];
- float dg = d[SkPM4f::G];
- float db = d[SkPM4f::B];
-
- float Dr = dr;
- float Dg = dg;
- float Db = db;
- SetLum(&Dr, &Dg, &Db, sa * da, Lum(sr, sg, sb) * da);
-
- Sk4f res = color_alpha(s * inv_alpha(d) + d * inv_alpha(s) + set_argb(0, Dr, Dg, Db),
- sa + da - sa * da);
- // Can return tiny negative values ...
- return Sk4f::Max(res, Sk4f(0));
-}
-
-///////////////////////////////////////////////////////////////////////////////
// kClear_Mode, //!< [0, 0]
static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) {
@@ -924,71 +622,39 @@ static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) {
///////////////////////////////////////////////////////////////////////////////////////////////////
-static SkPM4f as_pm4f(const Sk4f& x) {
- SkPM4f pm4;
- x.store(pm4.fVec);
- return pm4;
-}
-
-static Sk4f as_4f(const SkPM4f& pm4) {
- return Sk4f::Load(pm4.fVec);
-}
-
-static void assert_unit(const SkPM4f& r) {
-#ifdef SK_DEBUG
- const float eps = 0.00001f;
- const float min = 0 - eps;
- const float max = 1 + eps;
- for (int i = 0; i < 4; ++i) {
- SkASSERT(r.fVec[i] >= min && r.fVec[i] <= max);
- }
-#endif
-}
-
-template <Sk4f (blend)(const Sk4f&, const Sk4f&)> SkPM4f proc_4f(const SkPM4f& s, const SkPM4f& d) {
- assert_unit(s);
- assert_unit(d);
- SkPM4f r = as_pm4f(blend(as_4f(s), as_4f(d)));
- // Turn this assert off for now because srgb conversions may end up in rgb > a
- // assert_unit(r);
- return r;
-}
-
-const ProcCoeff gProcCoeffs[] = {
- { clear_modeproc, proc_4f<clear_4f> },
- { src_modeproc, proc_4f<src_4f> },
- { dst_modeproc, proc_4f<dst_4f> },
- { srcover_modeproc, proc_4f<srcover_4f> },
- { dstover_modeproc, proc_4f<dstover_4f> },
- { srcin_modeproc, proc_4f<srcin_4f> },
- { dstin_modeproc, proc_4f<dstin_4f> },
- { srcout_modeproc, proc_4f<srcout_4f> },
- { dstout_modeproc, proc_4f<dstout_4f> },
- { srcatop_modeproc, proc_4f<srcatop_4f> },
- { dstatop_modeproc, proc_4f<dstatop_4f> },
- { xor_modeproc, proc_4f<xor_4f> },
-
- { plus_modeproc, proc_4f<plus_4f> },
- { modulate_modeproc, proc_4f<modulate_4f> },
- { screen_modeproc, proc_4f<screen_4f> },
- { overlay_modeproc, proc_4f<overlay_4f> },
- { darken_modeproc, proc_4f<darken_4f> },
- { lighten_modeproc, proc_4f<lighten_4f> },
- { colordodge_modeproc, proc_4f<colordodge_4f> },
- { colorburn_modeproc, proc_4f<colorburn_4f> },
- { hardlight_modeproc, proc_4f<hardlight_4f> },
- { softlight_modeproc, proc_4f<softlight_4f> },
- { difference_modeproc, proc_4f<difference_4f> },
- { exclusion_modeproc, proc_4f<exclusion_4f> },
- { multiply_modeproc, proc_4f<multiply_4f> },
- { hue_modeproc, proc_4f<hue_4f> },
- { saturation_modeproc, proc_4f<saturation_4f> },
- { color_modeproc, proc_4f<color_4f> },
- { luminosity_modeproc, proc_4f<luminosity_4f> },
+const SkXfermodeProc gProcs[] = {
+ clear_modeproc,
+ src_modeproc,
+ dst_modeproc,
+ srcover_modeproc,
+ dstover_modeproc,
+ srcin_modeproc,
+ dstin_modeproc,
+ srcout_modeproc,
+ dstout_modeproc,
+ srcatop_modeproc,
+ dstatop_modeproc,
+ xor_modeproc,
+
+ plus_modeproc,
+ modulate_modeproc,
+ screen_modeproc,
+ overlay_modeproc,
+ darken_modeproc,
+ lighten_modeproc,
+ colordodge_modeproc,
+ colorburn_modeproc,
+ hardlight_modeproc,
+ softlight_modeproc,
+ difference_modeproc,
+ exclusion_modeproc,
+ multiply_modeproc,
+ hue_modeproc,
+ saturation_modeproc,
+ color_modeproc,
+ luminosity_modeproc,
};
-///////////////////////////////////////////////////////////////////////////////
-
bool SkXfermode::asMode(SkBlendMode* mode) const {
return false;
}
@@ -1015,7 +681,7 @@ const GrXPFactory* SkXfermode::asXPFactory() const {
sk_sp<SkFlattenable> SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) {
uint32_t mode32 = buffer.read32();
- if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) {
+ if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcs))) {
return nullptr;
}
return SkXfermode::Make((SkBlendMode)mode32);
@@ -1115,17 +781,17 @@ sk_sp<SkXfermode> SkXfermode::Make(SkBlendMode mode) {
}
const int COUNT_BLENDMODES = (int)SkBlendMode::kLastMode + 1;
- SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == COUNT_BLENDMODES);
+ SkASSERT(SK_ARRAY_COUNT(gProcs) == COUNT_BLENDMODES);
static SkOnce once[COUNT_BLENDMODES];
static SkXfermode* cached[COUNT_BLENDMODES];
once[(int)mode]([mode] {
- ProcCoeff rec = gProcCoeffs[(int)mode];
- if (auto xfermode = SkOpts::create_xfermode(rec, mode)) {
+ SkXfermodeProc proc = gProcs[(int)mode];
+ if (auto xfermode = SkOpts::create_xfermode(proc, mode)) {
cached[(int)mode] = xfermode;
} else {
- cached[(int)mode] = new SkProcCoeffXfermode(rec, mode);
+ cached[(int)mode] = new SkProcCoeffXfermode(proc, mode);
}
});
return sk_ref_sp(cached[(int)mode]);
@@ -1134,15 +800,7 @@ sk_sp<SkXfermode> SkXfermode::Make(SkBlendMode mode) {
SkXfermodeProc SkXfermode::GetProc(SkBlendMode mode) {
SkXfermodeProc proc = nullptr;
if ((unsigned)mode <= (unsigned)SkBlendMode::kLastMode) {
- proc = gProcCoeffs[(unsigned)mode].fProc;
- }
- return proc;
-}
-
-SkXfermodeProc4f SkXfermode::GetProc4f(SkBlendMode mode) {
- SkXfermodeProc4f proc = nullptr;
- if ((unsigned)mode <= (unsigned)SkBlendMode::kLastMode) {
- proc = gProcCoeffs[(unsigned)mode].fProc4f;
+ proc = gProcs[(unsigned)mode];
}
return proc;
}
diff --git a/src/core/SkXfermodePriv.h b/src/core/SkXfermodePriv.h
index 51e08be137..c150666b5d 100644
--- a/src/core/SkXfermodePriv.h
+++ b/src/core/SkXfermodePriv.h
@@ -72,7 +72,6 @@ public:
}
static SkXfermodeProc GetProc(SkBlendMode);
- static SkXfermodeProc4f GetProc4f(SkBlendMode);
enum SrcColorOpacity {
// The src color is known to be opaque (alpha == 255)
diff --git a/src/core/SkXfermode_proccoeff.h b/src/core/SkXfermode_proccoeff.h
index fdc36c6e86..5bcd3a05c2 100644
--- a/src/core/SkXfermode_proccoeff.h
+++ b/src/core/SkXfermode_proccoeff.h
@@ -10,18 +10,13 @@
#include "SkXfermodePriv.h"
-struct ProcCoeff {
- SkXfermodeProc fProc;
- SkXfermodeProc4f fProc4f;
-};
-
#define CANNOT_USE_COEFF SkXfermode::Coeff(-1)
class SK_API SkProcCoeffXfermode : public SkXfermode {
public:
- SkProcCoeffXfermode(const ProcCoeff& rec, SkBlendMode mode) {
+ SkProcCoeffXfermode(SkXfermodeProc proc, SkBlendMode mode) {
fMode = mode;
- fProc = rec.fProc;
+ fProc = proc;
}
void xfer32(SkPMColor dst[], const SkPMColor src[], int count,
diff --git a/src/effects/SkXfermodeImageFilter.cpp b/src/effects/SkXfermodeImageFilter.cpp
index 3228d15932..dd37611775 100644
--- a/src/effects/SkXfermodeImageFilter.cpp
+++ b/src/effects/SkXfermodeImageFilter.cpp
@@ -327,10 +327,9 @@ SkXfermodeImageFilter_Base::makeFGFrag(sk_sp<GrFragmentProcessor> bgFP) const {
// It would be awesome to use SkXfermode::Create here but it knows better
// than us and won't return a kSrcOver_Mode SkXfermode. That means we
// have to get one the hard way.
- struct ProcCoeff rec;
- rec.fProc = SkXfermode::GetProc(SkBlendMode::kSrcOver);
+ SkXfermodeProc proc = SkXfermode::GetProc(SkBlendMode::kSrcOver);
- srcover.reset(new SkProcCoeffXfermode(rec, SkBlendMode::kSrcOver));
+ srcover.reset(new SkProcCoeffXfermode(proc, SkBlendMode::kSrcOver));
xfer = srcover.get();
}
diff --git a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
index 8779c558cd..f034938852 100644
--- a/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
+++ b/src/gpu/effects/GrXfermodeFragmentProcessor.cpp
@@ -143,8 +143,8 @@ private:
GrColor4f dstColor = ConstantOutputForConstantInput(this->childProcessor(1), input);
SkPM4f src = GrColor4fToSkPM4f(srcColor);
SkPM4f dst = GrColor4fToSkPM4f(dstColor);
- auto proc = SkXfermode::GetProc4f(fMode);
- return SkPM4fToGrColor4f(proc(src, dst)).mulByScalar(alpha);
+ SkPM4f res = SkBlendMode_Apply(fMode, src, dst);
+ return SkPM4fToGrColor4f(res).mulByScalar(alpha);
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@@ -391,8 +391,8 @@ private:
src = GrColor4fToSkPM4f(inputColor);
dst = GrColor4fToSkPM4f(childColor);
}
- auto proc = SkXfermode::GetProc4f(fMode);
- return SkPM4fToGrColor4f(proc(src, dst));
+ SkPM4f res = SkBlendMode_Apply(fMode, src, dst);
+ return SkPM4fToGrColor4f(res);
}
private:
diff --git a/src/opts/SkXfermode_opts.h b/src/opts/SkXfermode_opts.h
index e7db073392..85715fad3e 100644
--- a/src/opts/SkXfermode_opts.h
+++ b/src/opts/SkXfermode_opts.h
@@ -217,8 +217,8 @@ template <> void mark_dst_initialized_if_safe<Clear>(void* dst, void* end) {
template <typename Xfermode>
class Sk4pxXfermode : public SkProcCoeffXfermode {
public:
- Sk4pxXfermode(const ProcCoeff& rec, SkBlendMode mode)
- : INHERITED(rec, mode) {}
+ Sk4pxXfermode(SkXfermodeProc proc, SkBlendMode mode)
+ : INHERITED(proc, mode) {}
void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[]) const override {
mark_dst_initialized_if_safe<Xfermode>(dst, dst+n);
@@ -236,8 +236,8 @@ private:
template <typename Xfermode>
class Sk4fXfermode : public SkProcCoeffXfermode {
public:
- Sk4fXfermode(const ProcCoeff& rec, SkBlendMode mode)
- : INHERITED(rec, mode) {}
+ Sk4fXfermode(SkXfermodeProc proc, SkBlendMode mode)
+ : INHERITED(proc, mode) {}
void xfer32(SkPMColor dst[], const SkPMColor src[], int n, const SkAlpha aa[]) const override {
for (int i = 0; i < n; i++) {
@@ -274,10 +274,10 @@ private:
namespace SK_OPTS_NS {
-static SkXfermode* create_xfermode(const ProcCoeff& rec, SkBlendMode mode) {
+static SkXfermode* create_xfermode(SkXfermodeProc proc, SkBlendMode mode) {
switch (mode) {
#define CASE(Xfermode) \
- case SkBlendMode::k##Xfermode: return new Sk4pxXfermode<Xfermode>(rec, mode)
+ case SkBlendMode::k##Xfermode: return new Sk4pxXfermode<Xfermode>(proc, mode)
CASE(Clear);
CASE(Src);
CASE(Dst);
@@ -303,7 +303,7 @@ static SkXfermode* create_xfermode(const ProcCoeff& rec, SkBlendMode mode) {
#undef CASE
#define CASE(Xfermode) \
- case SkBlendMode::k##Xfermode: return new Sk4fXfermode<Xfermode>(rec, mode)
+ case SkBlendMode::k##Xfermode: return new Sk4fXfermode<Xfermode>(proc, mode)
CASE(ColorDodge);
CASE(ColorBurn);
CASE(SoftLight);