Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(399)

Side by Side Diff: src/effects/SkMorphologyImageFilter.cpp

Issue 920513003: Make filters use SkImage instead of SkBitmap Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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"
11 #include "SkImage.h"
12 #include "SkImagePriv.h"
13 #include "SkImage_Base.h"
11 #include "SkReadBuffer.h" 14 #include "SkReadBuffer.h"
12 #include "SkWriteBuffer.h" 15 #include "SkWriteBuffer.h"
13 #include "SkRect.h" 16 #include "SkRect.h"
14 #include "SkMorphology_opts.h" 17 #include "SkMorphology_opts.h"
15 #if SK_SUPPORT_GPU 18 #if SK_SUPPORT_GPU
16 #include "GrContext.h" 19 #include "GrContext.h"
17 #include "GrInvariantOutput.h" 20 #include "GrInvariantOutput.h"
18 #include "GrTexture.h" 21 #include "GrTexture.h"
19 #include "effects/Gr1DKernelEffect.h" 22 #include "effects/Gr1DKernelEffect.h"
20 #include "gl/GrGLProcessor.h" 23 #include "gl/GrGLProcessor.h"
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 static void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds) 128 static void callProcY(SkMorphologyImageFilter::Proc procY, const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRect& bounds)
126 { 129 {
127 procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), 130 procY(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0),
128 radiusY, bounds.height(), bounds.width(), 131 radiusY, bounds.height(), bounds.width(),
129 src.rowBytesAsPixels(), dst->rowBytesAsPixels()); 132 src.rowBytesAsPixels(), dst->rowBytesAsPixels());
130 } 133 }
131 134
132 bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p rocX, 135 bool SkMorphologyImageFilter::filterImageGeneric(SkMorphologyImageFilter::Proc p rocX,
133 SkMorphologyImageFilter::Proc p rocY, 136 SkMorphologyImageFilter::Proc p rocY,
134 Proxy* proxy, 137 Proxy* proxy,
135 const SkBitmap& source, 138 const SkImage* source,
136 const Context& ctx, 139 const Context& ctx,
137 SkBitmap* dst, 140 SkAutoTUnref<const SkImage>& ds t,
138 SkIPoint* offset) const { 141 SkIPoint* offset) const {
139 SkBitmap src = source; 142 SkAutoTUnref<const SkImage> src(SkRef(source));
140 SkIPoint srcOffset = SkIPoint::Make(0, 0); 143 SkIPoint srcOffset = SkIPoint::Make(0, 0);
141 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, &src, &srcO ffset)) { 144 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctx, src, &srcOf fset)) {
142 return false;
143 }
144
145 if (src.colorType() != kN32_SkColorType) {
146 return false; 145 return false;
147 } 146 }
148 147
149 SkIRect bounds; 148 SkIRect bounds;
150 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { 149 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, src)) {
151 return false; 150 return false;
152 } 151 }
153 152
154 SkAutoLockPixels alp(src); 153 SkBitmap srcBitmap;
155 if (!src.getPixels()) { 154 SkAutoAdoptImageAsN32Bitmap aai(src, &srcBitmap);
155 if (NULL == srcBitmap.getPixels()) {
156 return false; 156 return false;
157 } 157 }
158 158
159 if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height())) ) { 159 SkBitmap dstBitmap;
160 if (!dstBitmap.tryAllocPixels(srcBitmap.info().makeWH(bounds.width(), bounds .height()))) {
160 return false; 161 return false;
161 } 162 }
162 163
163 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 164 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
164 SkIntToScalar(this->radius().height())); 165 SkIntToScalar(this->radius().height()));
165 ctx.ctm().mapVectors(&radius, 1); 166 ctx.ctm().mapVectors(&radius, 1);
166 int width = SkScalarFloorToInt(radius.fX); 167 int width = SkScalarFloorToInt(radius.fX);
167 int height = SkScalarFloorToInt(radius.fY); 168 int height = SkScalarFloorToInt(radius.fY);
168 169
169 if (width < 0 || height < 0) { 170 if (width < 0 || height < 0) {
170 return false; 171 return false;
171 } 172 }
172 173
173 SkIRect srcBounds = bounds; 174 SkIRect srcBounds = bounds;
174 srcBounds.offset(-srcOffset); 175 srcBounds.offset(-srcOffset);
175 176
176 if (width == 0 && height == 0) { 177 if (width == 0 && height == 0) {
177 src.extractSubset(dst, srcBounds); 178 srcBitmap.extractSubset(&dstBitmap, srcBounds);
179 SkImage* image = SkNewImageFromBitmap(dstBitmap, NULL);
180 if (NULL == image) {
181 return false;
182 }
183 dst.reset(image);
178 offset->fX = bounds.left(); 184 offset->fX = bounds.left();
179 offset->fY = bounds.top(); 185 offset->fY = bounds.top();
180 return true; 186 return true;
181 } 187 }
182 188
183 SkBitmap temp; 189 SkBitmap temp;
184 if (!temp.tryAllocPixels(dst->info())) { 190 if (!temp.tryAllocPixels(dstBitmap.info())) {
185 return false; 191 return false;
186 } 192 }
187 193
188 if (width > 0 && height > 0) { 194 if (width > 0 && height > 0) {
189 callProcX(procX, src, &temp, width, srcBounds); 195 callProcX(procX, srcBitmap, &temp, width, srcBounds);
190 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( )); 196 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( ));
191 callProcY(procY, temp, dst, height, tmpBounds); 197 callProcY(procY, temp, &dstBitmap, height, tmpBounds);
192 } else if (width > 0) { 198 } else if (width > 0) {
193 callProcX(procX, src, dst, width, srcBounds); 199 callProcX(procX, srcBitmap, &dstBitmap, width, srcBounds);
194 } else if (height > 0) { 200 } else if (height > 0) {
195 callProcY(procY, src, dst, height, srcBounds); 201 callProcY(procY, srcBitmap, &dstBitmap, height, srcBounds);
196 } 202 }
203
204 srcBitmap = SkBitmap();
205 temp = SkBitmap();
206
207 SkImage* image = SkNewImageFromBitmap(dstBitmap, NULL);
208 if (NULL == image) {
209 return false;
210 }
211 dst.reset(image);
197 offset->fX = bounds.left(); 212 offset->fX = bounds.left();
198 offset->fY = bounds.top(); 213 offset->fY = bounds.top();
199 return true; 214 return true;
200 } 215 }
201 216
202 bool SkErodeImageFilter::onFilterImage(Proxy* proxy, 217 bool SkErodeImageFilter::onFilterImage(Proxy* proxy,
203 const SkBitmap& source, const Context& ct x, 218 const SkImage* source, const Context& ctx ,
204 SkBitmap* dst, SkIPoint* offset) const { 219 SkAutoTUnref<const SkImage>& dst, SkIPoin t* offset) const {
205 Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); 220 Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType);
206 if (!erodeXProc) { 221 if (!erodeXProc) {
207 erodeXProc = erode<kX>; 222 erodeXProc = erode<kX>;
208 } 223 }
209 Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType); 224 Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType);
210 if (!erodeYProc) { 225 if (!erodeYProc) {
211 erodeYProc = erode<kY>; 226 erodeYProc = erode<kY>;
212 } 227 }
213 return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); 228 return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset);
214 } 229 }
215 230
216 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, 231 bool SkDilateImageFilter::onFilterImage(Proxy* proxy,
217 const SkBitmap& source, const Context& c tx, 232 const SkImage* source, const Context& ct x,
218 SkBitmap* dst, SkIPoint* offset) const { 233 SkAutoTUnref<const SkImage>& dst, SkIPoi nt* offset) const {
219 Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType ); 234 Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType );
220 if (!dilateXProc) { 235 if (!dilateXProc) {
221 dilateXProc = dilate<kX>; 236 dilateXProc = dilate<kX>;
222 } 237 }
223 Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType ); 238 Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType );
224 if (!dilateYProc) { 239 if (!dilateYProc) {
225 dilateYProc = dilate<kY>; 240 dilateYProc = dilate<kY>;
226 } 241 }
227 return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx , dst, offset); 242 return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx , dst, offset);
228 } 243 }
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 // Draw upper and lower margins with bounds; middle without. 651 // Draw upper and lower margins with bounds; middle without.
637 apply_morphology_rect(context, rt,texture, lowerSrcRect, lowerDstRect, r adius, 652 apply_morphology_rect(context, rt,texture, lowerSrcRect, lowerDstRect, r adius,
638 morphType, bounds, direction); 653 morphType, bounds, direction);
639 apply_morphology_rect(context, rt, texture, upperSrcRect, upperDstRect, radius, 654 apply_morphology_rect(context, rt, texture, upperSrcRect, upperDstRect, radius,
640 morphType, bounds, direction); 655 morphType, bounds, direction);
641 apply_morphology_rect_no_bounds(context, rt, texture, middleSrcRect, mid dleDstRect, radius, 656 apply_morphology_rect_no_bounds(context, rt, texture, middleSrcRect, mid dleDstRect, radius,
642 morphType, direction); 657 morphType, direction);
643 } 658 }
644 } 659 }
645 660
646 bool apply_morphology(const SkBitmap& input, 661 bool apply_morphology(const SkImage* input,
647 const SkIRect& rect, 662 const SkIRect& rect,
648 GrMorphologyEffect::MorphologyType morphType, 663 GrMorphologyEffect::MorphologyType morphType,
649 SkISize radius, 664 SkISize radius,
650 SkBitmap* dst) { 665 SkAutoTUnref<const SkImage>& dst) {
651 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture())); 666 SkAutoTUnref<GrTexture> srcTexture(SkRef(input->getTexture()));
652 SkASSERT(srcTexture); 667 SkASSERT(srcTexture);
653 GrContext* context = srcTexture->getContext(); 668 GrContext* context = srcTexture->getContext();
654 669
655 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi dth()), 670 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi dth()),
656 SkIntToScalar(srcTexture->he ight()))); 671 SkIntToScalar(srcTexture->he ight())));
657 672
658 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 673 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
659 GrSurfaceDesc desc; 674 GrSurfaceDesc desc;
660 desc.fFlags = kRenderTarget_GrSurfaceFlag; 675 desc.fFlags = kRenderTarget_GrSurfaceFlag;
661 desc.fWidth = rect.width(); 676 desc.fWidth = rect.width();
(...skipping 19 matching lines...) Expand all
681 } 696 }
682 if (radius.fHeight > 0) { 697 if (radius.fHeight > 0) {
683 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); 698 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch);
684 if (NULL == texture) { 699 if (NULL == texture) {
685 return false; 700 return false;
686 } 701 }
687 apply_morphology_pass(context, texture->asRenderTarget(), srcTexture, sr cRect, dstRect, 702 apply_morphology_pass(context, texture->asRenderTarget(), srcTexture, sr cRect, dstRect,
688 radius.fHeight, morphType, Gr1DKernelEffect::kY_Di rection); 703 radius.fHeight, morphType, Gr1DKernelEffect::kY_Di rection);
689 srcTexture.reset(texture); 704 srcTexture.reset(texture);
690 } 705 }
691 SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); 706 if (!SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst )) {
707 return false;
708 }
692 return true; 709 return true;
693 } 710 }
694 711
695 }; 712 };
696 713
697 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 714 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate,
698 Proxy* proxy, 715 Proxy* proxy,
699 const SkBitmap& src, 716 const SkImage* src,
700 const Context& ctx, 717 const Context& ctx,
701 SkBitmap* result, 718 SkAutoTUnref<const SkImage>& result,
702 SkIPoint* offset) const { 719 SkIPoint* offset) const {
703 SkBitmap input = src; 720 SkAutoTUnref<const SkImage> input(SkRef(src));
704 SkIPoint srcOffset = SkIPoint::Make(0, 0); 721 SkIPoint srcOffset = SkIPoint::Make(0, 0);
705 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 722 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, input, & srcOffset)) {
706 return false; 723 return false;
707 } 724 }
708 SkIRect bounds; 725 SkIRect bounds;
709 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 726 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, input)) {
710 return false; 727 return false;
711 } 728 }
712 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 729 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
713 SkIntToScalar(this->radius().height())); 730 SkIntToScalar(this->radius().height()));
714 ctx.ctm().mapVectors(&radius, 1); 731 ctx.ctm().mapVectors(&radius, 1);
715 int width = SkScalarFloorToInt(radius.fX); 732 int width = SkScalarFloorToInt(radius.fX);
716 int height = SkScalarFloorToInt(radius.fY); 733 int height = SkScalarFloorToInt(radius.fY);
717 734
718 if (width < 0 || height < 0) { 735 if (width < 0 || height < 0) {
719 return false; 736 return false;
720 } 737 }
721 738
722 SkIRect srcBounds = bounds; 739 SkIRect srcBounds = bounds;
723 srcBounds.offset(-srcOffset); 740 srcBounds.offset(-srcOffset);
724 if (width == 0 && height == 0) { 741 if (width == 0 && height == 0) {
725 input.extractSubset(result, srcBounds); 742 SkImage* image = input->newImage(srcBounds.width(), srcBounds.height(), &srcBounds);
743 if (NULL == image) {
744 return false;
745 }
746 result.reset(image);
726 offset->fX = bounds.left(); 747 offset->fX = bounds.left();
727 offset->fY = bounds.top(); 748 offset->fY = bounds.top();
728 return true; 749 return true;
729 } 750 }
730 751
731 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; 752 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType : GrMorphologyEffect::kErode_MorphologyType;
732 if (!apply_morphology(input, srcBounds, type, 753 if (!apply_morphology(input, srcBounds, type,
733 SkISize::Make(width, height), result)) { 754 SkISize::Make(width, height), result)) {
734 return false; 755 return false;
735 } 756 }
736 offset->fX = bounds.left(); 757 offset->fX = bounds.left();
737 offset->fY = bounds.top(); 758 offset->fY = bounds.top();
738 return true; 759 return true;
739 } 760 }
740 761
741 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons t Context& ctx, 762 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkImage* src, const Context& ctx,
742 SkBitmap* result, SkIPoint* offset) con st { 763 SkAutoTUnref<const SkImage>& result, Sk IPoint* offset) const {
743 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); 764 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset);
744 } 765 }
745 766
746 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 767 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkImage* src, const Context& ctx,
747 SkBitmap* result, SkIPoint* offset) cons t { 768 SkAutoTUnref<const SkImage>& result, SkI Point* offset) const {
748 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); 769 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset);
749 } 770 }
750 771
751 #endif 772 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698