Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(125)

Unified Diff: src/core/SkColorMatrixFilterRowMajor255.cpp

Issue 1648933002: Move SkColorMatrixFilter implementation to core. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: add back newComposed override Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkColorMatrixFilterRowMajor255.h ('k') | src/effects/SkColorMatrixFilter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkColorMatrixFilterRowMajor255.cpp
diff --git a/src/effects/SkColorMatrixFilter.cpp b/src/core/SkColorMatrixFilterRowMajor255.cpp
similarity index 70%
copy from src/effects/SkColorMatrixFilter.cpp
copy to src/core/SkColorMatrixFilterRowMajor255.cpp
index a0878a5044c5c363a74d8132f1cbebcb9da10b52..6fdfa0b446195ee6792900e688ac608a75976126 100644
--- a/src/effects/SkColorMatrixFilter.cpp
+++ b/src/core/SkColorMatrixFilterRowMajor255.cpp
@@ -5,8 +5,7 @@
* found in the LICENSE file.
*/
-#include "SkColorMatrixFilter.h"
-#include "SkColorMatrix.h"
+#include "SkColorMatrixFilterRowMajor255.h"
#include "SkColorPriv.h"
#include "SkNx.h"
#include "SkReadBuffer.h"
@@ -35,10 +34,10 @@ static void transpose_to_pmorder(float dst[20], const float src[20]) {
// src is [20] but some compilers won't accept __restrict__ on anything
// but an raw pointer or reference
-void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) {
+void SkColorMatrixFilterRowMajor255::initState(const SkScalar* SK_RESTRICT src) {
transpose_to_pmorder(fTranspose, src);
- const float* array = fMatrix.fMat;
+ const float* array = fMatrix;
// check if we have to munge Alpha
bool changesAlpha = (array[15] || array[16] || array[17] || (array[18] - 1) || array[19]);
@@ -54,16 +53,12 @@ void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) {
///////////////////////////////////////////////////////////////////////////////
-SkColorMatrixFilter::SkColorMatrixFilter(const SkColorMatrix& cm) : fMatrix(cm) {
- this->initState(cm.fMat);
-}
-
-SkColorMatrixFilter::SkColorMatrixFilter(const SkScalar array[20]) {
- memcpy(fMatrix.fMat, array, 20 * sizeof(SkScalar));
+SkColorMatrixFilterRowMajor255::SkColorMatrixFilterRowMajor255(const SkScalar array[20]) {
+ memcpy(fMatrix, array, 20 * sizeof(SkScalar));
this->initState(array);
}
-uint32_t SkColorMatrixFilter::getFlags() const {
+uint32_t SkColorMatrixFilterRowMajor255::getFlags() const {
return this->INHERITED::getFlags() | fFlags;
}
@@ -135,7 +130,7 @@ struct SkPMColorAdaptor {
return SkNx_cast<float>(Sk4b::Load(&c)) * Sk4f(1.0f/255);
}
};
-void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
+void SkColorMatrixFilterRowMajor255::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const {
filter_span<SkPMColorAdaptor>(fTranspose, src, count, dst);
}
@@ -149,38 +144,92 @@ struct SkPM4fAdaptor {
return Sk4f::Load(&c);
}
};
-void SkColorMatrixFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
+void SkColorMatrixFilterRowMajor255::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
filter_span<SkPM4fAdaptor>(fTranspose, src, count, dst);
}
///////////////////////////////////////////////////////////////////////////////
-void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const {
- SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20);
- buffer.writeScalarArray(fMatrix.fMat, 20);
+void SkColorMatrixFilterRowMajor255::flatten(SkWriteBuffer& buffer) const {
+ SkASSERT(sizeof(fMatrix)/sizeof(SkScalar) == 20);
+ buffer.writeScalarArray(fMatrix, 20);
}
-SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) {
- SkColorMatrix matrix;
- if (buffer.readScalarArray(matrix.fMat, 20)) {
- return Create(matrix);
+SkFlattenable* SkColorMatrixFilterRowMajor255::CreateProc(SkReadBuffer& buffer) {
+ SkScalar matrix[20];
+ if (buffer.readScalarArray(matrix, 20)) {
+ return new SkColorMatrixFilterRowMajor255(matrix);
}
return nullptr;
}
-bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const {
+bool SkColorMatrixFilterRowMajor255::asColorMatrix(SkScalar matrix[20]) const {
if (matrix) {
- memcpy(matrix, fMatrix.fMat, 20 * sizeof(SkScalar));
+ memcpy(matrix, fMatrix, 20 * sizeof(SkScalar));
}
return true;
}
-SkColorFilter* SkColorMatrixFilter::newComposed(const SkColorFilter* innerFilter) const {
+///////////////////////////////////////////////////////////////////////////////
+// This code was duplicated from src/effects/SkColorMatrixc.cpp in order to be used in core.
+//////
+
+// To detect if we need to apply clamping after applying a matrix, we check if
+// any output component might go outside of [0, 255] for any combination of
+// input components in [0..255].
+// Each output component is an affine transformation of the input component, so
+// the minimum and maximum values are for any combination of minimum or maximum
+// values of input components (i.e. 0 or 255).
+// E.g. if R' = x*R + y*G + z*B + w*A + t
+// Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
+// minimum value will be for R=0 if x>0 or R=255 if x<0.
+// Same goes for all components.
+static bool component_needs_clamping(const SkScalar row[5]) {
+ SkScalar maxValue = row[4] / 255;
+ SkScalar minValue = row[4] / 255;
+ for (int i = 0; i < 4; ++i) {
+ if (row[i] > 0)
+ maxValue += row[i];
+ else
+ minValue += row[i];
+ }
+ return (maxValue > 1) || (minValue < 0);
+}
+
+static bool needs_clamping(const SkScalar matrix[20]) {
+ return component_needs_clamping(matrix)
+ || component_needs_clamping(matrix+5)
+ || component_needs_clamping(matrix+10)
+ || component_needs_clamping(matrix+15);
+}
+
+static void set_concat(SkScalar result[20], const SkScalar outer[20], const SkScalar inner[20]) {
+ int index = 0;
+ for (int j = 0; j < 20; j += 5) {
+ for (int i = 0; i < 4; i++) {
+ result[index++] = outer[j + 0] * inner[i + 0] +
+ outer[j + 1] * inner[i + 5] +
+ outer[j + 2] * inner[i + 10] +
+ outer[j + 3] * inner[i + 15];
+ }
+ result[index++] = outer[j + 0] * inner[4] +
+ outer[j + 1] * inner[9] +
+ outer[j + 2] * inner[14] +
+ outer[j + 3] * inner[19] +
+ outer[j + 4];
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// End duplication
+//////
+
+SkColorFilter* SkColorMatrixFilterRowMajor255::newComposed(const SkColorFilter* innerFilter) const {
SkScalar innerMatrix[20];
- if (innerFilter->asColorMatrix(innerMatrix) && !SkColorMatrix::NeedsClamping(innerMatrix)) {
+ if (innerFilter->asColorMatrix(innerMatrix) && !needs_clamping(innerMatrix)) {
SkScalar concat[20];
- SkColorMatrix::SetConcat(concat, fMatrix.fMat, innerMatrix);
- return SkColorMatrixFilter::Create(concat);
+ set_concat(concat, fMatrix, innerMatrix);
+ return new SkColorMatrixFilterRowMajor255(concat);
}
return nullptr;
}
@@ -195,7 +244,7 @@ SkColorFilter* SkColorMatrixFilter::newComposed(const SkColorFilter* innerFilter
class ColorMatrixEffect : public GrFragmentProcessor {
public:
- static const GrFragmentProcessor* Create(const SkColorMatrix& matrix) {
+ static const GrFragmentProcessor* Create(const SkScalar matrix[20]) {
return new ColorMatrixEffect(matrix);
}
@@ -242,7 +291,7 @@ public:
virtual void onSetData(const GrGLSLProgramDataManager& uniManager,
const GrProcessor& proc) override {
const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>();
- const float* m = cme.fMatrix.fMat;
+ const float* m = cme.fMatrix;
// The GL matrix is transposed from SkColorMatrix.
float mt[] = {
m[0], m[5], m[10], m[15],
@@ -266,7 +315,8 @@ public:
};
private:
- ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {
+ ColorMatrixEffect(const SkScalar matrix[20]) {
+ memcpy(fMatrix, matrix, sizeof(SkScalar) * 20);
this->initClassID<ColorMatrixEffect>();
}
@@ -281,7 +331,7 @@ private:
bool onIsEqual(const GrFragmentProcessor& s) const override {
const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>();
- return cme.fMatrix == fMatrix;
+ return 0 == memcmp(fMatrix, cme.fMatrix, sizeof(fMatrix));
}
void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
@@ -309,17 +359,17 @@ private:
for (int i = 0; i < 4; ++i) {
// If any relevant component of the color to be passed through the matrix is non-const
// then we can't know the final result.
- if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) {
+ if (0 != fMatrix[kAlphaRowStartIdx + i]) {
if (!(inout->validFlags() & kRGBAFlags[i])) {
inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
return;
} else {
uint32_t component = (inout->color() >> kShifts[i]) & 0xFF;
- outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component;
+ outputA += fMatrix[kAlphaRowStartIdx + i] * component;
}
}
}
- outputA += fMatrix.fMat[kAlphaRowTranslateIdx];
+ outputA += fMatrix[kAlphaRowTranslateIdx];
// We pin the color to [0,1]. This would happen to the *final* color output from the frag
// shader but currently the effect does not pin its own output. So in the case of over/
// underflow this may deviate from the actual result. Maybe the effect should pin its
@@ -329,7 +379,7 @@ private:
GrInvariantOutput::kWill_ReadInput);
}
- SkColorMatrix fMatrix;
+ SkScalar fMatrix[20];
typedef GrFragmentProcessor INHERITED;
};
@@ -337,26 +387,26 @@ private:
GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect);
const GrFragmentProcessor* ColorMatrixEffect::TestCreate(GrProcessorTestData* d) {
- SkColorMatrix colorMatrix;
- for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) {
- colorMatrix.fMat[i] = d->fRandom->nextSScalar1();
+ SkScalar colorMatrix[20];
+ for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix); ++i) {
+ colorMatrix[i] = d->fRandom->nextSScalar1();
}
return ColorMatrixEffect::Create(colorMatrix);
}
-const GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*) const {
+const GrFragmentProcessor* SkColorMatrixFilterRowMajor255::asFragmentProcessor(GrContext*) const {
return ColorMatrixEffect::Create(fMatrix);
}
#endif
#ifndef SK_IGNORE_TO_STRING
-void SkColorMatrixFilter::toString(SkString* str) const {
- str->append("SkColorMatrixFilter: ");
+void SkColorMatrixFilterRowMajor255::toString(SkString* str) const {
+ str->append("SkColorMatrixFilterRowMajor255: ");
str->append("matrix: (");
for (int i = 0; i < 20; ++i) {
- str->appendScalar(fMatrix.fMat[i]);
+ str->appendScalar(fMatrix[i]);
if (i < 19) {
str->append(", ");
}
@@ -367,24 +417,6 @@ void SkColorMatrixFilter::toString(SkString* str) const {
///////////////////////////////////////////////////////////////////////////////
-static SkScalar byte_to_scale(U8CPU byte) {
- if (0xFF == byte) {
- // want to get this exact
- return 1;
- } else {
- return byte * 0.00392156862745f;
- }
-}
-
-SkColorFilter* SkColorMatrixFilter::CreateLightingFilter(SkColor mul, SkColor add) {
- SkColorMatrix matrix;
- matrix.setScale(byte_to_scale(SkColorGetR(mul)),
- byte_to_scale(SkColorGetG(mul)),
- byte_to_scale(SkColorGetB(mul)),
- 1);
- matrix.postTranslate(SkIntToScalar(SkColorGetR(add)),
- SkIntToScalar(SkColorGetG(add)),
- SkIntToScalar(SkColorGetB(add)),
- 0);
- return SkColorMatrixFilter::Create(matrix);
+SkColorFilter* SkColorFilter::CreateMatrixFilterRowMajor255(const SkScalar array[20]) {
+ return new SkColorMatrixFilterRowMajor255(array);
}
« no previous file with comments | « src/core/SkColorMatrixFilterRowMajor255.h ('k') | src/effects/SkColorMatrixFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698