| 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 |