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" |
11 #include "SkGpuBlurUtils.h" | 11 #include "SkGpuBlurUtils.h" |
12 #include "SkReadBuffer.h" | 12 #include "SkReadBuffer.h" |
13 #include "SkWriteBuffer.h" | 13 #include "SkWriteBuffer.h" |
14 #include "SkMaskCache.h" | |
15 #include "SkMaskFilter.h" | 14 #include "SkMaskFilter.h" |
16 #include "SkRRect.h" | 15 #include "SkRRect.h" |
17 #include "SkRTConf.h" | 16 #include "SkRTConf.h" |
18 #include "SkStringUtils.h" | 17 #include "SkStringUtils.h" |
19 #include "SkStrokeRec.h" | 18 #include "SkStrokeRec.h" |
20 | 19 |
21 #if SK_SUPPORT_GPU | 20 #if SK_SUPPORT_GPU |
22 #include "GrContext.h" | 21 #include "GrContext.h" |
23 #include "GrTexture.h" | 22 #include "GrTexture.h" |
24 #include "GrFragmentProcessor.h" | 23 #include "GrFragmentProcessor.h" |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
254 canvas.drawPath(path, paint); | 253 canvas.drawPath(path, paint); |
255 } | 254 } |
256 return true; | 255 return true; |
257 } | 256 } |
258 | 257 |
259 static bool rect_exceeds(const SkRect& r, SkScalar v) { | 258 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
260 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 || |
261 r.width() > v || r.height() > v; | 260 r.width() > v || r.height() > v; |
262 } | 261 } |
263 | 262 |
| 263 #include "SkMaskCache.h" |
| 264 |
| 265 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) { |
| 266 const size_t size = data->size(); |
| 267 SkASSERT(mask->computeTotalImageSize() <= size); |
| 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 |
264 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 315 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
265 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" ); |
266 #else | 317 #else |
267 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" ); |
268 #endif | 319 #endif |
269 | 320 |
270 SkMaskFilter::FilterReturn | 321 SkMaskFilter::FilterReturn |
271 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, | 322 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, |
272 const SkIRect& clipBounds, | 323 const SkIRect& clipBounds, |
273 NinePatch* patch) const { | 324 NinePatch* patch) const { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
362 | 413 |
363 SkRRect smallRR; | 414 SkRRect smallRR; |
364 SkVector radii[4]; | 415 SkVector radii[4]; |
365 radii[SkRRect::kUpperLeft_Corner] = UL; | 416 radii[SkRRect::kUpperLeft_Corner] = UL; |
366 radii[SkRRect::kUpperRight_Corner] = UR; | 417 radii[SkRRect::kUpperRight_Corner] = UR; |
367 radii[SkRRect::kLowerRight_Corner] = LR; | 418 radii[SkRRect::kLowerRight_Corner] = LR; |
368 radii[SkRRect::kLowerLeft_Corner] = LL; | 419 radii[SkRRect::kLowerLeft_Corner] = LL; |
369 smallRR.setRectRadii(smallR, radii); | 420 smallRR.setRectRadii(smallR, radii); |
370 | 421 |
371 const SkScalar sigma = this->computeXformedSigma(matrix); | 422 const SkScalar sigma = this->computeXformedSigma(matrix); |
372 if (!SkMaskCache::FindAndCopy(sigma, fBlurStyle, this->getQuality(), smallRR
, &patch->fMask)) { | 423 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallRR)) { |
373 bool analyticBlurWorked = false; | 424 bool analyticBlurWorked = false; |
374 if (c_analyticBlurRRect) { | 425 if (c_analyticBlurRRect) { |
375 analyticBlurWorked = | 426 analyticBlurWorked = |
376 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, | 427 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
377 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); | 428 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); |
378 } | 429 } |
379 | 430 |
380 if (!analyticBlurWorked) { | 431 if (!analyticBlurWorked) { |
381 if (!draw_rrect_into_mask(smallRR, &srcM)) { | 432 if (!draw_rrect_into_mask(smallRR, &srcM)) { |
382 return kFalse_FilterReturn; | 433 return kFalse_FilterReturn; |
383 } | 434 } |
384 | 435 |
385 SkAutoMaskFreeImage amf(srcM.fImage); | 436 SkAutoMaskFreeImage amf(srcM.fImage); |
386 | 437 |
387 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 438 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
388 return kFalse_FilterReturn; | 439 return kFalse_FilterReturn; |
389 } | 440 } |
390 } | 441 } |
391 SkMaskCache::AddAndCopy(sigma, fBlurStyle, this->getQuality(), smallRR,
patch->fMask); | 442 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allRR); |
392 } | 443 } |
393 | 444 |
394 patch->fMask.fBounds.offsetTo(0, 0); | 445 patch->fMask.fBounds.offsetTo(0, 0); |
395 patch->fOuterRect = dstM.fBounds; | 446 patch->fOuterRect = dstM.fBounds; |
396 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 447 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
397 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 448 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
398 return kTrue_FilterReturn; | 449 return kTrue_FilterReturn; |
399 } | 450 } |
400 | 451 |
401 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); | 452 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 if (smallR[0].width() < 2 || smallR[0].height() < 2) { | 543 if (smallR[0].width() < 2 || smallR[0].height() < 2) { |
493 return kUnimplemented_FilterReturn; | 544 return kUnimplemented_FilterReturn; |
494 } | 545 } |
495 if (2 == count) { | 546 if (2 == count) { |
496 smallR[1].set(rects[1].left(), rects[1].top(), | 547 smallR[1].set(rects[1].left(), rects[1].top(), |
497 rects[1].right() - dx, rects[1].bottom() - dy); | 548 rects[1].right() - dx, rects[1].bottom() - dy); |
498 SkASSERT(!smallR[1].isEmpty()); | 549 SkASSERT(!smallR[1].isEmpty()); |
499 } | 550 } |
500 | 551 |
501 const SkScalar sigma = this->computeXformedSigma(matrix); | 552 const SkScalar sigma = this->computeXformedSigma(matrix); |
502 if (!SkMaskCache::FindAndCopy(sigma, fBlurStyle, this->getQuality(), | 553 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallR, count)) { |
503 smallR, count, &patch->fMask)) { | |
504 if (count > 1 || !c_analyticBlurNinepatch) { | 554 if (count > 1 || !c_analyticBlurNinepatch) { |
505 if (!draw_rects_into_mask(smallR, count, &srcM)) { | 555 if (!draw_rects_into_mask(smallR, count, &srcM)) { |
506 return kFalse_FilterReturn; | 556 return kFalse_FilterReturn; |
507 } | 557 } |
508 | 558 |
509 SkAutoMaskFreeImage amf(srcM.fImage); | 559 SkAutoMaskFreeImage amf(srcM.fImage); |
510 | 560 |
511 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 561 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
512 return kFalse_FilterReturn; | 562 return kFalse_FilterReturn; |
513 } | 563 } |
514 } else { | 564 } else { |
515 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | 565 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, |
516 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { | 566 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { |
517 return kFalse_FilterReturn; | 567 return kFalse_FilterReturn; |
518 } | 568 } |
519 } | 569 } |
520 SkMaskCache::AddAndCopy(sigma, fBlurStyle, this->getQuality(), smallR, c
ount, patch->fMask); | 570 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allR, count); |
521 } | 571 } |
522 patch->fMask.fBounds.offsetTo(0, 0); | 572 patch->fMask.fBounds.offsetTo(0, 0); |
523 patch->fOuterRect = dstM.fBounds; | 573 patch->fOuterRect = dstM.fBounds; |
524 patch->fCenter = center; | 574 patch->fCenter = center; |
525 return kTrue_FilterReturn; | 575 return kTrue_FilterReturn; |
526 } | 576 } |
527 | 577 |
528 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 578 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
529 SkRect* dst) const { | 579 SkRect* dst) const { |
530 SkScalar pad = 3.0f * fSigma; | 580 SkScalar pad = 3.0f * fSigma; |
(...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1215 } else { | 1265 } else { |
1216 str->append("None"); | 1266 str->append("None"); |
1217 } | 1267 } |
1218 str->append("))"); | 1268 str->append("))"); |
1219 } | 1269 } |
1220 #endif | 1270 #endif |
1221 | 1271 |
1222 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1272 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1223 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1273 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1224 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1274 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |