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

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 SkImage& source,
136 const Context& ctx, 139 const Context& ctx,
137 SkBitmap* dst, 140 SkAutoTUnref<SkImage>& dst,
138 SkIPoint* offset) const { 141 SkIPoint* offset) const {
139 SkBitmap src = source; 142 SkAutoTUnref<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)) {
145 return false;
146 }
147 #if 0
148 if (src.colorType() != kN32_SkColorType) {
149 return false;
150 }
151 #endif
152 SkIRect bounds;
153 if (!this->applyCropRect(ctx, proxy, *src, &srcOffset, &bounds, src)) {
142 return false; 154 return false;
143 } 155 }
144 156
145 if (src.colorType() != kN32_SkColorType) { 157 SkBitmap srcBitmap;
158 if (!as_IB(src)->getROPixels(&srcBitmap)) {
159 return false;
160 }
161 src.reset(NULL);
162 SkAutoLockPixels alp(srcBitmap);
163 if (!srcBitmap.getPixels()) {
146 return false; 164 return false;
147 } 165 }
148 166
149 SkIRect bounds; 167 SkBitmap dstBitmap;
150 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { 168 if (!dstBitmap.tryAllocPixels(srcBitmap.info().makeWH(bounds.width(), bounds .height()))) {
151 return false; 169 return false;
152 } 170 }
153 171
154 SkAutoLockPixels alp(src);
155 if (!src.getPixels()) {
156 return false;
157 }
158
159 if (!dst->tryAllocPixels(src.info().makeWH(bounds.width(), bounds.height())) ) {
160 return false;
161 }
162
163 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 172 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
164 SkIntToScalar(this->radius().height())); 173 SkIntToScalar(this->radius().height()));
165 ctx.ctm().mapVectors(&radius, 1); 174 ctx.ctm().mapVectors(&radius, 1);
166 int width = SkScalarFloorToInt(radius.fX); 175 int width = SkScalarFloorToInt(radius.fX);
167 int height = SkScalarFloorToInt(radius.fY); 176 int height = SkScalarFloorToInt(radius.fY);
168 177
169 if (width < 0 || height < 0) { 178 if (width < 0 || height < 0) {
170 return false; 179 return false;
171 } 180 }
172 181
173 SkIRect srcBounds = bounds; 182 SkIRect srcBounds = bounds;
174 srcBounds.offset(-srcOffset); 183 srcBounds.offset(-srcOffset);
175 184
176 if (width == 0 && height == 0) { 185 if (width == 0 && height == 0) {
177 src.extractSubset(dst, srcBounds); 186 srcBitmap.extractSubset(&dstBitmap, srcBounds);
187 SkImage* image = SkNewImageFromBitmap(dstBitmap, true, NULL);
188 if (NULL == image) {
189 return false;
190 }
191 dst.reset(image);
178 offset->fX = bounds.left(); 192 offset->fX = bounds.left();
179 offset->fY = bounds.top(); 193 offset->fY = bounds.top();
180 return true; 194 return true;
181 } 195 }
182 196
183 SkBitmap temp; 197 SkBitmap temp;
184 if (!temp.tryAllocPixels(dst->info())) { 198 if (!temp.tryAllocPixels(dstBitmap.info())) {
185 return false; 199 return false;
186 } 200 }
187 201
188 if (width > 0 && height > 0) { 202 if (width > 0 && height > 0) {
189 callProcX(procX, src, &temp, width, srcBounds); 203 callProcX(procX, srcBitmap, &temp, width, srcBounds);
190 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( )); 204 SkIRect tmpBounds = SkIRect::MakeWH(srcBounds.width(), srcBounds.height( ));
191 callProcY(procY, temp, dst, height, tmpBounds); 205 callProcY(procY, temp, &dstBitmap, height, tmpBounds);
192 } else if (width > 0) { 206 } else if (width > 0) {
193 callProcX(procX, src, dst, width, srcBounds); 207 callProcX(procX, srcBitmap, &dstBitmap, width, srcBounds);
194 } else if (height > 0) { 208 } else if (height > 0) {
195 callProcY(procY, src, dst, height, srcBounds); 209 callProcY(procY, srcBitmap, &dstBitmap, height, srcBounds);
196 } 210 }
211
212 srcBitmap = SkBitmap();
213 temp = SkBitmap();
214
215 SkImage* image = SkNewImageFromBitmap(dstBitmap, true, NULL);
216 if (NULL == image) {
217 return false;
218 }
219 dst.reset(image);
197 offset->fX = bounds.left(); 220 offset->fX = bounds.left();
198 offset->fY = bounds.top(); 221 offset->fY = bounds.top();
199 return true; 222 return true;
200 } 223 }
201 224
202 bool SkErodeImageFilter::onFilterImage(Proxy* proxy, 225 bool SkErodeImageFilter::onFilterImage(Proxy* proxy,
203 const SkBitmap& source, const Context& ct x, 226 SkImage& source, const Context& ctx,
204 SkBitmap* dst, SkIPoint* offset) const { 227 SkAutoTUnref<SkImage>& dst, SkIPoint* off set) const {
205 Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType); 228 Proc erodeXProc = SkMorphologyGetPlatformProc(kErodeX_SkMorphologyProcType);
206 if (!erodeXProc) { 229 if (!erodeXProc) {
207 erodeXProc = erode<kX>; 230 erodeXProc = erode<kX>;
208 } 231 }
209 Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType); 232 Proc erodeYProc = SkMorphologyGetPlatformProc(kErodeY_SkMorphologyProcType);
210 if (!erodeYProc) { 233 if (!erodeYProc) {
211 erodeYProc = erode<kY>; 234 erodeYProc = erode<kY>;
212 } 235 }
213 return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset); 236 return this->filterImageGeneric(erodeXProc, erodeYProc, proxy, source, ctx, dst, offset);
214 } 237 }
215 238
216 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, 239 bool SkDilateImageFilter::onFilterImage(Proxy* proxy,
217 const SkBitmap& source, const Context& c tx, 240 SkImage& source, const Context& ctx,
218 SkBitmap* dst, SkIPoint* offset) const { 241 SkAutoTUnref<SkImage>& dst, SkIPoint* of fset) const {
219 Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType ); 242 Proc dilateXProc = SkMorphologyGetPlatformProc(kDilateX_SkMorphologyProcType );
220 if (!dilateXProc) { 243 if (!dilateXProc) {
221 dilateXProc = dilate<kX>; 244 dilateXProc = dilate<kX>;
222 } 245 }
223 Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType ); 246 Proc dilateYProc = SkMorphologyGetPlatformProc(kDilateY_SkMorphologyProcType );
224 if (!dilateYProc) { 247 if (!dilateYProc) {
225 dilateYProc = dilate<kY>; 248 dilateYProc = dilate<kY>;
226 } 249 }
227 return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx , dst, offset); 250 return this->filterImageGeneric(dilateXProc, dilateYProc, proxy, source, ctx , dst, offset);
228 } 251 }
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 // Draw upper and lower margins with bounds; middle without. 656 // Draw upper and lower margins with bounds; middle without.
634 apply_morphology_rect(context, texture, lowerSrcRect, lowerDstRect, radi us, 657 apply_morphology_rect(context, texture, lowerSrcRect, lowerDstRect, radi us,
635 morphType, bounds, direction); 658 morphType, bounds, direction);
636 apply_morphology_rect(context, texture, upperSrcRect, upperDstRect, radi us, 659 apply_morphology_rect(context, texture, upperSrcRect, upperDstRect, radi us,
637 morphType, bounds, direction); 660 morphType, bounds, direction);
638 apply_morphology_rect_no_bounds(context, texture, middleSrcRect, middleD stRect, radius, 661 apply_morphology_rect_no_bounds(context, texture, middleSrcRect, middleD stRect, radius,
639 morphType, direction); 662 morphType, direction);
640 } 663 }
641 } 664 }
642 665
643 bool apply_morphology(const SkBitmap& input, 666 bool apply_morphology(SkImage& input,
644 const SkIRect& rect, 667 const SkIRect& rect,
645 GrMorphologyEffect::MorphologyType morphType, 668 GrMorphologyEffect::MorphologyType morphType,
646 SkISize radius, 669 SkISize radius,
647 SkBitmap* dst) { 670 SkAutoTUnref<SkImage>& dst) {
648 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture())); 671 SkAutoTUnref<GrTexture> srcTexture(SkRef(input.getTexture()));
649 SkASSERT(srcTexture); 672 SkASSERT(srcTexture);
650 GrContext* context = srcTexture->getContext(); 673 GrContext* context = srcTexture->getContext();
651 674
652 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi dth()), 675 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi dth()),
653 SkIntToScalar(srcTexture->he ight()))); 676 SkIntToScalar(srcTexture->he ight())));
654 677
655 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); 678 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height());
656 GrSurfaceDesc desc; 679 GrSurfaceDesc desc;
657 desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag; 680 desc.fFlags = kRenderTarget_GrSurfaceFlag | kNoStencil_GrSurfaceFlag;
(...skipping 22 matching lines...) Expand all
680 if (radius.fHeight > 0) { 703 if (radius.fHeight > 0) {
681 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch); 704 GrTexture* texture = context->refScratchTexture(desc, GrContext::kApprox _ScratchTexMatch);
682 if (NULL == texture) { 705 if (NULL == texture) {
683 return false; 706 return false;
684 } 707 }
685 GrContext::AutoRenderTarget art(context, texture->asRenderTarget()); 708 GrContext::AutoRenderTarget art(context, texture->asRenderTarget());
686 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fHei ght, 709 apply_morphology_pass(context, srcTexture, srcRect, dstRect, radius.fHei ght,
687 morphType, Gr1DKernelEffect::kY_Direction); 710 morphType, Gr1DKernelEffect::kY_Direction);
688 srcTexture.reset(texture); 711 srcTexture.reset(texture);
689 } 712 }
690 SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst); 713 if (!SkImageFilter::WrapTexture(srcTexture, rect.width(), rect.height(), dst )) {
714 return false;
715 }
691 return true; 716 return true;
692 } 717 }
693 718
694 }; 719 };
695 720
696 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate, 721 bool SkMorphologyImageFilter::filterImageGPUGeneric(bool dilate,
697 Proxy* proxy, 722 Proxy* proxy,
698 const SkBitmap& src, 723 SkImage& src,
699 const Context& ctx, 724 const Context& ctx,
700 SkBitmap* result, 725 SkAutoTUnref<SkImage>& resul t,
701 SkIPoint* offset) const { 726 SkIPoint* offset) const {
702 SkBitmap input = src; 727 SkAutoTUnref<SkImage> input(SkRef(&src));
703 SkIPoint srcOffset = SkIPoint::Make(0, 0); 728 SkIPoint srcOffset = SkIPoint::Make(0, 0);
704 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, &input, &srcOffset)) { 729 if (getInput(0) && !getInput(0)->getInputResultGPU(proxy, src, ctx, input, & srcOffset)) {
705 return false; 730 return false;
706 } 731 }
707 SkIRect bounds; 732 SkIRect bounds;
708 if (!this->applyCropRect(ctx, proxy, input, &srcOffset, &bounds, &input)) { 733 if (!this->applyCropRect(ctx, proxy, *input, &srcOffset, &bounds, input)) {
709 return false; 734 return false;
710 } 735 }
711 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()), 736 SkVector radius = SkVector::Make(SkIntToScalar(this->radius().width()),
712 SkIntToScalar(this->radius().height())); 737 SkIntToScalar(this->radius().height()));
713 ctx.ctm().mapVectors(&radius, 1); 738 ctx.ctm().mapVectors(&radius, 1);
714 int width = SkScalarFloorToInt(radius.fX); 739 int width = SkScalarFloorToInt(radius.fX);
715 int height = SkScalarFloorToInt(radius.fY); 740 int height = SkScalarFloorToInt(radius.fY);
716 741
717 if (width < 0 || height < 0) { 742 if (width < 0 || height < 0) {
718 return false; 743 return false;
719 } 744 }
720 745
721 SkIRect srcBounds = bounds; 746 SkIRect srcBounds = bounds;
722 srcBounds.offset(-srcOffset); 747 srcBounds.offset(-srcOffset);
723 if (width == 0 && height == 0) { 748 if (width == 0 && height == 0) {
724 input.extractSubset(result, srcBounds); 749 SkImage* image = input->newImage(srcBounds.width(), srcBounds.height(), &srcBounds);
750 if (NULL == image) {
751 return false;
752 }
753 result.reset(image);
725 offset->fX = bounds.left(); 754 offset->fX = bounds.left();
726 offset->fY = bounds.top(); 755 offset->fY = bounds.top();
727 return true; 756 return true;
728 } 757 }
729 758
730 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType : GrMorphologyEffect::kErode_MorphologyType; 759 GrMorphologyEffect::MorphologyType type = dilate ? GrMorphologyEffect::kDila te_MorphologyType : GrMorphologyEffect::kErode_MorphologyType;
731 if (!apply_morphology(input, srcBounds, type, 760 if (!apply_morphology(*input, srcBounds, type,
732 SkISize::Make(width, height), result)) { 761 SkISize::Make(width, height), result)) {
733 return false; 762 return false;
734 } 763 }
735 offset->fX = bounds.left(); 764 offset->fX = bounds.left();
736 offset->fY = bounds.top(); 765 offset->fY = bounds.top();
737 return true; 766 return true;
738 } 767 }
739 768
740 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons t Context& ctx, 769 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, SkImage& src, const Conte xt& ctx,
741 SkBitmap* result, SkIPoint* offset) con st { 770 SkAutoTUnref<SkImage>& result, SkIPoint * offset) const {
742 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset); 771 return this->filterImageGPUGeneric(true, proxy, src, ctx, result, offset);
743 } 772 }
744 773
745 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const Context& ctx, 774 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, SkImage& src, const Contex t& ctx,
746 SkBitmap* result, SkIPoint* offset) cons t { 775 SkAutoTUnref<SkImage>& result, SkIPoint* offset) const {
747 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset); 776 return this->filterImageGPUGeneric(false, proxy, src, ctx, result, offset);
748 } 777 }
749 778
750 #endif 779 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698