aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/core/SkColorFilter.h19
-rw-r--r--include/effects/SkLumaColorFilter.h2
-rw-r--r--src/core/SkColorFilter.cpp19
-rw-r--r--src/core/SkColorMatrixFilterRowMajor255.cpp75
-rw-r--r--src/core/SkColorMatrixFilterRowMajor255.h1
-rw-r--r--src/core/SkModeColorFilter.cpp41
-rw-r--r--src/core/SkModeColorFilter.h1
-rw-r--r--src/effects/SkColorMatrixFilter.cpp4
-rw-r--r--src/effects/SkHighContrastFilter.cpp120
-rw-r--r--src/effects/SkLumaColorFilter.cpp19
-rw-r--r--src/effects/SkOverdrawColorFilter.cpp11
-rw-r--r--src/effects/SkOverdrawColorFilter.h1
-rw-r--r--src/effects/SkTableColorFilter.cpp45
-rw-r--r--src/shaders/SkColorFilterShader.cpp60
-rw-r--r--src/shaders/SkColorFilterShader.h22
-rw-r--r--src/utils/SkShadowUtils.cpp71
-rw-r--r--tests/ColorFilterTest.cpp121
-rw-r--r--tools/sk_tool_utils.cpp3
18 files changed, 12 insertions, 623 deletions
diff --git a/include/core/SkColorFilter.h b/include/core/SkColorFilter.h
index d8876f3cc3..1033a7268e 100644
--- a/include/core/SkColorFilter.h
+++ b/include/core/SkColorFilter.h
@@ -63,15 +63,6 @@ public:
*/
virtual bool asComponentTable(SkBitmap* table) const;
- /** Called with a scanline of colors, as if there was a shader installed.
- The implementation writes out its filtered version into result[].
- Note: shader and result may be the same buffer.
- @param src array of colors, possibly generated by a shader
- @param count the number of entries in the src[] and result[] arrays
- @param result written by the filter
- */
- virtual void filterSpan(const SkPMColor src[], int count, SkPMColor result[]) const = 0;
-
void appendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool shaderIsOpaque) const;
enum Flags {
@@ -93,17 +84,7 @@ public:
*/
virtual sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter>) const { return nullptr; }
- /**
- * Apply this colorfilter to the specified SkColor. This routine handles
- * converting to SkPMColor, calling the filter, and then converting back
- * to SkColor. This method is not virtual, but will call filterSpan()
- * which is virtual.
- */
SkColor filterColor(SkColor) const;
-
- /**
- * Filters a single color.
- */
SkColor4f filterColor4f(const SkColor4f&) const;
/** Create a colorfilter that uses the specified color and mode.
diff --git a/include/effects/SkLumaColorFilter.h b/include/effects/SkLumaColorFilter.h
index af9dff12aa..dc27ec3beb 100644
--- a/include/effects/SkLumaColorFilter.h
+++ b/include/effects/SkLumaColorFilter.h
@@ -28,8 +28,6 @@ class SK_API SkLumaColorFilter : public SkColorFilter {
public:
static sk_sp<SkColorFilter> Make();
- void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
-
#if SK_SUPPORT_GPU
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index 0bcde271ca..a107a06e8c 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -49,9 +49,17 @@ void SkColorFilter::appendStages(SkRasterPipeline* p,
}
SkColor SkColorFilter::filterColor(SkColor c) const {
- SkPMColor dst, src = SkPreMultiplyColor(c);
- this->filterSpan(&src, 1, &dst);
- return SkUnPreMultiply::PMColorToColor(dst);
+ const float inv255 = 1.0f / 255;
+ SkColor4f c4 = this->filterColor4f({
+ SkColorGetR(c) * inv255,
+ SkColorGetG(c) * inv255,
+ SkColorGetB(c) * inv255,
+ SkColorGetA(c) * inv255,
+ });
+ return SkColorSetARGB(sk_float_round2int(c4.fA*255),
+ sk_float_round2int(c4.fR*255),
+ sk_float_round2int(c4.fG*255),
+ sk_float_round2int(c4.fB*255));
}
#include "SkRasterPipeline.h"
@@ -89,11 +97,6 @@ public:
return fOuter->getFlags() & fInner->getFlags();
}
- void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override {
- fInner->filterSpan(shader, count, result);
- fOuter->filterSpan(result, count, result);
- }
-
#ifndef SK_IGNORE_TO_STRING
void toString(SkString* str) const override {
SkString outerS, innerS;
diff --git a/src/core/SkColorMatrixFilterRowMajor255.cpp b/src/core/SkColorMatrixFilterRowMajor255.cpp
index aa11746d0a..f08a7f5698 100644
--- a/src/core/SkColorMatrixFilterRowMajor255.cpp
+++ b/src/core/SkColorMatrixFilterRowMajor255.cpp
@@ -62,81 +62,6 @@ uint32_t SkColorMatrixFilterRowMajor255::getFlags() const {
return this->INHERITED::getFlags() | fFlags;
}
-static Sk4f scale_rgb(float scale) {
- static_assert(SkPM4f::A == 3, "Alpha is lane 3");
- return Sk4f(scale, scale, scale, 1);
-}
-
-static Sk4f premul(const Sk4f& x) {
- return x * scale_rgb(x[SkPM4f::A]);
-}
-
-static Sk4f unpremul(const Sk4f& x) {
- return x * scale_rgb(1 / x[SkPM4f::A]); // TODO: fast/approx invert?
-}
-
-static Sk4f clamp_0_1(const Sk4f& x) {
- return Sk4f::Max(Sk4f::Min(x, Sk4f(1)), Sk4f(0));
-}
-
-static SkPMColor round(const Sk4f& x) {
- SkPMColor c;
- SkNx_cast<uint8_t>(x * Sk4f(255) + Sk4f(0.5f)).store(&c);
- return c;
-}
-
-template <typename Adaptor, typename T>
-void filter_span(const float array[], const T src[], int count, T dst[]) {
- const Sk4f c0 = Sk4f::Load(array + 0);
- const Sk4f c1 = Sk4f::Load(array + 4);
- const Sk4f c2 = Sk4f::Load(array + 8);
- const Sk4f c3 = Sk4f::Load(array + 12);
- const Sk4f c4 = Sk4f::Load(array + 16);
-
- // todo: we could cache this in the constructor...
- T matrix_translate_pmcolor = Adaptor::From4f(premul(clamp_0_1(c4)));
-
- for (int i = 0; i < count; i++) {
- Sk4f srcf = Adaptor::To4f(src[i]);
- float srcA = srcf[SkPM4f::A];
-
- if (0 == srcA) {
- dst[i] = matrix_translate_pmcolor;
- continue;
- }
- if (1 != srcA) {
- srcf = unpremul(srcf);
- }
-
- Sk4f r4 = srcf[Adaptor::R];
- Sk4f g4 = srcf[Adaptor::G];
- Sk4f b4 = srcf[Adaptor::B];
- Sk4f a4 = srcf[Adaptor::A];
- // apply matrix
- Sk4f dst4 = c0 * r4 + c1 * g4 + c2 * b4 + c3 * a4 + c4;
-
- dst[i] = Adaptor::From4f(premul(clamp_0_1(dst4)));
- }
-}
-
-struct SkPMColorAdaptor {
- enum {
- R = SK_R_INDEX,
- G = SK_G_INDEX,
- B = SK_B_INDEX,
- A = SK_A_INDEX,
- };
- static SkPMColor From4f(const Sk4f& c4) {
- return round(swizzle_rb_if_bgra(c4));
- }
- static Sk4f To4f(SkPMColor c) {
- return Sk4f_fromL32(c);
- }
-};
-void SkColorMatrixFilterRowMajor255::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- filter_span<SkPMColorAdaptor>(fTranspose, src, count, dst);
-}
-
///////////////////////////////////////////////////////////////////////////////
void SkColorMatrixFilterRowMajor255::flatten(SkWriteBuffer& buffer) const {
diff --git a/src/core/SkColorMatrixFilterRowMajor255.h b/src/core/SkColorMatrixFilterRowMajor255.h
index 43e18510f8..7a1471ae23 100644
--- a/src/core/SkColorMatrixFilterRowMajor255.h
+++ b/src/core/SkColorMatrixFilterRowMajor255.h
@@ -18,7 +18,6 @@ public:
/** Creates a color matrix filter that returns the same value in all four channels. */
static sk_sp<SkColorFilter> MakeSingleChannelOutput(const SkScalar row[5]);
- void filterSpan(const SkPMColor src[], int count, SkPMColor[]) const override;
uint32_t getFlags() const override;
bool asColorMatrix(SkScalar matrix[20]) const override;
sk_sp<SkColorFilter> makeComposed(sk_sp<SkColorFilter>) const override;
diff --git a/src/core/SkModeColorFilter.cpp b/src/core/SkModeColorFilter.cpp
index 0b553333ac..d145a666e1 100644
--- a/src/core/SkModeColorFilter.cpp
+++ b/src/core/SkModeColorFilter.cpp
@@ -62,47 +62,6 @@ uint32_t SkModeColorFilter::getFlags() const {
return flags;
}
-void SkModeColorFilter::filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const {
- SkPMColor color = fPMColor;
-
- switch (fMode) {
- case SkBlendMode::kSrc:
- sk_memset32(result, color, count);
- break;
- case SkBlendMode::kSrcIn:
- for (int i = 0; i < count; ++i) {
- result[i] = SkAlphaMulQ(color, SkAlpha255To256(SkGetPackedA32(shader[i])));
- }
- break;
- case SkBlendMode::kModulate:
- for (int i = 0; i < count; ++i) {
- int a = SkMulDiv255Round(SkGetPackedA32(color), SkGetPackedA32(shader[i]));
- int r = SkMulDiv255Round(SkGetPackedR32(color), SkGetPackedR32(shader[i]));
- int g = SkMulDiv255Round(SkGetPackedG32(color), SkGetPackedG32(shader[i]));
- int b = SkMulDiv255Round(SkGetPackedB32(color), SkGetPackedB32(shader[i]));
- result[i] = SkPackARGB32(a, r, g, b);
- }
- break;
- default: {
- SkSTArenaAlloc<256> alloc;
- SkRasterPipeline p(&alloc);
-
- if (kN32_SkColorType == kBGRA_8888_SkColorType) {
- p.append(SkRasterPipeline::load_bgra, &shader);
- } else {
- p.append(SkRasterPipeline::load_8888, &shader);
- }
- this->appendStages(&p, nullptr, &alloc, false);
- if (kN32_SkColorType == kBGRA_8888_SkColorType) {
- p.append(SkRasterPipeline::store_bgra, &result);
- } else {
- p.append(SkRasterPipeline::store_8888, &result);
- }
- p.run(0, 0, count);
- } break;
- }
-}
-
void SkModeColorFilter::flatten(SkWriteBuffer& buffer) const {
buffer.writeColor(fColor);
buffer.writeUInt((int)fMode);
diff --git a/src/core/SkModeColorFilter.h b/src/core/SkModeColorFilter.h
index afff93c772..ea503ac0d6 100644
--- a/src/core/SkModeColorFilter.h
+++ b/src/core/SkModeColorFilter.h
@@ -21,7 +21,6 @@ public:
bool asColorMode(SkColor*, SkBlendMode*) const override;
uint32_t getFlags() const override;
- void filterSpan(const SkPMColor shader[], int count, SkPMColor result[]) const override;
#ifndef SK_IGNORE_TO_STRING
void toString(SkString* str) const override;
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/effects/SkColorMatrixFilter.cpp
index 12cfbb36b9..148db9326b 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/effects/SkColorMatrixFilter.cpp
@@ -44,9 +44,7 @@ public:
}
// Let fMatrixFilter handle all the other calls directly.
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override {
- fMatrixFilter->filterSpan(src, count, dst);
- }
+
uint32_t getFlags() const override {
return fMatrixFilter->getFlags();
}
diff --git a/src/effects/SkHighContrastFilter.cpp b/src/effects/SkHighContrastFilter.cpp
index c6f132842e..01efd9e17d 100644
--- a/src/effects/SkHighContrastFilter.cpp
+++ b/src/effects/SkHighContrastFilter.cpp
@@ -22,111 +22,6 @@
using InvertStyle = SkHighContrastConfig::InvertStyle;
-namespace {
-
-SkScalar Hue2RGB(SkScalar p, SkScalar q, SkScalar t) {
- if (t < 0) {
- t += 1;
- } else if (t > 1) {
- t -= 1;
- }
-
- if (t < 1/6.f) {
- return p + (q - p) * 6 * t;
- }
-
- if (t < 1/2.f) {
- return q;
- }
-
- if (t < 2/3.f) {
- return p + (q - p) * (2/3.f - t) * 6;
- }
-
- return p;
-}
-
-SkScalar IncreaseContrast(SkScalar f, SkScalar contrast) {
- SkScalar m = (1 + contrast) / (1 - contrast);
- SkScalar b = (-0.5f * m + 0.5f);
- return m * f + b;
-}
-
-SkColor4f ApplyHighContrastFilter(const SkHighContrastConfig& config, const SkColor4f& src) {
- // Apply a gamma of 2.0 so that the rest of the calculations
- // happen roughly in linear space.
- float rf = src.fR * src.fR;
- float gf = src.fG * src.fG;
- float bf = src.fB * src.fB;
-
- // Convert to grayscale using luminance coefficients.
- if (config.fGrayscale) {
- SkScalar lum =
- rf * SK_LUM_COEFF_R + gf * SK_LUM_COEFF_G + bf * SK_LUM_COEFF_B;
- rf = lum;
- gf = lum;
- bf = lum;
- }
-
- // Now invert.
- if (config.fInvertStyle == InvertStyle::kInvertBrightness) {
- rf = 1 - rf;
- gf = 1 - gf;
- bf = 1 - bf;
- } else if (config.fInvertStyle == InvertStyle::kInvertLightness) {
- // Convert to HSL
- SkScalar max = SkTMax(SkTMax(rf, gf), bf);
- SkScalar min = SkTMin(SkTMin(rf, gf), bf);
- SkScalar l = (max + min) / 2;
- SkScalar h, s;
-
- if (max == min) {
- h = 0;
- s = 0;
- } else {
- SkScalar d = max - min;
- s = l > 0.5f ? d / (2 - max - min) : d / (max + min);
- if (max == rf) {
- h = (gf - bf) / d + (gf < bf ? 6 : 0);
- } else if (max == gf) {
- h = (bf - rf) / d + 2;
- } else {
- h = (rf - gf) / d + 4;
- }
- h /= 6;
- }
-
- // Invert lightness.
- l = 1 - l;
-
- // Now convert back to RGB.
- if (s == 0) {
- // Grayscale
- rf = l;
- gf = l;
- bf = l;
- } else {
- SkScalar q = l < 0.5f ? l * (1 + s) : l + s - l * s;
- SkScalar p = 2 * l - q;
- rf = Hue2RGB(p, q, h + 1/3.f);
- gf = Hue2RGB(p, q, h);
- bf = Hue2RGB(p, q, h - 1/3.f);
- }
- }
-
- // Increase contrast.
- if (config.fContrast != 0.0f) {
- rf = IncreaseContrast(rf, config.fContrast);
- gf = IncreaseContrast(gf, config.fContrast);
- bf = IncreaseContrast(bf, config.fContrast);
- }
-
- // Convert back from linear to a color space with a gamma of ~2.0.
- return SkColor4f::Pin(SkScalarSqrt(rf), SkScalarSqrt(gf), SkScalarSqrt(bf), src.fA);
-}
-
-} // namespace
-
class SkHighContrast_Filter : public SkColorFilter {
public:
SkHighContrast_Filter(const SkHighContrastConfig& config) {
@@ -143,7 +38,6 @@ public:
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
void onAppendStages(SkRasterPipeline* p,
SkColorSpace* dst,
SkArenaAlloc* scratch,
@@ -164,20 +58,6 @@ private:
typedef SkColorFilter INHERITED;
};
-void SkHighContrast_Filter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- const float oneOver255 = 1.0f / 255;
- for (int i = 0; i < count; ++i) {
- SkColor color = SkUnPreMultiply::PMColorToColor(src[i]);
- // be sure to NOT treat color as sRGB, as we are in legacy mode here
- SkColor4f s4 {
- SkColorGetR(color) * oneOver255, SkColorGetG(color) * oneOver255,
- SkColorGetB(color) * oneOver255, SkColorGetA(color) * oneOver255,
- };
- SkColor4f d4 = ApplyHighContrastFilter(fConfig, s4);
- dst[i] = d4.premul().toPMColor();
- }
-}
-
void SkHighContrast_Filter::onAppendStages(SkRasterPipeline* p,
SkColorSpace* dstCS,
SkArenaAlloc* alloc,
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index efe44a4258..f090858fe5 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -17,25 +17,6 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#endif
-void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- for (int i = 0; i < count; ++i) {
- SkPMColor c = src[i];
-
- /*
- * While LuminanceToAlpha is defined to operate on un-premultiplied
- * inputs, due to the final alpha scaling it can be computed based on
- * premultipled components:
- *
- * LumA = (k1 * r / a + k2 * g / a + k3 * b / a) * a
- * LumA = (k1 * r + k2 * g + k3 * b)
- */
- unsigned luma = SkComputeLuminance(SkGetPackedR32(c),
- SkGetPackedG32(c),
- SkGetPackedB32(c));
- dst[i] = SkPackARGB32(luma, 0, 0, 0);
- }
-}
-
void SkLumaColorFilter::onAppendStages(SkRasterPipeline* p,
SkColorSpace* dst,
SkArenaAlloc* scratch,
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index a4e13f9935..516b752088 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -12,17 +12,6 @@
#include "SkReadBuffer.h"
#include "../jumper/SkJumper.h"
-void SkOverdrawColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- for (int x = 0; x < count; x++) {
- uint8_t alpha = SkGetPackedA32(src[x]);
- if (alpha >= kNumColors) {
- alpha = kNumColors - 1;
- }
-
- dst[x] = fColors[alpha];
- }
-}
-
void SkOverdrawColorFilter::onAppendStages(SkRasterPipeline* p,
SkColorSpace* dstCS,
SkArenaAlloc* alloc,
diff --git a/src/effects/SkOverdrawColorFilter.h b/src/effects/SkOverdrawColorFilter.h
index 41d7988577..2840a09690 100644
--- a/src/effects/SkOverdrawColorFilter.h
+++ b/src/effects/SkOverdrawColorFilter.h
@@ -31,7 +31,6 @@ public:
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
void toString(SkString* str) const override;
static sk_sp<SkFlattenable> CreateProc(SkReadBuffer& buffer);
diff --git a/src/effects/SkTableColorFilter.cpp b/src/effects/SkTableColorFilter.cpp
index 589b672622..d44c8bd6b6 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -89,8 +89,6 @@ public:
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
-
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkTable_ColorFilter)
@@ -141,49 +139,6 @@ private:
typedef SkColorFilter INHERITED;
};
-void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- const uint8_t* table = fStorage;
- const uint8_t* tableA = gIdentityTable;
- const uint8_t* tableR = gIdentityTable;
- const uint8_t* tableG = gIdentityTable;
- const uint8_t* tableB = gIdentityTable;
- if (fFlags & kA_Flag) {
- tableA = table; table += 256;
- }
- if (fFlags & kR_Flag) {
- tableR = table; table += 256;
- }
- if (fFlags & kG_Flag) {
- tableG = table; table += 256;
- }
- if (fFlags & kB_Flag) {
- tableB = table;
- }
-
- const SkUnPreMultiply::Scale* scaleTable = SkUnPreMultiply::GetScaleTable();
- for (int i = 0; i < count; ++i) {
- SkPMColor c = src[i];
- unsigned a, r, g, b;
- if (0 == c) {
- a = r = g = b = 0;
- } else {
- a = SkGetPackedA32(c);
- r = SkGetPackedR32(c);
- g = SkGetPackedG32(c);
- b = SkGetPackedB32(c);
-
- if (a < 255) {
- SkUnPreMultiply::Scale scale = scaleTable[a];
- r = SkUnPreMultiply::ApplyScale(scale, r);
- g = SkUnPreMultiply::ApplyScale(scale, g);
- b = SkUnPreMultiply::ApplyScale(scale, b);
- }
- }
- dst[i] = SkPremultiplyARGBInline(tableA[a], tableR[r],
- tableG[g], tableB[b]);
- }
-}
-
#ifndef SK_IGNORE_TO_STRING
void SkTable_ColorFilter::toString(SkString* str) const {
const uint8_t* table = fStorage;
diff --git a/src/shaders/SkColorFilterShader.cpp b/src/shaders/SkColorFilterShader.cpp
index b7d6b15da2..a2d5433bad 100644
--- a/src/shaders/SkColorFilterShader.cpp
+++ b/src/shaders/SkColorFilterShader.cpp
@@ -39,21 +39,6 @@ void SkColorFilterShader::flatten(SkWriteBuffer& buffer) const {
buffer.writeFlattenable(fFilter.get());
}
-uint32_t SkColorFilterShader::FilterShaderContext::getFlags() const {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- uint32_t shaderF = fShaderContext->getFlags();
- uint32_t filterF = filterShader.fFilter->getFlags();
-
- // If the filter does not support a given feature, but sure to clear the corresponding flag
- // in the shader flags.
- //
- if (!(filterF & SkColorFilter::kAlphaUnchanged_Flag)) {
- shaderF &= ~kOpaqueAlpha_Flag;
- }
- return shaderF;
-}
-
bool SkColorFilterShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpace* dstCS,
SkArenaAlloc* alloc, const SkMatrix& ctm,
const SkPaint& paint, const SkMatrix* localM) const {
@@ -64,55 +49,10 @@ bool SkColorFilterShader::onAppendStages(SkRasterPipeline* pipeline, SkColorSpac
return true;
}
-SkShaderBase::Context* SkColorFilterShader::onMakeContext(const ContextRec& rec,
- SkArenaAlloc* alloc) const {
- auto* shaderContext = as_SB(fShader)->makeContext(rec, alloc);
- if (nullptr == shaderContext) {
- return nullptr;
- }
- return alloc->make<FilterShaderContext>(*this, shaderContext, rec);
-}
-
sk_sp<SkShader> SkColorFilterShader::onMakeColorSpace(SkColorSpaceXformer* xformer) const {
return xformer->apply(fShader.get())->makeWithColorFilter(xformer->apply(fFilter.get()));
}
-SkColorFilterShader::FilterShaderContext::FilterShaderContext(
- const SkColorFilterShader& filterShader,
- SkShaderBase::Context* shaderContext,
- const ContextRec& rec)
- : INHERITED(filterShader, rec)
- , fShaderContext(shaderContext)
-{}
-
-void SkColorFilterShader::FilterShaderContext::shadeSpan(int x, int y, SkPMColor result[],
- int count) {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- fShaderContext->shadeSpan(x, y, result, count);
- filterShader.fFilter->filterSpan(result, count, result);
-}
-
-#include "SkRasterPipeline.h"
-void SkColorFilterShader::FilterShaderContext::shadeSpan4f(int x, int y, SkPM4f result[],
- int count) {
- const SkColorFilterShader& filterShader = static_cast<const SkColorFilterShader&>(fShader);
-
- fShaderContext->shadeSpan4f(x, y, result, count);
-
- // now apply the filter
-
- SkSTArenaAlloc<128> alloc;
- SkRasterPipeline pipeline(&alloc);
-
- const SkPM4f* src = result;
- pipeline.append(SkRasterPipeline::load_f32, &src);
- filterShader.fFilter->appendStages(&pipeline, nullptr, &alloc, filterShader.isOpaque());
- SkPM4f* dst = result;
- pipeline.append(SkRasterPipeline::store_f32, &dst);
- pipeline.run(0,y, count);
-}
-
#if SK_SUPPORT_GPU
/////////////////////////////////////////////////////////////////////
diff --git a/src/shaders/SkColorFilterShader.h b/src/shaders/SkColorFilterShader.h
index 7c931543e8..a3a3c41d6e 100644
--- a/src/shaders/SkColorFilterShader.h
+++ b/src/shaders/SkColorFilterShader.h
@@ -21,33 +21,11 @@ public:
sk_sp<GrFragmentProcessor> asFragmentProcessor(const AsFPArgs&) const override;
#endif
- class FilterShaderContext : public Context {
- public:
- // Takes ownership of shaderContext and calls its destructor.
- FilterShaderContext(const SkColorFilterShader&, SkShaderBase::Context*, const ContextRec&);
-
- uint32_t getFlags() const override;
-
- void shadeSpan(int x, int y, SkPMColor[], int count) override;
- void shadeSpan4f(int x, int y, SkPM4f[], int count) override;
-
- void set3DMask(const SkMask* mask) override {
- // forward to our proxy
- fShaderContext->set3DMask(mask);
- }
-
- private:
- SkShaderBase::Context* fShaderContext;
-
- typedef Context INHERITED;
- };
-
SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkColorFilterShader)
protected:
void flatten(SkWriteBuffer&) const override;
- Context* onMakeContext(const ContextRec&, SkArenaAlloc* alloc) const override;
sk_sp<SkShader> onMakeColorSpace(SkColorSpaceXformer* xformer) const override;
bool onAppendStages(SkRasterPipeline*, SkColorSpace* dstCS, SkArenaAlloc*,
const SkMatrix&, const SkPaint&, const SkMatrix* localM) const override;
diff --git a/src/utils/SkShadowUtils.cpp b/src/utils/SkShadowUtils.cpp
index c5b04f311b..29437e529b 100644
--- a/src/utils/SkShadowUtils.cpp
+++ b/src/utils/SkShadowUtils.cpp
@@ -37,8 +37,6 @@ public:
return sk_sp<SkColorFilter>(new SkGaussianColorFilter);
}
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
-
#if SK_SUPPORT_GPU
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
@@ -58,75 +56,6 @@ private:
typedef SkColorFilter INHERITED;
};
-static inline float eval_gaussian(float x) {
- // x = 1 - x;
- // return sk_float_exp(-x * x * 4) - 0.018f;
-
- return 0.00030726194381713867f +
- x*(0.15489584207534790039f +
- x*(0.21345567703247070312f +
- (2.89795351028442382812f - 2.26661229133605957031f*x)*x));
-}
-
-static void build_table() {
- SkDebugf("const uint8_t gByteExpU8Table[256] = {");
- for (int i = 0; i <= 255; ++i) {
- if (!(i % 8)) {
- SkDebugf("\n");
- }
- int v = (int)(eval_gaussian(i / 255.f) * 256);
- SkDebugf(" 0x%02X,", v);
- }
- SkDebugf("\n};\n");
-}
-
-const uint8_t gByteExpU8Table[256] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04,
- 0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x07,
- 0x07, 0x07, 0x08, 0x08, 0x08, 0x09, 0x09, 0x09,
- 0x0A, 0x0A, 0x0B, 0x0B, 0x0B, 0x0C, 0x0C, 0x0D,
- 0x0D, 0x0E, 0x0E, 0x0F, 0x0F, 0x10, 0x10, 0x11,
- 0x11, 0x12, 0x12, 0x13, 0x14, 0x14, 0x15, 0x15,
- 0x16, 0x17, 0x17, 0x18, 0x19, 0x19, 0x1A, 0x1B,
- 0x1C, 0x1C, 0x1D, 0x1E, 0x1F, 0x1F, 0x20, 0x21,
- 0x22, 0x23, 0x24, 0x24, 0x25, 0x26, 0x27, 0x28,
- 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30,
- 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x38, 0x39,
- 0x3A, 0x3B, 0x3C, 0x3D, 0x3F, 0x40, 0x41, 0x42,
- 0x44, 0x45, 0x46, 0x48, 0x49, 0x4A, 0x4C, 0x4D,
- 0x4E, 0x50, 0x51, 0x53, 0x54, 0x55, 0x57, 0x58,
- 0x5A, 0x5B, 0x5D, 0x5E, 0x60, 0x61, 0x63, 0x64,
- 0x66, 0x68, 0x69, 0x6B, 0x6C, 0x6E, 0x70, 0x71,
- 0x73, 0x75, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F,
- 0x80, 0x82, 0x84, 0x85, 0x87, 0x89, 0x8A, 0x8C,
- 0x8E, 0x90, 0x91, 0x93, 0x95, 0x96, 0x98, 0x9A,
- 0x9C, 0x9D, 0x9F, 0xA1, 0xA2, 0xA4, 0xA6, 0xA8,
- 0xA9, 0xAB, 0xAD, 0xAE, 0xB0, 0xB2, 0xB3, 0xB5,
- 0xB7, 0xB8, 0xBA, 0xBC, 0xBD, 0xBF, 0xC0, 0xC2,
- 0xC3, 0xC5, 0xC7, 0xC8, 0xCA, 0xCB, 0xCD, 0xCE,
- 0xCF, 0xD1, 0xD2, 0xD4, 0xD5, 0xD6, 0xD8, 0xD9,
- 0xDA, 0xDC, 0xDD, 0xDE, 0xDF, 0xE1, 0xE2, 0xE3,
- 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB,
- 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF0, 0xF1, 0xF2,
- 0xF3, 0xF3, 0xF4, 0xF5, 0xF5, 0xF6, 0xF6, 0xF7,
- 0xF7, 0xF8, 0xF8, 0xF9, 0xF9, 0xF9, 0xFA, 0xFA,
- 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFB, 0xFB,
-};
-
-void SkGaussianColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
- // to re-build the table, call build_table() which will dump it out using SkDebugf.
- if (false) {
- build_table();
- }
- for (int i = 0; i < count; ++i) {
- SkPMColor c = src[i];
- uint8_t a = gByteExpU8Table[SkGetPackedA32(c)];
- dst[i] = SkPackARGB32(a, a, a, a);
- }
-}
-
sk_sp<SkFlattenable> SkGaussianColorFilter::CreateProc(SkReadBuffer&) {
return Make();
}
diff --git a/tests/ColorFilterTest.cpp b/tests/ColorFilterTest.cpp
index b6456a6414..c502a70a4f 100644
--- a/tests/ColorFilterTest.cpp
+++ b/tests/ColorFilterTest.cpp
@@ -110,124 +110,3 @@ DEF_TEST(ColorFilter, reporter) {
test_composecolorfilter_limit(reporter);
}
-
-///////////////////////////////////////////////////////////////////////////////
-
-DEF_TEST(LumaColorFilter, reporter) {
- SkPMColor in, out;
- auto lf(SkLumaColorFilter::Make());
-
- // Applying luma to white produces black with the same transparency.
- for (unsigned i = 0; i < 256; ++i) {
- in = SkPackARGB32(i, i, i, i);
- lf->filterSpan(&in, 1, &out);
- REPORTER_ASSERT(reporter, SkGetPackedA32(out) == i);
- REPORTER_ASSERT(reporter, SkGetPackedR32(out) == 0);
- REPORTER_ASSERT(reporter, SkGetPackedG32(out) == 0);
- REPORTER_ASSERT(reporter, SkGetPackedB32(out) == 0);
- }
-
- // Applying luma to black yields transparent black (luminance(black) == 0)
- for (unsigned i = 0; i < 256; ++i) {
- in = SkPackARGB32(i, 0, 0, 0);
- lf->filterSpan(&in, 1, &out);
- REPORTER_ASSERT(reporter, out == SK_ColorTRANSPARENT);
- }
-
- // For general colors, a luma filter generates black with an attenuated alpha channel.
- for (unsigned i = 1; i < 256; ++i) {
- in = SkPackARGB32(i, i, i / 2, i / 3);
- lf->filterSpan(&in, 1, &out);
- REPORTER_ASSERT(reporter, out != in);
- REPORTER_ASSERT(reporter, SkGetPackedA32(out) <= i);
- REPORTER_ASSERT(reporter, SkGetPackedR32(out) == 0);
- REPORTER_ASSERT(reporter, SkGetPackedG32(out) == 0);
- REPORTER_ASSERT(reporter, SkGetPackedB32(out) == 0);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#include "SkColorMatrixFilter.h"
-
-static void get_brightness_matrix(float amount, float matrix[20]) {
- // Spec implementation
- // (http://dvcs.w3.org/hg/FXTF/raw-file/tip/filters/index.html#brightnessEquivalent)
- // <feFunc[R|G|B] type="linear" slope="[amount]">
- memset(matrix, 0, 20 * sizeof(SkScalar));
- matrix[0] = matrix[6] = matrix[12] = amount;
- matrix[18] = 1.f;
-}
-
-static void get_grayscale_matrix(float amount, float matrix[20]) {
- // Note, these values are computed to ensure MatrixNeedsClamping is false
- // for amount in [0..1]
- matrix[0] = 0.2126f + 0.7874f * amount;
- matrix[1] = 0.7152f - 0.7152f * amount;
- matrix[2] = 1.f - (matrix[0] + matrix[1]);
- matrix[3] = matrix[4] = 0.f;
-
- matrix[5] = 0.2126f - 0.2126f * amount;
- matrix[6] = 0.7152f + 0.2848f * amount;
- matrix[7] = 1.f - (matrix[5] + matrix[6]);
- matrix[8] = matrix[9] = 0.f;
-
- matrix[10] = 0.2126f - 0.2126f * amount;
- matrix[11] = 0.7152f - 0.7152f * amount;
- matrix[12] = 1.f - (matrix[10] + matrix[11]);
- matrix[13] = matrix[14] = 0.f;
-
- matrix[15] = matrix[16] = matrix[17] = matrix[19] = 0.f;
- matrix[18] = 1.f;
-}
-
-static sk_sp<SkColorFilter> make_cf0() {
- SkScalar matrix[20];
- get_brightness_matrix(0.5f, matrix);
- return SkColorFilter::MakeMatrixFilterRowMajor255(matrix);
-}
-static sk_sp<SkColorFilter> make_cf1() {
- SkScalar matrix[20];
- get_grayscale_matrix(1, matrix);
- return SkColorFilter::MakeMatrixFilterRowMajor255(matrix);
-}
-static sk_sp<SkColorFilter> make_cf2() {
- SkColorMatrix m0, m1;
- get_brightness_matrix(0.5f, m0.fMat);
- get_grayscale_matrix(1, m1.fMat);
- m0.preConcat(m1);
- return SkColorFilter::MakeMatrixFilterRowMajor255(m0.fMat);
-}
-static sk_sp<SkColorFilter> make_cf3() {
- SkColorMatrix m0, m1;
- get_brightness_matrix(0.5f, m0.fMat);
- get_grayscale_matrix(1, m1.fMat);
- m0.postConcat(m1);
- return SkColorFilter::MakeMatrixFilterRowMajor255(m0.fMat);
-}
-typedef sk_sp<SkColorFilter> (*CFProc)();
-
-// Test that a colormatrix that "should" preserve opaquness actually does.
-DEF_TEST(ColorMatrixFilter, reporter) {
- const CFProc procs[] = {
- make_cf0, make_cf1, make_cf2, make_cf3,
- };
-
- for (size_t i = 0; i < SK_ARRAY_COUNT(procs); ++i) {
- auto cf(procs[i]());
-
- // generate all possible r,g,b triples
- for (int r = 0; r < 256; ++r) {
- for (int g = 0; g < 256; ++g) {
- SkPMColor storage[256];
- for (int b = 0; b < 256; ++b) {
- storage[b] = SkPackARGB32(0xFF, r, g, b);
- }
- cf->filterSpan(storage, 256, storage);
- for (int b = 0; b < 256; ++b) {
- REPORTER_ASSERT(reporter, 0xFF == SkGetPackedA32(storage[b]));
- }
- }
- }
- }
-}
diff --git a/tools/sk_tool_utils.cpp b/tools/sk_tool_utils.cpp
index ba1f534cd1..f4257f00aa 100644
--- a/tools/sk_tool_utils.cpp
+++ b/tools/sk_tool_utils.cpp
@@ -37,9 +37,6 @@ public:
return GrSRGBEffect::Make(fMode);
}
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override {
- SK_ABORT("SkSRGBColorFilter is only implemented for GPU");
- }
void onAppendStages(SkRasterPipeline*, SkColorSpace*, SkArenaAlloc*, bool) const override {
SK_ABORT("SkSRGBColorFilter is only implemented for GPU");
}