OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2011 Google Inc. | 3 * Copyright 2011 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 #include "SkColorMatrixFilter.h" | 8 #include "SkColorMatrixFilter.h" |
9 #include "SkColorMatrix.h" | 9 #include "SkColorMatrix.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 | 326 |
327 bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const { | 327 bool SkColorMatrixFilter::asColorMatrix(SkScalar matrix[20]) const { |
328 if (matrix) { | 328 if (matrix) { |
329 memcpy(matrix, fMatrix.fMat, 20 * sizeof(SkScalar)); | 329 memcpy(matrix, fMatrix.fMat, 20 * sizeof(SkScalar)); |
330 } | 330 } |
331 return true; | 331 return true; |
332 } | 332 } |
333 | 333 |
334 #if SK_SUPPORT_GPU | 334 #if SK_SUPPORT_GPU |
335 #include "GrFragmentProcessor.h" | 335 #include "GrFragmentProcessor.h" |
| 336 #include "GrInvariantOutput.h" |
336 #include "GrTBackendProcessorFactory.h" | 337 #include "GrTBackendProcessorFactory.h" |
337 #include "gl/GrGLProcessor.h" | 338 #include "gl/GrGLProcessor.h" |
338 #include "gl/builders/GrGLProgramBuilder.h" | 339 #include "gl/builders/GrGLProgramBuilder.h" |
339 | 340 |
340 class ColorMatrixEffect : public GrFragmentProcessor { | 341 class ColorMatrixEffect : public GrFragmentProcessor { |
341 public: | 342 public: |
342 static GrFragmentProcessor* Create(const SkColorMatrix& matrix) { | 343 static GrFragmentProcessor* Create(const SkColorMatrix& matrix) { |
343 return SkNEW_ARGS(ColorMatrixEffect, (matrix)); | 344 return SkNEW_ARGS(ColorMatrixEffect, (matrix)); |
344 } | 345 } |
345 | 346 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 }; | 420 }; |
420 | 421 |
421 private: | 422 private: |
422 ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} | 423 ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} |
423 | 424 |
424 virtual bool onIsEqual(const GrFragmentProcessor& s) const { | 425 virtual bool onIsEqual(const GrFragmentProcessor& s) const { |
425 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>(); | 426 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>(); |
426 return cme.fMatrix == fMatrix; | 427 return cme.fMatrix == fMatrix; |
427 } | 428 } |
428 | 429 |
429 virtual void onComputeInvariantOutput(InvariantOutput* inout) const SK_OVERR
IDE { | 430 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE
RRIDE { |
430 // We only bother to check whether the alpha channel will be constant. I
f SkColorMatrix had | 431 // We only bother to check whether the alpha channel will be constant. I
f SkColorMatrix had |
431 // type flags it might be worth checking the other components. | 432 // type flags it might be worth checking the other components. |
432 | 433 |
433 // The matrix is defined such the 4th row determines the output alpha. T
he first four | 434 // The matrix is defined such the 4th row determines the output alpha. T
he first four |
434 // columns of that row multiply the input r, g, b, and a, respectively,
and the last column | 435 // columns of that row multiply the input r, g, b, and a, respectively,
and the last column |
435 // is the "translation". | 436 // is the "translation". |
436 static const uint32_t kRGBAFlags[] = { | 437 static const uint32_t kRGBAFlags[] = { |
437 kR_GrColorComponentFlag, | 438 kR_GrColorComponentFlag, |
438 kG_GrColorComponentFlag, | 439 kG_GrColorComponentFlag, |
439 kB_GrColorComponentFlag, | 440 kB_GrColorComponentFlag, |
440 kA_GrColorComponentFlag | 441 kA_GrColorComponentFlag |
441 }; | 442 }; |
442 static const int kShifts[] = { | 443 static const int kShifts[] = { |
443 GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A, | 444 GrColor_SHIFT_R, GrColor_SHIFT_G, GrColor_SHIFT_B, GrColor_SHIFT_A, |
444 }; | 445 }; |
445 enum { | 446 enum { |
446 kAlphaRowStartIdx = 15, | 447 kAlphaRowStartIdx = 15, |
447 kAlphaRowTranslateIdx = 19, | 448 kAlphaRowTranslateIdx = 19, |
448 }; | 449 }; |
449 | 450 |
450 SkScalar outputA = 0; | 451 SkScalar outputA = 0; |
451 for (int i = 0; i < 4; ++i) { | 452 for (int i = 0; i < 4; ++i) { |
452 // If any relevant component of the color to be passed through the m
atrix is non-const | 453 // If any relevant component of the color to be passed through the m
atrix is non-const |
453 // then we can't know the final result. | 454 // then we can't know the final result. |
454 if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) { | 455 if (0 != fMatrix.fMat[kAlphaRowStartIdx + i]) { |
455 if (!(inout->validFlags() & kRGBAFlags[i])) { | 456 if (!(inout->validFlags() & kRGBAFlags[i])) { |
456 inout->setToUnknown(InvariantOutput::kWill_ReadInput); | 457 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput); |
457 return; | 458 return; |
458 } else { | 459 } else { |
459 uint32_t component = (inout->color() >> kShifts[i]) & 0xFF; | 460 uint32_t component = (inout->color() >> kShifts[i]) & 0xFF; |
460 outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component; | 461 outputA += fMatrix.fMat[kAlphaRowStartIdx + i] * component; |
461 } | 462 } |
462 } | 463 } |
463 } | 464 } |
464 outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; | 465 outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; |
465 // We pin the color to [0,1]. This would happen to the *final* color out
put from the frag | 466 // We pin the color to [0,1]. This would happen to the *final* color out
put from the frag |
466 // shader but currently the effect does not pin its own output. So in th
e case of over/ | 467 // shader but currently the effect does not pin its own output. So in th
e case of over/ |
467 // underflow this may deviate from the actual result. Maybe the effect s
hould pin its | 468 // underflow this may deviate from the actual result. Maybe the effect s
hould pin its |
468 // result if the matrix could over/underflow for any component? | 469 // result if the matrix could over/underflow for any component? |
469 inout->setToOther(kA_GrColorComponentFlag, | 470 inout->setToOther(kA_GrColorComponentFlag, |
470 static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) <<
GrColor_SHIFT_A, | 471 static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) <<
GrColor_SHIFT_A, |
471 InvariantOutput::kWill_ReadInput); | 472 GrInvariantOutput::kWill_ReadInput); |
472 } | 473 } |
473 | 474 |
474 SkColorMatrix fMatrix; | 475 SkColorMatrix fMatrix; |
475 | 476 |
476 typedef GrFragmentProcessor INHERITED; | 477 typedef GrFragmentProcessor INHERITED; |
477 }; | 478 }; |
478 | 479 |
479 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect); | 480 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect); |
480 | 481 |
481 GrFragmentProcessor* ColorMatrixEffect::TestCreate(SkRandom* random, | 482 GrFragmentProcessor* ColorMatrixEffect::TestCreate(SkRandom* random, |
(...skipping 20 matching lines...) Expand all Loading... |
502 str->append("matrix: ("); | 503 str->append("matrix: ("); |
503 for (int i = 0; i < 20; ++i) { | 504 for (int i = 0; i < 20; ++i) { |
504 str->appendScalar(fMatrix.fMat[i]); | 505 str->appendScalar(fMatrix.fMat[i]); |
505 if (i < 19) { | 506 if (i < 19) { |
506 str->append(", "); | 507 str->append(", "); |
507 } | 508 } |
508 } | 509 } |
509 str->append(")"); | 510 str->append(")"); |
510 } | 511 } |
511 #endif | 512 #endif |
OLD | NEW |