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 "SkGr.h" |
| 131 |
| 132 namespace { |
| 133 /** |
| 134 * A definition of blend equation for one coefficient. Generates a |
| 135 * blend_coeff * value "expression". |
| 136 */ |
| 137 template<typename ColorExpr> |
| 138 static inline ColorExpr blend_term(SkXfermode::Coeff coeff, |
| 139 const ColorExpr& src, |
| 140 const ColorExpr& dst, |
| 141 const ColorExpr& value) { |
| 142 switch (coeff) { |
| 143 default: |
| 144 GrCrash("Unexpected xfer coeff."); |
| 145 case SkXfermode::kZero_Coeff: /** 0 */ |
| 146 return ColorExpr(0); |
| 147 case SkXfermode::kOne_Coeff: /** 1 */ |
| 148 return value; |
| 149 case SkXfermode::kSC_Coeff: |
| 150 return src * value; |
| 151 case SkXfermode::kISC_Coeff: |
| 152 return (ColorExpr(1) - src) * dst; |
| 153 case SkXfermode::kDC_Coeff: |
| 154 return dst * value; |
| 155 case SkXfermode::kIDC_Coeff: |
| 156 return (ColorExpr(1) - dst) * value; |
| 157 case SkXfermode::kSA_Coeff: /** src alpha */ |
| 158 return src.a() * value; |
| 159 case SkXfermode::kISA_Coeff: /** inverse src alpha (i.e. 1 - sa) */ |
| 160 return (typename ColorExpr::AExpr(1) - src.a()) * value; |
| 161 case SkXfermode::kDA_Coeff: /** dst alpha */ |
| 162 return dst.a() * value; |
| 163 case SkXfermode::kIDA_Coeff: /** inverse dst alpha (i.e. 1 - da) */ |
| 164 return (typename ColorExpr::AExpr(1) - dst.a()) * value; |
| 165 } |
| 166 } |
| 167 /** |
| 168 * Creates a color filter expression which modifies the color by |
| 169 * the specified color filter. |
| 170 */ |
| 171 template <typename ColorExpr> |
| 172 static inline ColorExpr color_filter_expression(const SkXfermode::Mode& mode, |
| 173 const ColorExpr& filterColor, |
| 174 const ColorExpr& inColor) { |
| 175 SkXfermode::Coeff colorCoeff; |
| 176 SkXfermode::Coeff filterColorCoeff; |
| 177 SkAssertResult(SkXfermode::ModeAsCoeff(mode, &filterColorCoeff, &colorCoeff)
); |
| 178 return blend_term(colorCoeff, filterColor, inColor, inColor) + |
| 179 blend_term(filterColorCoeff, filterColor, inColor, filterColor); |
| 180 } |
| 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 bool willUseFilterColor() const { |
| 194 SkXfermode::Coeff dstCoeff; |
| 195 SkXfermode::Coeff srcCoeff; |
| 196 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); |
| 197 if (SkXfermode::kZero_Coeff == srcCoeff) { |
| 198 return GrBlendCoeffRefsSrc(sk_blend_to_grblend(dstCoeff)); |
| 199 } |
| 200 return true; |
| 201 } |
| 202 |
| 203 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE { |
| 204 return GrTBackendEffectFactory<ModeColorFilterEffect>::getInstance(); |
| 205 } |
| 206 |
| 207 static const char* Name() { return "ModeColorFilterEffect"; } |
| 208 |
| 209 SkXfermode::Mode mode() const { return fMode; } |
| 210 GrColor color() const { return fColor; } |
| 211 |
| 212 class GLEffect : public GrGLEffect { |
| 213 public: |
| 214 GLEffect(const GrBackendEffectFactory& factory, const GrDrawEffect&) |
| 215 : INHERITED(factory) { |
| 216 } |
| 217 |
| 218 virtual void emitCode(GrGLShaderBuilder* builder, |
| 219 const GrDrawEffect& drawEffect, |
| 220 EffectKey key, |
| 221 const char* outputColor, |
| 222 const char* inputColor, |
| 223 const TransformedCoordsArray& coords, |
| 224 const TextureSamplerArray& samplers) SK_OVERRIDE { |
| 225 SkXfermode::Mode mode = drawEffect.castEffect<ModeColorFilterEffect>
().mode(); |
| 226 |
| 227 SkASSERT(SkXfermode::kDst_Mode != mode); |
| 228 const char* colorFilterColorUniName = NULL; |
| 229 if (drawEffect.castEffect<ModeColorFilterEffect>().willUseFilterColo
r()) { |
| 230 fFilterColorUni = builder->addUniform(GrGLShaderBuilder::kFragme
nt_Visibility, |
| 231 kVec4f_GrSLType, "FilterCo
lor", |
| 232 &colorFilterColorUniName); |
| 233 } |
| 234 |
| 235 GrGLSLExpr4 filter = |
| 236 color_filter_expression(mode, GrGLSLExpr4(colorFilterColorUniNam
e), GrGLSLExpr4(inputColor)); |
| 237 |
| 238 builder->fsCodeAppendf("\t%s = %s;\n", outputColor, filter.c_str()); |
| 239 } |
| 240 |
| 241 static inline EffectKey GenKey(const GrDrawEffect& drawEffect, const GrG
LCaps&) { |
| 242 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEffect
<ModeColorFilterEffect>(); |
| 243 // The SL code does not depend on filter color at the moment, so no
need to represent it |
| 244 // in the key. |
| 245 EffectKey modeKey = colorModeFilter.mode(); |
| 246 return modeKey; |
| 247 } |
| 248 |
| 249 virtual void setData(const GrGLUniformManager& uman, const GrDrawEffect&
drawEffect) SK_OVERRIDE { |
| 250 if (fFilterColorUni.isValid()) { |
| 251 const ModeColorFilterEffect& colorModeFilter = drawEffect.castEf
fect<ModeColorFilterEffect>(); |
| 252 GrGLfloat c[4]; |
| 253 GrColorToRGBAFloat(colorModeFilter.color(), c); |
| 254 uman.set4fv(fFilterColorUni, 0, 1, c); |
| 255 } |
| 256 } |
| 257 |
| 258 private: |
| 259 |
| 260 GrGLUniformManager::UniformHandle fFilterColorUni; |
| 261 typedef GrGLEffect INHERITED; |
| 262 }; |
| 263 |
| 264 GR_DECLARE_EFFECT_TEST; |
| 265 |
| 266 private: |
| 267 ModeColorFilterEffect(GrColor color, SkXfermode::Mode mode) |
| 268 : fMode(mode), |
| 269 fColor(color) { |
| 270 |
| 271 SkXfermode::Coeff dstCoeff; |
| 272 SkXfermode::Coeff srcCoeff; |
| 273 SkAssertResult(SkXfermode::ModeAsCoeff(fMode, &srcCoeff, &dstCoeff)); |
| 274 // These could be calculated from the blend equation with template trick
ery.. |
| 275 if (SkXfermode::kZero_Coeff == dstCoeff && !GrBlendCoeffRefsDst(sk_blend
_to_grblend(srcCoeff))) { |
| 276 this->setWillNotUseInputColor(); |
| 277 } |
| 278 } |
| 279 |
| 280 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE { |
| 281 const ModeColorFilterEffect& s = CastEffect<ModeColorFilterEffect>(other
); |
| 282 return fMode == s.fMode && fColor == s.fColor; |
| 283 } |
| 284 |
| 285 SkXfermode::Mode fMode; |
| 286 GrColor fColor; |
| 287 |
| 288 typedef GrEffect INHERITED; |
| 289 }; |
| 290 |
| 291 namespace { |
| 292 |
| 293 /** Function color_component_to_int tries to reproduce the GLSL rounding. The sp
ec doesn't specify |
| 294 * to which direction the 0.5 goes. |
| 295 */ |
| 296 static inline int color_component_to_int(float value) { |
| 297 return sk_float_round2int(GrMax(0.f, GrMin(1.f, value)) * 255.f); |
| 298 } |
| 299 |
| 300 /** MaskedColorExpr is used to evaluate the color and valid color component flag
s through the |
| 301 * blending equation. It has members similar to GrGLSLExpr so that it can be use
d with the |
| 302 * templated helpers above. |
| 303 */ |
| 304 class MaskedColorExpr { |
| 305 public: |
| 306 MaskedColorExpr(const float color[], uint32_t flags) |
| 307 : fFlags(flags) { |
| 308 fColor[0] = color[0]; |
| 309 fColor[1] = color[1]; |
| 310 fColor[2] = color[2]; |
| 311 fColor[3] = color[3]; |
| 312 } |
| 313 |
| 314 MaskedColorExpr(float v, uint32_t flags = kRGBA_GrColorComponentFlags) |
| 315 : fFlags(flags) { |
| 316 fColor[0] = v; |
| 317 fColor[1] = v; |
| 318 fColor[2] = v; |
| 319 fColor[3] = v; |
| 320 } |
| 321 |
| 322 MaskedColorExpr operator*(const MaskedColorExpr& other) const { |
| 323 float tmp[4]; |
| 324 tmp[0] = fColor[0] * other.fColor[0]; |
| 325 tmp[1] = fColor[1] * other.fColor[1]; |
| 326 tmp[2] = fColor[2] * other.fColor[2]; |
| 327 tmp[3] = fColor[3] * other.fColor[3]; |
| 328 |
| 329 return MaskedColorExpr(tmp, fFlags & other.fFlags); |
| 330 } |
| 331 |
| 332 MaskedColorExpr operator+(const MaskedColorExpr& other) const { |
| 333 float tmp[4]; |
| 334 tmp[0] = fColor[0] + other.fColor[0]; |
| 335 tmp[1] = fColor[1] + other.fColor[1]; |
| 336 tmp[2] = fColor[2] + other.fColor[2]; |
| 337 tmp[3] = fColor[3] + other.fColor[3]; |
| 338 |
| 339 return MaskedColorExpr(tmp, fFlags & other.fFlags); |
| 340 } |
| 341 |
| 342 MaskedColorExpr operator-(const MaskedColorExpr& other) const { |
| 343 float tmp[4]; |
| 344 tmp[0] = fColor[0] - other.fColor[0]; |
| 345 tmp[1] = fColor[1] - other.fColor[1]; |
| 346 tmp[2] = fColor[2] - other.fColor[2]; |
| 347 tmp[3] = fColor[3] - other.fColor[3]; |
| 348 |
| 349 return MaskedColorExpr(tmp, fFlags & other.fFlags); |
| 350 } |
| 351 |
| 352 MaskedColorExpr a() const { |
| 353 uint32_t flags = (fFlags & kA_GrColorComponentFlag) ? kRGBA_GrColorCompo
nentFlags : 0; |
| 354 return MaskedColorExpr(fColor[3], flags); |
| 355 } |
| 356 |
| 357 GrColor getColor() const { |
| 358 return GrColorPackRGBA(color_component_to_int(fColor[0]), |
| 359 color_component_to_int(fColor[1]), |
| 360 color_component_to_int(fColor[2]), |
| 361 color_component_to_int(fColor[3])); |
| 362 } |
| 363 |
| 364 uint32_t getValidComponents() const { return fFlags; } |
| 365 |
| 366 typedef MaskedColorExpr AExpr; |
| 367 private: |
| 368 float fColor[4]; |
| 369 uint32_t fFlags; |
| 370 }; |
| 371 |
| 372 } |
| 373 |
| 374 void ModeColorFilterEffect::getConstantColorComponents(GrColor* color, uint32_t*
validFlags) const { |
| 375 float inputColor[4]; |
| 376 GrColorToRGBAFloat(*color, inputColor); |
| 377 float filterColor[4]; |
| 378 GrColorToRGBAFloat(fColor, filterColor); |
| 379 MaskedColorExpr result = |
| 380 color_filter_expression(fMode, |
| 381 MaskedColorExpr(filterColor, kRGBA_GrColorCompon
entFlags), |
| 382 MaskedColorExpr(inputColor, *validFlags)); |
| 383 |
| 384 *color = result.getColor(); |
| 385 *validFlags = result.getValidComponents(); |
| 386 } |
| 387 |
| 388 GR_DEFINE_EFFECT_TEST(ModeColorFilterEffect); |
| 389 GrEffectRef* ModeColorFilterEffect::TestCreate(SkRandom* rand, |
| 390 GrContext*, |
| 391 const GrDrawTargetCaps&, |
| 392 GrTexture*[]) { |
| 393 int mode = rand->nextRangeU(0, SkXfermode::kLastCoeffMode); |
| 394 GrColor color = rand->nextU(); |
| 395 static AutoEffectUnref gEffect(SkNEW_ARGS(ModeColorFilterEffect, (color, sta
tic_cast<SkXfermode::Mode>(mode)))); |
| 396 return CreateEffectRef(gEffect); |
| 397 } |
| 398 |
| 399 GrEffectRef* SkModeColorFilter::asNewEffect(GrContext*) const { |
| 400 if (SkXfermode::kDst_Mode != fMode) { |
| 401 return ModeColorFilterEffect::Create(SkColor2GrColor(fColor), fMode); |
| 402 } |
| 403 return NULL; |
| 404 } |
| 405 |
| 406 #endif |
| 407 |
| 408 /////////////////////////////////////////////////////////////////////////////// |
| 409 |
120 class Src_SkModeColorFilter : public SkModeColorFilter { | 410 class Src_SkModeColorFilter : public SkModeColorFilter { |
121 public: | 411 public: |
122 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod
e) {} | 412 Src_SkModeColorFilter(SkColor color) : INHERITED(color, SkXfermode::kSrc_Mod
e) {} |
123 | 413 |
124 virtual uint32_t getFlags() const SK_OVERRIDE { | 414 virtual uint32_t getFlags() const SK_OVERRIDE { |
125 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { | 415 if (SkGetPackedA32(this->getPMColor()) == 0xFF) { |
126 return kAlphaUnchanged_Flag | kHasFilter16_Flag; | 416 return kAlphaUnchanged_Flag | kHasFilter16_Flag; |
127 } else { | 417 } else { |
128 return 0; | 418 return 0; |
129 } | 419 } |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) | 828 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkModeColorFilter) |
539 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) | 829 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(Src_SkModeColorFilter) |
540 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) | 830 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SrcOver_SkModeColorFilter) |
541 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) | 831 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter) |
542 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) | 832 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustAdd) |
543 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) | 833 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_JustMul) |
544 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) | 834 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_SingleMul) |
545 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) | 835 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkLightingColorFilter_NoPin) |
546 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) | 836 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSimpleColorFilter) |
547 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 837 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |