diff options
-rw-r--r-- | src/core/SkBlendMode.cpp | 28 | ||||
-rw-r--r-- | src/core/SkBlendModePriv.h | 6 | ||||
-rw-r--r-- | src/core/SkOpts.h | 2 | ||||
-rw-r--r-- | src/core/SkXfermode.cpp | 416 | ||||
-rw-r--r-- | src/core/SkXfermodePriv.h | 1 | ||||
-rw-r--r-- | src/core/SkXfermode_proccoeff.h | 9 | ||||
-rw-r--r-- | src/effects/SkXfermodeImageFilter.cpp | 5 | ||||
-rw-r--r-- | src/gpu/effects/GrXfermodeFragmentProcessor.cpp | 8 | ||||
-rw-r--r-- | src/opts/SkXfermode_opts.h | 14 |
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); |