| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkBlurMaskFilter.h" | 9 #include "SkBlurMaskFilter.h" |
| 10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 return true; | 255 return true; |
| 256 } | 256 } |
| 257 | 257 |
| 258 static bool rect_exceeds(const SkRect& r, SkScalar v) { | 258 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
| 259 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || | 259 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || |
| 260 r.width() > v || r.height() > v; | 260 r.width() > v || r.height() > v; |
| 261 } | 261 } |
| 262 | 262 |
| 263 #include "SkMaskCache.h" | 263 #include "SkMaskCache.h" |
| 264 | 264 |
| 265 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) { | 265 static SkCachedData* copy_mask_to_cacheddata(SkMask* mask) { |
| 266 const size_t size = data->size(); | 266 const size_t size = mask->computeTotalImageSize(); |
| 267 SkASSERT(mask->computeTotalImageSize() <= size); | 267 SkCachedData* data = SkResourceCache::NewCachedData(size); |
| 268 | 268 if (data) { |
| 269 mask->fImage = SkMask::AllocImage(size); | 269 memcpy(data->writable_data(), mask->fImage, size); |
| 270 if (mask->fImage) { | 270 SkMask::FreeImage(mask->fImage); |
| 271 memcpy(mask->fImage, data->data(), size); | 271 mask->fImage = (uint8_t*)data->data(); |
| 272 return true; | |
| 273 } | 272 } |
| 274 return false; | 273 return data; |
| 275 } | 274 } |
| 276 | 275 |
| 277 static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) { | 276 static SkCachedData* find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle
style, |
| 278 const size_t size = mask.computeTotalImageSize(); | 277 SkBlurQuality quality, const SkRRect& rre
ct) { |
| 279 SkCachedData* data = SkResourceCache::NewCachedData(size); | 278 return SkMaskCache::FindAndRef(sigma, style, quality, rrect, mask); |
| 280 if (data) { | |
| 281 memcpy(data->writable_data(), mask.fImage, size); | |
| 282 return data; | |
| 283 } | |
| 284 return NULL; | |
| 285 } | 279 } |
| 286 | 280 |
| 287 static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style, | 281 static SkCachedData* add_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle
style, |
| 288 SkBlurQuality quality, const SkRRect& rrect) { | 282 SkBlurQuality quality, const SkRRect& rrec
t) { |
| 289 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit
y, rrect, mask)); | 283 SkCachedData* cache = copy_mask_to_cacheddata(mask); |
| 290 return data.get() && copy_cacheddata_to_mask(data, mask); | 284 if (cache) { |
| 285 SkMaskCache::Add(sigma, style, quality, rrect, *mask, cache); |
| 286 } |
| 287 return cache; |
| 291 } | 288 } |
| 292 | 289 |
| 293 static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle sty
le, | 290 static SkCachedData* find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle
style, |
| 294 SkBlurQuality quality, const SkRRect& rrect) { | 291 SkBlurQuality quality, const SkRect rects
[], int count) { |
| 295 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); | 292 return SkMaskCache::FindAndRef(sigma, style, quality, rects, count, mask); |
| 296 if (data.get()) { | |
| 297 SkMaskCache::Add(sigma, style, quality, rrect, mask, data); | |
| 298 } | |
| 299 } | 293 } |
| 300 | 294 |
| 301 static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, | 295 static SkCachedData* add_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle
style, |
| 302 SkBlurQuality quality, const SkRect rects[], int c
ount) { | 296 SkBlurQuality quality, const SkRect rects[
], int count) { |
| 303 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit
y, rects, count, mask)); | 297 SkCachedData* cache = copy_mask_to_cacheddata(mask); |
| 304 return data.get() && copy_cacheddata_to_mask(data, mask); | 298 if (cache) { |
| 305 } | 299 SkMaskCache::Add(sigma, style, quality, rects, count, *mask, cache); |
| 306 | |
| 307 static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle sty
le, | |
| 308 SkBlurQuality quality, const SkRect rects[], int co
unt) { | |
| 309 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); | |
| 310 if (data.get()) { | |
| 311 SkMaskCache::Add(sigma, style, quality, rects, count, mask, data); | |
| 312 } | 300 } |
| 301 return cache; |
| 313 } | 302 } |
| 314 | 303 |
| 315 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 304 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
| 316 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); | 305 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); |
| 317 #else | 306 #else |
| 318 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); | 307 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); |
| 319 #endif | 308 #endif |
| 320 | 309 |
| 321 SkMaskFilter::FilterReturn | 310 SkMaskFilter::FilterReturn |
| 322 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, | 311 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 413 | 402 |
| 414 SkRRect smallRR; | 403 SkRRect smallRR; |
| 415 SkVector radii[4]; | 404 SkVector radii[4]; |
| 416 radii[SkRRect::kUpperLeft_Corner] = UL; | 405 radii[SkRRect::kUpperLeft_Corner] = UL; |
| 417 radii[SkRRect::kUpperRight_Corner] = UR; | 406 radii[SkRRect::kUpperRight_Corner] = UR; |
| 418 radii[SkRRect::kLowerRight_Corner] = LR; | 407 radii[SkRRect::kLowerRight_Corner] = LR; |
| 419 radii[SkRRect::kLowerLeft_Corner] = LL; | 408 radii[SkRRect::kLowerLeft_Corner] = LL; |
| 420 smallRR.setRectRadii(smallR, radii); | 409 smallRR.setRectRadii(smallR, radii); |
| 421 | 410 |
| 422 const SkScalar sigma = this->computeXformedSigma(matrix); | 411 const SkScalar sigma = this->computeXformedSigma(matrix); |
| 423 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallRR)) { | 412 SkCachedData* cache = find_cached_rrect(&patch->fMask, sigma, fBlurStyle, |
| 413 this->getQuality(), smallRR); |
| 414 if (!cache) { |
| 424 bool analyticBlurWorked = false; | 415 bool analyticBlurWorked = false; |
| 425 if (c_analyticBlurRRect) { | 416 if (c_analyticBlurRRect) { |
| 426 analyticBlurWorked = | 417 analyticBlurWorked = |
| 427 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, | 418 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
| 428 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); | 419 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); |
| 429 } | 420 } |
| 430 | 421 |
| 431 if (!analyticBlurWorked) { | 422 if (!analyticBlurWorked) { |
| 432 if (!draw_rrect_into_mask(smallRR, &srcM)) { | 423 if (!draw_rrect_into_mask(smallRR, &srcM)) { |
| 433 return kFalse_FilterReturn; | 424 return kFalse_FilterReturn; |
| 434 } | 425 } |
| 435 | 426 |
| 436 SkAutoMaskFreeImage amf(srcM.fImage); | 427 SkAutoMaskFreeImage amf(srcM.fImage); |
| 437 | 428 |
| 438 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 429 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
| 439 return kFalse_FilterReturn; | 430 return kFalse_FilterReturn; |
| 440 } | 431 } |
| 441 } | 432 } |
| 442 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allRR); | 433 cache = add_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallRR); |
| 443 } | 434 } |
| 444 | 435 |
| 445 patch->fMask.fBounds.offsetTo(0, 0); | 436 patch->fMask.fBounds.offsetTo(0, 0); |
| 446 patch->fOuterRect = dstM.fBounds; | 437 patch->fOuterRect = dstM.fBounds; |
| 447 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 438 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| 448 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 439 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| 440 SkASSERT(NULL == patch->fCache); |
| 441 patch->fCache = cache; // transfer ownership to patch |
| 449 return kTrue_FilterReturn; | 442 return kTrue_FilterReturn; |
| 450 } | 443 } |
| 451 | 444 |
| 452 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); | 445 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); |
| 453 | 446 |
| 454 SkMaskFilter::FilterReturn | 447 SkMaskFilter::FilterReturn |
| 455 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, | 448 SkBlurMaskFilterImpl::filterRectsToNine(const SkRect rects[], int count, |
| 456 const SkMatrix& matrix, | 449 const SkMatrix& matrix, |
| 457 const SkIRect& clipBounds, | 450 const SkIRect& clipBounds, |
| 458 NinePatch* patch) const { | 451 NinePatch* patch) const { |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 543 if (smallR[0].width() < 2 || smallR[0].height() < 2) { | 536 if (smallR[0].width() < 2 || smallR[0].height() < 2) { |
| 544 return kUnimplemented_FilterReturn; | 537 return kUnimplemented_FilterReturn; |
| 545 } | 538 } |
| 546 if (2 == count) { | 539 if (2 == count) { |
| 547 smallR[1].set(rects[1].left(), rects[1].top(), | 540 smallR[1].set(rects[1].left(), rects[1].top(), |
| 548 rects[1].right() - dx, rects[1].bottom() - dy); | 541 rects[1].right() - dx, rects[1].bottom() - dy); |
| 549 SkASSERT(!smallR[1].isEmpty()); | 542 SkASSERT(!smallR[1].isEmpty()); |
| 550 } | 543 } |
| 551 | 544 |
| 552 const SkScalar sigma = this->computeXformedSigma(matrix); | 545 const SkScalar sigma = this->computeXformedSigma(matrix); |
| 553 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallR, count)) { | 546 SkCachedData* cache = find_cached_rects(&patch->fMask, sigma, fBlurStyle, |
| 547 this->getQuality(), smallR, count); |
| 548 if (!cache) { |
| 554 if (count > 1 || !c_analyticBlurNinepatch) { | 549 if (count > 1 || !c_analyticBlurNinepatch) { |
| 555 if (!draw_rects_into_mask(smallR, count, &srcM)) { | 550 if (!draw_rects_into_mask(smallR, count, &srcM)) { |
| 556 return kFalse_FilterReturn; | 551 return kFalse_FilterReturn; |
| 557 } | 552 } |
| 558 | 553 |
| 559 SkAutoMaskFreeImage amf(srcM.fImage); | 554 SkAutoMaskFreeImage amf(srcM.fImage); |
| 560 | 555 |
| 561 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 556 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
| 562 return kFalse_FilterReturn; | 557 return kFalse_FilterReturn; |
| 563 } | 558 } |
| 564 } else { | 559 } else { |
| 565 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | 560 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, |
| 566 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { | 561 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { |
| 567 return kFalse_FilterReturn; | 562 return kFalse_FilterReturn; |
| 568 } | 563 } |
| 569 } | 564 } |
| 570 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allR, count); | 565 cache = add_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQual
ity(), smallR, count); |
| 571 } | 566 } |
| 572 patch->fMask.fBounds.offsetTo(0, 0); | 567 patch->fMask.fBounds.offsetTo(0, 0); |
| 573 patch->fOuterRect = dstM.fBounds; | 568 patch->fOuterRect = dstM.fBounds; |
| 574 patch->fCenter = center; | 569 patch->fCenter = center; |
| 570 SkASSERT(NULL == patch->fCache); |
| 571 patch->fCache = cache; // transfer ownership to patch |
| 575 return kTrue_FilterReturn; | 572 return kTrue_FilterReturn; |
| 576 } | 573 } |
| 577 | 574 |
| 578 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 575 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
| 579 SkRect* dst) const { | 576 SkRect* dst) const { |
| 580 SkScalar pad = 3.0f * fSigma; | 577 SkScalar pad = 3.0f * fSigma; |
| 581 | 578 |
| 582 dst->set(src.fLeft - pad, src.fTop - pad, | 579 dst->set(src.fLeft - pad, src.fTop - pad, |
| 583 src.fRight + pad, src.fBottom + pad); | 580 src.fRight + pad, src.fBottom + pad); |
| 584 } | 581 } |
| (...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1267 } else { | 1264 } else { |
| 1268 str->append("None"); | 1265 str->append("None"); |
| 1269 } | 1266 } |
| 1270 str->append("))"); | 1267 str->append("))"); |
| 1271 } | 1268 } |
| 1272 #endif | 1269 #endif |
| 1273 | 1270 |
| 1274 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1271 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1275 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1272 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1276 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1273 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |