| 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 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 325 } | 325 } |
| 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 "GrEffect.h" | 335 #include "GrProcessor.h" |
| 336 #include "GrTBackendEffectFactory.h" | 336 #include "GrTBackendProcessorFactory.h" |
| 337 #include "gl/GrGLEffect.h" | 337 #include "gl/GrGLProcessor.h" |
| 338 #include "gl/builders/GrGLProgramBuilder.h" | 338 #include "gl/builders/GrGLProgramBuilder.h" |
| 339 | 339 |
| 340 class ColorMatrixEffect : public GrEffect { | 340 class ColorMatrixEffect : public GrFragmentProcessor { |
| 341 public: | 341 public: |
| 342 static GrEffect* Create(const SkColorMatrix& matrix) { | 342 static GrFragmentProcessor* Create(const SkColorMatrix& matrix) { |
| 343 return SkNEW_ARGS(ColorMatrixEffect, (matrix)); | 343 return SkNEW_ARGS(ColorMatrixEffect, (matrix)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 static const char* Name() { return "Color Matrix"; } | 346 static const char* Name() { return "Color Matrix"; } |
| 347 | 347 |
| 348 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { | 348 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE { |
| 349 return GrTBackendEffectFactory<ColorMatrixEffect>::getInstance(); | 349 return GrTBackendFragmentProcessorFactory<ColorMatrixEffect>::getInstanc
e(); |
| 350 } | 350 } |
| 351 | 351 |
| 352 virtual void getConstantColorComponents(GrColor* color, | 352 virtual void getConstantColorComponents(GrColor* color, |
| 353 uint32_t* validFlags) const SK_OVERR
IDE { | 353 uint32_t* validFlags) const SK_OVERR
IDE { |
| 354 // We only bother to check whether the alpha channel will be constant. I
f SkColorMatrix had | 354 // We only bother to check whether the alpha channel will be constant. I
f SkColorMatrix had |
| 355 // type flags it might be worth checking the other components. | 355 // type flags it might be worth checking the other components. |
| 356 | 356 |
| 357 // The matrix is defined such the 4th row determines the output alpha. T
he first four | 357 // The matrix is defined such the 4th row determines the output alpha. T
he first four |
| 358 // columns of that row multiply the input r, g, b, and a, respectively,
and the last column | 358 // columns of that row multiply the input r, g, b, and a, respectively,
and the last column |
| 359 // is the "translation". | 359 // is the "translation". |
| (...skipping 27 matching lines...) Expand all Loading... |
| 387 } | 387 } |
| 388 outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; | 388 outputA += fMatrix.fMat[kAlphaRowTranslateIdx]; |
| 389 *validFlags = kA_GrColorComponentFlag; | 389 *validFlags = kA_GrColorComponentFlag; |
| 390 // We pin the color to [0,1]. This would happen to the *final* color out
put from the frag | 390 // We pin the color to [0,1]. This would happen to the *final* color out
put from the frag |
| 391 // shader but currently the effect does not pin its own output. So in th
e case of over/ | 391 // shader but currently the effect does not pin its own output. So in th
e case of over/ |
| 392 // underflow this may deviate from the actual result. Maybe the effect s
hould pin its | 392 // underflow this may deviate from the actual result. Maybe the effect s
hould pin its |
| 393 // result if the matrix could over/underflow for any component? | 393 // result if the matrix could over/underflow for any component? |
| 394 *color = static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_S
HIFT_A; | 394 *color = static_cast<uint8_t>(SkScalarPin(outputA, 0, 255)) << GrColor_S
HIFT_A; |
| 395 } | 395 } |
| 396 | 396 |
| 397 GR_DECLARE_EFFECT_TEST; | 397 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 398 | 398 |
| 399 class GLEffect : public GrGLEffect { | 399 class GLProcessor : public GrGLFragmentProcessor { |
| 400 public: | 400 public: |
| 401 // this class always generates the same code. | 401 // this class always generates the same code. |
| 402 static void GenKey(const GrEffect&, const GrGLCaps&, GrEffectKeyBuilder*
b) {} | 402 static void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKeyBu
ilder* b) {} |
| 403 | 403 |
| 404 GLEffect(const GrBackendEffectFactory& factory, | 404 GLProcessor(const GrBackendProcessorFactory& factory, |
| 405 const GrEffect&) | 405 const GrProcessor&) |
| 406 : INHERITED(factory) { | 406 : INHERITED(factory) { |
| 407 } | 407 } |
| 408 | 408 |
| 409 virtual void emitCode(GrGLProgramBuilder* builder, | 409 virtual void emitCode(GrGLProgramBuilder* builder, |
| 410 const GrEffect&, | 410 const GrFragmentProcessor&, |
| 411 const GrEffectKey&, | 411 const GrProcessorKey&, |
| 412 const char* outputColor, | 412 const char* outputColor, |
| 413 const char* inputColor, | 413 const char* inputColor, |
| 414 const TransformedCoordsArray&, | 414 const TransformedCoordsArray&, |
| 415 const TextureSamplerArray&) SK_OVERRIDE { | 415 const TextureSamplerArray&) SK_OVERRIDE { |
| 416 fMatrixHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Vi
sibility, | 416 fMatrixHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Vi
sibility, |
| 417 kMat44f_GrSLType, | 417 kMat44f_GrSLType, |
| 418 "ColorMatrix"); | 418 "ColorMatrix"); |
| 419 fVectorHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Vi
sibility, | 419 fVectorHandle = builder->addUniform(GrGLProgramBuilder::kFragment_Vi
sibility, |
| 420 kVec4f_GrSLType, | 420 kVec4f_GrSLType, |
| 421 "ColorMatrixVector"); | 421 "ColorMatrixVector"); |
| 422 | 422 |
| 423 if (NULL == inputColor) { | 423 if (NULL == inputColor) { |
| 424 // could optimize this case, but we aren't for now. | 424 // could optimize this case, but we aren't for now. |
| 425 inputColor = "vec4(1)"; | 425 inputColor = "vec4(1)"; |
| 426 } | 426 } |
| 427 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); | 427 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBui
lder(); |
| 428 // The max() is to guard against 0 / 0 during unpremul when the inco
ming color is | 428 // The max() is to guard against 0 / 0 during unpremul when the inco
ming color is |
| 429 // transparent black. | 429 // transparent black. |
| 430 fsBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n
", inputColor); | 430 fsBuilder->codeAppendf("\tfloat nonZeroAlpha = max(%s.a, 0.00001);\n
", inputColor); |
| 431 fsBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZ
eroAlpha) + %s;\n", | 431 fsBuilder->codeAppendf("\t%s = %s * vec4(%s.rgb / nonZeroAlpha, nonZ
eroAlpha) + %s;\n", |
| 432 outputColor, | 432 outputColor, |
| 433 builder->getUniformCStr(fMatrixHandle), | 433 builder->getUniformCStr(fMatrixHandle), |
| 434 inputColor, | 434 inputColor, |
| 435 builder->getUniformCStr(fVectorHandle)); | 435 builder->getUniformCStr(fVectorHandle)); |
| 436 fsBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor,
outputColor); | 436 fsBuilder->codeAppendf("\t%s = clamp(%s, 0.0, 1.0);\n", outputColor,
outputColor); |
| 437 fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputCol
or); | 437 fsBuilder->codeAppendf("\t%s.rgb *= %s.a;\n", outputColor, outputCol
or); |
| 438 } | 438 } |
| 439 | 439 |
| 440 virtual void setData(const GrGLProgramDataManager& uniManager, | 440 virtual void setData(const GrGLProgramDataManager& uniManager, |
| 441 const GrEffect& effect) SK_OVERRIDE { | 441 const GrProcessor& proc) SK_OVERRIDE { |
| 442 const ColorMatrixEffect& cme = effect.cast<ColorMatrixEffect>(); | 442 const ColorMatrixEffect& cme = proc.cast<ColorMatrixEffect>(); |
| 443 const float* m = cme.fMatrix.fMat; | 443 const float* m = cme.fMatrix.fMat; |
| 444 // The GL matrix is transposed from SkColorMatrix. | 444 // The GL matrix is transposed from SkColorMatrix. |
| 445 GrGLfloat mt[] = { | 445 GrGLfloat mt[] = { |
| 446 m[0], m[5], m[10], m[15], | 446 m[0], m[5], m[10], m[15], |
| 447 m[1], m[6], m[11], m[16], | 447 m[1], m[6], m[11], m[16], |
| 448 m[2], m[7], m[12], m[17], | 448 m[2], m[7], m[12], m[17], |
| 449 m[3], m[8], m[13], m[18], | 449 m[3], m[8], m[13], m[18], |
| 450 }; | 450 }; |
| 451 static const float kScale = 1.0f / 255.0f; | 451 static const float kScale = 1.0f / 255.0f; |
| 452 GrGLfloat vec[] = { | 452 GrGLfloat vec[] = { |
| 453 m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale, | 453 m[4] * kScale, m[9] * kScale, m[14] * kScale, m[19] * kScale, |
| 454 }; | 454 }; |
| 455 uniManager.setMatrix4fv(fMatrixHandle, 1, mt); | 455 uniManager.setMatrix4fv(fMatrixHandle, 1, mt); |
| 456 uniManager.set4fv(fVectorHandle, 1, vec); | 456 uniManager.set4fv(fVectorHandle, 1, vec); |
| 457 } | 457 } |
| 458 | 458 |
| 459 private: | 459 private: |
| 460 GrGLProgramDataManager::UniformHandle fMatrixHandle; | 460 GrGLProgramDataManager::UniformHandle fMatrixHandle; |
| 461 GrGLProgramDataManager::UniformHandle fVectorHandle; | 461 GrGLProgramDataManager::UniformHandle fVectorHandle; |
| 462 | 462 |
| 463 typedef GrGLEffect INHERITED; | 463 typedef GrGLFragmentProcessor INHERITED; |
| 464 }; | 464 }; |
| 465 | 465 |
| 466 private: | 466 private: |
| 467 ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} | 467 ColorMatrixEffect(const SkColorMatrix& matrix) : fMatrix(matrix) {} |
| 468 | 468 |
| 469 virtual bool onIsEqual(const GrEffect& s) const { | 469 virtual bool onIsEqual(const GrProcessor& s) const { |
| 470 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>(); | 470 const ColorMatrixEffect& cme = s.cast<ColorMatrixEffect>(); |
| 471 return cme.fMatrix == fMatrix; | 471 return cme.fMatrix == fMatrix; |
| 472 } | 472 } |
| 473 | 473 |
| 474 SkColorMatrix fMatrix; | 474 SkColorMatrix fMatrix; |
| 475 | 475 |
| 476 typedef GrEffect INHERITED; | 476 typedef GrFragmentProcessor INHERITED; |
| 477 }; | 477 }; |
| 478 | 478 |
| 479 GR_DEFINE_EFFECT_TEST(ColorMatrixEffect); | 479 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(ColorMatrixEffect); |
| 480 | 480 |
| 481 GrEffect* ColorMatrixEffect::TestCreate(SkRandom* random, | 481 GrFragmentProcessor* ColorMatrixEffect::TestCreate(SkRandom* random, |
| 482 GrContext*, | 482 GrContext*, |
| 483 const GrDrawTargetCaps&, | 483 const GrDrawTargetCaps&, |
| 484 GrTexture* dummyTextures[2]) { | 484 GrTexture* dummyTextures[2])
{ |
| 485 SkColorMatrix colorMatrix; | 485 SkColorMatrix colorMatrix; |
| 486 for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) { | 486 for (size_t i = 0; i < SK_ARRAY_COUNT(colorMatrix.fMat); ++i) { |
| 487 colorMatrix.fMat[i] = random->nextSScalar1(); | 487 colorMatrix.fMat[i] = random->nextSScalar1(); |
| 488 } | 488 } |
| 489 return ColorMatrixEffect::Create(colorMatrix); | 489 return ColorMatrixEffect::Create(colorMatrix); |
| 490 } | 490 } |
| 491 | 491 |
| 492 GrEffect* SkColorMatrixFilter::asNewEffect(GrContext*) const { | 492 GrFragmentProcessor* SkColorMatrixFilter::asFragmentProcessor(GrContext*) const
{ |
| 493 return ColorMatrixEffect::Create(fMatrix); | 493 return ColorMatrixEffect::Create(fMatrix); |
| 494 } | 494 } |
| 495 | 495 |
| 496 #endif | 496 #endif |
| 497 | 497 |
| 498 #ifndef SK_IGNORE_TO_STRING | 498 #ifndef SK_IGNORE_TO_STRING |
| 499 void SkColorMatrixFilter::toString(SkString* str) const { | 499 void SkColorMatrixFilter::toString(SkString* str) const { |
| 500 str->append("SkColorMatrixFilter: "); | 500 str->append("SkColorMatrixFilter: "); |
| 501 | 501 |
| 502 str->append("matrix: ("); | 502 str->append("matrix: ("); |
| 503 for (int i = 0; i < 20; ++i) { | 503 for (int i = 0; i < 20; ++i) { |
| 504 str->appendScalar(fMatrix.fMat[i]); | 504 str->appendScalar(fMatrix.fMat[i]); |
| 505 if (i < 19) { | 505 if (i < 19) { |
| 506 str->append(", "); | 506 str->append(", "); |
| 507 } | 507 } |
| 508 } | 508 } |
| 509 str->append(")"); | 509 str->append(")"); |
| 510 } | 510 } |
| 511 #endif | 511 #endif |
| OLD | NEW |