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

Side by Side 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, 9 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 unified diff | Download patch
« no previous file with comments | « src/effects/SkColorFilterImageFilter.cpp ('k') | src/effects/SkColorMatrixFilter.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 #include "SkColorMatrix.h" 7 #include "SkColorMatrix.h"
8 8
9 // To detect if we need to apply clamping after applying a matrix, we check if
10 // any output component might go outside of [0, 255] for any combination of
11 // input components in [0..255].
12 // Each output component is an affine transformation of the input component, so
13 // the minimum and maximum values are for any combination of minimum or maximum
14 // values of input components (i.e. 0 or 255).
15 // E.g. if R' = x*R + y*G + z*B + w*A + t
16 // Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
17 // minimum value will be for R=0 if x>0 or R=255 if x<0.
18 // Same goes for all components.
19 static bool component_needs_clamping(const SkScalar row[5]) {
20 SkScalar maxValue = row[4] / 255;
21 SkScalar minValue = row[4] / 255;
22 for (int i = 0; i < 4; ++i) {
23 if (row[i] > 0)
24 maxValue += row[i];
25 else
26 minValue += row[i];
27 }
28 return (maxValue > 1) || (minValue < 0);
29 }
30
31 bool SkColorMatrix::NeedsClamping(const SkScalar matrix[20]) {
32 return component_needs_clamping(matrix)
33 || component_needs_clamping(matrix+5)
34 || component_needs_clamping(matrix+10)
35 || component_needs_clamping(matrix+15);
36 }
37
38 void SkColorMatrix::SetConcat(SkScalar result[20],
39 const SkScalar outer[20], const SkScalar inner[20] ) {
40 SkScalar tmp[20];
41 SkScalar* target;
42
43 if (outer == result || inner == result) {
44 target = tmp; // will memcpy answer when we're done into result
45 } else {
46 target = result;
47 }
48
49 int index = 0;
50 for (int j = 0; j < 20; j += 5) {
51 for (int i = 0; i < 4; i++) {
52 target[index++] = outer[j + 0] * inner[i + 0] +
53 outer[j + 1] * inner[i + 5] +
54 outer[j + 2] * inner[i + 10] +
55 outer[j + 3] * inner[i + 15];
56 }
57 target[index++] = outer[j + 0] * inner[4] +
58 outer[j + 1] * inner[9] +
59 outer[j + 2] * inner[14] +
60 outer[j + 3] * inner[19] +
61 outer[j + 4];
62 }
63
64 if (target != result) {
65 memcpy(result, target, 20 * sizeof(SkScalar));
66 }
67 }
68
69 ///////////////////////////////////////////////////////////////////////////////
70
9 void SkColorMatrix::setIdentity() { 71 void SkColorMatrix::setIdentity() {
10 memset(fMat, 0, sizeof(fMat)); 72 memset(fMat, 0, sizeof(fMat));
11 fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1; 73 fMat[kR_Scale] = fMat[kG_Scale] = fMat[kB_Scale] = fMat[kA_Scale] = 1;
12 } 74 }
13 75
14 void SkColorMatrix::setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale, 76 void SkColorMatrix::setScale(SkScalar rScale, SkScalar gScale, SkScalar bScale,
15 SkScalar aScale) { 77 SkScalar aScale) {
16 memset(fMat, 0, sizeof(fMat)); 78 memset(fMat, 0, sizeof(fMat));
17 fMat[kR_Scale] = rScale; 79 fMat[kR_Scale] = rScale;
18 fMat[kG_Scale] = gScale; 80 fMat[kG_Scale] = gScale;
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 tmp.setRotate(axis, degrees); 122 tmp.setRotate(axis, degrees);
61 this->preConcat(tmp); 123 this->preConcat(tmp);
62 } 124 }
63 125
64 void SkColorMatrix::postRotate(Axis axis, SkScalar degrees) { 126 void SkColorMatrix::postRotate(Axis axis, SkScalar degrees) {
65 SkColorMatrix tmp; 127 SkColorMatrix tmp;
66 tmp.setRotate(axis, degrees); 128 tmp.setRotate(axis, degrees);
67 this->postConcat(tmp); 129 this->postConcat(tmp);
68 } 130 }
69 131
70 /////////////////////////////////////////////////////////////////////////////// 132 void SkColorMatrix::setConcat(const SkColorMatrix& matA, const SkColorMatrix& ma tB) {
71 133 SetConcat(fMat, matA.fMat, matB.fMat);
72 void SkColorMatrix::setConcat(const SkColorMatrix& matA,
73 const SkColorMatrix& matB) {
74 SkScalar tmp[20];
75 SkScalar* result = fMat;
76
77 if (&matA == this || &matB == this) {
78 result = tmp;
79 }
80
81 const SkScalar* a = matA.fMat;
82 const SkScalar* b = matB.fMat;
83
84 int index = 0;
85 for (int j = 0; j < 20; j += 5) {
86 for (int i = 0; i < 4; i++) {
87 result[index++] = SkScalarMul(a[j + 0], b[i + 0]) +
88 SkScalarMul(a[j + 1], b[i + 5]) +
89 SkScalarMul(a[j + 2], b[i + 10]) +
90 SkScalarMul(a[j + 3], b[i + 15]);
91 }
92 result[index++] = SkScalarMul(a[j + 0], b[4]) +
93 SkScalarMul(a[j + 1], b[9]) +
94 SkScalarMul(a[j + 2], b[14]) +
95 SkScalarMul(a[j + 3], b[19]) +
96 a[j + 4];
97 }
98
99 if (fMat != result) {
100 memcpy(fMat, result, sizeof(fMat));
101 }
102 } 134 }
103 135
104 /////////////////////////////////////////////////////////////////////////////// 136 ///////////////////////////////////////////////////////////////////////////////
105 137
106 static void setrow(SkScalar row[], SkScalar r, SkScalar g, SkScalar b) { 138 static void setrow(SkScalar row[], SkScalar r, SkScalar g, SkScalar b) {
107 row[0] = r; 139 row[0] = r;
108 row[1] = g; 140 row[1] = g;
109 row[2] = b; 141 row[2] = b;
110 } 142 }
111 143
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 static const SkScalar kU2B = 1.772f; 185 static const SkScalar kU2B = 1.772f;
154 186
155 void SkColorMatrix::setYUV2RGB() { 187 void SkColorMatrix::setYUV2RGB() {
156 memset(fMat, 0, sizeof(fMat)); 188 memset(fMat, 0, sizeof(fMat));
157 189
158 setrow(fMat + 0, 1, 0, kV2R); 190 setrow(fMat + 0, 1, 0, kV2R);
159 setrow(fMat + 5, 1, kU2G, kV2G); 191 setrow(fMat + 5, 1, kU2G, kV2G);
160 setrow(fMat + 10, 1, kU2B, 0); 192 setrow(fMat + 10, 1, kU2B, 0);
161 fMat[kA_Scale] = 1; 193 fMat[kA_Scale] = 1;
162 } 194 }
195
OLDNEW
« 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