| 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 #include "SkBlurMaskFilter.h" | 9 #include "SkBlurMaskFilter.h" |
| 10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
| (...skipping 539 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 550 typedef GrGLRectBlurEffect GLEffect; | 550 typedef GrGLRectBlurEffect GLEffect; |
| 551 | 551 |
| 552 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | 552 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; |
| 553 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; | 553 virtual void getConstantColorComponents(GrColor* color, uint32_t* validFlags
) const SK_OVERRIDE; |
| 554 | 554 |
| 555 /** | 555 /** |
| 556 * Create a simple filter effect with custom bicubic coefficients. | 556 * Create a simple filter effect with custom bicubic coefficients. |
| 557 */ | 557 */ |
| 558 static GrEffectRef* Create(GrContext *context, const SkRect& rect, | 558 static GrEffectRef* Create(GrContext *context, const SkRect& rect, |
| 559 float sigma) { | 559 float sigma) { |
| 560 GrTexture *blurProfileTexture = NULL; | 560 GrTexture *horizontalScanline = NULL, *verticalScanline = NULL; |
| 561 int doubleProfileSize = SkScalarCeilToInt(12*sigma); | 561 bool createdScanlines = CreateScanlineTextures(context, sigma, |
| 562 | 562 SkScalarCeilToInt(rect.wi
dth()), |
| 563 if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.heigh
t()) { | 563 SkScalarCeilToInt(rect.he
ight()), |
| 564 // if the blur sigma is too large so the gaussian overlaps the whole | 564 &horizontalScanline, &ver
ticalScanline); |
| 565 // rect in either direction, fall back to CPU path for now. | 565 SkAutoTUnref<GrTexture> hunref(horizontalScanline), vunref(verticalScan
line); |
| 566 | 566 if (!createdScanlines) { |
| 567 return NULL; | 567 return NULL; |
| 568 } | 568 } |
| 569 | 569 AutoEffectUnref effect(SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, |
| 570 bool createdBlurProfileTexture = CreateBlurProfileTexture(context, sigma
, &blurProfileTexture); | 570 horizontalScanline,
verticalScanline))); |
| 571 SkAutoTUnref<GrTexture> hunref(blurProfileTexture); | |
| 572 if (!createdBlurProfileTexture) { | |
| 573 return NULL; | |
| 574 } | |
| 575 AutoEffectUnref effect(SkNEW_ARGS(GrRectBlurEffect, (rect, sigma, blurPr
ofileTexture))); | |
| 576 return CreateEffectRef(effect); | 571 return CreateEffectRef(effect); |
| 577 } | 572 } |
| 578 | 573 |
| 579 const SkRect& getRect() const { return fRect; } | 574 unsigned int getWidth() const { return fWidth; } |
| 575 unsigned int getHeight() const { return fHeight; } |
| 580 float getSigma() const { return fSigma; } | 576 float getSigma() const { return fSigma; } |
| 577 const GrCoordTransform& getTransform() const { return fTransform; } |
| 581 | 578 |
| 582 private: | 579 private: |
| 583 GrRectBlurEffect(const SkRect& rect, float sigma, GrTexture *blur_profile); | 580 GrRectBlurEffect(const SkRect& rect, float sigma, |
| 581 GrTexture *horizontal_scanline, GrTexture *vertical_scanlin
e); |
| 584 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; | 582 virtual bool onIsEqual(const GrEffect&) const SK_OVERRIDE; |
| 585 | 583 |
| 586 static bool CreateBlurProfileTexture(GrContext *context, float sigma, | 584 static bool CreateScanlineTextures(GrContext *context, float sigma, |
| 587 GrTexture **blurProfileTexture); | 585 unsigned int width, unsigned int height, |
| 586 GrTexture **horizontalScanline, |
| 587 GrTexture **verticalScanline); |
| 588 | 588 |
| 589 SkRect fRect; | 589 unsigned int fWidth, fHeight; |
| 590 float fSigma; | 590 float fSigma; |
| 591 GrTextureAccess fBlurProfileAccess; | 591 GrTextureAccess fHorizontalScanlineAccess; |
| 592 GrTextureAccess fVerticalScanlineAccess; |
| 593 GrCoordTransform fTransform; |
| 592 | 594 |
| 593 GR_DECLARE_EFFECT_TEST; | 595 GR_DECLARE_EFFECT_TEST; |
| 594 | 596 |
| 595 typedef GrEffect INHERITED; | 597 typedef GrEffect INHERITED; |
| 596 }; | 598 }; |
| 597 | 599 |
| 598 class GrGLRectBlurEffect : public GrGLEffect { | 600 class GrGLRectBlurEffect : public GrGLEffect { |
| 599 public: | 601 public: |
| 600 GrGLRectBlurEffect(const GrBackendEffectFactory& factory, | 602 GrGLRectBlurEffect(const GrBackendEffectFactory& factory, |
| 601 const GrDrawEffect&); | 603 const GrDrawEffect&); |
| 602 virtual void emitCode(GrGLShaderBuilder*, | 604 virtual void emitCode(GrGLShaderBuilder*, |
| 603 const GrDrawEffect&, | 605 const GrDrawEffect&, |
| 604 EffectKey, | 606 EffectKey, |
| 605 const char* outputColor, | 607 const char* outputColor, |
| 606 const char* inputColor, | 608 const char* inputColor, |
| 607 const TransformedCoordsArray&, | 609 const TransformedCoordsArray&, |
| 608 const TextureSamplerArray&) SK_OVERRIDE; | 610 const TextureSamplerArray&) SK_OVERRIDE; |
| 609 | 611 |
| 610 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; | 612 virtual void setData(const GrGLUniformManager&, const GrDrawEffect&) SK_OVER
RIDE; |
| 611 | 613 |
| 612 private: | 614 private: |
| 613 typedef GrGLUniformManager::UniformHandle UniformHandle; | 615 typedef GrGLUniformManager::UniformHandle UniformHandle; |
| 614 | 616 |
| 615 UniformHandle fProxyRectUniform; | 617 UniformHandle fWidthUni; |
| 616 UniformHandle fProfileSizeUniform; | 618 UniformHandle fHeightUni; |
| 617 | 619 |
| 618 typedef GrGLEffect INHERITED; | 620 typedef GrGLEffect INHERITED; |
| 619 }; | 621 }; |
| 620 | 622 |
| 621 | |
| 622 | |
| 623 GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendEffectFactory& factory, co
nst GrDrawEffect&) | 623 GrGLRectBlurEffect::GrGLRectBlurEffect(const GrBackendEffectFactory& factory, co
nst GrDrawEffect&) |
| 624 : INHERITED(factory) { | 624 : INHERITED(factory) { |
| 625 } | 625 } |
| 626 | 626 |
| 627 void OutputRectBlurProfileLookup(GrGLShaderBuilder* builder, | |
| 628 const GrGLShaderBuilder::TextureSampler& sample
r, | |
| 629 const char *output, | |
| 630 const char *profileSize, const char *loc, | |
| 631 const char *blurred_width, | |
| 632 const char *sharp_width) { | |
| 633 builder->fsCodeAppendf("\t\tfloat coord = (0.5 * (abs(2.0*%s - %s) - %s))/%s
;\n", | |
| 634 loc, blurred_width, sharp_width, profileSize); | |
| 635 builder->fsCodeAppendf("\t\t%s = ", output); | |
| 636 builder->fsAppendTextureLookup(sampler, "vec2(coord,0.5)"); | |
| 637 builder->fsCodeAppend(".a;\n"); | |
| 638 } | |
| 639 | |
| 640 void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder, | 627 void GrGLRectBlurEffect::emitCode(GrGLShaderBuilder* builder, |
| 641 const GrDrawEffect&, | 628 const GrDrawEffect&, |
| 642 EffectKey key, | 629 EffectKey key, |
| 643 const char* outputColor, | 630 const char* outputColor, |
| 644 const char* inputColor, | 631 const char* inputColor, |
| 645 const TransformedCoordsArray& coords, | 632 const TransformedCoordsArray& coords, |
| 646 const TextureSamplerArray& samplers) { | 633 const TextureSamplerArray& samplers) { |
| 647 | 634 |
| 648 const char *rectName; | 635 SkString texture_coords = builder->ensureFSCoords2D(coords, 0); |
| 649 const char *profileSizeName; | |
| 650 | |
| 651 fProxyRectUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visibil
ity, | |
| 652 kVec4f_GrSLType, | |
| 653 "proxyRect", | |
| 654 &rectName); | |
| 655 fProfileSizeUniform = builder->addUniform(GrGLShaderBuilder::kFragment_Visib
ility, | |
| 656 kFloat_GrSLType, | |
| 657 "profileSize", | |
| 658 &profileSizeName); | |
| 659 | |
| 660 const char *fragmentPos = builder->fragmentPosition(); | |
| 661 | 636 |
| 662 if (inputColor) { | 637 if (inputColor) { |
| 663 builder->fsCodeAppendf("\tvec4 src=%s;\n", inputColor); | 638 builder->fsCodeAppendf("\tvec4 src=%s;\n", inputColor); |
| 664 } else { | 639 } else { |
| 665 builder->fsCodeAppendf("\tvec4 src=vec4(1)\n;"); | 640 builder->fsCodeAppendf("\tvec4 src=vec4(1)\n;"); |
| 666 } | 641 } |
| 667 | 642 |
| 668 builder->fsCodeAppendf("\tvec2 translatedPos = %s.xy - %s.xy;\n", fragmentPo
s, rectName ); | 643 builder->fsCodeAppendf("\tvec4 horiz = "); |
| 669 builder->fsCodeAppendf("\tfloat width = %s.z - %s.x;\n", rectName, rectName)
; | 644 builder->fsAppendTextureLookup( samplers[0], texture_coords.c_str() ); |
| 670 builder->fsCodeAppendf("\tfloat height = %s.w - %s.y;\n", rectName, rectName
); | 645 builder->fsCodeAppendf(";\n"); |
| 646 builder->fsCodeAppendf("\tvec4 vert = "); |
| 647 builder->fsAppendTextureLookup( samplers[1], texture_coords.c_str() ); |
| 648 builder->fsCodeAppendf(";\n"); |
| 671 | 649 |
| 672 builder->fsCodeAppendf("\tvec2 smallDims = vec2(width - %s, height-%s);\n",
profileSizeName, profileSizeName); | 650 builder->fsCodeAppendf("\tfloat final = (horiz*vert).r;\n"); |
| 673 builder->fsCodeAppendf("\tfloat center = 2.0 * floor(%s/2.0 + .25) - 1.0;\n"
, profileSizeName); | 651 builder->fsCodeAppendf("\t%s = final*src;\n", outputColor); |
| 674 builder->fsCodeAppendf("\tvec2 wh = smallDims - vec2(center,center);\n"); | |
| 675 | |
| 676 builder->fsCodeAppendf("\tfloat horiz_lookup;\n"); | |
| 677 builder->fsCodeAppendf("\tif (%s <= smallDims.x) {\n", profileSizeName); | |
| 678 OutputRectBlurProfileLookup(builder, samplers[0], "horiz_lookup", profileSiz
eName, "translatedPos.x", "width", "wh.x"); | |
| 679 builder->fsCodeAppendf("\t}\n"); | |
| 680 | |
| 681 builder->fsCodeAppendf("\tfloat vert_lookup;\n"); | |
| 682 builder->fsCodeAppendf("\tif (%s <= smallDims.y) {\n", profileSizeName); | |
| 683 OutputRectBlurProfileLookup(builder, samplers[0], "vert_lookup", profileSize
Name, "translatedPos.y", "height", "wh.y"); | |
| 684 builder->fsCodeAppendf("\t}\n"); | |
| 685 | |
| 686 builder->fsCodeAppendf("\tfloat final = 1.0 - horiz_lookup * vert_lookup;\n"
); | |
| 687 | |
| 688 builder->fsCodeAppendf("\t%s = vec4(final, final, final, 1.0);\n", outputCol
or ); | |
| 689 } | 652 } |
| 690 | 653 |
| 691 void GrGLRectBlurEffect::setData(const GrGLUniformManager& uman, | 654 void GrGLRectBlurEffect::setData(const GrGLUniformManager& uman, |
| 692 const GrDrawEffect& drawEffect) { | 655 const GrDrawEffect& drawEffect) { |
| 693 const GrRectBlurEffect& rbe = drawEffect.castEffect<GrRectBlurEffect>(); | |
| 694 SkRect rect = rbe.getRect(); | |
| 695 | |
| 696 uman.set4f(fProxyRectUniform, rect.fLeft, rect.fTop, rect.fRight, rect.fBott
om); | |
| 697 uman.set1f(fProfileSizeUniform, SkScalarCeilToScalar(6*rbe.getSigma())); | |
| 698 } | 656 } |
| 699 | 657 |
| 700 bool GrRectBlurEffect::CreateBlurProfileTexture(GrContext *context, float sigma, | 658 bool GrRectBlurEffect::CreateScanlineTextures(GrContext *context, float sigma, |
| 701 GrTexture **blurProfileTexture) { | 659 unsigned int width, unsigned int h
eight, |
| 660 GrTexture **horizontalScanline, |
| 661 GrTexture **verticalScanline) { |
| 702 GrTextureParams params; | 662 GrTextureParams params; |
| 703 GrTextureDesc texDesc; | 663 GrTextureDesc texDesc; |
| 704 | 664 |
| 705 unsigned int profile_size = SkScalarCeilToInt(6*sigma); | 665 unsigned int profile_size = SkScalarFloorToInt(6*sigma); |
| 706 | 666 |
| 707 texDesc.fWidth = profile_size; | 667 texDesc.fWidth = width; |
| 708 texDesc.fHeight = 1; | 668 texDesc.fHeight = 1; |
| 709 texDesc.fConfig = kAlpha_8_GrPixelConfig; | 669 texDesc.fConfig = kAlpha_8_GrPixelConfig; |
| 710 | 670 |
| 711 static const GrCacheID::Domain gBlurProfileDomain = GrCacheID::GenerateDomai
n(); | 671 static const GrCacheID::Domain gBlurProfileDomain = GrCacheID::GenerateDomai
n(); |
| 712 GrCacheID::Key key; | 672 GrCacheID::Key key; |
| 713 memset(&key, 0, sizeof(key)); | 673 memset(&key, 0, sizeof(key)); |
| 714 key.fData32[0] = profile_size; | 674 key.fData32[0] = profile_size; |
| 715 key.fData32[1] = 1; | 675 key.fData32[1] = width; |
| 716 GrCacheID blurProfileKey(gBlurProfileDomain, key); | 676 key.fData32[2] = 1; |
| 677 GrCacheID horizontalCacheID(gBlurProfileDomain, key); |
| 717 | 678 |
| 718 uint8_t *profile = NULL; | 679 uint8_t *profile = NULL; |
| 719 SkAutoTDeleteArray<uint8_t> ada(NULL); | 680 SkAutoTDeleteArray<uint8_t> ada(NULL); |
| 720 | 681 |
| 721 *blurProfileTexture = context->findAndRefTexture(texDesc, blurProfileKey, &p
arams); | 682 *horizontalScanline = context->findAndRefTexture(texDesc, horizontalCacheID,
¶ms); |
| 722 | 683 |
| 723 if (NULL == *blurProfileTexture) { | 684 if (NULL == *horizontalScanline) { |
| 724 | 685 |
| 725 SkBlurMask::ComputeBlurProfile(sigma, &profile); | 686 SkBlurMask::ComputeBlurProfile(sigma, &profile); |
| 726 ada.reset(profile); | 687 ada.reset(profile); |
| 727 | 688 |
| 728 *blurProfileTexture = context->createTexture(¶ms, texDesc, blurProfi
leKey, | 689 SkAutoTMalloc<uint8_t> horizontalPixels(width); |
| 729 profile, 0); | 690 SkBlurMask::ComputeBlurredScanline(horizontalPixels, profile, width, sig
ma); |
| 730 | 691 |
| 731 if (NULL == *blurProfileTexture) { | 692 *horizontalScanline = context->createTexture(¶ms, texDesc, horizonta
lCacheID, |
| 693 horizontalPixels, 0); |
| 694 |
| 695 if (NULL == *horizontalScanline) { |
| 732 return false; | 696 return false; |
| 733 } | 697 } |
| 734 } | 698 } |
| 735 | 699 |
| 700 texDesc.fWidth = 1; |
| 701 texDesc.fHeight = height; |
| 702 key.fData32[1] = 1; |
| 703 key.fData32[2] = height; |
| 704 GrCacheID verticalCacheID(gBlurProfileDomain, key); |
| 705 |
| 706 *verticalScanline = context->findAndRefTexture(texDesc, verticalCacheID, &pa
rams); |
| 707 if (NULL == *verticalScanline) { |
| 708 if (NULL == profile) { |
| 709 SkBlurMask::ComputeBlurProfile(sigma, &profile); |
| 710 ada.reset(profile); |
| 711 } |
| 712 |
| 713 SkAutoTMalloc<uint8_t> verticalPixels(height); |
| 714 SkBlurMask::ComputeBlurredScanline(verticalPixels, profile, height, sigm
a); |
| 715 |
| 716 *verticalScanline = context->createTexture(¶ms, texDesc, verticalCac
heID, |
| 717 verticalPixels, 0); |
| 718 |
| 719 if (NULL == *verticalScanline) { |
| 720 SkSafeSetNull(*horizontalScanline); |
| 721 return false; |
| 722 } |
| 723 |
| 724 } |
| 736 return true; | 725 return true; |
| 737 } | 726 } |
| 738 | 727 |
| 739 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, | 728 GrRectBlurEffect::GrRectBlurEffect(const SkRect& rect, float sigma, |
| 740 GrTexture *blur_profile) | 729 GrTexture *horizontal_scanline, GrTexture *ve
rtical_scanline) |
| 741 : INHERITED(), | 730 : INHERITED(), |
| 742 fRect(rect), | 731 fWidth(horizontal_scanline->width()), |
| 732 fHeight(vertical_scanline->width()), |
| 743 fSigma(sigma), | 733 fSigma(sigma), |
| 744 fBlurProfileAccess(blur_profile) { | 734 fHorizontalScanlineAccess(horizontal_scanline), |
| 745 this->addTextureAccess(&fBlurProfileAccess); | 735 fVerticalScanlineAccess(vertical_scanline) { |
| 746 this->setWillReadFragmentPosition(); | 736 SkMatrix mat; |
| 737 mat.setRectToRect(rect, SkRect::MakeWH(1,1), SkMatrix::kFill_ScaleToFit); |
| 738 fTransform.reset(kLocal_GrCoordSet, mat); |
| 739 this->addTextureAccess(&fHorizontalScanlineAccess); |
| 740 this->addTextureAccess(&fVerticalScanlineAccess); |
| 741 this->addCoordTransform(&fTransform); |
| 747 } | 742 } |
| 748 | 743 |
| 749 GrRectBlurEffect::~GrRectBlurEffect() { | 744 GrRectBlurEffect::~GrRectBlurEffect() { |
| 750 } | 745 } |
| 751 | 746 |
| 752 const GrBackendEffectFactory& GrRectBlurEffect::getFactory() const { | 747 const GrBackendEffectFactory& GrRectBlurEffect::getFactory() const { |
| 753 return GrTBackendEffectFactory<GrRectBlurEffect>::getInstance(); | 748 return GrTBackendEffectFactory<GrRectBlurEffect>::getInstance(); |
| 754 } | 749 } |
| 755 | 750 |
| 756 bool GrRectBlurEffect::onIsEqual(const GrEffect& sBase) const { | 751 bool GrRectBlurEffect::onIsEqual(const GrEffect& sBase) const { |
| 757 const GrRectBlurEffect& s = CastEffect<GrRectBlurEffect>(sBase); | 752 const GrRectBlurEffect& s = CastEffect<GrRectBlurEffect>(sBase); |
| 758 return this->getSigma() == s.getSigma(); | 753 return this->getWidth() == s.getWidth() && |
| 754 this->getHeight() == s.getHeight() && |
| 755 this->getSigma() == s.getSigma() && |
| 756 this->getTransform() == s.getTransform(); |
| 759 } | 757 } |
| 760 | 758 |
| 761 void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* vali
dFlags) const { | 759 void GrRectBlurEffect::getConstantColorComponents(GrColor* color, uint32_t* vali
dFlags) const { |
| 762 *validFlags = 0; | 760 *validFlags = 0; |
| 763 return; | 761 return; |
| 764 } | 762 } |
| 765 | 763 |
| 766 GR_DEFINE_EFFECT_TEST(GrRectBlurEffect); | 764 GR_DEFINE_EFFECT_TEST(GrRectBlurEffect); |
| 767 | 765 |
| 768 GrEffectRef* GrRectBlurEffect::TestCreate(SkRandom* random, | 766 GrEffectRef* GrRectBlurEffect::TestCreate(SkRandom* random, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 788 if (!path.isRect(&rect)) { | 786 if (!path.isRect(&rect)) { |
| 789 return false; | 787 return false; |
| 790 } | 788 } |
| 791 | 789 |
| 792 if (!strokeRec.isFillStyle()) { | 790 if (!strokeRec.isFillStyle()) { |
| 793 return false; | 791 return false; |
| 794 } | 792 } |
| 795 | 793 |
| 796 SkMatrix ctm = context->getMatrix(); | 794 SkMatrix ctm = context->getMatrix(); |
| 797 SkScalar xformedSigma = this->computeXformedSigma(ctm); | 795 SkScalar xformedSigma = this->computeXformedSigma(ctm); |
| 798 | 796 rect.outset(3*xformedSigma, 3*xformedSigma); |
| 799 int pad=SkScalarCeilToInt(6*xformedSigma)/2; | |
| 800 rect.outset(SkIntToScalar(pad), SkIntToScalar(pad)); | |
| 801 | 797 |
| 802 SkAutoTUnref<GrEffectRef> effect(GrRectBlurEffect::Create( | 798 SkAutoTUnref<GrEffectRef> effect(GrRectBlurEffect::Create( |
| 803 context, rect, xformedSigma)); | 799 context, rect, xformedSigma)); |
| 804 if (!effect) { | 800 if (!effect) { |
| 805 return false; | 801 return false; |
| 806 } | 802 } |
| 807 | 803 |
| 808 GrContext::AutoMatrix am; | 804 GrContext::AutoMatrix am; |
| 809 if (!am.setIdentity(context, grp)) { | 805 if (!am.setIdentity(context, grp)) { |
| 810 return false; | 806 return false; |
| 811 } | 807 } |
| 812 | 808 |
| 809 |
| 813 grp->addCoverageEffect(effect); | 810 grp->addCoverageEffect(effect); |
| 814 | 811 |
| 815 context->drawRect(*grp, rect); | 812 context->drawRect(*grp, rect); |
| 816 return true; | 813 return true; |
| 817 } | 814 } |
| 818 | 815 |
| 819 class GrGLRRectBlurEffect; | 816 class GrGLRRectBlurEffect; |
| 820 | 817 |
| 821 class GrRRectBlurEffect : public GrEffect { | 818 class GrRRectBlurEffect : public GrEffect { |
| 822 public: | 819 public: |
| (...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1212 } else { | 1209 } else { |
| 1213 str->append("None"); | 1210 str->append("None"); |
| 1214 } | 1211 } |
| 1215 str->append("))"); | 1212 str->append("))"); |
| 1216 } | 1213 } |
| 1217 #endif | 1214 #endif |
| 1218 | 1215 |
| 1219 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1216 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1220 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1217 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1221 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1218 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |