1 2/* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#include "SkBlitRow.h" 11#include "SkColorFilter.h" 12#include "SkColorPriv.h" 13#include "SkFlattenableBuffers.h" 14#include "SkUtils.h" 15#include "SkString.h" 16#include "SkValidationUtils.h" 17 18#define ILLEGAL_XFERMODE_MODE ((SkXfermode::Mode)-1) 19 20// baseclass for filters that store a color and mode 21class SkModeColorFilter : public SkColorFilter { 22public: 23 SkModeColorFilter(SkColor color) { 24 fColor = color; 25 fMode = ILLEGAL_XFERMODE_MODE; 26 this->updateCache(); 27 } 28 29 SkModeColorFilter(SkColor color, SkXfermode::Mode mode) { 30 fColor = color; 31 fMode = mode; 32 this->updateCache(); 33 }; 34 35 SkColor getColor() const { return fColor; } 36 SkXfermode::Mode getMode() const { return fMode; } 37 bool isModeValid() const { return ILLEGAL_XFERMODE_MODE != fMode; } 38 SkPMColor getPMColor() const { return fPMColor; } 39 40 virtual bool asColorMode(SkColor* color, SkXfermode::Mode* mode) const SK_OVERRIDE { 41 if (ILLEGAL_XFERMODE_MODE == fMode) { 42 return false; 43 } 44 45 if (color) { 46 *color = fColor; 47 } 48 if (mode) { 49 *mode = fMode; 50 } 51 return true; 52 } 53 54 virtual uint32_t getFlags() const SK_OVERRIDE { 55 return fProc16 ? (kAlphaUnchanged_Flag | kHasFilter16_Flag) : 0; 56 } 57 58 virtual void filterSpan(const SkPMColor shader[], int count, 59 SkPMColor result[]) const SK_OVERRIDE { 60 SkPMColor color = fPMColor; 61 SkXfermodeProc proc = fProc; 62 63 for (int i = 0; i < count; i++) { 64 result[i] = proc(color, shader[i]); 65 } 66 } 67 68 virtual void filterSpan16(const uint16_t shader[], int count, 69 uint16_t result[]) const SK_OVERRIDE { 70 SkASSERT(this->getFlags() & kHasFilter16_Flag); 71 72 SkPMColor color = fPMColor; 73 SkXfermodeProc16 proc16 = fProc16; 74 75 for (int i = 0; i < count; i++) { 76 result[i] = proc16(color, shader[i]); 77 } 78 } 79 80#ifdef SK_DEVELOPER 81 virtual void toString(SkString* str) const SK_OVERRIDE { 82 str->append("SkModeColorFilter: color: 0x"); 83 str->appendHex(fColor); 84 str->append(" mode: "); 85 str->append(SkXfermode::ModeName(fMode)); 86 } 87#endif 88 89#if SK_SUPPORT_GPU 90 virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; 91#endif 92 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) 93 94protected: 95 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 96 this->INHERITED::flatten(buffer); 97 buffer.writeColor(fColor); 98 buffer.writeUInt(fMode); 99 } 100 101 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { 102 fColor = buffer.readColor(); 103 fMode = (SkXfermode::Mode)buffer.readUInt(); 104 if (buffer.isValid()) { 105 this->updateCache(); 106 buffer.validate(SkIsValidMode(fMode)); 107 } 108 } 109 110private: 111 SkColor fColor; 112 SkXfermode::Mode fMode; 113 // cache 114 SkPMColor fPMColor; 115 SkXfermodeProc fProc; 116 SkXfermodeProc16 fProc16; 117 118 void updateCache() { 119 fPMColor = SkPreMultiplyColor(fColor); 120 fProc = SkXfermode::GetProc(fMode); 121 fProc16 = SkXfermode::GetProc16(fMode, fColor); 122 } 123 124 typedef SkColorFilter INHERITED; 125}; 126 127/////////////////////////////////////////////////////////////////////////////// 128#if SK_SUPPORT_GPU 129#include "GrBlend.h" 130#include "GrEffect.h" 131#include "GrEffectUnitTest.h" 132#include "GrTBackendEffectFactory.h" 133#include "gl/GrGLEffect.h" 134#include "SkGr.h" 135 136namespace { 137/** 138 * A definition of blend equation for one coefficient. Generates a 139 * blend_coeff * value "expression". 140 */ 141template<typename ColorExpr> 142static inline ColorExpr blend_term(SkXfermode::Coeff coeff, 143 const ColorExpr& src, 144 const ColorExpr& dst, 145 const ColorExpr& value) { 146 switch (coeff) { 147 default: 148 GrCrash("Unexpected xfer coeff."); 149 case SkXfermode::kZero_Coeff: /** 0 */ 150 return ColorExpr(0); 151 case SkXfermode::kOne_Coeff: /** 1 */ 152 return value; 153 case SkXfermode::kSC_Coeff: 154 return src * value; 155 case SkXfermode::kISC_Coeff: 156 return (ColorExpr(1) - src) * dst; 157 case SkXfermode::kDC_Coeff: 158 return dst * value; 159 case SkXfermode::kIDC_Coeff: 160 return (ColorExpr(1) - dst) * value; 161 case SkXfermode::kSA_Coeff: /** src alpha */ 162 return src.a() * value; 163 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ 164 return (typename ColorExpr::AExpr(1) - src.a()) * value; 165 case SkXfermode::kDA_Coeff: /** dst alpha */ 166 return dst.a() * value; 167 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ 168 return (typename ColorExpr::AExpr(1) - dst.a()) * value; 169 } 170} 171/** 172 * Creates a color filter expression which modifies the color by 173 * the specified color filter. 174 */ 175template <typename ColorExpr> 176static inline ColorExpr color_filter_expression(const SkXfermode::Mode& mode, 177 const ColorExpr& filterColor, 178 const ColorExpr& inColor) { 179 SkXfermode::Coeff colorCoeff; 180 SkXfermode::Coeff filterColorCoeff; 181 SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff)); 182 return blend_term(colorCoeff, filterColor, inColor, inColor) + 183 blend_term(filterColorCoeff, filterColor, inColor, filterColor); 184} 185 186} 187 188class ModeColorFilterEffect : public GrEffect { 189public: 190 static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) { 191 // TODO: Make the effect take the coeffs rather than mode since we already do the 192 // conversion here. 193 SkXfermode::Coeff srcCoeff, dstCoeff; 194 if (!SkXfermode::ModeAsCoeff(mode, &srcCoeff, &dstCoeff)) { 195 SkDebugf("Failing to create color filter for mode %d\n", mode); 196 return NULL; 197 } 198 AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode))); 199 return CreateEffectRef(effect); 200 } 201 202 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags) const SK_OVERRIDE; 203 204 bool willUseFilterColor() const { 205 SkXfermode::Coeff dstCoeff; 206 SkXfermode::Coeff srcCoeff; 207 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); 208 if (SkXfermode::kZero_Coeff == srcCoeff) { 209 return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff)); 210 } 211 return true; 212 } 213 214 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { 215 return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance(); 216 } 217 218 static const char* Name() { return "ModeColorFilterEffect"; } 219 220 SkXfermode::Mode mode() const { return fMode; } 221 GrColor color() const { return fColor; } 222 223 class GLEffect : public GrGLEffect { 224 public: 225 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) 226 : INHERITED(factory) { 227 } 228 229 virtual void emitCode(GrGLShaderBuilder* builder, 230 const GrDrawEffect& drawEffect, 231 EffectKey key, 232 const char* outputColor, 233 const char* inputColor, 234 const TransformedCoordsArray& coords, 235 const TextureSamplerArray& samplers) SK_OVERRIDE { 236 SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect>().mode(); 237 238 SkASSERT(SkXfermode::kDst_Mode != mode); 239 const char* colorFilterColorUniName = NULL; 240 if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColor()) { 241 fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, 242 kVec4f_GrSLType, "FilterColor", 243 &colorFilterColorUniName); 244 } 245 246 GrGLSLExpr4 filter = 247 color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniName), GrGLSLExpr4(inputColor)); 248 249 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str()); 250 } 251 252 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrGLCaps&) { 253 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>(); 254 // The SL code does not depend on filter color at the moment, so no need to represent it 255 // in the key. 256 EffectKey modeKey = colorModeFilter.mode(); 257 return modeKey; 258 } 259 260 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE { 261 if (fFilterColorUni.isValid()) { 262 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect<ModeColorFilterEffect>(); 263 GrGLfloat c[4]; 264 GrColorToRGBAFloat(colorModeFilter.color(), c); 265 uman.set4fv(fFilterColorUni, 1, c); 266 } 267 } 268 269 private: 270 271 GrGLUniformManager::UniformHandle fFilterColorUni; 272 typedef GrGLEffect INHERITED; 273 }; 274 275 GR_DECLARE_EFFECT_TEST; 276 277private: 278 ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode) 279 : fMode(mode), 280 fColor(color) { 281 282 SkXfermode::Coeff dstCoeff; 283 SkXfermode::Coeff srcCoeff; 284 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); 285 // These could be calculated from the blend equation with template trickery.. 286 if (SkXfermode::kZero_Coeff == dstCoeff && !GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff))) { 287 this->setWillNotUseInputColor(); 288 } 289 } 290 291 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { 292 const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other); 293 return fMode == s.fMode && fColor == s.fColor; 294 } 295 296 SkXfermode::Mode fMode; 297 GrColor fColor; 298 299 typedef GrEffect INHERITED; 300}; 301 302namespace { 303 304/** Function color_component_to_int tries to reproduce the GLSL rounding. The spec doesn't specify 305 * to which direction the 0.5 goes. 306 */ 307static inline int color_component_to_int(float value) { 308 return sk_float_round2int(GrMax(0.f, GrMin(1.f, value)) * 255.f); 309} 310 311/** MaskedColorExpr is used to evaluate the color and valid color component flags through the 312 * blending equation. It has members similar to GrGLSLExpr so that it can be used with the 313 * templated helpers above. 314 */ 315class MaskedColorExpr { 316public: 317 MaskedColorExpr(const float color[], uint32_t flags) 318 : fFlags(flags) { 319 fColor[0] = color[0]; 320 fColor[1] = color[1]; 321 fColor[2] = color[2]; 322 fColor[3] = color[3]; 323 } 324 325 MaskedColorExpr(float v, uint32_t flags = kRGBA_GrColorComponentFlags) 326 : fFlags(flags) { 327 fColor[0] = v; 328 fColor[1] = v; 329 fColor[2] = v; 330 fColor[3] = v; 331 } 332 333 MaskedColorExpr operator*(const MaskedColorExpr& other) const { 334 float tmp[4]; 335 tmp[0] = fColor[0] * other.fColor[0]; 336 tmp[1] = fColor[1] * other.fColor[1]; 337 tmp[2] = fColor[2] * other.fColor[2]; 338 tmp[3] = fColor[3] * other.fColor[3]; 339 340 return MaskedColorExpr(tmp, fFlags & other.fFlags); 341 } 342 343 MaskedColorExpr operator+(const MaskedColorExpr& other) const { 344 float tmp[4]; 345 tmp[0] = fColor[0] + other.fColor[0]; 346 tmp[1] = fColor[1] + other.fColor[1]; 347 tmp[2] = fColor[2] + other.fColor[2]; 348 tmp[3] = fColor[3] + other.fColor[3]; 349 350 return MaskedColorExpr(tmp, fFlags & other.fFlags); 351 } 352 353 MaskedColorExpr operator-(const MaskedColorExpr& other) const { 354 float tmp[4]; 355 tmp[0] = fColor[0] - other.fColor[0]; 356 tmp[1] = fColor[1] - other.fColor[1]; 357 tmp[2] = fColor[2] - other.fColor[2]; 358 tmp[3] = fColor[3] - other.fColor[3]; 359 360 return MaskedColorExpr(tmp, fFlags & other.fFlags); 361 } 362 363 MaskedColorExpr a() const { 364 uint32_t flags = (fFlags & kA_GrColorComponentFlag) ? kRGBA_GrColorComponentFlags : 0; 365 return MaskedColorExpr(fColor[3], flags); 366 } 367 368 GrColor getColor() const { 369 return GrColorPackRGBA(color_component_to_int(fColor[0]), 370 color_component_to_int(fColor[1]), 371 color_component_to_int(fColor[2]), 372 color_component_to_int(fColor[3])); 373 } 374 375 uint32_t getValidComponents() const { return fFlags; } 376 377 typedef MaskedColorExpr AExpr; 378private: 379 float fColor[4]; 380 uint32_t fFlags; 381}; 382 383} 384 385void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { 386 float inputColor[4]; 387 GrColorToRGBAFloat(*color, inputColor); 388 float filterColor[4]; 389 GrColorToRGBAFloat(fColor, filterColor); 390 MaskedColorExpr result = 391 color_filter_expression(fMode, 392 MaskedColorExpr(filterColor, kRGBA_GrColorComponentFlags), 393 MaskedColorExpr(inputColor, *validFlags)); 394 395 *color = result.getColor(); 396 *validFlags = result.getValidComponents(); 397} 398 399GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect); 400GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand, 401 GrContext*, 402 const GrDrawTargetCaps&, 403 GrTexture*[]) { 404 SkXfermode::Mode mode = SkXfermode::kDst_Mode; 405 while (SkXfermode::kDst_Mode == mode) { 406 mode = static_cast<SkXfermode::Mode>(rand->nextRangeU(0, SkXfermode::kLastCoeffMode)); 407 } 408 GrColor color = rand->nextU(); 409 return ModeColorFilterEffect::Create(color, mode); 410} 411 412GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const { 413 if (SkXfermode::kDst_Mode != fMode) { 414 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); 415 } 416 return NULL; 417} 418 419#endif 420 421/////////////////////////////////////////////////////////////////////////////// 422 423class Src_SkModeColorFilter : public SkModeColorFilter { 424public: 425 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mode) {} 426 427 virtual uint32_t getFlags() const SK_OVERRIDE { 428 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 429 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 430 } else { 431 return 0; 432 } 433 } 434 435 virtual void filterSpan(const SkPMColor shader[], int count, 436 SkPMColor result[]) const SK_OVERRIDE { 437 sk_memset32(result, this->getPMColor(), count); 438 } 439 440 virtual void filterSpan16(const uint16_t shader[], int count, 441 uint16_t result[]) const SK_OVERRIDE { 442 SkASSERT(this->getFlags() & kHasFilter16_Flag); 443 sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); 444 } 445 446 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(Src_SkModeColorFilter) 447 448protected: 449 Src_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 450 : INHERITED(buffer) {} 451 452private: 453 typedef SkModeColorFilter INHERITED; 454}; 455 456class SrcOver_SkModeColorFilter : public SkModeColorFilter { 457public: 458 SrcOver_SkModeColorFilter(SkColor color) 459 : INHERITED(color, SkXfermode::kSrcOver_Mode) { 460 fColor32Proc = SkBlitRow::ColorProcFactory(); 461 } 462 463 virtual uint32_t getFlags() const SK_OVERRIDE { 464 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { 465 return kAlphaUnchanged_Flag | kHasFilter16_Flag; 466 } else { 467 return 0; 468 } 469 } 470 471 virtual void filterSpan(const SkPMColor shader[], int count, 472 SkPMColor result[]) const SK_OVERRIDE { 473 fColor32Proc(result, shader, count, this->getPMColor()); 474 } 475 476 virtual void filterSpan16(const uint16_t shader[], int count, 477 uint16_t result[]) const SK_OVERRIDE { 478 SkASSERT(this->getFlags() & kHasFilter16_Flag); 479 sk_memset16(result, SkPixel32ToPixel16(this->getPMColor()), count); 480 } 481 482 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SrcOver_SkModeColorFilter) 483 484protected: 485 SrcOver_SkModeColorFilter(SkFlattenableReadBuffer& buffer) 486 : INHERITED(buffer) { 487 fColor32Proc = SkBlitRow::ColorProcFactory(); 488 } 489 490private: 491 492 SkBlitRow::ColorProc fColor32Proc; 493 494 typedef SkModeColorFilter INHERITED; 495}; 496 497/////////////////////////////////////////////////////////////////////////////// 498 499SkColorFilter* SkColorFilter::CreateModeFilter(SkColor color, 500 SkXfermode::Mode mode) { 501 unsigned alpha = SkColorGetA(color); 502 503 // first collaps some modes if possible 504 505 if (SkXfermode::kClear_Mode == mode) { 506 color = 0; 507 mode = SkXfermode::kSrc_Mode; 508 } else if (SkXfermode::kSrcOver_Mode == mode) { 509 if (0 == alpha) { 510 mode = SkXfermode::kDst_Mode; 511 } else if (255 == alpha) { 512 mode = SkXfermode::kSrc_Mode; 513 } 514 // else just stay srcover 515 } 516 517 // weed out combinations that are noops, and just return null 518 if (SkXfermode::kDst_Mode == mode || 519 (0 == alpha && (SkXfermode::kSrcOver_Mode == mode || 520 SkXfermode::kDstOver_Mode == mode || 521 SkXfermode::kDstOut_Mode == mode || 522 SkXfermode::kSrcATop_Mode == mode || 523 SkXfermode::kXor_Mode == mode || 524 SkXfermode::kDarken_Mode == mode)) || 525 (0xFF == alpha && SkXfermode::kDstIn_Mode == mode)) { 526 return NULL; 527 } 528 529 switch (mode) { 530 case SkXfermode::kSrc_Mode: 531 return SkNEW_ARGS(Src_SkModeColorFilter, (color)); 532 case SkXfermode::kSrcOver_Mode: 533 return SkNEW_ARGS(SrcOver_SkModeColorFilter, (color)); 534 default: 535 return SkNEW_ARGS(SkModeColorFilter, (color, mode)); 536 } 537} 538 539/////////////////////////////////////////////////////////////////////////////// 540 541static inline unsigned pin(unsigned value, unsigned max) { 542 if (value > max) { 543 value = max; 544 } 545 return value; 546} 547 548class SkLightingColorFilter : public SkColorFilter { 549public: 550 SkLightingColorFilter(SkColor mul, SkColor add) : fMul(mul), fAdd(add) {} 551 552 virtual void filterSpan(const SkPMColor shader[], int count, 553 SkPMColor result[]) const SK_OVERRIDE { 554 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 555 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 556 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 557 558 unsigned addR = SkColorGetR(fAdd); 559 unsigned addG = SkColorGetG(fAdd); 560 unsigned addB = SkColorGetB(fAdd); 561 562 for (int i = 0; i < count; i++) { 563 SkPMColor c = shader[i]; 564 if (c) { 565 unsigned a = SkGetPackedA32(c); 566 unsigned scaleA = SkAlpha255To256(a); 567 unsigned r = pin(SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA), a); 568 unsigned g = pin(SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA), a); 569 unsigned b = pin(SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA), a); 570 c = SkPackARGB32(a, r, g, b); 571 } 572 result[i] = c; 573 } 574 } 575 576#ifdef SK_DEVELOPER 577 virtual void toString(SkString* str) const SK_OVERRIDE { 578 str->append("SkLightingColorFilter: mul: 0x"); 579 str->appendHex(fMul); 580 str->append(" add: 0x"); 581 str->appendHex(fAdd); 582 } 583#endif 584 585 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter) 586 587protected: 588 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { 589 this->INHERITED::flatten(buffer); 590 buffer.writeColor(fMul); 591 buffer.writeColor(fAdd); 592 } 593 594 SkLightingColorFilter(SkFlattenableReadBuffer& buffer) { 595 fMul = buffer.readColor(); 596 fAdd = buffer.readColor(); 597 } 598 599 SkColor fMul, fAdd; 600 601private: 602 typedef SkColorFilter INHERITED; 603}; 604 605class SkLightingColorFilter_JustAdd : public SkLightingColorFilter { 606public: 607 SkLightingColorFilter_JustAdd(SkColor mul, SkColor add) 608 : INHERITED(mul, add) {} 609 610 virtual void filterSpan(const SkPMColor shader[], int count, 611 SkPMColor result[]) const SK_OVERRIDE { 612 unsigned addR = SkColorGetR(fAdd); 613 unsigned addG = SkColorGetG(fAdd); 614 unsigned addB = SkColorGetB(fAdd); 615 616 for (int i = 0; i < count; i++) { 617 SkPMColor c = shader[i]; 618 if (c) { 619 unsigned a = SkGetPackedA32(c); 620 unsigned scaleA = SkAlpha255To256(a); 621 unsigned r = pin(SkGetPackedR32(c) + SkAlphaMul(addR, scaleA), a); 622 unsigned g = pin(SkGetPackedG32(c) + SkAlphaMul(addG, scaleA), a); 623 unsigned b = pin(SkGetPackedB32(c) + SkAlphaMul(addB, scaleA), a); 624 c = SkPackARGB32(a, r, g, b); 625 } 626 result[i] = c; 627 } 628 } 629 630#ifdef SK_DEVELOPER 631 virtual void toString(SkString* str) const SK_OVERRIDE { 632 str->append("SkLightingColorFilter_JustAdd: add: 0x"); 633 str->appendHex(fAdd); 634 } 635#endif 636 637 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_JustAdd) 638 639protected: 640 SkLightingColorFilter_JustAdd(SkFlattenableReadBuffer& buffer) 641 : INHERITED(buffer) {} 642 643private: 644 typedef SkLightingColorFilter INHERITED; 645}; 646 647class SkLightingColorFilter_JustMul : public SkLightingColorFilter { 648public: 649 SkLightingColorFilter_JustMul(SkColor mul, SkColor add) 650 : INHERITED(mul, add) {} 651 652 virtual void filterSpan(const SkPMColor shader[], int count, 653 SkPMColor result[]) const SK_OVERRIDE { 654 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 655 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 656 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 657 658 for (int i = 0; i < count; i++) { 659 SkPMColor c = shader[i]; 660 if (c) { 661 unsigned a = SkGetPackedA32(c); 662 unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR); 663 unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG); 664 unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB); 665 c = SkPackARGB32(a, r, g, b); 666 } 667 result[i] = c; 668 } 669 } 670 671#ifdef SK_DEVELOPER 672 virtual void toString(SkString* str) const SK_OVERRIDE { 673 str->append("SkLightingColorFilter_JustMul: mul: 0x"); 674 str->appendHex(fMul); 675 } 676#endif 677 678 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_JustMul) 679 680protected: 681 SkLightingColorFilter_JustMul(SkFlattenableReadBuffer& buffer) 682 : INHERITED(buffer) {} 683 684private: 685 typedef SkLightingColorFilter INHERITED; 686}; 687 688class SkLightingColorFilter_SingleMul : public SkLightingColorFilter { 689public: 690 SkLightingColorFilter_SingleMul(SkColor mul, SkColor add) 691 : INHERITED(mul, add) { 692 SkASSERT(SkColorGetR(add) == 0); 693 SkASSERT(SkColorGetG(add) == 0); 694 SkASSERT(SkColorGetB(add) == 0); 695 SkASSERT(SkColorGetR(mul) == SkColorGetG(mul)); 696 SkASSERT(SkColorGetR(mul) == SkColorGetB(mul)); 697 } 698 699 virtual uint32_t getFlags() const SK_OVERRIDE { 700 return this->INHERITED::getFlags() | (kAlphaUnchanged_Flag | kHasFilter16_Flag); 701 } 702 703 virtual void filterSpan16(const uint16_t shader[], int count, 704 uint16_t result[]) const SK_OVERRIDE { 705 // all mul components are the same 706 unsigned scale = SkAlpha255To256(SkColorGetR(fMul)); 707 708 if (count > 0) { 709 do { 710 *result++ = SkAlphaMulRGB16(*shader++, scale); 711 } while (--count > 0); 712 } 713 } 714 715#ifdef SK_DEVELOPER 716 virtual void toString(SkString* str) const SK_OVERRIDE { 717 str->append("SkLightingColorFilter_SingleMul: mul: 0x"); 718 str->appendHex(fMul); 719 } 720#endif 721 722 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_SingleMul) 723 724protected: 725 SkLightingColorFilter_SingleMul(SkFlattenableReadBuffer& buffer) 726 : INHERITED(buffer) {} 727 728private: 729 typedef SkLightingColorFilter INHERITED; 730}; 731 732class SkLightingColorFilter_NoPin : public SkLightingColorFilter { 733public: 734 SkLightingColorFilter_NoPin(SkColor mul, SkColor add) 735 : INHERITED(mul, add) {} 736 737 virtual void filterSpan(const SkPMColor shader[], int count, 738 SkPMColor result[]) const SK_OVERRIDE { 739 unsigned scaleR = SkAlpha255To256(SkColorGetR(fMul)); 740 unsigned scaleG = SkAlpha255To256(SkColorGetG(fMul)); 741 unsigned scaleB = SkAlpha255To256(SkColorGetB(fMul)); 742 743 unsigned addR = SkColorGetR(fAdd); 744 unsigned addG = SkColorGetG(fAdd); 745 unsigned addB = SkColorGetB(fAdd); 746 747 for (int i = 0; i < count; i++) { 748 SkPMColor c = shader[i]; 749 if (c) { 750 unsigned a = SkGetPackedA32(c); 751 unsigned scaleA = SkAlpha255To256(a); 752 unsigned r = SkAlphaMul(SkGetPackedR32(c), scaleR) + SkAlphaMul(addR, scaleA); 753 unsigned g = SkAlphaMul(SkGetPackedG32(c), scaleG) + SkAlphaMul(addG, scaleA); 754 unsigned b = SkAlphaMul(SkGetPackedB32(c), scaleB) + SkAlphaMul(addB, scaleA); 755 c = SkPackARGB32(a, r, g, b); 756 } 757 result[i] = c; 758 } 759 } 760 761#ifdef SK_DEVELOPER 762 virtual void toString(SkString* str) const SK_OVERRIDE { 763 str->append("SkLightingColorFilter_NoPin: mul: 0x"); 764 str->appendHex(fMul); 765 str->append(" add: 0x"); 766 str->appendHex(fAdd); 767 } 768#endif 769 770 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkLightingColorFilter_NoPin) 771 772protected: 773 SkLightingColorFilter_NoPin(SkFlattenableReadBuffer& buffer) 774 : INHERITED(buffer) {} 775 776private: 777 typedef SkLightingColorFilter INHERITED; 778}; 779 780/////////////////////////////////////////////////////////////////////////////// 781 782class SkSimpleColorFilter : public SkColorFilter { 783public: 784 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) { 785 return SkNEW(SkSimpleColorFilter); 786 } 787 788#ifdef SK_DEVELOPER 789 virtual void toString(SkString* str) const SK_OVERRIDE { 790 str->append("SkSimpleColorFilter"); 791 } 792#endif 793 794protected: 795 void filterSpan(const SkPMColor src[], int count, SkPMColor 796 result[]) const SK_OVERRIDE { 797 if (result != src) { 798 memcpy(result, src, count * sizeof(SkPMColor)); 799 } 800 } 801 802 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE {} 803 804 virtual Factory getFactory() const { 805 return CreateProc; 806 } 807 808}; 809 810SkColorFilter* SkColorFilter::CreateLightingFilter(SkColor mul, SkColor add) { 811 mul &= 0x00FFFFFF; 812 add &= 0x00FFFFFF; 813 814 if (0xFFFFFF == mul) { 815 if (0 == add) { 816 return SkNEW(SkSimpleColorFilter); // no change to the colors 817 } else { 818 return SkNEW_ARGS(SkLightingColorFilter_JustAdd, (mul, add)); 819 } 820 } 821 822 if (0 == add) { 823 if (SkColorGetR(mul) == SkColorGetG(mul) && 824 SkColorGetR(mul) == SkColorGetB(mul)) { 825 return SkNEW_ARGS(SkLightingColorFilter_SingleMul, (mul, add)); 826 } else { 827 return SkNEW_ARGS(SkLightingColorFilter_JustMul, (mul, add)); 828 } 829 } 830 831 if (SkColorGetR(mul) + SkColorGetR(add) <= 255 && 832 SkColorGetG(mul) + SkColorGetG(add) <= 255 && 833 SkColorGetB(mul) + SkColorGetB(add) <= 255) { 834 return SkNEW_ARGS(SkLightingColorFilter_NoPin, (mul, add)); 835 } 836 837 return SkNEW_ARGS(SkLightingColorFilter, (mul, add)); 838} 839 840SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkColorFilter) 841 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) 842 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) 843 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) 844 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) 845 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) 846 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) 847 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) 848 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) 849 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) 850SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 851