extend modecolorfilter to 4f
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1670063002 Review URL: https://codereview.chromium.org/1670063002
This commit is contained in:
parent
21eaf3b00a
commit
3125565804
@ -45,10 +45,14 @@ static SkColorFilter* make_cf1() {
|
||||
return SkColorFilter::CreateComposeFilter(a, b);
|
||||
}
|
||||
|
||||
static SkColorFilter* make_cf2() {
|
||||
return SkColorFilter::CreateModeFilter(0x8044CC88, SkXfermode::kSrcATop_Mode);
|
||||
}
|
||||
|
||||
static void draw_into_canvas(SkCanvas* canvas) {
|
||||
const SkRect r = SkRect::MakeWH(100, 100);
|
||||
const SkRect r = SkRect::MakeWH(50, 100);
|
||||
SkShader* (*shaders[])() { make_opaque_color, make_alpha_color };
|
||||
SkColorFilter* (*filters[])() { make_cf_null, make_cf0, make_cf1 };
|
||||
SkColorFilter* (*filters[])() { make_cf_null, make_cf0, make_cf1, make_cf2 };
|
||||
|
||||
SkPaint paint;
|
||||
for (auto shProc : shaders) {
|
||||
@ -56,13 +60,13 @@ static void draw_into_canvas(SkCanvas* canvas) {
|
||||
for (auto cfProc : filters) {
|
||||
SkSafeUnref(paint.setColorFilter(cfProc()));
|
||||
canvas->drawRect(r, paint);
|
||||
canvas->translate(120, 0);
|
||||
canvas->translate(60, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEF_SIMPLE_GM(color4f, canvas, 620, 260) {
|
||||
canvas->translate(20, 20);
|
||||
DEF_SIMPLE_GM(color4f, canvas, 1024, 260) {
|
||||
canvas->translate(10, 10);
|
||||
|
||||
SkPaint bg;
|
||||
// need the target to be opaque, so we can draw it to the screen
|
||||
@ -71,7 +75,7 @@ DEF_SIMPLE_GM(color4f, canvas, 620, 260) {
|
||||
|
||||
SkColorProfileType const profiles[] { kLinear_SkColorProfileType, kSRGB_SkColorProfileType };
|
||||
for (auto profile : profiles) {
|
||||
const SkImageInfo info = SkImageInfo::Make(600, 100, kN32_SkColorType, kPremul_SkAlphaType,
|
||||
const SkImageInfo info = SkImageInfo::Make(1024, 100, kN32_SkColorType, kPremul_SkAlphaType,
|
||||
profile);
|
||||
SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
|
||||
surface->getCanvas()->drawPaint(bg);
|
||||
|
@ -192,6 +192,8 @@ struct SkPM4f {
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
|
||||
|
||||
/*
|
||||
* The float values are 0...1 unpremultiplied
|
||||
*/
|
||||
|
@ -144,6 +144,7 @@ public:
|
||||
porter-duff transfer mode.
|
||||
*/
|
||||
static SkXfermodeProc GetProc(Mode mode);
|
||||
static SkXfermodeProc4f GetProc4f(Mode);
|
||||
|
||||
/**
|
||||
* If the specified mode can be represented by a pair of Coeff, then return
|
||||
@ -241,6 +242,7 @@ public:
|
||||
int count, const SkAlpha coverage[]);
|
||||
typedef void (*PM4fProcN)(const PM4fState&, uint32_t dst[], const SkPM4f src[],
|
||||
int count, const SkAlpha coverage[]);
|
||||
|
||||
static PM4fProc1 GetPM4fProc1(Mode, uint32_t flags);
|
||||
static PM4fProcN GetPM4fProcN(Mode, uint32_t flags);
|
||||
virtual PM4fProc1 getPM4fProc1(uint32_t flags) const;
|
||||
|
@ -37,14 +37,15 @@ bool SkModeColorFilter::asColorMode(SkColor* color, SkXfermode::Mode* mode) cons
|
||||
}
|
||||
|
||||
uint32_t SkModeColorFilter::getFlags() const {
|
||||
uint32_t flags = kSupports4f_Flag;
|
||||
switch (fMode) {
|
||||
case SkXfermode::kDst_Mode: //!< [Da, Dc]
|
||||
case SkXfermode::kSrcATop_Mode: //!< [Da, Sc * Da + (1 - Sa) * Dc]
|
||||
return kAlphaUnchanged_Flag;
|
||||
flags |= kAlphaUnchanged_Flag;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return flags;
|
||||
}
|
||||
|
||||
void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const {
|
||||
@ -56,6 +57,15 @@ void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColo
|
||||
}
|
||||
}
|
||||
|
||||
void SkModeColorFilter::filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const {
|
||||
SkPM4f color = SkPM4f::FromPMColor(fPMColor);
|
||||
SkXfermodeProc4f proc = SkXfermode::GetProc4f(fMode);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
result[i] = proc(color, shader[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const {
|
||||
buffer.writeColor(fColor);
|
||||
buffer.writeUInt(fMode);
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
bool asColorMode(SkColor*, SkXfermode::Mode*) const override;
|
||||
uint32_t getFlags() const override;
|
||||
void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override;
|
||||
void filterSpan4f(const SkPM4f shader[], int count, SkPM4f result[]) const override;
|
||||
|
||||
#ifndef SK_IGNORE_TO_STRING
|
||||
void toString(SkString* str) const override;
|
||||
|
@ -47,6 +47,54 @@ static inline int clamp_div255round(int prod) {
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
#include "SkNx.h"
|
||||
|
||||
static Sk4f alpha(const Sk4f& color) { return Sk4f(color.kth<3>()); }
|
||||
static Sk4f inv_alpha(const Sk4f& color) { return Sk4f(1 - color.kth<3>()); }
|
||||
static Sk4f pin_1(const Sk4f& value) { return Sk4f::Min(value, Sk4f(1)); }
|
||||
|
||||
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 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);
|
||||
}
|
||||
|
||||
template <Sk4f (blend)(const Sk4f&, const Sk4f&)>
|
||||
SkPM4f proc_4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return as_pm4f(blend(as_4f(src), as_4f(dst)));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static SkPM4f not_implemented_yet_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return {{ 0.5f, 1.0f, 0.25f, 0.5f }};
|
||||
}
|
||||
|
||||
// kClear_Mode, //!< [0, 0]
|
||||
static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
@ -219,6 +267,9 @@ static SkPMColor overlay_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = overlay_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f overlay_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kDarken_Mode
|
||||
static inline int darken_byte(int sc, int dc, int sa, int da) {
|
||||
@ -241,6 +292,9 @@ static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = darken_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f darken_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kLighten_Mode
|
||||
static inline int lighten_byte(int sc, int dc, int sa, int da) {
|
||||
@ -263,6 +317,9 @@ static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = lighten_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f lighten_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kColorDodge_Mode
|
||||
static inline int colordodge_byte(int sc, int dc, int sa, int da) {
|
||||
@ -287,6 +344,9 @@ static SkPMColor colordodge_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = colordodge_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f colordodge_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kColorBurn_Mode
|
||||
static inline int colorburn_byte(int sc, int dc, int sa, int da) {
|
||||
@ -311,6 +371,9 @@ static SkPMColor colorburn_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = colorburn_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f colorburn_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kHardLight_Mode
|
||||
static inline int hardlight_byte(int sc, int dc, int sa, int da) {
|
||||
@ -331,6 +394,9 @@ static SkPMColor hardlight_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = hardlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f hardlight_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// returns 255 * sqrt(n/255)
|
||||
static U8CPU sqrt_unit_byte(U8CPU n) {
|
||||
@ -361,6 +427,9 @@ static SkPMColor softlight_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = softlight_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f softlight_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kDifference_Mode
|
||||
static inline int difference_byte(int sc, int dc, int sa, int da) {
|
||||
@ -376,6 +445,9 @@ static SkPMColor difference_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = difference_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f difference_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kExclusion_Mode
|
||||
static inline int exclusion_byte(int sc, int dc, int, int) {
|
||||
@ -395,6 +467,9 @@ static SkPMColor exclusion_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = exclusion_byte(SkGetPackedB32(src), SkGetPackedB32(dst), sa, da);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f exclusion_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// The CSS compositing spec introduces the following formulas:
|
||||
// (See https://dvcs.w3.org/hg/FXTF/rawfile/tip/compositing/index.html#blendingnonseparable)
|
||||
@ -510,6 +585,9 @@ static SkPMColor hue_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f hue_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kSaturation_Mode
|
||||
// B(Cb, Cs) = SetLum(SetSat(Cb, Sat(Cs)), Lum(Cb))
|
||||
@ -544,6 +622,9 @@ static SkPMColor saturation_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = blendfunc_nonsep_byte(sb, db, sa, da, Db);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f saturation_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kColor_Mode
|
||||
// B(Cb, Cs) = SetLum(Cs, Lum(Cb))
|
||||
@ -577,6 +658,9 @@ static SkPMColor color_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = blendfunc_nonsep_byte(sb, db, sa, da, Sb);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f color_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
// kLuminosity_Mode
|
||||
// B(Cb, Cs) = SetLum(Cb, Lum(Cs))
|
||||
@ -610,38 +694,41 @@ static SkPMColor luminosity_modeproc(SkPMColor src, SkPMColor dst) {
|
||||
int b = blendfunc_nonsep_byte(sb, db, sa, da, Db);
|
||||
return SkPackARGB32(a, r, g, b);
|
||||
}
|
||||
static SkPM4f luminosity_proc4f(const SkPM4f& src, const SkPM4f& dst) {
|
||||
return not_implemented_yet_proc4f(src, dst);
|
||||
}
|
||||
|
||||
const ProcCoeff gProcCoeffs[] = {
|
||||
{ clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
|
||||
{ srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
|
||||
{ xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ clear_modeproc, proc_4f<clear_4f>, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ src_modeproc, proc_4f<src_4f>, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dst_modeproc, proc_4f<dst_4f>, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ srcover_modeproc, proc_4f<srcover_4f>, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ dstover_modeproc, proc_4f<dstover_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ srcin_modeproc, proc_4f<srcin_4f>, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dstin_modeproc, proc_4f<dstin_4f>, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
|
||||
{ srcout_modeproc, proc_4f<srcout_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
|
||||
{ dstout_modeproc, proc_4f<dstout_4f>, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ srcatop_modeproc, proc_4f<srcatop_4f>, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
|
||||
{ dstatop_modeproc, proc_4f<dstatop_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
|
||||
{ xor_modeproc, proc_4f<xor_4f>, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
|
||||
|
||||
{ plus_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ modulate_modeproc,SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
|
||||
{ screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff },
|
||||
{ overlay_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ colordodge_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ colorburn_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ hardlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ softlight_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ difference_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ exclusion_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ multiply_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ hue_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ saturation_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ color_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ luminosity_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ plus_modeproc, proc_4f<plus_4f>, SkXfermode::kOne_Coeff, SkXfermode::kOne_Coeff },
|
||||
{ modulate_modeproc, proc_4f<modulate_4f>, SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
|
||||
{ screen_modeproc, proc_4f<screen_4f>, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff },
|
||||
{ overlay_modeproc, overlay_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ darken_modeproc, darken_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ lighten_modeproc, lighten_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ colordodge_modeproc, colordodge_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ colorburn_modeproc, colorburn_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ hardlight_modeproc, hardlight_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ softlight_modeproc, softlight_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ difference_modeproc, difference_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ exclusion_modeproc, exclusion_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ multiply_modeproc, proc_4f<multiply_4f>, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ hue_modeproc, hue_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ saturation_modeproc, saturation_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ color_modeproc, color_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
{ luminosity_modeproc, luminosity_proc4f, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@ -1006,6 +1093,14 @@ SkXfermodeProc SkXfermode::GetProc(Mode mode) {
|
||||
return proc;
|
||||
}
|
||||
|
||||
SkXfermodeProc4f SkXfermode::GetProc4f(Mode mode) {
|
||||
SkXfermodeProc4f proc = nullptr;
|
||||
if ((unsigned)mode < kModeCount) {
|
||||
proc = gProcCoeffs[mode].fProc4f;
|
||||
}
|
||||
return proc;
|
||||
}
|
||||
|
||||
bool SkXfermode::ModeAsCoeff(Mode mode, Coeff* src, Coeff* dst) {
|
||||
SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == kModeCount);
|
||||
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
struct ProcCoeff {
|
||||
SkXfermodeProc fProc;
|
||||
SkXfermodeProc4f fProc4f;
|
||||
SkXfermode::Coeff fSC;
|
||||
SkXfermode::Coeff fDC;
|
||||
};
|
||||
|
@ -168,9 +168,9 @@ DEF_TEST(Color4f_colorfilter, reporter) {
|
||||
SkColorFilter* (*fFact)();
|
||||
bool fSupports4f;
|
||||
} recs[] = {
|
||||
{ make_mode_cf, false },
|
||||
{ make_mode_cf, true },
|
||||
{ make_mx_cf, true },
|
||||
{ make_compose_cf, false },
|
||||
{ make_compose_cf, true },
|
||||
};
|
||||
|
||||
// prepare the src
|
||||
@ -197,3 +197,45 @@ DEF_TEST(Color4f_colorfilter, reporter) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef SkPM4f (*SkXfermodeProc4f)(const SkPM4f& src, const SkPM4f& dst);
|
||||
|
||||
static bool compare_procs(SkXfermodeProc proc32, SkXfermodeProc4f proc4f) {
|
||||
const float kTolerance = 1.0f / 255;
|
||||
|
||||
const SkColor colors[] = {
|
||||
0, 0xFF000000, 0xFFFFFFFF, 0x80FF0000
|
||||
};
|
||||
|
||||
for (auto s32 : colors) {
|
||||
SkPMColor s_pm32 = SkPreMultiplyColor(s32);
|
||||
SkPM4f s_pm4f = SkColor4f::FromColor(s32).premul();
|
||||
for (auto d32 : colors) {
|
||||
SkPMColor d_pm32 = SkPreMultiplyColor(d32);
|
||||
SkPM4f d_pm4f = SkColor4f::FromColor(d32).premul();
|
||||
|
||||
SkPMColor r32 = proc32(s_pm32, d_pm32);
|
||||
SkPM4f r4f = proc4f(s_pm4f, d_pm4f);
|
||||
|
||||
SkPM4f r32_4f = SkPM4f::FromPMColor(r32);
|
||||
if (!nearly_equal(r4f, r32_4f, kTolerance)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Check that our Proc and Proc4f return (nearly) the same results
|
||||
//
|
||||
DEF_TEST(Color4f_xfermode_proc4f, reporter) {
|
||||
// TODO: extend xfermodes so that all cases can be tested.
|
||||
//
|
||||
for (int mode = SkXfermode::kClear_Mode; mode <= SkXfermode::kScreen_Mode; ++mode) {
|
||||
SkXfermodeProc proc32 = SkXfermode::GetProc((SkXfermode::Mode)mode);
|
||||
SkXfermodeProc4f proc4f = SkXfermode::GetProc4f((SkXfermode::Mode)mode);
|
||||
REPORTER_ASSERT(reporter, compare_procs(proc32, proc4f));
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user