Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 The Android Open Source Project |
| 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 "SkMorphologyImageFilter.h" | 8 #include "SkMorphologyImageFilter.h" |
| 9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
| 10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
| (...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 279 */ | 279 */ |
| 280 class GrMorphologyEffect : public Gr1DKernelEffect { | 280 class GrMorphologyEffect : public Gr1DKernelEffect { |
| 281 | 281 |
| 282 public: | 282 public: |
| 283 | 283 |
| 284 enum MorphologyType { | 284 enum MorphologyType { |
| 285 kErode_MorphologyType, | 285 kErode_MorphologyType, |
| 286 kDilate_MorphologyType, | 286 kDilate_MorphologyType, |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius , | 289 static GrFragmentProcessor* Create(GrTexture* tex, Direction dir, int radius , bool useBounds, float bounds[2], |
|
Justin Novosad
2014/12/22 20:11:11
Instead of having useBounds, you should consider h
cwallez
2015/01/19 21:34:38
Done.
| |
| 290 MorphologyType type) { | 290 MorphologyType type) { |
| 291 return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, type)); | 291 return SkNEW_ARGS(GrMorphologyEffect, (tex, dir, radius, useBounds, boun ds, type)); |
| 292 } | 292 } |
| 293 | 293 |
| 294 virtual ~GrMorphologyEffect(); | 294 virtual ~GrMorphologyEffect(); |
| 295 | 295 |
| 296 MorphologyType type() const { return fType; } | 296 MorphologyType type() const { return fType; } |
| 297 bool useBounds() const { return fUseBounds; } | |
| 298 const float* bounds() const { return fBounds; } | |
|
Justin Novosad
2014/12/22 20:11:11
"Bounds" are usually SkRect throughout skia. Perha
cwallez
2015/01/19 21:34:39
This is not an actual x-y par but more like a min-
| |
| 297 | 299 |
| 298 static const char* Name() { return "Morphology"; } | 300 static const char* Name() { return "Morphology"; } |
| 299 | 301 |
| 300 typedef GrGLMorphologyEffect GLProcessor; | 302 typedef GrGLMorphologyEffect GLProcessor; |
| 301 | 303 |
| 302 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR IDE; | 304 virtual const GrBackendFragmentProcessorFactory& getFactory() const SK_OVERR IDE; |
| 303 | 305 |
| 304 protected: | 306 protected: |
| 305 | 307 |
| 306 MorphologyType fType; | 308 MorphologyType fType; |
| 309 bool fUseBounds; | |
| 310 float fBounds[2]; | |
| 307 | 311 |
| 308 private: | 312 private: |
| 309 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE; | 313 virtual bool onIsEqual(const GrFragmentProcessor&) const SK_OVERRIDE; |
| 310 | 314 |
| 311 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE; | 315 virtual void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVE RRIDE; |
| 312 | 316 |
| 313 GrMorphologyEffect(GrTexture*, Direction, int radius, MorphologyType); | 317 GrMorphologyEffect(GrTexture*, Direction, int radius, bool useBounds, float bounds[2], MorphologyType); |
| 314 | 318 |
| 315 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; | 319 GR_DECLARE_FRAGMENT_PROCESSOR_TEST; |
| 316 | 320 |
| 317 typedef Gr1DKernelEffect INHERITED; | 321 typedef Gr1DKernelEffect INHERITED; |
| 318 }; | 322 }; |
| 319 | 323 |
| 320 /////////////////////////////////////////////////////////////////////////////// | 324 /////////////////////////////////////////////////////////////////////////////// |
| 321 | 325 |
| 322 class GrGLMorphologyEffect : public GrGLFragmentProcessor { | 326 class GrGLMorphologyEffect : public GrGLFragmentProcessor { |
| 323 public: | 327 public: |
| 324 GrGLMorphologyEffect (const GrBackendProcessorFactory&, const GrProcessor&); | 328 GrGLMorphologyEffect (const GrBackendProcessorFactory&, const GrProcessor&); |
| 325 | 329 |
| 326 virtual void emitCode(GrGLFPBuilder*, | 330 virtual void emitCode(GrGLFPBuilder*, |
| 327 const GrFragmentProcessor&, | 331 const GrFragmentProcessor&, |
| 328 const char* outputColor, | 332 const char* outputColor, |
| 329 const char* inputColor, | 333 const char* inputColor, |
| 330 const TransformedCoordsArray&, | 334 const TransformedCoordsArray&, |
| 331 const TextureSamplerArray&) SK_OVERRIDE; | 335 const TextureSamplerArray&) SK_OVERRIDE; |
| 332 | 336 |
| 333 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe yBuilder* b); | 337 static inline void GenKey(const GrProcessor&, const GrGLCaps&, GrProcessorKe yBuilder* b); |
| 334 | 338 |
| 335 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE; | 339 virtual void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_O VERRIDE; |
| 336 | 340 |
| 337 private: | 341 private: |
| 338 int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } | 342 int width() const { return GrMorphologyEffect::WidthFromRadius(fRadius); } |
| 339 | 343 |
| 340 int fRadius; | 344 int fRadius; |
| 345 Gr1DKernelEffect::Direction fDirection; | |
| 346 bool fUseBounds; | |
| 341 GrMorphologyEffect::MorphologyType fType; | 347 GrMorphologyEffect::MorphologyType fType; |
| 342 GrGLProgramDataManager::UniformHandle fImageIncrementUni; | 348 GrGLProgramDataManager::UniformHandle fPixelSizeUni; |
| 349 GrGLProgramDataManager::UniformHandle fBoundsUni; | |
| 343 | 350 |
| 344 typedef GrGLFragmentProcessor INHERITED; | 351 typedef GrGLFragmentProcessor INHERITED; |
| 345 }; | 352 }; |
| 346 | 353 |
| 347 GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendProcessorFactory& fact ory, | 354 GrGLMorphologyEffect::GrGLMorphologyEffect(const GrBackendProcessorFactory& fact ory, |
| 348 const GrProcessor& proc) | 355 const GrProcessor& proc) |
| 349 : INHERITED(factory) { | 356 : INHERITED(factory) { |
| 350 const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); | 357 const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); |
| 351 fRadius = m.radius(); | 358 fRadius = m.radius(); |
| 359 fDirection = m.direction(); | |
| 360 fUseBounds = m.useBounds(); | |
| 352 fType = m.type(); | 361 fType = m.type(); |
| 353 } | 362 } |
| 354 | 363 |
| 355 void GrGLMorphologyEffect::emitCode(GrGLFPBuilder* builder, | 364 void GrGLMorphologyEffect::emitCode(GrGLFPBuilder* builder, |
| 356 const GrFragmentProcessor&, | 365 const GrFragmentProcessor&, |
| 357 const char* outputColor, | 366 const char* outputColor, |
| 358 const char* inputColor, | 367 const char* inputColor, |
| 359 const TransformedCoordsArray& coords, | 368 const TransformedCoordsArray& coords, |
| 360 const TextureSamplerArray& samplers) { | 369 const TextureSamplerArray& samplers) { |
| 361 fImageIncrementUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visib ility, | 370 fPixelSizeUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility , |
| 362 kVec2f_GrSLType, "ImageIncrement"); | 371 kFloat_GrSLType, "PixelSize"); |
| 372 const char* pixelSizeInc = builder->getUniformCStr(fPixelSizeUni); | |
| 373 fBoundsUni = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility, | |
| 374 kVec2f_GrSLType, "Bounds"); | |
| 375 const char* bounds = builder->getUniformCStr(fBoundsUni); | |
| 363 | 376 |
| 364 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); | 377 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder(); |
| 365 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); | 378 SkString coords2D = fsBuilder->ensureFSCoords2D(coords, 0); |
| 366 const char* func; | 379 const char* func; |
| 367 switch (fType) { | 380 switch (fType) { |
| 368 case GrMorphologyEffect::kErode_MorphologyType: | 381 case GrMorphologyEffect::kErode_MorphologyType: |
| 369 fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor); | 382 fsBuilder->codeAppendf("\t\t%s = vec4(1, 1, 1, 1);\n", outputColor); |
| 370 func = "min"; | 383 func = "min"; |
| 371 break; | 384 break; |
| 372 case GrMorphologyEffect::kDilate_MorphologyType: | 385 case GrMorphologyEffect::kDilate_MorphologyType: |
| 373 fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); | 386 fsBuilder->codeAppendf("\t\t%s = vec4(0, 0, 0, 0);\n", outputColor); |
| 374 func = "max"; | 387 func = "max"; |
| 375 break; | 388 break; |
| 376 default: | 389 default: |
| 377 SkFAIL("Unexpected type"); | 390 SkFAIL("Unexpected type"); |
| 378 func = ""; // suppress warning | 391 func = ""; // suppress warning |
| 379 break; | 392 break; |
| 380 } | 393 } |
| 381 const char* imgInc = builder->getUniformCStr(fImageIncrementUni); | |
| 382 | 394 |
| 383 fsBuilder->codeAppendf("\t\tvec2 coord = %s - %d.0 * %s;\n", coords2D.c_str( ), fRadius, imgInc); | 395 const char* dir; |
| 384 fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", this->width() ); | 396 switch (fDirection) { |
| 397 case Gr1DKernelEffect::kX_Direction: | |
| 398 dir = "x"; | |
| 399 break; | |
| 400 case Gr1DKernelEffect::kY_Direction: | |
| 401 dir = "y"; | |
| 402 break; | |
| 403 default: | |
| 404 SkFAIL("Unknown filter direction."); | |
| 405 dir = ""; // suppress warning | |
| 406 } | |
| 407 | |
| 408 // vec2 coord = coord2D; | |
| 409 fsBuilder->codeAppendf("\t\tvec2 coord = %s;\n", coords2D.c_str()); | |
| 410 // coord.x -= radius * pixelSize; | |
| 411 fsBuilder->codeAppendf("\t\tcoord.%s -= %d.0 * %s; \n", dir, fRadius, pixelS izeInc); | |
| 412 if (fUseBounds) { | |
| 413 // highBound = min(highBound, coord.x + (width-1) * pixelSize); | |
| 414 fsBuilder->codeAppendf("\t\tfloat highBound = min(%s.y, coord.%s + %d * %s);", | |
| 415 bounds, dir, width() - 1, pixelSizeInc); | |
| 416 // coord.x = max(lowBound, coord.x); | |
| 417 fsBuilder->codeAppendf("\t\tcoord.%s = max(%s.x, coord.%s);", dir, bound s, dir); | |
| 418 } | |
| 419 fsBuilder->codeAppendf("\t\tfor (int i = 0; i < %d; i++) {\n", width()); | |
| 385 fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor) ; | 420 fsBuilder->codeAppendf("\t\t\t%s = %s(%s, ", outputColor, func, outputColor) ; |
| 386 fsBuilder->appendTextureLookup(samplers[0], "coord"); | 421 fsBuilder->appendTextureLookup(samplers[0], "coord"); |
| 387 fsBuilder->codeAppend(");\n"); | 422 fsBuilder->codeAppend(");\n"); |
| 388 fsBuilder->codeAppendf("\t\t\tcoord += %s;\n", imgInc); | 423 // coord.x += pixelSize; |
| 424 fsBuilder->codeAppendf("\t\t\tcoord.%s += %s;\n", dir, pixelSizeInc); | |
| 425 if (fUseBounds) { | |
| 426 // coord.x = min(highBound, coord.x); | |
| 427 fsBuilder->codeAppendf("\t\t\tcoord.%s = min(highBound, coord.%s);", dir , dir); | |
| 428 } | |
| 389 fsBuilder->codeAppend("\t\t}\n"); | 429 fsBuilder->codeAppend("\t\t}\n"); |
| 390 SkString modulate; | 430 SkString modulate; |
| 391 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); | 431 GrGLSLMulVarBy4f(&modulate, outputColor, inputColor); |
| 392 fsBuilder->codeAppend(modulate.c_str()); | 432 fsBuilder->codeAppend(modulate.c_str()); |
| 393 } | 433 } |
| 394 | 434 |
| 395 void GrGLMorphologyEffect::GenKey(const GrProcessor& proc, | 435 void GrGLMorphologyEffect::GenKey(const GrProcessor& proc, |
| 396 const GrGLCaps&, GrProcessorKeyBuilder* b) { | 436 const GrGLCaps&, GrProcessorKeyBuilder* b) { |
| 397 const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); | 437 const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); |
| 398 uint32_t key = static_cast<uint32_t>(m.radius()); | 438 uint32_t key = static_cast<uint32_t>(m.radius()); |
| 399 key |= (m.type() << 8); | 439 key |= (m.type() << 8); |
| 440 key |= (m.direction() << 9); | |
| 441 if (m.useBounds()) key |= 1 << 10; | |
| 400 b->add32(key); | 442 b->add32(key); |
| 401 } | 443 } |
| 402 | 444 |
| 403 void GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman, | 445 void GrGLMorphologyEffect::setData(const GrGLProgramDataManager& pdman, |
| 404 const GrProcessor& proc) { | 446 const GrProcessor& proc) { |
| 405 const Gr1DKernelEffect& kern = proc.cast<Gr1DKernelEffect>(); | 447 const GrMorphologyEffect& m = proc.cast<GrMorphologyEffect>(); |
| 406 GrTexture& texture = *kern.texture(0); | 448 GrTexture& texture = *m.texture(0); |
| 407 // the code we generated was for a specific kernel radius | 449 // the code we generated was for a specific kernel radius, direction and bou nd usage |
| 408 SkASSERT(kern.radius() == fRadius); | 450 SkASSERT(m.radius() == fRadius); |
| 409 float imageIncrement[2] = { 0 }; | 451 SkASSERT(m.direction() == fDirection); |
| 410 switch (kern.direction()) { | 452 SkASSERT(m.useBounds() == fUseBounds); |
| 453 | |
| 454 float pixelSize = 0.0f; | |
| 455 switch (fDirection) { | |
| 411 case Gr1DKernelEffect::kX_Direction: | 456 case Gr1DKernelEffect::kX_Direction: |
| 412 imageIncrement[0] = 1.0f / texture.width(); | 457 pixelSize = 1.0f / texture.width(); |
| 413 break; | 458 break; |
| 414 case Gr1DKernelEffect::kY_Direction: | 459 case Gr1DKernelEffect::kY_Direction: |
| 415 imageIncrement[1] = 1.0f / texture.height(); | 460 pixelSize = 1.0f / texture.height(); |
| 416 break; | 461 break; |
| 417 default: | 462 default: |
| 418 SkFAIL("Unknown filter direction."); | 463 SkFAIL("Unknown filter direction."); |
| 419 } | 464 } |
| 420 pdman.set2fv(fImageIncrementUni, 1, imageIncrement); | 465 pdman.set1f(fPixelSizeUni, pixelSize); |
| 466 | |
| 467 if (fUseBounds) { | |
| 468 const float* bounds = m.bounds(); | |
| 469 if (fDirection && texture.origin() == kBottomLeft_GrSurfaceOrigin) { | |
| 470 pdman.set2f(fBoundsUni, 1.0f - bounds[1], 1.0f - bounds[0]); | |
| 471 } else { | |
| 472 pdman.set2f(fBoundsUni, bounds[0], bounds[1]); | |
| 473 } | |
| 474 } | |
| 421 } | 475 } |
| 422 | 476 |
| 423 /////////////////////////////////////////////////////////////////////////////// | 477 /////////////////////////////////////////////////////////////////////////////// |
| 424 | 478 |
| 425 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, | 479 GrMorphologyEffect::GrMorphologyEffect(GrTexture* texture, |
| 426 Direction direction, | 480 Direction direction, |
| 427 int radius, | 481 int radius, |
| 482 bool useBounds, | |
| 483 float bounds[2], | |
| 428 MorphologyType type) | 484 MorphologyType type) |
| 429 : Gr1DKernelEffect(texture, direction, radius) | 485 : Gr1DKernelEffect(texture, direction, radius) |
| 430 , fType(type) { | 486 , fType(type), fUseBounds(useBounds) { |
| 487 fBounds[0] = bounds[0]; | |
| 488 fBounds[1] = bounds[1]; | |
| 431 } | 489 } |
| 432 | 490 |
| 433 GrMorphologyEffect::~GrMorphologyEffect() { | 491 GrMorphologyEffect::~GrMorphologyEffect() { |
| 434 } | 492 } |
| 435 | 493 |
| 436 const GrBackendFragmentProcessorFactory& GrMorphologyEffect::getFactory() const { | 494 const GrBackendFragmentProcessorFactory& GrMorphologyEffect::getFactory() const { |
| 437 return GrTBackendFragmentProcessorFactory<GrMorphologyEffect>::getInstance() ; | 495 return GrTBackendFragmentProcessorFactory<GrMorphologyEffect>::getInstance() ; |
| 438 } | 496 } |
| 439 | 497 |
| 440 bool GrMorphologyEffect::onIsEqual(const GrFragmentProcessor& sBase) const { | 498 bool GrMorphologyEffect::onIsEqual(const GrFragmentProcessor& sBase) const { |
| 441 const GrMorphologyEffect& s = sBase.cast<GrMorphologyEffect>(); | 499 const GrMorphologyEffect& s = sBase.cast<GrMorphologyEffect>(); |
| 442 return (this->radius() == s.radius() && | 500 return (this->radius() == s.radius() && |
| 443 this->direction() == s.direction() && | 501 this->direction() == s.direction() && |
| 502 this->useBounds() == s.useBounds() && | |
| 444 this->type() == s.type()); | 503 this->type() == s.type()); |
| 445 } | 504 } |
| 446 | 505 |
| 447 void GrMorphologyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) cons t { | 506 void GrMorphologyEffect::onComputeInvariantOutput(GrInvariantOutput* inout) cons t { |
| 448 // This is valid because the color components of the result of the kernel al l come | 507 // This is valid because the color components of the result of the kernel al l come |
| 449 // exactly from existing values in the source texture. | 508 // exactly from existing values in the source texture. |
| 450 this->updateInvariantOutputForModulation(inout); | 509 this->updateInvariantOutputForModulation(inout); |
| 451 } | 510 } |
| 452 | 511 |
| 453 /////////////////////////////////////////////////////////////////////////////// | 512 /////////////////////////////////////////////////////////////////////////////// |
| 454 | 513 |
| 455 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect); | 514 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMorphologyEffect); |
| 456 | 515 |
| 516 static float unusedBounds[2] = {0.0f, 0.0f}; | |
| 517 | |
| 457 GrFragmentProcessor* GrMorphologyEffect::TestCreate(SkRandom* random, | 518 GrFragmentProcessor* GrMorphologyEffect::TestCreate(SkRandom* random, |
| 458 GrContext*, | 519 GrContext*, |
| 459 const GrDrawTargetCaps&, | 520 const GrDrawTargetCaps&, |
| 460 GrTexture* textures[]) { | 521 GrTexture* textures[]) { |
| 461 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : | 522 int texIdx = random->nextBool() ? GrProcessorUnitTest::kSkiaPMTextureIdx : |
| 462 GrProcessorUnitTest::kAlphaTextureIdx; | 523 GrProcessorUnitTest::kAlphaTextureIdx; |
| 463 Direction dir = random->nextBool() ? kX_Direction : kY_Direction; | 524 Direction dir = random->nextBool() ? kX_Direction : kY_Direction; |
| 464 static const int kMaxRadius = 10; | 525 static const int kMaxRadius = 10; |
| 465 int radius = random->nextRangeU(1, kMaxRadius); | 526 int radius = random->nextRangeU(1, kMaxRadius); |
| 466 MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_Morpho logyType : | 527 MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_Morpho logyType : |
| 467 GrMorphologyEffect::kDilate_Morph ologyType; | 528 GrMorphologyEffect::kDilate_Morph ologyType; |
| 468 | 529 |
| 469 return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); | 530 return GrMorphologyEffect::Create(textures[texIdx], dir, radius, false, unus edBounds, type); |
| 470 } | 531 } |
| 471 | 532 |
| 472 namespace { | 533 namespace { |
| 473 | 534 |
| 535 | |
| 536 void apply_morphology_rect(GrContext* context, | |
| 537 GrTexture* texture, | |
| 538 const SkIRect& srcRect, | |
| 539 const SkIRect& dstRect, | |
| 540 int radius, | |
| 541 GrMorphologyEffect::MorphologyType morphType, | |
| 542 bool useBounds, | |
| 543 float bounds[2], | |
| 544 Gr1DKernelEffect::Direction direction) { | |
| 545 GrPaint paint; | |
| 546 paint.addColorProcessor(GrMorphologyEffect::Create(texture, | |
| 547 direction, | |
| 548 radius, | |
| 549 useBounds, | |
| 550 bounds, | |
| 551 morphType))->unref(); | |
| 552 context->drawRectToRect(paint, SkRect::Make(dstRect), SkRect::Make(srcRect)) ; | |
| 553 } | |
| 554 | |
| 474 void apply_morphology_pass(GrContext* context, | 555 void apply_morphology_pass(GrContext* context, |
| 475 GrTexture* texture, | 556 GrTexture* texture, |
| 476 const SkIRect& srcRect, | 557 const SkIRect& srcRect, |
| 477 const SkIRect& dstRect, | 558 const SkIRect& dstRect, |
| 478 int radius, | 559 int radius, |
| 479 GrMorphologyEffect::MorphologyType morphType, | 560 GrMorphologyEffect::MorphologyType morphType, |
| 480 Gr1DKernelEffect::Direction direction) { | 561 Gr1DKernelEffect::Direction direction) { |
| 481 GrPaint paint; | 562 float bounds[2] = { 0.0f, 1.0f }; |
| 482 paint.addColorProcessor(GrMorphologyEffect::Create(texture, | 563 SkIRect lowerSrcRect = srcRect, lowerDstRect = dstRect; |
| 483 direction, | 564 SkIRect middleSrcRect = srcRect, middleDstRect = dstRect; |
| 484 radius, | 565 SkIRect upperSrcRect = srcRect, upperDstRect = dstRect; |
| 485 morphType))->unref(); | 566 if (direction == Gr1DKernelEffect::kX_Direction) { |
| 486 context->drawRectToRect(paint, SkRect::Make(dstRect), SkRect::Make(srcRect)) ; | 567 bounds[0] = (SkIntToScalar(srcRect.left()) + 0.5f) / texture->width(); |
| 568 bounds[1] = (SkIntToScalar(srcRect.right()) - 0.5f) / texture->width(); | |
| 569 lowerSrcRect.fRight = srcRect.left() + radius; | |
| 570 lowerDstRect.fRight = dstRect.left() + radius; | |
| 571 upperSrcRect.fLeft = srcRect.right() - radius; | |
| 572 upperDstRect.fLeft = dstRect.right() - radius; | |
| 573 middleSrcRect.inset(radius, 0); | |
| 574 middleDstRect.inset(radius, 0); | |
| 575 } else { | |
| 576 bounds[0] = (SkIntToScalar(srcRect.top()) + 0.5f) / texture->height(); | |
| 577 bounds[1] = (SkIntToScalar(srcRect.bottom()) - 0.5f) / texture->height() ; | |
| 578 lowerSrcRect.fBottom = srcRect.top() + radius; | |
| 579 lowerDstRect.fBottom = dstRect.top() + radius; | |
| 580 upperSrcRect.fTop = srcRect.bottom() - radius; | |
| 581 upperDstRect.fTop = dstRect.bottom() - radius; | |
| 582 middleSrcRect.inset(0, radius); | |
| 583 middleDstRect.inset(0, radius); | |
| 584 } | |
| 585 if (middleSrcRect.fLeft - middleSrcRect.fRight >= 0) { | |
| 586 // radius covers srcRect; use bounds over entire draw | |
| 587 apply_morphology_rect(context, texture, srcRect, dstRect, radius, | |
| 588 morphType, true, bounds, direction); | |
| 589 } else { | |
| 590 // Draw upper and lower margins with bounds; middle without. | |
| 591 apply_morphology_rect(context, texture, lowerSrcRect, lowerDstRect, radi us, | |
| 592 morphType, true, bounds, direction); | |
| 593 apply_morphology_rect(context, texture, upperSrcRect, upperDstRect, radi us, | |
| 594 morphType, true, bounds, direction); | |
| 595 apply_morphology_rect(context, texture, middleSrcRect, middleDstRect, ra dius, | |
| 596 morphType, false, bounds, direction); | |
| 597 } | |
| 487 } | 598 } |
| 488 | 599 |
| 489 bool apply_morphology(const SkBitmap& input, | 600 bool apply_morphology(const SkBitmap& input, |
| 490 const SkIRect& rect, | 601 const SkIRect& rect, |
| 491 GrMorphologyEffect::MorphologyType morphType, | 602 GrMorphologyEffect::MorphologyType morphType, |
| 492 SkISize radius, | 603 SkISize radius, |
| 493 SkBitmap* dst) { | 604 SkBitmap* dst) { |
| 494 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture())); | 605 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture())); |
| 495 SkASSERT(srcTexture); | 606 SkASSERT(srcTexture); |
| 496 GrContext* context = srcTexture->getContext(); | 607 GrContext* context = srcTexture->getContext(); |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 510 SkIRect srcRect = rect; | 621 SkIRect srcRect = rect; |
| 511 | 622 |
| 512 if (radius.fWidth > 0) { | 623 if (radius.fWidth > 0) { |
| 513 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); | 624 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); |
| 514 if (NULL == texture) { | 625 if (NULL == texture) { |
| 515 return false; | 626 return false; |
| 516 } | 627 } |
| 517 GrContext::AutoRenderTarget art(context, texture->asRenderTarget()); | 628 GrContext::AutoRenderTarget art(context, texture->asRenderTarget()); |
| 518 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fWid th, | 629 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fWid th, |
| 519 morphType, Gr1DKernelEffect::kX_Direction); | 630 morphType, Gr1DKernelEffect::kX_Direction); |
| 520 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, | 631 /*SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, |
|
Justin Novosad
2014/12/22 20:11:11
Don't commit commented code
cwallez
2015/01/19 21:34:39
Done.
| |
| 521 dstRect.width(), radius.fHeight); | 632 dstRect.width(), radius.fHeight); |
| 522 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ? | 633 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT ype ? |
| 523 SK_ColorWHITE : | 634 SK_ColorWHITE : |
| 524 SK_ColorTRANSPARENT; | 635 SK_ColorTRANSPARENT; |
| 525 context->clear(&clearRect, clearColor, false, texture->asRenderTarget()) ; | 636 context->clear(&clearRect, clearColor, false, texture->asRenderTarget()) ;*/ |
| 526 srcTexture.reset(texture); | 637 srcTexture.reset(texture); |
| 527 srcRect = dstRect; | 638 srcRect = dstRect; |
| 528 } | 639 } |
| 529 if (radius.fHeight > 0) { | 640 if (radius.fHeight > 0) { |
| 530 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); | 641 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); |
| 531 if (NULL == texture) { | 642 if (NULL == texture) { |
| 532 return false; | 643 return false; |
| 533 } | 644 } |
| 534 GrContext::AutoRenderTarget art(context, texture->asRenderTarget()); | 645 GrContext::AutoRenderTarget art(context, texture->asRenderTarget()); |
| 535 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fHei ght, | 646 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fHei ght, |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 SkBitmap* result, SkIPoint* offset) con st { | 701 SkBitmap* result, SkIPoint* offset) con st { |
| 591 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); | 702 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); |
| 592 } | 703 } |
| 593 | 704 |
| 594 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, | 705 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, |
| 595 SkBitmap* result, SkIPoint* offset) cons t { | 706 SkBitmap* result, SkIPoint* offset) cons t { |
| 596 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); | 707 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); |
| 597 } | 708 } |
| 598 | 709 |
| 599 #endif | 710 #endif |
| OLD | NEW |