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

Side by Side 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, 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 unified diff | Download patch
« no previous file with comments | « src/core/SkColorMatrixFilterRowMajor255.h ('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 7
8 #include "SkColorMatrixFilter.h" 8 #include "SkColorMatrixFilterRowMajor255.h"
9 #include "SkColorMatrix.h"
10 #include "SkColorPriv.h" 9 #include "SkColorPriv.h"
11 #include "SkNx.h" 10 #include "SkNx.h"
12 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
13 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
14 #include "SkUnPreMultiply.h" 13 #include "SkUnPreMultiply.h"
15 #include "SkString.h" 14 #include "SkString.h"
16 15
17 #define SK_PMORDER_INDEX_A (SK_A32_SHIFT / 8) 16 #define SK_PMORDER_INDEX_A (SK_A32_SHIFT / 8)
18 #define SK_PMORDER_INDEX_R (SK_R32_SHIFT / 8) 17 #define SK_PMORDER_INDEX_R (SK_R32_SHIFT / 8)
19 #define SK_PMORDER_INDEX_G (SK_G32_SHIFT / 8) 18 #define SK_PMORDER_INDEX_G (SK_G32_SHIFT / 8)
20 #define SK_PMORDER_INDEX_B (SK_B32_SHIFT / 8) 19 #define SK_PMORDER_INDEX_B (SK_B32_SHIFT / 8)
21 20
22 static void transpose_to_pmorder(float dst[20], const float src[20]) { 21 static void transpose_to_pmorder(float dst[20], const float src[20]) {
23 const float* srcR = src + 0; 22 const float* srcR = src + 0;
24 const float* srcG = src + 5; 23 const float* srcG = src + 5;
25 const float* srcB = src + 10; 24 const float* srcB = src + 10;
26 const float* srcA = src + 15; 25 const float* srcA = src + 15;
27 26
28 for (int i = 0; i < 20; i += 4) { 27 for (int i = 0; i < 20; i += 4) {
29 dst[i + SK_PMORDER_INDEX_A] = *srcA++; 28 dst[i + SK_PMORDER_INDEX_A] = *srcA++;
30 dst[i + SK_PMORDER_INDEX_R] = *srcR++; 29 dst[i + SK_PMORDER_INDEX_R] = *srcR++;
31 dst[i + SK_PMORDER_INDEX_G] = *srcG++; 30 dst[i + SK_PMORDER_INDEX_G] = *srcG++;
32 dst[i + SK_PMORDER_INDEX_B] = *srcB++; 31 dst[i + SK_PMORDER_INDEX_B] = *srcB++;
33 } 32 }
34 } 33 }
35 34
36 // src is [20] but some compilers won't accept __restrict__ on anything 35 // src is [20] but some compilers won't accept __restrict__ on anything
37 // but an raw pointer or reference 36 // but an raw pointer or reference
38 void SkColorMatrixFilter::initState(const SkScalar* SK_RESTRICT src) { 37 void SkColorMatrixFilterRowMajor255::initState(const SkScalar* SK_RESTRICT src) {
39 transpose_to_pmorder(fTranspose, src); 38 transpose_to_pmorder(fTranspose, src);
40 39
41 const float* array = fMatrix.fMat; 40 const float* array = fMatrix;
42 41
43 // check if we have to munge Alpha 42 // check if we have to munge Alpha
44 bool changesAlpha = (array[15] || array[16] || array[17] || (array[18] - 1) || array[19]); 43 bool changesAlpha = (array[15] || array[16] || array[17] || (array[18] - 1) || array[19]);
45 bool usesAlpha = (array[3] || array[8] || array[13]); 44 bool usesAlpha = (array[3] || array[8] || array[13]);
46 45
47 if (changesAlpha || usesAlpha) { 46 if (changesAlpha || usesAlpha) {
48 fFlags = changesAlpha ? 0 : kAlphaUnchanged_Flag; 47 fFlags = changesAlpha ? 0 : kAlphaUnchanged_Flag;
49 } else { 48 } else {
50 fFlags = kAlphaUnchanged_Flag; 49 fFlags = kAlphaUnchanged_Flag;
51 } 50 }
52 fFlags |= kSupports4f_Flag; 51 fFlags |= kSupports4f_Flag;
53 } 52 }
54 53
55 /////////////////////////////////////////////////////////////////////////////// 54 ///////////////////////////////////////////////////////////////////////////////
56 55
57 SkColorMatrixFilter::SkColorMatrixFilter(const SkColorMatrix& cm) : fMatrix(cm) { 56 SkColorMatrixFilterRowMajor255::SkColorMatrixFilterRowMajor255(const SkScalar ar ray[20]) {
58 this->initState(cm.fMat); 57 memcpy(fMatrix, array, 20 * sizeof(SkScalar));
59 }
60
61 SkColorMatrixFilter::SkColorMatrixFilter(const SkScalar array[20]) {
62 memcpy(fMatrix.fMat, array, 20 * sizeof(SkScalar));
63 this->initState(array); 58 this->initState(array);
64 } 59 }
65 60
66 uint32_t SkColorMatrixFilter::getFlags() const { 61 uint32_t SkColorMatrixFilterRowMajor255::getFlags() const {
67 return this->INHERITED::getFlags() | fFlags; 62 return this->INHERITED::getFlags() | fFlags;
68 } 63 }
69 64
70 static Sk4f scale_rgb(float scale) { 65 static Sk4f scale_rgb(float scale) {
71 static_assert(SkPM4f::A == 3, "Alpha is lane 3"); 66 static_assert(SkPM4f::A == 3, "Alpha is lane 3");
72 return Sk4f(scale, scale, scale, 1); 67 return Sk4f(scale, scale, scale, 1);
73 } 68 }
74 69
75 static Sk4f premul(const Sk4f& x) { 70 static Sk4f premul(const Sk4f& x) {
76 return x * scale_rgb(x.kth<SkPM4f::A>()); 71 return x * scale_rgb(x.kth<SkPM4f::A>());
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
128 } 123 }
129 124
130 struct SkPMColorAdaptor { 125 struct SkPMColorAdaptor {
131 static SkPMColor From4f(const Sk4f& c4) { 126 static SkPMColor From4f(const Sk4f& c4) {
132 return round(c4); 127 return round(c4);
133 } 128 }
134 static Sk4f To4f(SkPMColor c) { 129 static Sk4f To4f(SkPMColor c) {
135 return SkNx_cast<float>(Sk4b::Load(&c)) * Sk4f(1.0f/255); 130 return SkNx_cast<float>(Sk4b::Load(&c)) * Sk4f(1.0f/255);
136 } 131 }
137 }; 132 };
138 void SkColorMatrixFilter::filterSpan(const SkPMColor src[], int count, SkPMColor dst[]) const { 133 void SkColorMatrixFilterRowMajor255::filterSpan(const SkPMColor src[], int count , SkPMColor dst[]) const {
139 filter_span<SkPMColorAdaptor>(fTranspose, src, count, dst); 134 filter_span<SkPMColorAdaptor>(fTranspose, src, count, dst);
140 } 135 }
141 136
142 struct SkPM4fAdaptor { 137 struct SkPM4fAdaptor {
143 static SkPM4f From4f(const Sk4f& c4) { 138 static SkPM4f From4f(const Sk4f& c4) {
144 SkPM4f c; 139 SkPM4f c;
145 c4.store(&c); 140 c4.store(&c);
146 return c; 141 return c;
147 } 142 }
148 static Sk4f To4f(const SkPM4f& c) { 143 static Sk4f To4f(const SkPM4f& c) {
149 return Sk4f::Load(&c); 144 return Sk4f::Load(&c);
150 } 145 }
151 }; 146 };
152 void SkColorMatrixFilter::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst []) const { 147 void SkColorMatrixFilterRowMajor255::filterSpan4f(const SkPM4f src[], int count, SkPM4f dst[]) const {
153 filter_span<SkPM4fAdaptor>(fTranspose, src, count, dst); 148 filter_span<SkPM4fAdaptor>(fTranspose, src, count, dst);
154 } 149 }
155 150
156 /////////////////////////////////////////////////////////////////////////////// 151 ///////////////////////////////////////////////////////////////////////////////
157 152
158 void SkColorMatrixFilter::flatten(SkWriteBuffer& buffer) const { 153 void SkColorMatrixFilterRowMajor255::flatten(SkWriteBuffer& buffer) const {
159 SkASSERT(sizeof(fMatrix.fMat)/sizeof(SkScalar) == 20); 154 SkASSERT(sizeof(fMatrix)/sizeof(SkScalar) == 20);
160 buffer.writeScalarArray(fMatrix.fMat, 20); 155 buffer.writeScalarArray(fMatrix, 20);
161 } 156 }
162 157
163 SkFlattenable* SkColorMatrixFilter::CreateProc(SkReadBuffer& buffer) { 158 SkFlattenable* SkColorMatrixFilterRowMajor255::CreateProc(SkReadBuffer& buffer) {
164 SkColorMatrix matrix; 159 SkScalar matrix[20];
165 if (buffer.readScalarArray(matrix.fMat, 20)) { 160 if (buffer.readScalarArray(matrix, 20)) {
166 return Create(matrix); 161 return new SkColorMatrixFilterRowMajor255(matrix);
167 } 162 }
168 return nullptr; 163 return nullptr;
169 } 164 }
170 165
171 bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const { 166 bool SkColorMatrixFilterRowMajor255::asColorMatrix(SkScalar matrix[20]) const {
172 if (matrix) { 167 if (matrix) {
173 memcpy(matrix, fMatrix.fMat, 20 * sizeof(SkScalar)); 168 memcpy(matrix, fMatrix, 20 * sizeof(SkScalar));
174 } 169 }
175 return true; 170 return true;
176 } 171 }
177 172
178 SkColorFilter* SkColorMatrixFilter::newComposed(const SkColorFilter* innerFilter ) const { 173 ///////////////////////////////////////////////////////////////////////////////
174 // This code was duplicated from src/effects/SkColorMatrixc.cpp in order to be used in core.
175 //////
176
177 // To detect if we need to apply clamping after applying a matrix, we check if
178 // any output component might go outside of [0, 255] for any combination of
179 // input components in [0..255].
180 // Each output component is an affine transformation of the input component, so
181 // the minimum and maximum values are for any combination of minimum or maximum
182 // values of input components (i.e. 0 or 255).
183 // E.g. if R' = x*R + y*G + z*B + w*A + t
184 // Then the maximum value will be for R=255 if x>0 or R=0 if x<0, and the
185 // minimum value will be for R=0 if x>0 or R=255 if x<0.
186 // Same goes for all components.
187 static bool component_needs_clamping(const SkScalar row[5]) {
188 SkScalar maxValue = row[4] / 255;
189 SkScalar minValue = row[4] / 255;
190 for (int i = 0; i < 4; ++i) {
191 if (row[i] > 0)
192 maxValue += row[i];
193 else
194 minValue += row[i];
195 }
196 return (maxValue > 1) || (minValue < 0);
197 }
198
199 static bool needs_clamping(const SkScalar matrix[20]) {
200 return component_needs_clamping(matrix)
201 || component_needs_clamping(matrix+5)
202 || component_needs_clamping(matrix+10)
203 || component_needs_clamping(matrix+15);
204 }
205
206 static void set_concat(SkScalar result[20], const SkScalar outer[20], const SkSc alar inner[20]) {
207 int index = 0;
208 for (int j = 0; j < 20; j += 5) {
209 for (int i = 0; i < 4; i++) {
210 result[index++] = outer[j + 0] * inner[i + 0] +
211 outer[j + 1] * inner[i + 5] +
212 outer[j + 2] * inner[i + 10] +
213 outer[j + 3] * inner[i + 15];
214 }
215 result[index++] = outer[j + 0] * inner[4] +
216 outer[j + 1] * inner[9] +
217 outer[j + 2] * inner[14] +
218 outer[j + 3] * inner[19] +
219 outer[j + 4];
220 }
221 }
222
223 ///////////////////////////////////////////////////////////////////////////////
224 // End duplication
225 //////
226
227 SkColorFilter* SkColorMatrixFilterRowMajor255::newComposed(const SkColorFilter* innerFilter) const {
179 SkScalar innerMatrix[20]; 228 SkScalar innerMatrix[20];
180 if (innerFilter->asColorMatrix(innerMatrix) && !SkColorMatrix::NeedsClamping (innerMatrix)) { 229 if (innerFilter->asColorMatrix(innerMatrix) && !needs_clamping(innerMatrix)) {
181 SkScalar concat[20]; 230 SkScalar concat[20];
182 SkColorMatrix::SetConcat(concat, fMatrix.fMat, innerMatrix); 231 set_concat(concat, fMatrix, innerMatrix);
183 return SkColorMatrixFilter::Create(concat); 232 return new SkColorMatrixFilterRowMajor255(concat);
184 } 233 }
185 return nullptr; 234 return nullptr;
186 } 235 }
187 236
188 #if SK_SUPPORT_GPU 237 #if SK_SUPPORT_GPU
189 #include "GrFragmentProcessor.h" 238 #include "GrFragmentProcessor.h"
190 #include "GrInvariantOutput.h" 239 #include "GrInvariantOutput.h"
191 #include "glsl/GrGLSLFragmentProcessor.h" 240 #include "glsl/GrGLSLFragmentProcessor.h"
192 #include "glsl/GrGLSLFragmentShaderBuilder.h" 241 #include "glsl/GrGLSLFragmentShaderBuilder.h"
193 #include "glsl/GrGLSLProgramDataManager.h" 242 #include "glsl/GrGLSLProgramDataManager.h"
194 #include "glsl/GrGLSLUniformHandler.h" 243 #include "glsl/GrGLSLUniformHandler.h"
195 244
196 class ColorMatrixEffect : public GrFragmentProcessor { 245 class ColorMatrixEffect : public GrFragmentProcessor {
197 public: 246 public:
198 static const GrFragmentProcessor* Create(const SkColorMatrix& matrix) { 247 static const GrFragmentProcessor* Create(const SkScalar matrix[20]) {
199 return new ColorMatrixEffect(matrix); 248 return new ColorMatrixEffect(matrix);
200 } 249 }
201 250
202 const char* name() const override { return "Color Matrix"; } 251 const char* name() const override { return "Color Matrix"; }
203 252
204 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; 253 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
205 254
206 class GLSLProcessor : public GrGLSLFragmentProcessor { 255 class GLSLProcessor : public GrGLSLFragmentProcessor {
207 public: 256 public:
208 // this class always generates the same code. 257 // this class always generates the same code.
(...skipping 26 matching lines...) Expand all
235 uniformHandler->getUniformCStr(fVectorHandl e)); 284 uniformHandler->getUniformCStr(fVectorHandl e));
236 fragBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", 285 fragBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n",
237 args.fOutputColor, args.fOutputColor); 286 args.fOutputColor, args.fOutputColor);
238 fragBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, a rgs.fOutputColor); 287 fragBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", args.fOutputColor, a rgs.fOutputColor);
239 } 288 }
240 289
241 protected: 290 protected:
242 virtual void onSetData(const GrGLSLProgramDataManager& uniManager, 291 virtual void onSetData(const GrGLSLProgramDataManager& uniManager,
243 const GrProcessor& proc) override { 292 const GrProcessor& proc) override {
244 const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>(); 293 const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>();
245 const float* m = cme.fMatrix.fMat; 294 const float* m = cme.fMatrix;
246 // The GL matrix is transposed from SkColorMatrix. 295 // The GL matrix is transposed from SkColorMatrix.
247 float mt[] = { 296 float mt[] = {
248 m[0], m[5], m[10], m[15], 297 m[0], m[5], m[10], m[15],
249 m[1], m[6], m[11], m[16], 298 m[1], m[6], m[11], m[16],
250 m[2], m[7], m[12], m[17], 299 m[2], m[7], m[12], m[17],
251 m[3], m[8], m[13], m[18], 300 m[3], m[8], m[13], m[18],
252 }; 301 };
253 static const float kScale = 1.0f / 255.0f; 302 static const float kScale = 1.0f / 255.0f;
254 float vec[] = { 303 float vec[] = {
255 m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale, 304 m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale,
256 }; 305 };
257 uniManager.setMatrix4fv(fMatrixHandle, 1, mt); 306 uniManager.setMatrix4fv(fMatrixHandle, 1, mt);
258 uniManager.set4fv(fVectorHandle, 1, vec); 307 uniManager.set4fv(fVectorHandle, 1, vec);
259 } 308 }
260 309
261 private: 310 private:
262 GrGLSLProgramDataManager::UniformHandle fMatrixHandle; 311 GrGLSLProgramDataManager::UniformHandle fMatrixHandle;
263 GrGLSLProgramDataManager::UniformHandle fVectorHandle; 312 GrGLSLProgramDataManager::UniformHandle fVectorHandle;
264 313
265 typedef GrGLSLFragmentProcessor INHERITED; 314 typedef GrGLSLFragmentProcessor INHERITED;
266 }; 315 };
267 316
268 private: 317 private:
269 ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) { 318 ColorMatrixEffect(const SkScalar matrix[20]) {
319 memcpy(fMatrix, matrix, sizeof(SkScalar) * 20);
270 this->initClassID<ColorMatrixEffect>(); 320 this->initClassID<ColorMatrixEffect>();
271 } 321 }
272 322
273 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override { 323 GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
274 return new GLSLProcessor(*this); 324 return new GLSLProcessor(*this);
275 } 325 }
276 326
277 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps, 327 virtual void onGetGLSLProcessorKey(const GrGLSLCaps& caps,
278 GrProcessorKeyBuilder* b) const override { 328 GrProcessorKeyBuilder* b) const override {
279 GLSLProcessor::GenKey(*this, caps, b); 329 GLSLProcessor::GenKey(*this, caps, b);
280 } 330 }
281 331
282 bool onIsEqual(const GrFragmentProcessor& s) const override { 332 bool onIsEqual(const GrFragmentProcessor& s) const override {
283 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>(); 333 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>();
284 return cme.fMatrix == fMatrix; 334 return 0 == memcmp(fMatrix, cme.fMatrix, sizeof(fMatrix));
285 } 335 }
286 336
287 void onComputeInvariantOutput(GrInvariantOutput* inout) const override { 337 void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
288 // We only bother to check whether the alpha channel will be constant. I f SkColorMatrix had 338 // We only bother to check whether the alpha channel will be constant. I f SkColorMatrix had
289 // type flags it might be worth checking the other components. 339 // type flags it might be worth checking the other components.
290 340
291 // The matrix is defined such the 4th row determines the output alpha. T he first four 341 // The matrix is defined such the 4th row determines the output alpha. T he first four
292 // columns of that row multiply the input r, g, b, and a, respectively, and the last column 342 // columns of that row multiply the input r, g, b, and a, respectively, and the last column
293 // is the "translation". 343 // is the "translation".
294 static const uint32_t kRGBAFlags[] = { 344 static const uint32_t kRGBAFlags[] = {
295 kR_GrColorComponentFlag, 345 kR_GrColorComponentFlag,
296 kG_GrColorComponentFlag, 346 kG_GrColorComponentFlag,
297 kB_GrColorComponentFlag, 347 kB_GrColorComponentFlag,
298 kA_GrColorComponentFlag 348 kA_GrColorComponentFlag
299 }; 349 };
300 static const int kShifts[] = { 350 static const int kShifts[] = {
301 GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A, 351 GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A,
302 }; 352 };
303 enum { 353 enum {
304 kAlphaRowStartIdx = 15, 354 kAlphaRowStartIdx = 15,
305 kAlphaRowTranslateIdx = 19, 355 kAlphaRowTranslateIdx = 19,
306 }; 356 };
307 357
308 SkScalar outputA = 0; 358 SkScalar outputA = 0;
309 for (int i = 0; i < 4; ++i) { 359 for (int i = 0; i < 4; ++i) {
310 // If any relevant component of the color to be passed through the m atrix is non-const 360 // If any relevant component of the color to be passed through the m atrix is non-const
311 // then we can't know the final result. 361 // then we can't know the final result.
312 if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) { 362 if (0 != fMatrix[kAlphaRowStartIdx + i]) {
313 if (!(inout->validFlags() & kRGBAFlags[i])) { 363 if (!(inout->validFlags() & kRGBAFlags[i])) {
314 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); 364 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
315 return; 365 return;
316 } else { 366 } else {
317 uint32_t component = (inout->color() >> kShifts[i]) & 0xFF; 367 uint32_t component = (inout->color() >> kShifts[i]) & 0xFF;
318 outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component; 368 outputA += fMatrix[kAlphaRowStartIdx + i] * component;
319 } 369 }
320 } 370 }
321 } 371 }
322 outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; 372 outputA += fMatrix[kAlphaRowTranslateIdx];
323 // We pin the color to [0,1]. This would happen to the *final* color out put from the frag 373 // We pin the color to [0,1]. This would happen to the *final* color out put from the frag
324 // shader but currently the effect does not pin its own output. So in th e case of over/ 374 // shader but currently the effect does not pin its own output. So in th e case of over/
325 // underflow this may deviate from the actual result. Maybe the effect s hould pin its 375 // underflow this may deviate from the actual result. Maybe the effect s hould pin its
326 // result if the matrix could over/underflow for any component? 376 // result if the matrix could over/underflow for any component?
327 inout->setToOther(kA_GrColorComponentFlag, 377 inout->setToOther(kA_GrColorComponentFlag,
328 static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A, 378 static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_SHIFT_A,
329 GrInvariantOutput::kWill_ReadInput); 379 GrInvariantOutput::kWill_ReadInput);
330 } 380 }
331 381
332 SkColorMatrix fMatrix; 382 SkScalar fMatrix[20];
333 383
334 typedef GrFragmentProcessor INHERITED; 384 typedef GrFragmentProcessor INHERITED;
335 }; 385 };
336 386
337 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect); 387 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect);
338 388
339 const GrFragmentProcessor* ColorMatrixEffect::TestCreate(GrProcessorTestData* d) { 389 const GrFragmentProcessor* ColorMatrixEffect::TestCreate(GrProcessorTestData* d) {
340 SkColorMatrix colorMatrix; 390 SkScalar colorMatrix[20];
341 for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) { 391 for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix); ++i) {
342 colorMatrix.fMat[i] = d->fRandom->nextSScalar1(); 392 colorMatrix[i] = d->fRandom->nextSScalar1();
343 } 393 }
344 return ColorMatrixEffect::Create(colorMatrix); 394 return ColorMatrixEffect::Create(colorMatrix);
345 } 395 }
346 396
347 const GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*) const { 397 const GrFragmentProcessor* SkColorMatrixFilterRowMajor255::asFragmentProcessor(G rContext*) const {
348 return ColorMatrixEffect::Create(fMatrix); 398 return ColorMatrixEffect::Create(fMatrix);
349 } 399 }
350 400
351 #endif 401 #endif
352 402
353 #ifndef SK_IGNORE_TO_STRING 403 #ifndef SK_IGNORE_TO_STRING
354 void SkColorMatrixFilter::toString(SkString* str) const { 404 void SkColorMatrixFilterRowMajor255::toString(SkString* str) const {
355 str->append("SkColorMatrixFilter: "); 405 str->append("SkColorMatrixFilterRowMajor255: ");
356 406
357 str->append("matrix: ("); 407 str->append("matrix: (");
358 for (int i = 0; i < 20; ++i) { 408 for (int i = 0; i < 20; ++i) {
359 str->appendScalar(fMatrix.fMat[i]); 409 str->appendScalar(fMatrix[i]);
360 if (i < 19) { 410 if (i < 19) {
361 str->append(", "); 411 str->append(", ");
362 } 412 }
363 } 413 }
364 str->append(")"); 414 str->append(")");
365 } 415 }
366 #endif 416 #endif
367 417
368 /////////////////////////////////////////////////////////////////////////////// 418 ///////////////////////////////////////////////////////////////////////////////
369 419
370 static SkScalar byte_to_scale(U8CPU byte) { 420 SkColorFilter* SkColorFilter::CreateMatrixFilterRowMajor255(const SkScalar array [20]) {
371 if (0xFF == byte) { 421 return new SkColorMatrixFilterRowMajor255(array);
372 // want to get this exact
373 return 1;
374 } else {
375 return byte * 0.00392156862745f;
376 }
377 } 422 }
378
379 SkColorFilter* SkColorMatrixFilter::CreateLightingFilter(SkColor mul, SkColor ad d) {
380 SkColorMatrix matrix;
381 matrix.setScale(byte_to_scale(SkColorGetR(mul)),
382 byte_to_scale(SkColorGetG(mul)),
383 byte_to_scale(SkColorGetB(mul)),
384 1);
385 matrix.postTranslate(SkIntToScalar(SkColorGetR(add)),
386 SkIntToScalar(SkColorGetG(add)),
387 SkIntToScalar(SkColorGetB(add)),
388 0);
389 return SkColorMatrixFilter::Create(matrix);
390 }
OLDNEW
« 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