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 |