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 12 matching lines...) Expand all Loading... |
23 SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer
) | 23 SkMorphologyImageFilter::SkMorphologyImageFilter(SkFlattenableReadBuffer& buffer
) |
24 : INHERITED(buffer) { | 24 : INHERITED(buffer) { |
25 fRadius.fWidth = buffer.readInt(); | 25 fRadius.fWidth = buffer.readInt(); |
26 fRadius.fHeight = buffer.readInt(); | 26 fRadius.fHeight = buffer.readInt(); |
27 buffer.validate(SkScalarIsFinite(SkIntToScalar(fRadius.fWidth)) && | 27 buffer.validate(SkScalarIsFinite(SkIntToScalar(fRadius.fWidth)) && |
28 SkScalarIsFinite(SkIntToScalar(fRadius.fHeight)) && | 28 SkScalarIsFinite(SkIntToScalar(fRadius.fHeight)) && |
29 (fRadius.fWidth >= 0) && | 29 (fRadius.fWidth >= 0) && |
30 (fRadius.fHeight >= 0)); | 30 (fRadius.fHeight >= 0)); |
31 } | 31 } |
32 | 32 |
33 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, int radiusY, SkIma
geFilter* input) | 33 SkMorphologyImageFilter::SkMorphologyImageFilter(int radiusX, int radiusY, SkIma
geFilter* input, const SkIRect* cropRect) |
34 : INHERITED(input), fRadius(SkISize::Make(radiusX, radiusY)) { | 34 : INHERITED(input, cropRect), fRadius(SkISize::Make(radiusX, radiusY)) { |
35 } | 35 } |
36 | 36 |
37 | 37 |
38 void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { | 38 void SkMorphologyImageFilter::flatten(SkFlattenableWriteBuffer& buffer) const { |
39 this->INHERITED::flatten(buffer); | 39 this->INHERITED::flatten(buffer); |
40 buffer.writeInt(fRadius.fWidth); | 40 buffer.writeInt(fRadius.fWidth); |
41 buffer.writeInt(fRadius.fHeight); | 41 buffer.writeInt(fRadius.fHeight); |
42 } | 42 } |
43 | 43 |
44 static void erode(const SkPMColor* src, SkPMColor* dst, | 44 static void erode(const SkPMColor* src, SkPMColor* dst, |
(...skipping 23 matching lines...) Expand all Loading... |
68 dptr += dstStrideY; | 68 dptr += dstStrideY; |
69 lp += srcStrideY; | 69 lp += srcStrideY; |
70 up += srcStrideY; | 70 up += srcStrideY; |
71 } | 71 } |
72 if (x >= radius) src += srcStrideX; | 72 if (x >= radius) src += srcStrideX; |
73 if (x + radius < width - 1) upperSrc += srcStrideX; | 73 if (x + radius < width - 1) upperSrc += srcStrideX; |
74 dst += dstStrideX; | 74 dst += dstStrideX; |
75 } | 75 } |
76 } | 76 } |
77 | 77 |
78 static void erodeX(const SkBitmap& src, SkBitmap* dst, int radiusX) | 78 static void erodeX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRec
t& bounds) |
79 { | 79 { |
80 erode(src.getAddr32(0, 0), dst->getAddr32(0, 0), | 80 erode(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), |
81 radiusX, src.width(), src.height(), | 81 radiusX, bounds.width(), bounds.height(), |
82 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels()); | 82 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels()); |
83 } | 83 } |
84 | 84 |
85 static void erodeY(const SkBitmap& src, SkBitmap* dst, int radiusY) | 85 static void erodeY(const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRec
t& bounds) |
86 { | 86 { |
87 erode(src.getAddr32(0, 0), dst->getAddr32(0, 0), | 87 erode(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), |
88 radiusY, src.height(), src.width(), | 88 radiusY, bounds.height(), bounds.width(), |
89 src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1); | 89 src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1); |
90 } | 90 } |
91 | 91 |
92 static void dilate(const SkPMColor* src, SkPMColor* dst, | 92 static void dilate(const SkPMColor* src, SkPMColor* dst, |
93 int radius, int width, int height, | 93 int radius, int width, int height, |
94 int srcStrideX, int srcStrideY, | 94 int srcStrideX, int srcStrideY, |
95 int dstStrideX, int dstStrideY) | 95 int dstStrideX, int dstStrideY) |
96 { | 96 { |
97 radius = SkMin32(radius, width - 1); | 97 radius = SkMin32(radius, width - 1); |
98 const SkPMColor* upperSrc = src + radius * srcStrideX; | 98 const SkPMColor* upperSrc = src + radius * srcStrideX; |
(...skipping 17 matching lines...) Expand all Loading... |
116 dptr += dstStrideY; | 116 dptr += dstStrideY; |
117 lp += srcStrideY; | 117 lp += srcStrideY; |
118 up += srcStrideY; | 118 up += srcStrideY; |
119 } | 119 } |
120 if (x >= radius) src += srcStrideX; | 120 if (x >= radius) src += srcStrideX; |
121 if (x + radius < width - 1) upperSrc += srcStrideX; | 121 if (x + radius < width - 1) upperSrc += srcStrideX; |
122 dst += dstStrideX; | 122 dst += dstStrideX; |
123 } | 123 } |
124 } | 124 } |
125 | 125 |
126 static void dilateX(const SkBitmap& src, SkBitmap* dst, int radiusX) | 126 static void dilateX(const SkBitmap& src, SkBitmap* dst, int radiusX, const SkIRe
ct& bounds) |
127 { | 127 { |
128 dilate(src.getAddr32(0, 0), dst->getAddr32(0, 0), | 128 dilate(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), |
129 radiusX, src.width(), src.height(), | 129 radiusX, bounds.width(), bounds.height(), |
130 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels()); | 130 1, src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels()); |
131 } | 131 } |
132 | 132 |
133 static void dilateY(const SkBitmap& src, SkBitmap* dst, int radiusY) | 133 static void dilateY(const SkBitmap& src, SkBitmap* dst, int radiusY, const SkIRe
ct& bounds) |
134 { | 134 { |
135 dilate(src.getAddr32(0, 0), dst->getAddr32(0, 0), | 135 dilate(src.getAddr32(bounds.left(), bounds.top()), dst->getAddr32(0, 0), |
136 radiusY, src.height(), src.width(), | 136 radiusY, bounds.height(), bounds.width(), |
137 src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1); | 137 src.rowBytesAsPixels(), 1, dst->rowBytesAsPixels(), 1); |
138 } | 138 } |
139 | 139 |
140 bool SkErodeImageFilter::onFilterImage(Proxy* proxy, | 140 bool SkErodeImageFilter::onFilterImage(Proxy* proxy, |
141 const SkBitmap& source, const SkMatrix& c
tm, | 141 const SkBitmap& source, const SkMatrix& c
tm, |
142 SkBitmap* dst, SkIPoint* offset) { | 142 SkBitmap* dst, SkIPoint* offset) { |
143 SkBitmap src = source; | 143 SkBitmap src = source; |
144 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offse
t)) { | 144 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offse
t)) { |
145 return false; | 145 return false; |
146 } | 146 } |
147 | 147 |
148 if (src.config() != SkBitmap::kARGB_8888_Config) { | 148 if (src.config() != SkBitmap::kARGB_8888_Config) { |
149 return false; | 149 return false; |
150 } | 150 } |
151 | 151 |
| 152 SkIRect bounds; |
| 153 src.getBounds(&bounds); |
| 154 if (!this->applyCropRect(&bounds, ctm)) { |
| 155 return false; |
| 156 } |
| 157 |
152 SkAutoLockPixels alp(src); | 158 SkAutoLockPixels alp(src); |
153 if (!src.getPixels()) { | 159 if (!src.getPixels()) { |
154 return false; | 160 return false; |
155 } | 161 } |
156 | 162 |
157 dst->setConfig(src.config(), src.width(), src.height()); | 163 dst->setConfig(src.config(), bounds.width(), bounds.height()); |
158 dst->allocPixels(); | 164 dst->allocPixels(); |
159 | 165 |
160 int width = radius().width(); | 166 int width = radius().width(); |
161 int height = radius().height(); | 167 int height = radius().height(); |
162 | 168 |
163 if (width < 0 || height < 0) { | 169 if (width < 0 || height < 0) { |
164 return false; | 170 return false; |
165 } | 171 } |
166 | 172 |
167 if (width == 0 && height == 0) { | 173 if (width == 0 && height == 0) { |
168 src.copyTo(dst, dst->config()); | 174 src.extractSubset(dst, bounds); |
| 175 offset->fX += bounds.left(); |
| 176 offset->fY += bounds.top(); |
169 return true; | 177 return true; |
170 } | 178 } |
171 | 179 |
172 SkBitmap temp; | 180 SkBitmap temp; |
173 temp.setConfig(dst->config(), dst->width(), dst->height()); | 181 temp.setConfig(dst->config(), dst->width(), dst->height()); |
174 if (!temp.allocPixels()) { | 182 if (!temp.allocPixels()) { |
175 return false; | 183 return false; |
176 } | 184 } |
177 | 185 |
178 if (width > 0 && height > 0) { | 186 if (width > 0 && height > 0) { |
179 erodeX(src, &temp, width); | 187 erodeX(src, &temp, width, bounds); |
180 erodeY(temp, dst, height); | 188 SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); |
| 189 erodeY(temp, dst, height, tmpBounds); |
181 } else if (width > 0) { | 190 } else if (width > 0) { |
182 erodeX(src, dst, width); | 191 erodeX(src, dst, width, bounds); |
183 } else if (height > 0) { | 192 } else if (height > 0) { |
184 erodeY(src, dst, height); | 193 erodeY(src, dst, height, bounds); |
185 } | 194 } |
| 195 offset->fX += bounds.left(); |
| 196 offset->fY += bounds.top(); |
186 return true; | 197 return true; |
187 } | 198 } |
188 | 199 |
189 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, | 200 bool SkDilateImageFilter::onFilterImage(Proxy* proxy, |
190 const SkBitmap& source, const SkMatrix&
ctm, | 201 const SkBitmap& source, const SkMatrix&
ctm, |
191 SkBitmap* dst, SkIPoint* offset) { | 202 SkBitmap* dst, SkIPoint* offset) { |
192 SkBitmap src = source; | 203 SkBitmap src = source; |
193 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offse
t)) { | 204 if (getInput(0) && !getInput(0)->filterImage(proxy, source, ctm, &src, offse
t)) { |
194 return false; | 205 return false; |
195 } | 206 } |
196 if (src.config() != SkBitmap::kARGB_8888_Config) { | 207 if (src.config() != SkBitmap::kARGB_8888_Config) { |
197 return false; | 208 return false; |
198 } | 209 } |
199 | 210 |
| 211 SkIRect bounds; |
| 212 src.getBounds(&bounds); |
| 213 if (!this->applyCropRect(&bounds, ctm)) { |
| 214 return false; |
| 215 } |
| 216 |
200 SkAutoLockPixels alp(src); | 217 SkAutoLockPixels alp(src); |
201 if (!src.getPixels()) { | 218 if (!src.getPixels()) { |
202 return false; | 219 return false; |
203 } | 220 } |
204 | 221 |
205 dst->setConfig(src.config(), src.width(), src.height()); | 222 dst->setConfig(src.config(), bounds.width(), bounds.height()); |
206 dst->allocPixels(); | 223 dst->allocPixels(); |
207 | 224 |
208 int width = radius().width(); | 225 int width = radius().width(); |
209 int height = radius().height(); | 226 int height = radius().height(); |
210 | 227 |
211 if (width < 0 || height < 0) { | 228 if (width < 0 || height < 0) { |
212 return false; | 229 return false; |
213 } | 230 } |
214 | 231 |
215 if (width == 0 && height == 0) { | 232 if (width == 0 && height == 0) { |
216 src.copyTo(dst, dst->config()); | 233 src.extractSubset(dst, bounds); |
| 234 offset->fX += bounds.left(); |
| 235 offset->fY += bounds.top(); |
217 return true; | 236 return true; |
218 } | 237 } |
219 | 238 |
220 SkBitmap temp; | 239 SkBitmap temp; |
221 temp.setConfig(dst->config(), dst->width(), dst->height()); | 240 temp.setConfig(dst->config(), dst->width(), dst->height()); |
222 if (!temp.allocPixels()) { | 241 if (!temp.allocPixels()) { |
223 return false; | 242 return false; |
224 } | 243 } |
225 | 244 |
226 if (width > 0 && height > 0) { | 245 if (width > 0 && height > 0) { |
227 dilateX(src, &temp, width); | 246 dilateX(src, &temp, width, bounds); |
228 dilateY(temp, dst, height); | 247 SkIRect tmpBounds = SkIRect::MakeWH(bounds.width(), bounds.height()); |
| 248 dilateY(temp, dst, height, tmpBounds); |
229 } else if (width > 0) { | 249 } else if (width > 0) { |
230 dilateX(src, dst, width); | 250 dilateX(src, dst, width, bounds); |
231 } else if (height > 0) { | 251 } else if (height > 0) { |
232 dilateY(src, dst, height); | 252 dilateY(src, dst, height, bounds); |
233 } | 253 } |
| 254 offset->fX += bounds.left(); |
| 255 offset->fY += bounds.top(); |
234 return true; | 256 return true; |
235 } | 257 } |
236 | 258 |
237 #if SK_SUPPORT_GPU | 259 #if SK_SUPPORT_GPU |
238 | 260 |
239 /////////////////////////////////////////////////////////////////////////////// | 261 /////////////////////////////////////////////////////////////////////////////// |
240 | 262 |
241 class GrGLMorphologyEffect; | 263 class GrGLMorphologyEffect; |
242 | 264 |
243 /** | 265 /** |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_Morpho
logyType : | 465 MorphologyType type = random->nextBool() ? GrMorphologyEffect::kErode_Morpho
logyType : |
444 GrMorphologyEffect::kDilate_Morph
ologyType; | 466 GrMorphologyEffect::kDilate_Morph
ologyType; |
445 | 467 |
446 return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); | 468 return GrMorphologyEffect::Create(textures[texIdx], dir, radius, type); |
447 } | 469 } |
448 | 470 |
449 namespace { | 471 namespace { |
450 | 472 |
451 void apply_morphology_pass(GrContext* context, | 473 void apply_morphology_pass(GrContext* context, |
452 GrTexture* texture, | 474 GrTexture* texture, |
453 const SkIRect& rect, | 475 const SkIRect& srcRect, |
| 476 const SkIRect& dstRect, |
454 int radius, | 477 int radius, |
455 GrMorphologyEffect::MorphologyType morphType, | 478 GrMorphologyEffect::MorphologyType morphType, |
456 Gr1DKernelEffect::Direction direction) { | 479 Gr1DKernelEffect::Direction direction) { |
457 GrPaint paint; | 480 GrPaint paint; |
458 paint.addColorEffect(GrMorphologyEffect::Create(texture, | 481 paint.addColorEffect(GrMorphologyEffect::Create(texture, |
459 direction, | 482 direction, |
460 radius, | 483 radius, |
461 morphType))->unref(); | 484 morphType))->unref(); |
462 context->drawRect(paint, SkRect::MakeFromIRect(rect)); | 485 context->drawRectToRect(paint, SkRect::MakeFromIRect(dstRect), SkRect::MakeF
romIRect(srcRect)); |
463 } | 486 } |
464 | 487 |
465 GrTexture* apply_morphology(GrTexture* srcTexture, | 488 bool apply_morphology(const SkBitmap& input, |
466 const SkIRect& rect, | 489 const SkIRect& rect, |
467 GrMorphologyEffect::MorphologyType morphType, | 490 GrMorphologyEffect::MorphologyType morphType, |
468 SkISize radius) { | 491 SkISize radius, |
| 492 SkBitmap* dst) { |
| 493 GrTexture* srcTexture = input.getTexture(); |
| 494 SkASSERT(NULL != srcTexture); |
469 GrContext* context = srcTexture->getContext(); | 495 GrContext* context = srcTexture->getContext(); |
470 srcTexture->ref(); | 496 srcTexture->ref(); |
| 497 SkAutoTUnref<GrTexture> src(srcTexture); |
471 | 498 |
472 GrContext::AutoMatrix am; | 499 GrContext::AutoMatrix am; |
473 am.setIdentity(context); | 500 am.setIdentity(context); |
474 | 501 |
475 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi
dth()), | 502 GrContext::AutoClip acs(context, SkRect::MakeWH(SkIntToScalar(srcTexture->wi
dth()), |
476 SkIntToScalar(srcTexture->he
ight()))); | 503 SkIntToScalar(srcTexture->he
ight()))); |
477 | 504 |
| 505 SkIRect dstRect = SkIRect::MakeWH(rect.width(), rect.height()); |
478 GrTextureDesc desc; | 506 GrTextureDesc desc; |
479 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | 507 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
480 desc.fWidth = rect.width(); | 508 desc.fWidth = rect.width(); |
481 desc.fHeight = rect.height(); | 509 desc.fHeight = rect.height(); |
482 desc.fConfig = kSkia8888_GrPixelConfig; | 510 desc.fConfig = kSkia8888_GrPixelConfig; |
| 511 SkIRect srcRect = rect; |
483 | 512 |
484 if (radius.fWidth > 0) { | 513 if (radius.fWidth > 0) { |
485 GrAutoScratchTexture ast(context, desc); | 514 GrAutoScratchTexture ast(context, desc); |
486 GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()
); | 515 GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()
); |
487 apply_morphology_pass(context, srcTexture, rect, radius.fWidth, | 516 apply_morphology_pass(context, src, srcRect, dstRect, radius.fWidth, |
488 morphType, Gr1DKernelEffect::kX_Direction); | 517 morphType, Gr1DKernelEffect::kX_Direction); |
489 SkIRect clearRect = SkIRect::MakeXYWH(rect.fLeft, rect.fBottom, | 518 SkIRect clearRect = SkIRect::MakeXYWH(dstRect.fLeft, dstRect.fBottom, |
490 rect.width(), radius.fHeight); | 519 dstRect.width(), radius.fHeight); |
491 context->clear(&clearRect, 0x0); | 520 context->clear(&clearRect, 0x0); |
492 srcTexture->unref(); | 521 src.reset(ast.detach()); |
493 srcTexture = ast.detach(); | 522 srcRect = dstRect; |
494 } | 523 } |
495 if (radius.fHeight > 0) { | 524 if (radius.fHeight > 0) { |
496 GrAutoScratchTexture ast(context, desc); | 525 GrAutoScratchTexture ast(context, desc); |
497 GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()
); | 526 GrContext::AutoRenderTarget art(context, ast.texture()->asRenderTarget()
); |
498 apply_morphology_pass(context, srcTexture, rect, radius.fHeight, | 527 apply_morphology_pass(context, src, srcRect, dstRect, radius.fHeight, |
499 morphType, Gr1DKernelEffect::kY_Direction); | 528 morphType, Gr1DKernelEffect::kY_Direction); |
500 srcTexture->unref(); | 529 src.reset(ast.detach()); |
501 srcTexture = ast.detach(); | |
502 } | 530 } |
503 return srcTexture; | 531 return SkImageFilterUtils::WrapTexture(src, rect.width(), rect.height(), dst
); |
504 } | 532 } |
505 | 533 |
506 }; | 534 }; |
507 | 535 |
508 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t SkMatrix& ctm, | 536 bool SkDilateImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, cons
t SkMatrix& ctm, |
509 SkBitmap* result, SkIPoint* offset) { | 537 SkBitmap* result, SkIPoint* offset) { |
510 SkBitmap inputBM; | 538 SkBitmap input; |
511 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
putBM, offset)) { | 539 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, offset)) { |
512 return false; | 540 return false; |
513 } | 541 } |
514 GrTexture* input = inputBM.getTexture(); | |
515 SkIRect bounds; | 542 SkIRect bounds; |
516 src.getBounds(&bounds); | 543 src.getBounds(&bounds); |
517 SkAutoTUnref<GrTexture> resultTex(apply_morphology(input, bounds, | 544 if (!this->applyCropRect(&bounds, ctm)) { |
518 GrMorphologyEffect::kDilate_MorphologyType, radius())); | 545 return false; |
519 return SkImageFilterUtils::WrapTexture(resultTex, src.width(), src.height(),
result); | 546 } |
| 547 int width = radius().width(); |
| 548 int height = radius().height(); |
| 549 |
| 550 if (width < 0 || height < 0) { |
| 551 return false; |
| 552 } |
| 553 |
| 554 if (width == 0 && height == 0) { |
| 555 src.extractSubset(result, bounds); |
| 556 offset->fX += bounds.left(); |
| 557 offset->fY += bounds.top(); |
| 558 return true; |
| 559 } |
| 560 |
| 561 if (!apply_morphology(input, bounds, GrMorphologyEffect::kDilate_MorphologyT
ype, radius(), result)) { |
| 562 return false; |
| 563 } |
| 564 offset->fX += bounds.left(); |
| 565 offset->fY += bounds.top(); |
| 566 return true; |
520 } | 567 } |
521 | 568 |
522 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
SkMatrix& ctm, | 569 bool SkErodeImageFilter::filterImageGPU(Proxy* proxy, const SkBitmap& src, const
SkMatrix& ctm, |
523 SkBitmap* result, SkIPoint* offset) { | 570 SkBitmap* result, SkIPoint* offset) { |
524 SkBitmap inputBM; | 571 SkBitmap input; |
525 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
putBM, offset)) { | 572 if (!SkImageFilterUtils::GetInputResultGPU(getInput(0), proxy, src, ctm, &in
put, offset)) { |
526 return false; | 573 return false; |
527 } | 574 } |
528 GrTexture* input = inputBM.getTexture(); | |
529 SkIRect bounds; | 575 SkIRect bounds; |
530 src.getBounds(&bounds); | 576 src.getBounds(&bounds); |
531 SkAutoTUnref<GrTexture> resultTex(apply_morphology(input, bounds, | 577 if (!this->applyCropRect(&bounds, ctm)) { |
532 GrMorphologyEffect::kErode_MorphologyType, radius())); | 578 return false; |
533 return SkImageFilterUtils::WrapTexture(resultTex, src.width(), src.height(),
result); | 579 } |
| 580 int width = radius().width(); |
| 581 int height = radius().height(); |
| 582 |
| 583 if (width < 0 || height < 0) { |
| 584 return false; |
| 585 } |
| 586 |
| 587 if (width == 0 && height == 0) { |
| 588 src.extractSubset(result, bounds); |
| 589 offset->fX += bounds.left(); |
| 590 offset->fY += bounds.top(); |
| 591 return true; |
| 592 } |
| 593 |
| 594 if (!apply_morphology(input, bounds, GrMorphologyEffect::kErode_MorphologyTy
pe, radius(), result)) { |
| 595 return false; |
| 596 } |
| 597 offset->fX += bounds.left(); |
| 598 offset->fY += bounds.top(); |
| 599 return true; |
534 } | 600 } |
535 | 601 |
536 #endif | 602 #endif |
OLD | NEW |