| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2013 Google Inc. | 2 * Copyright 2013 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkArithmeticMode.h" | 8 #include "SkArithmeticMode.h" |
| 9 #include "SkColorPriv.h" | 9 #include "SkColorPriv.h" |
| 10 #include "SkReadBuffer.h" | 10 #include "SkReadBuffer.h" |
| 11 #include "SkWriteBuffer.h" | 11 #include "SkWriteBuffer.h" |
| 12 #include "SkString.h" | 12 #include "SkString.h" |
| 13 #include "SkUnPreMultiply.h" | 13 #include "SkUnPreMultiply.h" |
| 14 #if SK_SUPPORT_GPU | 14 #if SK_SUPPORT_GPU |
| 15 #include "GrContext.h" | 15 #include "GrContext.h" |
| 16 #include "GrCoordTransform.h" | 16 #include "GrCoordTransform.h" |
| 17 #include "gl/GrGLEffect.h" | 17 #include "gl/GrGLProcessor.h" |
| 18 #include "gl/builders/GrGLProgramBuilder.h" | 18 #include "gl/builders/GrGLProgramBuilder.h" |
| 19 #include "GrTBackendEffectFactory.h" | 19 #include "GrTBackendProcessorFactory.h" |
| 20 #endif | 20 #endif |
| 21 | 21 |
| 22 static const bool gUseUnpremul = false; | 22 static const bool gUseUnpremul = false; |
| 23 | 23 |
| 24 class SkArithmeticMode_scalar : public SkXfermode { | 24 class SkArithmeticMode_scalar : public SkXfermode { |
| 25 public: | 25 public: |
| 26 static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3
, SkScalar k4, | 26 static SkArithmeticMode_scalar* Create(SkScalar k1, SkScalar k2, SkScalar k3
, SkScalar k4, |
| 27 bool enforcePMColor) { | 27 bool enforcePMColor) { |
| 28 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, enforcePMCol
or)); | 28 return SkNEW_ARGS(SkArithmeticMode_scalar, (k1, k2, k3, k4, enforcePMCol
or)); |
| 29 } | 29 } |
| 30 | 30 |
| 31 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, | 31 virtual void xfer32(SkPMColor dst[], const SkPMColor src[], int count, |
| 32 const SkAlpha aa[]) const SK_OVERRIDE; | 32 const SkAlpha aa[]) const SK_OVERRIDE; |
| 33 | 33 |
| 34 SK_TO_STRING_OVERRIDE() | 34 SK_TO_STRING_OVERRIDE() |
| 35 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) | 35 SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkArithmeticMode_scalar) |
| 36 | 36 |
| 37 #if SK_SUPPORT_GPU | 37 #if SK_SUPPORT_GPU |
| 38 virtual bool asNewEffect(GrEffect** effect, GrTexture* background) const SK_
OVERRIDE; | 38 virtual bool asFragmentProcessor(GrFragmentProcessor**, |
| 39 GrTexture* background) const SK_OVERRIDE; |
| 39 #endif | 40 #endif |
| 40 | 41 |
| 41 private: | 42 private: |
| 42 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
bool enforcePMColor) { | 43 SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4,
bool enforcePMColor) { |
| 43 fK[0] = k1; | 44 fK[0] = k1; |
| 44 fK[1] = k2; | 45 fK[1] = k2; |
| 45 fK[2] = k3; | 46 fK[2] = k3; |
| 46 fK[3] = k4; | 47 fK[3] = k4; |
| 47 fEnforcePMColor = enforcePMColor; | 48 fEnforcePMColor = enforcePMColor; |
| 48 } | 49 } |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 #endif | 241 #endif |
| 241 } | 242 } |
| 242 return SkArithmeticMode_scalar::Create(k1, k2, k3, k4, enforcePMColor); | 243 return SkArithmeticMode_scalar::Create(k1, k2, k3, k4, enforcePMColor); |
| 243 } | 244 } |
| 244 | 245 |
| 245 | 246 |
| 246 ////////////////////////////////////////////////////////////////////////////// | 247 ////////////////////////////////////////////////////////////////////////////// |
| 247 | 248 |
| 248 #if SK_SUPPORT_GPU | 249 #if SK_SUPPORT_GPU |
| 249 | 250 |
| 250 class GrGLArithmeticEffect : public GrGLEffect { | 251 class GrGLArithmeticEffect : public GrGLFragmentProcessor { |
| 251 public: | 252 public: |
| 252 GrGLArithmeticEffect(const GrBackendEffectFactory&, const GrEffect&); | 253 GrGLArithmeticEffect(const GrBackendProcessorFactory&, const GrProcessor&); |
| 253 virtual ~GrGLArithmeticEffect(); | 254 virtual ~GrGLArithmeticEffect(); |
| 254 | 255 |
| 255 virtual void emitCode(GrGLProgramBuilder*, | 256 virtual void emitCode(GrGLProgramBuilder*, |
| 256 const GrEffect&, | 257 const GrFragmentProcessor&, |
| 257 const GrEffectKey&, | 258 const GrProcessorKey&, |
| 258 const char* outputColor, | 259 const char* outputColor, |
| 259 const char* inputColor, | 260 const char* inputColor, |
| 260 const TransformedCoordsArray&, | 261 const TransformedCoordsArray&, |
| 261 const TextureSamplerArray&) SK_OVERRIDE; | 262 const TextureSamplerArray&) SK_OVERRIDE; |
| 262 | 263 |
| 263 virtual void setData(const GrGLProgramDataManager&, const GrEffect&) SK_OVER
RIDE; | 264 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O
VERRIDE; |
| 264 | 265 |
| 265 static void GenKey(const GrEffect&, const GrGLCaps& caps, GrEffectKeyBuilder
* b); | 266 static void GenKey(const GrProcessor&, const GrGLCaps& caps, GrProcessorKeyB
uilder* b); |
| 266 | 267 |
| 267 private: | 268 private: |
| 268 GrGLProgramDataManager::UniformHandle fKUni; | 269 GrGLProgramDataManager::UniformHandle fKUni; |
| 269 bool fEnforcePMColor; | 270 bool fEnforcePMColor; |
| 270 | 271 |
| 271 typedef GrGLEffect INHERITED; | 272 typedef GrGLFragmentProcessor INHERITED; |
| 272 }; | 273 }; |
| 273 | 274 |
| 274 /////////////////////////////////////////////////////////////////////////////// | 275 /////////////////////////////////////////////////////////////////////////////// |
| 275 | 276 |
| 276 class GrArithmeticEffect : public GrEffect { | 277 class GrArithmeticEffect : public GrFragmentProcessor { |
| 277 public: | 278 public: |
| 278 static GrEffect* Create(float k1, float k2, float k3, float k4, bool enforce
PMColor, | 279 static GrFragmentProcessor* Create(float k1, float k2, float k3, float k4, b
ool enforcePMColor, |
| 279 GrTexture* background) { | 280 GrTexture* background) { |
| 280 return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, b
ackground)); | 281 return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, b
ackground)); |
| 281 } | 282 } |
| 282 | 283 |
| 283 virtual ~GrArithmeticEffect(); | 284 virtual ~GrArithmeticEffect(); |
| 284 | 285 |
| 285 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 286 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR
IDE; |
| 286 | 287 |
| 287 typedef GrGLArithmeticEffect GLEffect; | 288 typedef GrGLArithmeticEffect GLProcessor; |
| 288 static const char* Name() { return "Arithmetic"; } | 289 static const char* Name() { return "Arithmetic"; } |
| 289 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } | 290 GrTexture* backgroundTexture() const { return fBackgroundAccess.getTexture()
; } |
| 290 | 291 |
| 291 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 292 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 292 | 293 |
| 293 float k1() const { return fK1; } | 294 float k1() const { return fK1; } |
| 294 float k2() const { return fK2; } | 295 float k2() const { return fK2; } |
| 295 float k3() const { return fK3; } | 296 float k3() const { return fK3; } |
| 296 float k4() const { return fK4; } | 297 float k4() const { return fK4; } |
| 297 bool enforcePMColor() const { return fEnforcePMColor; } | 298 bool enforcePMColor() const { return fEnforcePMColor; } |
| 298 | 299 |
| 299 private: | 300 private: |
| 300 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 301 virtual bool onIsEqual(const GrProcessor&) const SK_OVERRIDE; |
| 301 | 302 |
| 302 GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMCol
or, | 303 GrArithmeticEffect(float k1, float k2, float k3, float k4, bool enforcePMCol
or, |
| 303 GrTexture* background); | 304 GrTexture* background); |
| 304 float fK1, fK2, fK3, fK4; | 305 float fK1, fK2, fK3, fK4; |
| 305 bool fEnforcePMColor; | 306 bool fEnforcePMColor; |
| 306 GrCoordTransform fBackgroundTransform; | 307 GrCoordTransform fBackgroundTransform; |
| 307 GrTextureAccess fBackgroundAccess; | 308 GrTextureAccess fBackgroundAccess; |
| 308 | 309 |
| 309 GR_DECLARE_EFFECT_TEST; | 310 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 310 typedef GrEffect INHERITED; | 311 typedef GrFragmentProcessor INHERITED; |
| 311 | 312 |
| 312 }; | 313 }; |
| 313 | 314 |
| 314 /////////////////////////////////////////////////////////////////////////////// | 315 /////////////////////////////////////////////////////////////////////////////// |
| 315 | 316 |
| 316 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, | 317 GrArithmeticEffect::GrArithmeticEffect(float k1, float k2, float k3, float k4, |
| 317 bool enforcePMColor, GrTexture* backgroun
d) | 318 bool enforcePMColor, GrTexture* backgroun
d) |
| 318 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) { | 319 : fK1(k1), fK2(k2), fK3(k3), fK4(k4), fEnforcePMColor(enforcePMColor) { |
| 319 if (background) { | 320 if (background) { |
| 320 fBackgroundTransform.reset(kLocal_GrCoordSet, background); | 321 fBackgroundTransform.reset(kLocal_GrCoordSet, background); |
| 321 this->addCoordTransform(&fBackgroundTransform); | 322 this->addCoordTransform(&fBackgroundTransform); |
| 322 fBackgroundAccess.reset(background); | 323 fBackgroundAccess.reset(background); |
| 323 this->addTextureAccess(&fBackgroundAccess); | 324 this->addTextureAccess(&fBackgroundAccess); |
| 324 } else { | 325 } else { |
| 325 this->setWillReadDstColor(); | 326 this->setWillReadDstColor(); |
| 326 } | 327 } |
| 327 } | 328 } |
| 328 | 329 |
| 329 GrArithmeticEffect::~GrArithmeticEffect() { | 330 GrArithmeticEffect::~GrArithmeticEffect() { |
| 330 } | 331 } |
| 331 | 332 |
| 332 bool GrArithmeticEffect::onIsEqual(const GrEffect& sBase) const { | 333 bool GrArithmeticEffect::onIsEqual(const GrProcessor& sBase) const { |
| 333 const GrArithmeticEffect& s = sBase.cast<GrArithmeticEffect>(); | 334 const GrArithmeticEffect& s = sBase.cast<GrArithmeticEffect>(); |
| 334 return fK1 == s.fK1 && | 335 return fK1 == s.fK1 && |
| 335 fK2 == s.fK2 && | 336 fK2 == s.fK2 && |
| 336 fK3 == s.fK3 && | 337 fK3 == s.fK3 && |
| 337 fK4 == s.fK4 && | 338 fK4 == s.fK4 && |
| 338 fEnforcePMColor == s.fEnforcePMColor && | 339 fEnforcePMColor == s.fEnforcePMColor && |
| 339 backgroundTexture() == s.backgroundTexture(); | 340 backgroundTexture() == s.backgroundTexture(); |
| 340 } | 341 } |
| 341 | 342 |
| 342 const GrBackendEffectFactory& GrArithmeticEffect::getFactory() const { | 343 const GrBackendFragmentProcessorFactory& GrArithmeticEffect::getFactory() const
{ |
| 343 return GrTBackendEffectFactory<GrArithmeticEffect>::getInstance(); | 344 return GrTBackendFragmentProcessorFactory<GrArithmeticEffect>::getInstance()
; |
| 344 } | 345 } |
| 345 | 346 |
| 346 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { | 347 void GrArithmeticEffect::getConstantColorComponents(GrColor* color, uint32_t* va
lidFlags) const { |
| 347 // TODO: optimize this | 348 // TODO: optimize this |
| 348 *validFlags = 0; | 349 *validFlags = 0; |
| 349 } | 350 } |
| 350 | 351 |
| 351 /////////////////////////////////////////////////////////////////////////////// | 352 /////////////////////////////////////////////////////////////////////////////// |
| 352 | 353 |
| 353 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendEffectFactory& factory
, | 354 GrGLArithmeticEffect::GrGLArithmeticEffect(const GrBackendProcessorFactory& fact
ory, |
| 354 const GrEffect& effect) | 355 const GrProcessor&) |
| 355 : INHERITED(factory), | 356 : INHERITED(factory), |
| 356 fEnforcePMColor(true) { | 357 fEnforcePMColor(true) { |
| 357 } | 358 } |
| 358 | 359 |
| 359 GrGLArithmeticEffect::~GrGLArithmeticEffect() { | 360 GrGLArithmeticEffect::~GrGLArithmeticEffect() { |
| 360 } | 361 } |
| 361 | 362 |
| 362 void GrGLArithmeticEffect::emitCode(GrGLProgramBuilder* builder, | 363 void GrGLArithmeticEffect::emitCode(GrGLProgramBuilder* builder, |
| 363 const GrEffect& effect, | 364 const GrFragmentProcessor& fp, |
| 364 const GrEffectKey& key, | 365 const GrProcessorKey& key, |
| 365 const char* outputColor, | 366 const char* outputColor, |
| 366 const char* inputColor, | 367 const char* inputColor, |
| 367 const TransformedCoordsArray& coords, | 368 const TransformedCoordsArray& coords, |
| 368 const TextureSamplerArray& samplers) { | 369 const TextureSamplerArray& samplers) { |
| 369 | 370 |
| 370 GrTexture* backgroundTex = effect.cast<GrArithmeticEffect>().backgroundTextu
re(); | 371 GrTexture* backgroundTex = fp.cast<GrArithmeticEffect>().backgroundTexture()
; |
| 371 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 372 GrGLFragmentShaderBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| 372 const char* dstColor; | 373 const char* dstColor; |
| 373 if (backgroundTex) { | 374 if (backgroundTex) { |
| 374 fsBuilder->codeAppend("\t\tvec4 bgColor = "); | 375 fsBuilder->codeAppend("\t\tvec4 bgColor = "); |
| 375 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0]
.getType()); | 376 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coords[0]
.getType()); |
| 376 fsBuilder->codeAppendf(";\n"); | 377 fsBuilder->codeAppendf(";\n"); |
| 377 dstColor = "bgColor"; | 378 dstColor = "bgColor"; |
| 378 } else { | 379 } else { |
| 379 dstColor = fsBuilder->dstColor(); | 380 dstColor = fsBuilder->dstColor(); |
| 380 } | 381 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 401 | 402 |
| 402 fsBuilder->codeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); | 403 fsBuilder->codeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst
+ %s.w;\n", outputColor, kUni, kUni, kUni, kUni); |
| 403 fsBuilder->codeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); | 404 fsBuilder->codeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outpu
tColor); |
| 404 if (gUseUnpremul) { | 405 if (gUseUnpremul) { |
| 405 fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); | 406 fsBuilder->codeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor
); |
| 406 } else if (fEnforcePMColor) { | 407 } else if (fEnforcePMColor) { |
| 407 fsBuilder->codeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor,
outputColor, outputColor); | 408 fsBuilder->codeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor,
outputColor, outputColor); |
| 408 } | 409 } |
| 409 } | 410 } |
| 410 | 411 |
| 411 void GrGLArithmeticEffect::setData(const GrGLProgramDataManager& pdman, const Gr
Effect& effect) { | 412 void GrGLArithmeticEffect::setData(const GrGLProgramDataManager& pdman, |
| 412 const GrArithmeticEffect& arith = effect.cast<GrArithmeticEffect>(); | 413 const GrProcessor& processor) { |
| 414 const GrArithmeticEffect& arith = processor.cast<GrArithmeticEffect>(); |
| 413 pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); | 415 pdman.set4f(fKUni, arith.k1(), arith.k2(), arith.k3(), arith.k4()); |
| 414 fEnforcePMColor = arith.enforcePMColor(); | 416 fEnforcePMColor = arith.enforcePMColor(); |
| 415 } | 417 } |
| 416 | 418 |
| 417 void GrGLArithmeticEffect::GenKey(const GrEffect& effect, | 419 void GrGLArithmeticEffect::GenKey(const GrProcessor& processor, |
| 418 const GrGLCaps&, GrEffectKeyBuilder* b) { | 420 const GrGLCaps&, GrProcessorKeyBuilder* b) { |
| 419 const GrArithmeticEffect& arith = effect.cast<GrArithmeticEffect>(); | 421 const GrArithmeticEffect& arith = processor.cast<GrArithmeticEffect>(); |
| 420 uint32_t key = arith.enforcePMColor() ? 1 : 0; | 422 uint32_t key = arith.enforcePMColor() ? 1 : 0; |
| 421 if (arith.backgroundTexture()) { | 423 if (arith.backgroundTexture()) { |
| 422 key |= 2; | 424 key |= 2; |
| 423 } | 425 } |
| 424 b->add32(key); | 426 b->add32(key); |
| 425 } | 427 } |
| 426 | 428 |
| 427 GrEffect* GrArithmeticEffect::TestCreate(SkRandom* rand, | 429 GrFragmentProcessor* GrArithmeticEffect::TestCreate(SkRandom* rand, |
| 428 GrContext*, | 430 GrContext*, |
| 429 const GrDrawTargetCaps&, | 431 const GrDrawTargetCaps&, |
| 430 GrTexture*[]) { | 432 GrTexture*[]) { |
| 431 float k1 = rand->nextF(); | 433 float k1 = rand->nextF(); |
| 432 float k2 = rand->nextF(); | 434 float k2 = rand->nextF(); |
| 433 float k3 = rand->nextF(); | 435 float k3 = rand->nextF(); |
| 434 float k4 = rand->nextF(); | 436 float k4 = rand->nextF(); |
| 435 bool enforcePMColor = rand->nextBool(); | 437 bool enforcePMColor = rand->nextBool(); |
| 436 | 438 |
| 437 return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, NULL)
); | 439 return SkNEW_ARGS(GrArithmeticEffect, (k1, k2, k3, k4, enforcePMColor, NULL)
); |
| 438 } | 440 } |
| 439 | 441 |
| 440 GR_DEFINE_EFFECT_TEST(GrArithmeticEffect); | 442 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrArithmeticEffect); |
| 441 | 443 |
| 442 bool SkArithmeticMode_scalar::asNewEffect(GrEffect** effect, GrTexture* backgrou
nd) const { | 444 bool SkArithmeticMode_scalar::asFragmentProcessor(GrFragmentProcessor** fp, |
| 443 if (effect) { | 445 GrTexture* background) const { |
| 444 *effect = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), | 446 if (fp) { |
| 445 SkScalarToFloat(fK[1]), | 447 *fp = GrArithmeticEffect::Create(SkScalarToFloat(fK[0]), |
| 446 SkScalarToFloat(fK[2]), | 448 SkScalarToFloat(fK[1]), |
| 447 SkScalarToFloat(fK[3]), | 449 SkScalarToFloat(fK[2]), |
| 448 fEnforcePMColor, | 450 SkScalarToFloat(fK[3]), |
| 449 background); | 451 fEnforcePMColor, |
| 452 background); |
| 450 } | 453 } |
| 451 return true; | 454 return true; |
| 452 } | 455 } |
| 453 | 456 |
| 454 #endif | 457 #endif |
| 455 | 458 |
| 456 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) | 459 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkArithmeticMode) |
| 457 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) | 460 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkArithmeticMode_scalar) |
| 458 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 461 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |