Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 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 | 8 |
| 9 | 9 |
| 10 #include "SkBlitRow.h" | 10 #include "SkBlitRow.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 78 | 78 |
| 79 #ifdef SK_DEVELOPER | 79 #ifdef SK_DEVELOPER |
| 80 virtual void toString(SkString* str) const SK_OVERRIDE { | 80 virtual void toString(SkString* str) const SK_OVERRIDE { |
| 81 str->append("SkModeColorFilter: color: 0x"); | 81 str->append("SkModeColorFilter: color: 0x"); |
| 82 str->appendHex(fColor); | 82 str->appendHex(fColor); |
| 83 str->append(" mode: "); | 83 str->append(" mode: "); |
| 84 str->append(SkXfermode::ModeName(fMode)); | 84 str->append(SkXfermode::ModeName(fMode)); |
| 85 } | 85 } |
| 86 #endif | 86 #endif |
| 87 | 87 |
| 88 #if SK_SUPPORT_GPU | |
| 89 virtual GrEffectRef* asNewEffect(GrContext*) const SK_OVERRIDE; | |
| 90 #endif | |
| 88 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) | 91 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkModeColorFilter) |
| 89 | 92 |
| 90 protected: | 93 protected: |
| 91 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { | 94 virtual void flatten(SkFlattenableWriteBuffer& buffer) const SK_OVERRIDE { |
| 92 this->INHERITED::flatten(buffer); | 95 this->INHERITED::flatten(buffer); |
| 93 buffer.writeColor(fColor); | 96 buffer.writeColor(fColor); |
| 94 buffer.writeUInt(fMode); | 97 buffer.writeUInt(fMode); |
| 95 } | 98 } |
| 96 | 99 |
| 97 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { | 100 SkModeColorFilter(SkFlattenableReadBuffer& buffer) { |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 110 | 113 |
| 111 void updateCache() { | 114 void updateCache() { |
| 112 fPMColor = SkPreMultiplyColor(fColor); | 115 fPMColor = SkPreMultiplyColor(fColor); |
| 113 fProc = SkXfermode::GetProc(fMode); | 116 fProc = SkXfermode::GetProc(fMode); |
| 114 fProc16 = SkXfermode::GetProc16(fMode, fColor); | 117 fProc16 = SkXfermode::GetProc16(fMode, fColor); |
| 115 } | 118 } |
| 116 | 119 |
| 117 typedef SkColorFilter INHERITED; | 120 typedef SkColorFilter INHERITED; |
| 118 }; | 121 }; |
| 119 | 122 |
| 123 /////////////////////////////////////////////////////////////////////////////// | |
| 124 #if SK_SUPPORT_GPU | |
| 125 #include "GrBlend.h" | |
| 126 #include "GrEffect.h" | |
| 127 #include "GrEffectUnitTest.h" | |
| 128 #include "GrTBackendEffectFactory.h" | |
| 129 #include "gl/GrGLEffect.h" | |
| 130 #include "gl/GrGLEffectMatrix.h" | |
| 131 #include "SkGr.h" | |
| 132 | |
| 133 namespace { | |
| 134 /** | |
| 135 * A definition of blend equation for one coefficient. Generates a | |
| 136 * blend_coeff * value "expression". | |
| 137 */ | |
| 138 template<typename ColorExpr> | |
| 139 static inline ColorExpr blend_term(SkXfermode::Coeff coeff, | |
| 140 const ColorExpr& src, | |
| 141 const ColorExpr& dst, | |
| 142 const ColorExpr& value) { | |
| 143 switch (coeff) { | |
| 144 default: | |
| 145 GrCrash("Unexpected xfer coeff."); | |
| 146 case SkXfermode::kZero_Coeff: /** 0 */ | |
| 147 return ColorExpr(0); | |
| 148 case SkXfermode::kOne_Coeff: /** 1 */ | |
| 149 return value; | |
| 150 case SkXfermode::kSC_Coeff: | |
| 151 return src * value; | |
| 152 case SkXfermode::kISC_Coeff: | |
| 153 return (1 - src) * dst; | |
| 154 case SkXfermode::kDC_Coeff: | |
| 155 return dst * value; | |
| 156 case SkXfermode::kIDC_Coeff: | |
| 157 return (1 - dst) * value; | |
| 158 case SkXfermode::kSA_Coeff: /** src alpha */ | |
| 159 return value * src.a(); | |
| 160 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ | |
| 161 return value * (1 - src.a()); | |
| 162 case SkXfermode::kDA_Coeff: /** dst alpha */ | |
| 163 return value * dst.a(); | |
| 164 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ | |
| 165 return value * (1 - dst.a()); | |
| 166 } | |
| 167 } | |
| 168 /** | |
| 169 * Creates a color filter expression which modifies the color by | |
| 170 * the specified color filter. | |
| 171 */ | |
| 172 template <typename ColorExpr> | |
| 173 static inline ColorExpr color_filter_expression(SkXfermode::Mode mode, | |
| 174 const ColorExpr& filterColor, | |
| 175 const ColorExpr& inColor) { | |
| 176 SkXfermode::Coeff colorCoeff; | |
| 177 SkXfermode::Coeff filterColorCoeff; | |
| 178 SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff) ); | |
| 179 return blend_term(colorCoeff, filterColor, inColor, inColor) + | |
| 180 blend_term(filterColorCoeff, filterColor, inColor, filterColor); | |
| 181 } | |
| 182 } | |
| 183 | |
| 184 class ModeColorFilterEffect : public GrEffect { | |
| 185 public: | |
| 186 static GrEffectRef* Create(const GrColor& c, SkXfermode::Mode mode) { | |
| 187 AutoEffectUnref effect(SkNEW_ARGS(ModeColorFilterEffect, (c, mode))); | |
| 188 return CreateEffectRef(effect); | |
| 189 } | |
| 190 | |
| 191 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags ) const SK_OVERRIDE; | |
| 192 | |
| 193 virtual bool willUseInputColor() const { | |
| 194 SkXfermode::Coeff dstCoeff; | |
| 195 SkXfermode::Coeff srcCoeff; | |
| 196 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); | |
| 197 // These could be calculated from the blend equation with template trick ery.. | |
| 198 if (SkXfermode::kZero_Coeff == dstCoeff) { | |
| 199 return GrBlendCoeffRefsDst(sk_blend_to_grblend(srcCoeff)); | |
| 200 } | |
| 201 return true; | |
| 202 } | |
| 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 TextureSamplerArray& samplers) SK_OVERRIDE { | |
| 235 SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect> ().mode(); | |
| 236 | |
| 237 SkASSERT(SkXfermode::kDst_Mode != mode); | |
| 238 const char* colorFilterColorUniName = NULL; | |
| 239 if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColo r()) { | |
| 240 fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragme nt_Visibility, | |
| 241 kVec4f_GrSLType, "FilterCo lor", | |
| 242 &colorFilterColorUniName); | |
| 243 } | |
| 244 | |
| 245 GrGLSLExpr<4> filter = color_filter_expression(mode, | |
| 246 GrGLSLExpr<4>(colorFi lterColorUniName), | |
| 247 GrGLSLExpr<4>(inputCo lor)); | |
| 248 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str()); | |
| 249 } | |
| 250 | |
| 251 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG LCaps&) { | |
| 252 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect <ModeColorFilterEffect>(); | |
| 253 // The SL code does not depend on filter color at the moment, so no need to represent it | |
| 254 // in the key. | |
| 255 EffectKey modeKey = colorModeFilter.mode(); | |
| 256 return modeKey; | |
| 257 } | |
| 258 | |
| 259 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) SK_OVERRIDE { | |
| 260 if (fFilterColorUni.isValid()) { | |
| 261 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEf fect<ModeColorFilterEffect>(); | |
| 262 GrGLfloat c[4]; | |
| 263 GrColorToRGBAFloat(colorModeFilter.color(), c); | |
| 264 uman.set4fv(fFilterColorUni, 0, 1, c); | |
| 265 } | |
| 266 } | |
| 267 | |
| 268 private: | |
| 269 | |
| 270 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsT ype; | |
| 271 GrGLUniformManager::UniformHandle fFilterColorUni; | |
| 272 typedef GrGLEffect INHERITED; | |
| 273 }; | |
| 274 | |
| 275 GR_DECLARE_EFFECT_TEST; | |
| 276 | |
| 277 private: | |
| 278 ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode) | |
| 279 : fMode(mode), | |
| 280 fColor(color) { | |
| 281 } | |
| 282 | |
| 283 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { | |
| 284 const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other ); | |
| 285 return fMode == s.fMode && fColor == s.fColor; | |
| 286 } | |
| 287 | |
| 288 SkXfermode::Mode fMode; | |
| 289 GrColor fColor; | |
| 290 | |
| 291 typedef GrEffect INHERITED; | |
| 292 }; | |
| 293 | |
| 294 namespace { | |
| 295 /** MaskedColorExpr is used to evaluate the color and valid color component | |
| 296 * flags through the blending equation. | |
| 297 */ | |
| 298 class MaskedColorExpr { | |
| 299 public: | |
| 300 MaskedColorExpr(const GrGLfloat color[], uint32_t flags) | |
| 301 : fFlags(flags) { | |
| 302 fColor[0] = color[0]; | |
| 303 fColor[1] = color[1]; | |
| 304 fColor[2] = color[2]; | |
| 305 fColor[3] = color[3]; | |
| 306 } | |
| 307 MaskedColorExpr(float v) | |
| 308 : fFlags(kRGBA_GrColorComponentFlags) { | |
| 309 fColor[0] = v; | |
| 310 fColor[1] = v; | |
| 311 fColor[2] = v; | |
| 312 fColor[3] = v; | |
| 313 } | |
| 314 | |
| 315 MaskedColorExpr operator*(const MaskedColorExpr& other) const { | |
| 316 GrGLfloat tmp[4]; | |
| 317 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] * other.fColor[0])); | |
| 318 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] * other.fColor[1])); | |
| 319 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] * other.fColor[2])); | |
| 320 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] * other.fColor[3])); | |
| 321 | |
| 322 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
| 323 } | |
| 324 | |
| 325 MaskedColorExpr operator+(const MaskedColorExpr& other) const { | |
| 326 GrGLfloat tmp[4]; | |
| 327 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] + other.fColor[0])); | |
| 328 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] + other.fColor[1])); | |
| 329 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] + other.fColor[2])); | |
| 330 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] + other.fColor[3])); | |
| 331 | |
| 332 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
| 333 } | |
| 334 | |
| 335 MaskedColorExpr operator-(const MaskedColorExpr& other) const { | |
| 336 GrGLfloat tmp[4]; | |
| 337 tmp[0] = GrMax(0.f, GrMin(1.f, fColor[0] - other.fColor[0])); | |
| 338 tmp[1] = GrMax(0.f, GrMin(1.f, fColor[1] - other.fColor[1])); | |
| 339 tmp[2] = GrMax(0.f, GrMin(1.f, fColor[2] - other.fColor[2])); | |
| 340 tmp[3] = GrMax(0.f, GrMin(1.f, fColor[3] - other.fColor[3])); | |
| 341 | |
| 342 return MaskedColorExpr(tmp, fFlags & other.fFlags); | |
| 343 } | |
| 344 | |
| 345 MaskedColorExpr a() const { | |
| 346 return MaskedColorExpr(fColor[3]); | |
| 347 } | |
| 348 | |
| 349 GrColor getColor() const { | |
| 350 return GrColorPackRGBA(fColor[0] * 255.f, fColor[1] * 255.f, | |
| 351 fColor[2] * 255.f, fColor[3] * 255.f); | |
| 352 } | |
| 353 | |
| 354 uint32_t getValidComponents() const { return fFlags; } | |
| 355 | |
| 356 private: | |
| 357 GrGLfloat fColor[4]; | |
| 358 uint32_t fFlags; | |
| 359 }; | |
| 360 | |
| 361 MaskedColorExpr operator-(int v, const MaskedColorExpr& other) { | |
| 362 return MaskedColorExpr(v) - other; | |
| 363 } | |
| 364 } | |
| 365 | |
| 366 void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t* validFlags) const { | |
|
Kimmo Kinnunen
2013/10/01 12:55:46
Btw: It'd be great to be able to unit test these s
| |
| 367 GrGLfloat inputColor[4]; | |
| 368 GrColorToRGBAFloat(*color, inputColor); | |
| 369 GrGLfloat filterColor[4]; | |
| 370 GrColorToRGBAFloat(fColor, filterColor); | |
| 371 MaskedColorExpr result = | |
| 372 color_filter_expression(fMode, | |
| 373 MaskedColorExpr(filterColor, kRGBA_GrColorCompon entFlags), | |
| 374 MaskedColorExpr(inputColor, *validFlags)); | |
| 375 | |
| 376 *color = result.getColor(); | |
| 377 *validFlags = result.getValidComponents(); | |
| 378 } | |
| 379 | |
| 380 GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect); | |
| 381 GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand, | |
| 382 GrContext*, | |
| 383 const GrDrawTargetCaps&, | |
| 384 GrTexture*[]) { | |
| 385 int mode = rand->nextRangeU(0, SkXfermode::kLastCoeffMode); | |
| 386 GrColor color = rand->nextU(); | |
| 387 static AutoEffectUnref gEffect(SkNEW_ARGS(ModeColorFilterEffect, (color, sta tic_cast<SkXfermode::Mode>(mode)))); | |
| 388 return CreateEffectRef(gEffect); | |
| 389 } | |
| 390 | |
| 391 GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const { | |
| 392 if (SkXfermode::kDst_Mode != fMode) { | |
| 393 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); | |
| 394 } | |
| 395 return NULL; | |
| 396 } | |
| 397 | |
| 398 #endif | |
| 399 | |
| 400 /////////////////////////////////////////////////////////////////////////////// | |
| 401 | |
| 120 class Src_SkModeColorFilter : public SkModeColorFilter { | 402 class Src_SkModeColorFilter : public SkModeColorFilter { |
| 121 public: | 403 public: |
| 122 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} | 404 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod e) {} |
| 123 | 405 |
| 124 virtual uint32_t getFlags() const SK_OVERRIDE { | 406 virtual uint32_t getFlags() const SK_OVERRIDE { |
| 125 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { | 407 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { |
| 126 return kAlphaUnchanged_Flag | kHasFilter16_Flag; | 408 return kAlphaUnchanged_Flag | kHasFilter16_Flag; |
| 127 } else { | 409 } else { |
| 128 return 0; | 410 return 0; |
| 129 } | 411 } |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 538 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) | 820 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) |
| 539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) | 821 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) |
| 540 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) | 822 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) |
| 541 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) | 823 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) |
| 542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) | 824 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) |
| 543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) | 825 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) |
| 544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) | 826 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) |
| 545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) | 827 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) |
| 546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) | 828 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) |
| 547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 829 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |