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 |