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

Unified Diff: src/effects/SkColorMatrix.cpp

Issue 968993004: add virtuals to optimize composing colorfilters (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix param warning Created 5 years, 10 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/effects/SkColorFilterImageFilter.cpp ('k') | src/effects/SkColorMatrixFilter.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/effects/SkColorMatrix.cpp
diff --git a/src/effects/SkColorMatrix.cpp b/src/effects/SkColorMatrix.cpp
index 3842285bf404c2fdb9b3ab2e69790681552439d7..d99d51e1de529ce166e824fc991a365898b5f8f8 100644
--- a/src/effects/SkColorMatrix.cpp
+++ b/src/effects/SkColorMatrix.cpp
@@ -6,6 +6,68 @@
*/
#include "SkColorMatrix.h"
+// 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);
+}
+
+bool SkColorMatrix::NeedsClamping(const SkScalar matrix[20]) {
+ return component_needs_clamping(matrix)
+ || component_needs_clamping(matrix+5)
+ || component_needs_clamping(matrix+10)
+ || component_needs_clamping(matrix+15);
+}
+
+void SkColorMatrix::SetConcat(SkScalar result[20],
+ const SkScalar outer[20], const SkScalar inner[20]) {
+ SkScalar tmp[20];
+ SkScalar* target;
+
+ if (outer == result || inner == result) {
+ target = tmp; // will memcpy answer when we're done into result
+ } else {
+ target = result;
+ }
+
+ int index = 0;
+ for (int j = 0; j < 20; j += 5) {
+ for (int i = 0; i < 4; i++) {
+ target[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];
+ }
+ target[index++] = outer[j + 0] * inner[4] +
+ outer[j + 1] * inner[9] +
+ outer[j + 2] * inner[14] +
+ outer[j + 3] * inner[19] +
+ outer[j + 4];
+ }
+
+ if (target != result) {
+ memcpy(result, target, 20 * sizeof(SkScalar));
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
void SkColorMatrix::setIdentity() {
memset(fMat, 0, sizeof(fMat));
fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1;
@@ -67,38 +129,8 @@ void SkColorMatrix::postRotate(Axis axis, SkScalar degrees) {
this->postConcat(tmp);
}
-///////////////////////////////////////////////////////////////////////////////
-
-void SkColorMatrix::setConcat(const SkColorMatrix& matA,
- const SkColorMatrix& matB) {
- SkScalar tmp[20];
- SkScalar* result = fMat;
-
- if (&matA == this || &matB == this) {
- result = tmp;
- }
-
- const SkScalar* a = matA.fMat;
- const SkScalar* b = matB.fMat;
-
- int index = 0;
- for (int j = 0; j < 20; j += 5) {
- for (int i = 0; i < 4; i++) {
- result[index++] = SkScalarMul(a[j + 0], b[i + 0]) +
- SkScalarMul(a[j + 1], b[i + 5]) +
- SkScalarMul(a[j + 2], b[i + 10]) +
- SkScalarMul(a[j + 3], b[i + 15]);
- }
- result[index++] = SkScalarMul(a[j + 0], b[4]) +
- SkScalarMul(a[j + 1], b[9]) +
- SkScalarMul(a[j + 2], b[14]) +
- SkScalarMul(a[j + 3], b[19]) +
- a[j + 4];
- }
-
- if (fMat != result) {
- memcpy(fMat, result, sizeof(fMat));
- }
+void SkColorMatrix::setConcat(const SkColorMatrix& matA, const SkColorMatrix& matB) {
+ SetConcat(fMat, matA.fMat, matB.fMat);
}
///////////////////////////////////////////////////////////////////////////////
@@ -160,3 +192,4 @@ void SkColorMatrix::setYUV2RGB() {
setrow(fMat + 10, 1, kU2B, 0);
fMat[kA_Scale] = 1;
}
+
« no previous file with comments | « src/effects/SkColorFilterImageFilter.cpp ('k') | src/effects/SkColorMatrixFilter.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698