| 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 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 660 SkIntToScalar(srcTexture->height()))); | 660 SkIntToScalar(srcTexture->height()))); |
| 661 | 661 |
| 662 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); | 662 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); |
| 663 GrSurfaceDesc desc; | 663 GrSurfaceDesc desc; |
| 664 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 664 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 665 desc.fWidth = rect.width(); | 665 desc.fWidth = rect.width(); |
| 666 desc.fHeight = rect.height(); | 666 desc.fHeight = rect.height(); |
| 667 desc.fConfig = kSkia8888_GrPixelConfig; | 667 desc.fConfig = kSkia8888_GrPixelConfig; |
| 668 SkIRect srcRect = rect; | 668 SkIRect srcRect = rect; |
| 669 | 669 |
| 670 GrDrawContext* drawContext = context->drawContext(); | 670 GrDrawContext* srcDrawContext = NULL; |
| 671 if (!drawContext) { | |
| 672 return false; | |
| 673 } | |
| 674 | 671 |
| 675 if (radius.fWidth > 0) { | 672 if (radius.fWidth > 0) { |
| 676 GrTexture* texture = context->textureProvider()->refScratchTexture( | 673 GrTexture* dst = context->textureProvider()->refScratchTexture( |
| 677 desc, GrTextureProvider::kApprox_ScratchTexMatch); | 674 desc, GrTextureProvider::kApprox_ScratchTexMatch); |
| 678 if (NULL == texture) { | 675 if (NULL == dst) { |
| 679 return false; | 676 return false; |
| 680 } | 677 } |
| 681 apply_morphology_pass(drawContext, texture->asRenderTarget(), clip, srcT
exture, | 678 GrDrawContext* dstDrawContext = context->drawContext(dst->asRenderTarget
()); |
| 679 if (!dstDrawContext) { |
| 680 return false; |
| 681 } |
| 682 dstDrawContext->uses(srcTexture); |
| 683 |
| 684 apply_morphology_pass(dstDrawContext, dst->asRenderTarget(), clip, srcTe
xture, |
| 682 srcRect, dstRect, radius.fWidth, morphType, | 685 srcRect, dstRect, radius.fWidth, morphType, |
| 683 Gr1DKernelEffect::kX_Direction); | 686 Gr1DKernelEffect::kX_Direction); |
| 684 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, | 687 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, |
| 685 dstRect.width(), radius.fHeight); | 688 dstRect.width(), radius.fHeight); |
| 686 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT
ype ? | 689 GrColor clearColor = GrMorphologyEffect::kErode_MorphologyType == morphT
ype ? |
| 687 SK_ColorWHITE : | 690 SK_ColorWHITE : |
| 688 SK_ColorTRANSPARENT; | 691 SK_ColorTRANSPARENT; |
| 689 drawContext->clear(texture->asRenderTarget(), &clearRect, clearColor, fa
lse); | 692 dstDrawContext->clear(dst->asRenderTarget(), &clearRect, clearColor, fal
se); |
| 690 srcTexture.reset(texture); | 693 |
| 694 srcDrawContext = dstDrawContext; |
| 695 srcTexture.reset(dst); |
| 691 srcRect = dstRect; | 696 srcRect = dstRect; |
| 692 } | 697 } |
| 693 if (radius.fHeight > 0) { | 698 if (radius.fHeight > 0) { |
| 694 GrTexture* texture = context->textureProvider()->refScratchTexture(desc, | 699 GrTexture* dst = context->textureProvider()->refScratchTexture(desc, |
| 695 GrTextureProvider::kApprox_ScratchTexMatch); | 700 GrTextureProvider::kApprox_ScratchTexMatch); |
| 696 if (NULL == texture) { | 701 if (NULL == dst) { |
| 697 return false; | 702 return false; |
| 698 } | 703 } |
| 699 apply_morphology_pass(drawContext, texture->asRenderTarget(), clip, srcT
exture, | 704 GrDrawContext* dstDrawContext = context->drawContext(dst->asRenderTarget
()); |
| 705 if (!dstDrawContext) { |
| 706 return false; |
| 707 } |
| 708 if (srcDrawContext) { |
| 709 dstDrawContext->uses(srcDrawContext); |
| 710 } else { |
| 711 dstDrawContext->uses(srcTexture); |
| 712 } |
| 713 |
| 714 apply_morphology_pass(dstDrawContext, dst->asRenderTarget(), clip, srcTe
xture, |
| 700 srcRect, dstRect, radius.fHeight, morphType, | 715 srcRect, dstRect, radius.fHeight, morphType, |
| 701 Gr1DKernelEffect::kY_Direction); | 716 Gr1DKernelEffect::kY_Direction); |
| 702 srcTexture.reset(texture); | 717 |
| 718 srcDrawContext = dstDrawContext; |
| 719 srcTexture.reset(dst); |
| 703 } | 720 } |
| 704 SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); | 721 SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); |
| 705 return true; | 722 return true; |
| 706 } | 723 } |
| 707 | 724 |
| 708 }; | 725 }; |
| 709 | 726 |
| 710 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, | 727 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, |
| 711 Proxy* proxy, | 728 Proxy* proxy, |
| 712 const SkBitmap& src, | 729 const SkBitmap& src, |
| 713 const Context& ctx, | 730 const Context& ctx, |
| 714 SkBitmap* result, | 731 SkBitmap* result, |
| 715 SkIPoint* offset) const { | 732 SkIPoint* offset) const { |
| 716 SkBitmap input = src; | 733 SkBitmap input = src; |
| 717 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 734 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
| 718 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input,
&srcOffset)) { | 735 if (this->getInput(0) && |
| 736 !this->getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffse
t)) { |
| 719 return false; | 737 return false; |
| 720 } | 738 } |
| 721 SkIRect bounds; | 739 SkIRect bounds; |
| 722 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { | 740 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { |
| 723 return false; | 741 return false; |
| 724 } | 742 } |
| 725 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), | 743 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), |
| 726 SkIntToScalar(this->radius().height())); | 744 SkIntToScalar(this->radius().height())); |
| 727 ctx.ctm().mapVectors(&radius, 1); | 745 ctx.ctm().mapVectors(&radius, 1); |
| 728 int width = SkScalarFloorToInt(radius.fX); | 746 int width = SkScalarFloorToInt(radius.fX); |
| 729 int height = SkScalarFloorToInt(radius.fY); | 747 int height = SkScalarFloorToInt(radius.fY); |
| 730 | 748 |
| 731 if (width < 0 || height < 0) { | 749 if (width < 0 || height < 0) { |
| 732 return false; | 750 return false; |
| 733 } | 751 } |
| 734 | 752 |
| 735 SkIRect srcBounds = bounds; | 753 SkIRect srcBounds = bounds; |
| 736 srcBounds.offset(-srcOffset); | 754 srcBounds.offset(-srcOffset); |
| 737 if (width == 0 && height == 0) { | 755 if (width == 0 && height == 0) { |
| 738 input.extractSubset(result, srcBounds); | 756 input.extractSubset(result, srcBounds); |
| 739 offset->fX = bounds.left(); | 757 offset->fX = bounds.left(); |
| 740 offset->fY = bounds.top(); | 758 offset->fY = bounds.top(); |
| 741 return true; | 759 return true; |
| 742 } | 760 } |
| 743 | 761 |
| 744 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila
te_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; | 762 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila
te_MorphologyType |
| 745 if (!apply_morphology(input, srcBounds, type, | 763 : GrMorphologyEffect::kErod
e_MorphologyType; |
| 746 SkISize::Make(width, height), result)) { | 764 if (!apply_morphology(input, srcBounds, type, SkISize::Make(width, height),
result)) { |
| 747 return false; | 765 return false; |
| 748 } | 766 } |
| 749 offset->fX = bounds.left(); | 767 offset->fX = bounds.left(); |
| 750 offset->fY = bounds.top(); | 768 offset->fY = bounds.top(); |
| 751 return true; | 769 return true; |
| 752 } | 770 } |
| 753 | 771 |
| 754 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t Context& ctx, | 772 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t Context& ctx, |
| 755 SkBitmap* result, SkIPoint* offset) con
st { | 773 SkBitmap* result, SkIPoint* offset) con
st { |
| 756 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); | 774 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); |
| 757 } | 775 } |
| 758 | 776 |
| 759 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
Context& ctx, | 777 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
Context& ctx, |
| 760 SkBitmap* result, SkIPoint* offset) cons
t { | 778 SkBitmap* result, SkIPoint* offset) cons
t { |
| 761 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); | 779 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); |
| 762 } | 780 } |
| 763 | 781 |
| 764 #endif | 782 #endif |
| OLD | NEW |