aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects
diff options
context:
space:
mode:
authorGravatar Mike Reed <reed@google.com>2017-05-04 10:57:40 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-05-04 15:21:39 +0000
commitb9641bd55a8f63757a63d9302755feb55d2e9502 (patch)
tree21cf4570aea3d430e9e5ef721d7e19f1b700dc5d /src/effects
parent342a9fa8e1c0bccff0d2d1569042bce29f2bbe85 (diff)
force all colorfilters to implement 4f
high-contrast gms differ at most by 1 bit Bug: skia: Change-Id: I1308bd105020ea3cd5a30fd3dd322ed134fb5ed5 Reviewed-on: https://skia-review.googlesource.com/15249 Commit-Queue: Mike Reed <reed@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org> Reviewed-by: Florin Malita <fmalita@chromium.org>
Diffstat (limited to 'src/effects')
-rw-r--r--src/effects/SkHighContrastFilter.cpp60
-rw-r--r--src/effects/SkLumaColorFilter.cpp24
-rw-r--r--src/effects/SkOverdrawColorFilter.cpp11
-rw-r--r--src/effects/SkOverdrawColorFilter.h1
-rw-r--r--src/effects/SkTableColorFilter.cpp48
5 files changed, 101 insertions, 43 deletions
diff --git a/src/effects/SkHighContrastFilter.cpp b/src/effects/SkHighContrastFilter.cpp
index 5d92cdf0d0..2d827db751 100644
--- a/src/effects/SkHighContrastFilter.cpp
+++ b/src/effects/SkHighContrastFilter.cpp
@@ -6,7 +6,7 @@
*/
#include "SkHighContrastFilter.h"
-
+#include "SkPM4f.h"
#include "SkArenaAlloc.h"
#include "SkRasterPipeline.h"
#include "SkReadBuffer.h"
@@ -45,33 +45,18 @@ SkScalar Hue2RGB(SkScalar p, SkScalar q, SkScalar t) {
return p;
}
-uint8_t SkScalarToUint8Clamp(SkScalar f) {
- if (f <= 0) {
- return 0;
- } else if (f >= 1) {
- return 255;
- }
- return static_cast<unsigned char>(255 * f);
-}
-
SkScalar IncreaseContrast(SkScalar f, SkScalar contrast) {
SkScalar m = (1 + contrast) / (1 - contrast);
SkScalar b = (-0.5f * m + 0.5f);
return m * f + b;
}
-static SkPMColor ApplyHighContrastFilter(const SkHighContrastConfig& config,
- SkPMColor pmColor) {
- SkColor color = SkUnPreMultiply::PMColorToColor(pmColor);
- SkScalar rf = SkColorGetR(color) / 255.f;
- SkScalar gf = SkColorGetG(color) / 255.f;
- SkScalar bf = SkColorGetB(color) / 255.f;
-
+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.
- rf *= rf;
- gf *= gf;
- bf *= bf;
+ 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) {
@@ -136,14 +121,7 @@ static SkPMColor ApplyHighContrastFilter(const SkHighContrastConfig& config,
}
// Convert back from linear to a color space with a gamma of ~2.0.
- rf = SkScalarSqrt(rf);
- gf = SkScalarSqrt(gf);
- bf = SkScalarSqrt(bf);
-
- return SkPremultiplyARGBInline(SkColorGetA(color),
- SkScalarToUint8Clamp(rf),
- SkScalarToUint8Clamp(gf),
- SkScalarToUint8Clamp(bf));
+ return SkColor4f::Pin(SkScalarSqrt(rf), SkScalarSqrt(gf), SkScalarSqrt(bf), src.fA);
}
} // namespace
@@ -164,8 +142,8 @@ public:
sk_sp<GrFragmentProcessor> asFragmentProcessor(GrContext*, SkColorSpace*) const override;
#endif
- void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const
- override;
+ void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
+ void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const override;
bool onAppendStages(SkRasterPipeline* p,
SkColorSpace* dst,
SkArenaAlloc* scratch,
@@ -186,10 +164,24 @@ private:
typedef SkColorFilter INHERITED;
};
-void SkHighContrast_Filter::filterSpan(const SkPMColor src[], int count,
- SkPMColor dst[]) const {
- for (int i = 0; i < count; ++i)
- dst[i] = ApplyHighContrastFilter(fConfig, src[i]);
+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::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
+ for (int i = 0; i < count; ++i) {
+ dst[i] = ApplyHighContrastFilter(fConfig, dst[i].unpremul()).premul();
+ }
}
bool SkHighContrast_Filter::onAppendStages(SkRasterPipeline* p,
diff --git a/src/effects/SkLumaColorFilter.cpp b/src/effects/SkLumaColorFilter.cpp
index 2809c8b492..b2f6b47a69 100644
--- a/src/effects/SkLumaColorFilter.cpp
+++ b/src/effects/SkLumaColorFilter.cpp
@@ -6,7 +6,7 @@
*/
#include "SkLumaColorFilter.h"
-
+#include "SkPM4f.h"
#include "SkColorPriv.h"
#include "SkRasterPipeline.h"
#include "SkString.h"
@@ -17,8 +17,7 @@
#include "glsl/GrGLSLFragmentShaderBuilder.h"
#endif
-void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
- SkPMColor dst[]) const {
+void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
for (int i = 0; i < count; ++i) {
SkPMColor c = src[i];
@@ -37,6 +36,25 @@ void SkLumaColorFilter::filterSpan(const SkPMColor src[], int count,
}
}
+void SkLumaColorFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
+ for (int i = 0; i < count; ++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)
+ */
+ dst[i].fVec[SkPM4f::R] = 0;
+ dst[i].fVec[SkPM4f::G] = 0;
+ dst[i].fVec[SkPM4f::B] = 0;
+ dst[i].fVec[SkPM4f::A] = src[i].r() * SK_LUM_COEFF_R +
+ src[i].g() * SK_LUM_COEFF_G +
+ src[i].b() * SK_LUM_COEFF_B;
+ }
+}
+
bool SkLumaColorFilter::onAppendStages(SkRasterPipeline* p,
SkColorSpace* dst,
SkArenaAlloc* scratch,
diff --git a/src/effects/SkOverdrawColorFilter.cpp b/src/effects/SkOverdrawColorFilter.cpp
index 87bbc1069e..2bed180bcc 100644
--- a/src/effects/SkOverdrawColorFilter.cpp
+++ b/src/effects/SkOverdrawColorFilter.cpp
@@ -6,6 +6,7 @@
*/
#include "SkOverdrawColorFilter.h"
+#include "SkPM4f.h"
void SkOverdrawColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
for (int x = 0; x < count; x++) {
@@ -18,6 +19,16 @@ void SkOverdrawColorFilter::filterSpan(const SkPMColor src[], int count, SkPMCol
}
}
+void SkOverdrawColorFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
+ for (int i = 0; i < count; ++i) {
+ uint8_t alpha = (int)(src[i].a() * 255);
+ if (alpha >= kNumColors) {
+ alpha = kNumColors - 1;
+ }
+ dst[i] = SkPM4f::FromPMColor(fColors[alpha]);
+ }
+}
+
void SkOverdrawColorFilter::toString(SkString* str) const {
str->append("SkOverdrawColorFilter (");
for (int i = 0; i < kNumColors; i++) {
diff --git a/src/effects/SkOverdrawColorFilter.h b/src/effects/SkOverdrawColorFilter.h
index 6c5ce592f3..772e07c674 100644
--- a/src/effects/SkOverdrawColorFilter.h
+++ b/src/effects/SkOverdrawColorFilter.h
@@ -32,6 +32,7 @@ public:
#endif
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
+ void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) 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 0253e60b59..d9ce98a7d8 100644
--- a/src/effects/SkTableColorFilter.cpp
+++ b/src/effects/SkTableColorFilter.cpp
@@ -1,12 +1,12 @@
/*
-* Copyright 2015 Google Inc.
-*
-* Use of this source code is governed by a BSD-style license that can be
-* found in the LICENSE file.
-*/
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
#include "SkTableColorFilter.h"
-
+#include "SkPM4f.h"
#include "SkArenaAlloc.h"
#include "SkBitmap.h"
#include "SkColorPriv.h"
@@ -90,6 +90,7 @@ public:
#endif
void filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const override;
+ void filterSpan4f(const SkPM4f src[], int count, SkPM4f result[]) const override;
SK_TO_STRING_OVERRIDE()
@@ -185,6 +186,41 @@ void SkTable_ColorFilter::filterSpan(const SkPMColor src[], int count, SkPMColor
}
}
+void SkTable_ColorFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f 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 float oneOver255 = 1.0f / 255;
+ for (int i = 0; i < count; ++i) {
+ SkColor4f c = src[i].unpremul();
+ int r = (int)(c.fR * 255.999) & 0xFF;
+ int g = (int)(c.fG * 255.999) & 0xFF;
+ int b = (int)(c.fB * 255.999) & 0xFF;
+ int a = (int)(c.fA * 255.999) & 0xFF;
+
+ SkColor4f d {
+ tableR[r] * oneOver255, tableG[g] * oneOver255,
+ tableB[b] * oneOver255, tableA[a] * oneOver255,
+ };
+ dst[i] = d.premul();
+ }
+}
+
#ifndef SK_IGNORE_TO_STRING
void SkTable_ColorFilter::toString(SkString* str) const {
const uint8_t* table = fStorage;