Chromium Code Reviews| 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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 250 canvas.drawPath(path, paint); | 250 canvas.drawPath(path, paint); |
| 251 } | 251 } |
| 252 return true; | 252 return true; |
| 253 } | 253 } |
| 254 | 254 |
| 255 static bool rect_exceeds(const SkRect& r, SkScalar v) { | 255 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
| 256 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || | 256 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || |
| 257 r.width() > v || r.height() > v; | 257 r.width() > v || r.height() > v; |
| 258 } | 258 } |
| 259 | 259 |
| 260 #include "SkMaskCache.h" | |
| 261 | |
| 262 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) { | |
| 263 const size_t size = data->size(); | |
| 264 #ifdef SK_DEBUG | |
| 265 const size_t computed_size = mask->computeTotalImageSize(); | |
| 266 SkASSERT(computed_size <= size); | |
|
mtklein
2014/10/23 18:18:10
Might just
SkASSERT(mask->computeTotalImageSize()
reed1
2014/10/23 19:22:51
Done.
| |
| 267 #endif | |
| 268 | |
| 269 mask->fImage = SkMask::AllocImage(size); | |
| 270 if (mask->fImage) { | |
| 271 memcpy(mask->fImage, data->data(), size); | |
| 272 return true; | |
| 273 } | |
| 274 return false; | |
| 275 } | |
| 276 | |
| 277 static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) { | |
| 278 const size_t size = mask.computeTotalImageSize(); | |
| 279 SkCachedData* data = SkResourceCache::NewCachedData(size); | |
| 280 if (data) { | |
| 281 memcpy(data->writable_data(), mask.fImage, size); | |
| 282 return data; | |
| 283 } | |
| 284 return NULL; | |
| 285 } | |
| 286 | |
| 287 static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style, | |
| 288 SkBlurQuality quality, const SkRRect& rrect) { | |
| 289 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rrect, mask)); | |
| 290 return data.get() && copy_cacheddata_to_mask(data, mask); | |
| 291 } | |
| 292 | |
| 293 static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle sty le, | |
| 294 SkBlurQuality quality, const SkRRect& rrect) { | |
| 295 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); | |
| 296 if (data.get()) { | |
| 297 SkMaskCache::Add(sigma, style, quality, rrect, mask, data); | |
| 298 } | |
| 299 } | |
| 300 | |
| 301 static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, | |
| 302 SkBlurQuality quality, const SkRect rects[], int c ount) { | |
| 303 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit y, rects, count, mask)); | |
| 304 return data.get() && copy_cacheddata_to_mask(data, mask); | |
| 305 } | |
| 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 } | |
| 313 } | |
| 314 | |
| 260 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 315 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
| 261 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" ); | 316 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , false, "Use the faster analytic blur approach for ninepatch rects" ); |
| 262 #else | 317 #else |
| 263 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" ); | 318 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect" , true, "Use the faster analytic blur approach for ninepatch round rects" ); |
| 264 #endif | 319 #endif |
| 265 | 320 |
| 266 SkMaskFilter::FilterReturn | 321 SkMaskFilter::FilterReturn |
| 267 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, | 322 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma trix, |
| 268 const SkIRect& clipBounds, | 323 const SkIRect& clipBounds, |
| 269 NinePatch* patch) const { | 324 NinePatch* patch) const { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 361 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); | 416 SkRect smallR = SkRect::MakeWH(totalSmallWidth, totalSmallHeight); |
| 362 | 417 |
| 363 SkRRect smallRR; | 418 SkRRect smallRR; |
| 364 SkVector radii[4]; | 419 SkVector radii[4]; |
| 365 radii[SkRRect::kUpperLeft_Corner] = UL; | 420 radii[SkRRect::kUpperLeft_Corner] = UL; |
| 366 radii[SkRRect::kUpperRight_Corner] = UR; | 421 radii[SkRRect::kUpperRight_Corner] = UR; |
| 367 radii[SkRRect::kLowerRight_Corner] = LR; | 422 radii[SkRRect::kLowerRight_Corner] = LR; |
| 368 radii[SkRRect::kLowerLeft_Corner] = LL; | 423 radii[SkRRect::kLowerLeft_Corner] = LL; |
| 369 smallRR.setRectRadii(smallR, radii); | 424 smallRR.setRectRadii(smallR, radii); |
| 370 | 425 |
| 371 bool analyticBlurWorked = false; | 426 const SkScalar sigma = this->computeXformedSigma(matrix); |
| 372 if (c_analyticBlurRRect) { | 427 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(), smallRR)) { |
| 373 analyticBlurWorked = | 428 bool analyticBlurWorked = false; |
| 374 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, | 429 if (c_analyticBlurRRect) { |
| 375 SkMask::kComputeBoundsAndRenderImage_CreateMod e); | 430 analyticBlurWorked = |
| 376 } | 431 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
| 377 | 432 SkMask::kComputeBoundsAndRenderImage_Creat eMode); |
| 378 if (!analyticBlurWorked) { | |
| 379 if (!draw_rrect_into_mask(smallRR, &srcM)) { | |
| 380 return kFalse_FilterReturn; | |
| 381 } | 433 } |
| 382 | 434 |
| 383 SkAutoMaskFreeImage amf(srcM.fImage); | 435 if (!analyticBlurWorked) { |
| 436 if (!draw_rrect_into_mask(smallRR, &srcM)) { | |
| 437 return kFalse_FilterReturn; | |
| 438 } | |
| 384 | 439 |
| 385 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 440 SkAutoMaskFreeImage amf(srcM.fImage); |
| 386 return kFalse_FilterReturn; | 441 |
| 442 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | |
| 443 return kFalse_FilterReturn; | |
| 444 } | |
| 387 } | 445 } |
| 446 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm allRR); | |
| 388 } | 447 } |
| 389 | 448 |
| 390 patch->fMask.fBounds.offsetTo(0, 0); | 449 patch->fMask.fBounds.offsetTo(0, 0); |
| 391 patch->fOuterRect = dstM.fBounds; | 450 patch->fOuterRect = dstM.fBounds; |
| 392 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 451 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
| 393 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 452 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
| 394 return kTrue_FilterReturn; | 453 return kTrue_FilterReturn; |
| 395 } | 454 } |
| 396 | 455 |
| 397 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); | 456 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch", true, "Use the faster analytic blur approach for ninepatch rects" ); |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 487 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy); | 546 smallR[0].set(rects[0].left(), rects[0].top(), rects[0].right() - dx, rects[ 0].bottom() - dy); |
| 488 if (smallR[0].width() < 2 || smallR[0].height() < 2) { | 547 if (smallR[0].width() < 2 || smallR[0].height() < 2) { |
| 489 return kUnimplemented_FilterReturn; | 548 return kUnimplemented_FilterReturn; |
| 490 } | 549 } |
| 491 if (2 == count) { | 550 if (2 == count) { |
| 492 smallR[1].set(rects[1].left(), rects[1].top(), | 551 smallR[1].set(rects[1].left(), rects[1].top(), |
| 493 rects[1].right() - dx, rects[1].bottom() - dy); | 552 rects[1].right() - dx, rects[1].bottom() - dy); |
| 494 SkASSERT(!smallR[1].isEmpty()); | 553 SkASSERT(!smallR[1].isEmpty()); |
| 495 } | 554 } |
| 496 | 555 |
| 497 if (count > 1 || !c_analyticBlurNinepatch) { | 556 const SkScalar sigma = this->computeXformedSigma(matrix); |
| 498 if (!draw_rects_into_mask(smallR, count, &srcM)) { | 557 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(), rects, count)) { |
| 499 return kFalse_FilterReturn; | 558 if (count > 1 || !c_analyticBlurNinepatch) { |
| 559 if (!draw_rects_into_mask(smallR, count, &srcM)) { | |
| 560 return kFalse_FilterReturn; | |
| 561 } | |
| 562 | |
| 563 SkAutoMaskFreeImage amf(srcM.fImage); | |
| 564 | |
| 565 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | |
| 566 return kFalse_FilterReturn; | |
| 567 } | |
| 568 } else { | |
| 569 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | |
| 570 SkMask::kComputeBoundsAndRenderImage_Creat eMode)) { | |
| 571 return kFalse_FilterReturn; | |
| 572 } | |
| 500 } | 573 } |
| 501 | 574 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), re cts, count); |
| 502 SkAutoMaskFreeImage amf(srcM.fImage); | |
| 503 | |
| 504 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | |
| 505 return kFalse_FilterReturn; | |
| 506 } | |
| 507 } else { | |
| 508 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | |
| 509 SkMask::kComputeBoundsAndRenderImage_CreateMod e)) { | |
| 510 return kFalse_FilterReturn; | |
| 511 } | |
| 512 } | 575 } |
| 513 patch->fMask.fBounds.offsetTo(0, 0); | 576 patch->fMask.fBounds.offsetTo(0, 0); |
| 514 patch->fOuterRect = dstM.fBounds; | 577 patch->fOuterRect = dstM.fBounds; |
| 515 patch->fCenter = center; | 578 patch->fCenter = center; |
| 516 return kTrue_FilterReturn; | 579 return kTrue_FilterReturn; |
| 517 } | 580 } |
| 518 | 581 |
| 519 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 582 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
| 520 SkRect* dst) const { | 583 SkRect* dst) const { |
| 521 SkScalar pad = 3.0f * fSigma; | 584 SkScalar pad = 3.0f * fSigma; |
| (...skipping 696 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1218 } else { | 1281 } else { |
| 1219 str->append("None"); | 1282 str->append("None"); |
| 1220 } | 1283 } |
| 1221 str->append("))"); | 1284 str->append("))"); |
| 1222 } | 1285 } |
| 1223 #endif | 1286 #endif |
| 1224 | 1287 |
| 1225 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1288 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
| 1226 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1289 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
| 1227 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1290 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
| OLD | NEW |