| 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 "SkDisplacementMapEffect.h" | 8 #include "SkDisplacementMapEffect.h" |
| 9 #include "SkFlattenableBuffers.h" | 9 #include "SkFlattenableBuffers.h" |
| 10 #include "SkUnPreMultiply.h" | 10 #include "SkUnPreMultiply.h" |
| 11 #include "SkColorPriv.h" | 11 #include "SkColorPriv.h" |
| 12 #if SK_SUPPORT_GPU | 12 #if SK_SUPPORT_GPU |
| 13 #include "GrContext.h" | 13 #include "GrContext.h" |
| 14 #include "GrCoordTransform.h" |
| 14 #include "gl/GrGLEffect.h" | 15 #include "gl/GrGLEffect.h" |
| 15 #include "gl/GrGLEffectMatrix.h" | |
| 16 #include "GrTBackendEffectFactory.h" | 16 #include "GrTBackendEffectFactory.h" |
| 17 #include "SkImageFilterUtils.h" | 17 #include "SkImageFilterUtils.h" |
| 18 #endif | 18 #endif |
| 19 | 19 |
| 20 namespace { | 20 namespace { |
| 21 | 21 |
| 22 template<SkDisplacementMapEffect::ChannelSelectorType type> | 22 template<SkDisplacementMapEffect::ChannelSelectorType type> |
| 23 uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) { | 23 uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) { |
| 24 SkDEBUGFAIL("Unknown channel selector"); | 24 SkDEBUGFAIL("Unknown channel selector"); |
| 25 return 0; | 25 return 0; |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 202 public: | 202 public: |
| 203 GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory, | 203 GrGLDisplacementMapEffect(const GrBackendEffectFactory& factory, |
| 204 const GrDrawEffect& drawEffect); | 204 const GrDrawEffect& drawEffect); |
| 205 virtual ~GrGLDisplacementMapEffect(); | 205 virtual ~GrGLDisplacementMapEffect(); |
| 206 | 206 |
| 207 virtual void emitCode(GrGLShaderBuilder*, | 207 virtual void emitCode(GrGLShaderBuilder*, |
| 208 const GrDrawEffect&, | 208 const GrDrawEffect&, |
| 209 EffectKey, | 209 EffectKey, |
| 210 const char* outputColor, | 210 const char* outputColor, |
| 211 const char* inputColor, | 211 const char* inputColor, |
| 212 const TransformedCoordsArray&, |
| 212 const TextureSamplerArray&) SK_OVERRIDE; | 213 const TextureSamplerArray&) SK_OVERRIDE; |
| 213 | 214 |
| 214 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); | 215 static inline EffectKey GenKey(const GrDrawEffect&, const GrGLCaps&); |
| 215 | 216 |
| 216 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 217 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
| 217 | 218 |
| 218 private: | 219 private: |
| 219 static const GrEffect::CoordsType kCoordsType = GrEffect::kLocal_CoordsType; | |
| 220 | |
| 221 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; | 220 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; |
| 222 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; | 221 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; |
| 223 GrGLEffectMatrix fDisplacementEffectMatrix; | |
| 224 GrGLEffectMatrix fColorEffectMatrix; | |
| 225 GrGLUniformManager::UniformHandle fScaleUni; | 222 GrGLUniformManager::UniformHandle fScaleUni; |
| 226 | 223 |
| 227 typedef GrGLEffect INHERITED; | 224 typedef GrGLEffect INHERITED; |
| 228 }; | 225 }; |
| 229 | 226 |
| 230 /////////////////////////////////////////////////////////////////////////////// | 227 /////////////////////////////////////////////////////////////////////////////// |
| 231 | 228 |
| 232 class GrDisplacementMapEffect : public GrEffect { | 229 class GrDisplacementMapEffect : public GrEffect { |
| 233 public: | 230 public: |
| 234 static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xCha
nnelSelector, | 231 static GrEffectRef* Create(SkDisplacementMapEffect::ChannelSelectorType xCha
nnelSelector, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 250 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const | 247 SkDisplacementMapEffect::ChannelSelectorType yChannelSelector() const |
| 251 { return fYChannelSelector; } | 248 { return fYChannelSelector; } |
| 252 SkScalar scale() const { return fScale; } | 249 SkScalar scale() const { return fScale; } |
| 253 | 250 |
| 254 typedef GrGLDisplacementMapEffect GLEffect; | 251 typedef GrGLDisplacementMapEffect GLEffect; |
| 255 static const char* Name() { return "DisplacementMap"; } | 252 static const char* Name() { return "DisplacementMap"; } |
| 256 | 253 |
| 257 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 254 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 258 | 255 |
| 259 private: | 256 private: |
| 260 | |
| 261 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 257 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 262 | 258 |
| 263 GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChanne
lSelector, | 259 GrDisplacementMapEffect(SkDisplacementMapEffect::ChannelSelectorType xChanne
lSelector, |
| 264 SkDisplacementMapEffect::ChannelSelectorType yChanne
lSelector, | 260 SkDisplacementMapEffect::ChannelSelectorType yChanne
lSelector, |
| 265 SkScalar scale, GrTexture* displacement, GrTexture*
color); | 261 SkScalar scale, GrTexture* displacement, GrTexture*
color); |
| 266 | 262 |
| 267 GR_DECLARE_EFFECT_TEST; | 263 GR_DECLARE_EFFECT_TEST; |
| 268 | 264 |
| 265 GrCoordTransform fDisplacementTransform; |
| 269 GrTextureAccess fDisplacementAccess; | 266 GrTextureAccess fDisplacementAccess; |
| 267 GrCoordTransform fColorTransform; |
| 270 GrTextureAccess fColorAccess; | 268 GrTextureAccess fColorAccess; |
| 271 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; | 269 SkDisplacementMapEffect::ChannelSelectorType fXChannelSelector; |
| 272 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; | 270 SkDisplacementMapEffect::ChannelSelectorType fYChannelSelector; |
| 273 SkScalar fScale; | 271 SkScalar fScale; |
| 274 | 272 |
| 275 typedef GrEffect INHERITED; | 273 typedef GrEffect INHERITED; |
| 276 }; | 274 }; |
| 277 | 275 |
| 278 bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
const SkMatrix& ctm, | 276 bool SkDisplacementMapEffect::filterImageGPU(Proxy* proxy, const SkBitmap& src,
const SkMatrix& ctm, |
| 279 SkBitmap* result, SkIPoint* offset)
{ | 277 SkBitmap* result, SkIPoint* offset)
{ |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 } | 318 } |
| 321 | 319 |
| 322 /////////////////////////////////////////////////////////////////////////////// | 320 /////////////////////////////////////////////////////////////////////////////// |
| 323 | 321 |
| 324 GrDisplacementMapEffect::GrDisplacementMapEffect( | 322 GrDisplacementMapEffect::GrDisplacementMapEffect( |
| 325 SkDisplacementMapEffect::ChannelSelectorType xChann
elSelector, | 323 SkDisplacementMapEffect::ChannelSelectorType xChann
elSelector, |
| 326 SkDisplacementMapEffect::ChannelSelectorType yChann
elSelector, | 324 SkDisplacementMapEffect::ChannelSelectorType yChann
elSelector, |
| 327 SkScalar scale, | 325 SkScalar scale, |
| 328 GrTexture* displacement, | 326 GrTexture* displacement, |
| 329 GrTexture* color) | 327 GrTexture* color) |
| 330 : fDisplacementAccess(displacement) | 328 : fDisplacementTransform(kLocal_GrCoordSet, displacement) |
| 329 , fDisplacementAccess(displacement) |
| 330 , fColorTransform(kLocal_GrCoordSet, color) |
| 331 , fColorAccess(color) | 331 , fColorAccess(color) |
| 332 , fXChannelSelector(xChannelSelector) | 332 , fXChannelSelector(xChannelSelector) |
| 333 , fYChannelSelector(yChannelSelector) | 333 , fYChannelSelector(yChannelSelector) |
| 334 , fScale(scale) { | 334 , fScale(scale) { |
| 335 this->addCoordTransform(&fDisplacementTransform); |
| 335 this->addTextureAccess(&fDisplacementAccess); | 336 this->addTextureAccess(&fDisplacementAccess); |
| 337 this->addCoordTransform(&fColorTransform); |
| 336 this->addTextureAccess(&fColorAccess); | 338 this->addTextureAccess(&fColorAccess); |
| 337 } | 339 } |
| 338 | 340 |
| 339 GrDisplacementMapEffect::~GrDisplacementMapEffect() { | 341 GrDisplacementMapEffect::~GrDisplacementMapEffect() { |
| 340 } | 342 } |
| 341 | 343 |
| 342 bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const { | 344 bool GrDisplacementMapEffect::onIsEqual(const GrEffect& sBase) const { |
| 343 const GrDisplacementMapEffect& s = CastEffect<GrDisplacementMapEffect>(sBase
); | 345 const GrDisplacementMapEffect& s = CastEffect<GrDisplacementMapEffect>(sBase
); |
| 344 return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture(
) && | 346 return fDisplacementAccess.getTexture() == s.fDisplacementAccess.getTexture(
) && |
| 345 fColorAccess.getTexture() == s.fColorAccess.getTexture() && | 347 fColorAccess.getTexture() == s.fColorAccess.getTexture() && |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 386 return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, s
cale, | 388 return GrDisplacementMapEffect::Create(xChannelSelector, yChannelSelector, s
cale, |
| 387 textures[texIdxDispl], textures[texId
xColor]); | 389 textures[texIdxDispl], textures[texId
xColor]); |
| 388 } | 390 } |
| 389 | 391 |
| 390 /////////////////////////////////////////////////////////////////////////////// | 392 /////////////////////////////////////////////////////////////////////////////// |
| 391 | 393 |
| 392 GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactor
y& factory, | 394 GrGLDisplacementMapEffect::GrGLDisplacementMapEffect(const GrBackendEffectFactor
y& factory, |
| 393 const GrDrawEffect& drawEff
ect) | 395 const GrDrawEffect& drawEff
ect) |
| 394 : INHERITED(factory) | 396 : INHERITED(factory) |
| 395 , fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChanne
lSelector()) | 397 , fXChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().xChanne
lSelector()) |
| 396 , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChanne
lSelector()) | 398 , fYChannelSelector(drawEffect.castEffect<GrDisplacementMapEffect>().yChanne
lSelector()) { |
| 397 , fDisplacementEffectMatrix(kCoordsType) | |
| 398 , fColorEffectMatrix(kCoordsType) { | |
| 399 } | 399 } |
| 400 | 400 |
| 401 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() { | 401 GrGLDisplacementMapEffect::~GrGLDisplacementMapEffect() { |
| 402 } | 402 } |
| 403 | 403 |
| 404 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder, | 404 void GrGLDisplacementMapEffect::emitCode(GrGLShaderBuilder* builder, |
| 405 const GrDrawEffect&, | 405 const GrDrawEffect&, |
| 406 EffectKey key, | 406 EffectKey key, |
| 407 const char* outputColor, | 407 const char* outputColor, |
| 408 const char* inputColor, | 408 const char* inputColor, |
| 409 const TransformedCoordsArray& coords, |
| 409 const TextureSamplerArray& samplers) { | 410 const TextureSamplerArray& samplers) { |
| 410 sk_ignore_unused_variable(inputColor); | 411 sk_ignore_unused_variable(inputColor); |
| 411 | 412 |
| 412 fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, | 413 fScaleUni = builder->addUniform(GrGLShaderBuilder::kFragment_Visibility, |
| 413 kVec2f_GrSLType, "Scale"); | 414 kVec2f_GrSLType, "Scale"); |
| 414 const char* scaleUni = builder->getUniformCStr(fScaleUni); | 415 const char* scaleUni = builder->getUniformCStr(fScaleUni); |
| 415 | |
| 416 SkString dCoordsIn; | |
| 417 GrSLType dCoordsType = fDisplacementEffectMatrix.emitCode( | |
| 418 builder, key, &dCoordsIn, NULL, "DISPL"); | |
| 419 SkString cCoordsIn; | |
| 420 GrSLType cCoordsType = fColorEffectMatrix.emitCode( | |
| 421 builder, key, &cCoordsIn, NULL, "COLOR"); | |
| 422 | |
| 423 const char* dColor = "dColor"; | 416 const char* dColor = "dColor"; |
| 424 const char* cCoords = "cCoords"; | 417 const char* cCoords = "cCoords"; |
| 425 const char* outOfBounds = "outOfBounds"; | 418 const char* outOfBounds = "outOfBounds"; |
| 426 const char* nearZero = "1e-6"; // Since 6.10352e−5 is the smallest half floa
t, use | 419 const char* nearZero = "1e-6"; // Since 6.10352e−5 is the smallest half floa
t, use |
| 427 // a number smaller than that to approximate
0, but | 420 // a number smaller than that to approximate
0, but |
| 428 // leave room for 32-bit float GPU rounding e
rrors. | 421 // leave room for 32-bit float GPU rounding e
rrors. |
| 429 | 422 |
| 430 builder->fsCodeAppendf("\t\tvec4 %s = ", dColor); | 423 builder->fsCodeAppendf("\t\tvec4 %s = ", dColor); |
| 431 builder->fsAppendTextureLookup(samplers[0], dCoordsIn.c_str(), dCoordsType); | 424 builder->fsAppendTextureLookup(samplers[0], coords[0].c_str(), coords[0].typ
e()); |
| 432 builder->fsCodeAppend(";\n"); | 425 builder->fsCodeAppend(";\n"); |
| 433 | 426 |
| 434 // Unpremultiply the displacement | 427 // Unpremultiply the displacement |
| 435 builder->fsCodeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb
/ %s.a, 0.0, 1.0);", | 428 builder->fsCodeAppendf("\t\t%s.rgb = (%s.a < %s) ? vec3(0.0) : clamp(%s.rgb
/ %s.a, 0.0, 1.0);", |
| 436 dColor, dColor, nearZero, dColor, dColor); | 429 dColor, dColor, nearZero, dColor, dColor); |
| 437 | 430 |
| 438 builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.", | 431 builder->fsCodeAppendf("\t\tvec2 %s = %s + %s*(%s.", |
| 439 cCoords, cCoordsIn.c_str(), scaleUni, dColor); | 432 cCoords, coords[1].c_str(), scaleUni, dColor); |
| 440 | 433 |
| 441 switch (fXChannelSelector) { | 434 switch (fXChannelSelector) { |
| 442 case SkDisplacementMapEffect::kR_ChannelSelectorType: | 435 case SkDisplacementMapEffect::kR_ChannelSelectorType: |
| 443 builder->fsCodeAppend("r"); | 436 builder->fsCodeAppend("r"); |
| 444 break; | 437 break; |
| 445 case SkDisplacementMapEffect::kG_ChannelSelectorType: | 438 case SkDisplacementMapEffect::kG_ChannelSelectorType: |
| 446 builder->fsCodeAppend("g"); | 439 builder->fsCodeAppend("g"); |
| 447 break; | 440 break; |
| 448 case SkDisplacementMapEffect::kB_ChannelSelectorType: | 441 case SkDisplacementMapEffect::kB_ChannelSelectorType: |
| 449 builder->fsCodeAppend("b"); | 442 builder->fsCodeAppend("b"); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 474 SkDEBUGFAIL("Unknown Y channel selector"); | 467 SkDEBUGFAIL("Unknown Y channel selector"); |
| 475 } | 468 } |
| 476 builder->fsCodeAppend("-vec2(0.5));\t\t"); | 469 builder->fsCodeAppend("-vec2(0.5));\t\t"); |
| 477 | 470 |
| 478 // FIXME : This can be achieved with a "clamp to border" texture repeat mode
and | 471 // FIXME : This can be achieved with a "clamp to border" texture repeat mode
and |
| 479 // a 0 border color instead of computing if cCoords is out of bounds
here. | 472 // a 0 border color instead of computing if cCoords is out of bounds
here. |
| 480 builder->fsCodeAppendf( | 473 builder->fsCodeAppendf( |
| 481 "bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);
\t\t", | 474 "bool %s = (%s.x < 0.0) || (%s.y < 0.0) || (%s.x > 1.0) || (%s.y > 1.0);
\t\t", |
| 482 outOfBounds, cCoords, cCoords, cCoords, cCoords); | 475 outOfBounds, cCoords, cCoords, cCoords, cCoords); |
| 483 builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds); | 476 builder->fsCodeAppendf("%s = %s ? vec4(0.0) : ", outputColor, outOfBounds); |
| 484 builder->fsAppendTextureLookup(samplers[1], cCoords, cCoordsType); | 477 builder->fsAppendTextureLookup(samplers[1], cCoords, coords[1].type()); |
| 485 builder->fsCodeAppend(";\n"); | 478 builder->fsCodeAppend(";\n"); |
| 486 } | 479 } |
| 487 | 480 |
| 488 void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, | 481 void GrGLDisplacementMapEffect::setData(const GrGLUniformManager& uman, |
| 489 const GrDrawEffect& drawEffect) { | 482 const GrDrawEffect& drawEffect) { |
| 490 const GrDisplacementMapEffect& displacementMap = | 483 const GrDisplacementMapEffect& displacementMap = |
| 491 drawEffect.castEffect<GrDisplacementMapEffect>(); | 484 drawEffect.castEffect<GrDisplacementMapEffect>(); |
| 492 GrTexture* displTex = displacementMap.texture(0); | |
| 493 GrTexture* colorTex = displacementMap.texture(1); | 485 GrTexture* colorTex = displacementMap.texture(1); |
| 494 fDisplacementEffectMatrix.setData(uman, | |
| 495 GrEffect::MakeDivByTextureWHMatrix(displTex
), | |
| 496 drawEffect, | |
| 497 displTex); | |
| 498 fColorEffectMatrix.setData(uman, | |
| 499 GrEffect::MakeDivByTextureWHMatrix(colorTex), | |
| 500 drawEffect, | |
| 501 colorTex); | |
| 502 | |
| 503 SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTe
x->width())); | 486 SkScalar scaleX = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTe
x->width())); |
| 504 SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTe
x->height())); | 487 SkScalar scaleY = SkScalarDiv(displacementMap.scale(), SkIntToScalar(colorTe
x->height())); |
| 505 uman.set2f(fScaleUni, SkScalarToFloat(scaleX), | 488 uman.set2f(fScaleUni, SkScalarToFloat(scaleX), |
| 506 colorTex->origin() == kTopLeft_GrSurfaceOrigin ? | 489 colorTex->origin() == kTopLeft_GrSurfaceOrigin ? |
| 507 SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY)); | 490 SkScalarToFloat(scaleY) : SkScalarToFloat(-scaleY)); |
| 508 } | 491 } |
| 509 | 492 |
| 510 GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& draw
Effect, | 493 GrGLEffect::EffectKey GrGLDisplacementMapEffect::GenKey(const GrDrawEffect& draw
Effect, |
| 511 const GrGLCaps&) { | 494 const GrGLCaps&) { |
| 512 const GrDisplacementMapEffect& displacementMap = | 495 const GrDisplacementMapEffect& displacementMap = |
| 513 drawEffect.castEffect<GrDisplacementMapEffect>(); | 496 drawEffect.castEffect<GrDisplacementMapEffect>(); |
| 514 | 497 |
| 515 GrTexture* displTex = displacementMap.texture(0); | 498 EffectKey xKey = displacementMap.xChannelSelector(); |
| 516 GrTexture* colorTex = displacementMap.texture(1); | 499 EffectKey yKey = displacementMap.yChannelSelector() << SkDisplacementMapEffe
ct::kKeyBits; |
| 517 | 500 |
| 518 EffectKey displKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMa
trix(displTex), | 501 return xKey | yKey; |
| 519 drawEffect, | |
| 520 kCoordsType, | |
| 521 displTex); | |
| 522 | |
| 523 EffectKey colorKey = GrGLEffectMatrix::GenKey(GrEffect::MakeDivByTextureWHMa
trix(colorTex), | |
| 524 drawEffect, | |
| 525 kCoordsType, | |
| 526 colorTex); | |
| 527 | |
| 528 colorKey <<= GrGLEffectMatrix::kKeyBits; | |
| 529 EffectKey xKey = displacementMap.xChannelSelector() << (2 * GrGLEffectMatrix
::kKeyBits); | |
| 530 EffectKey yKey = displacementMap.yChannelSelector() << (2 * GrGLEffectMatrix
::kKeyBits + | |
| 531 SkDisplacementMapEff
ect::kKeyBits); | |
| 532 | |
| 533 return xKey | yKey | displKey | colorKey; | |
| 534 } | 502 } |
| 535 #endif | 503 #endif |
| OLD | NEW |