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" |
14 #include "SkMaskFilter.h" | 15 #include "SkMaskFilter.h" |
15 #include "SkRRect.h" | 16 #include "SkRRect.h" |
16 #include "SkRTConf.h" | 17 #include "SkRTConf.h" |
17 #include "SkStringUtils.h" | 18 #include "SkStringUtils.h" |
18 #include "SkStrokeRec.h" | 19 #include "SkStrokeRec.h" |
19 | 20 |
20 #if SK_SUPPORT_GPU | 21 #if SK_SUPPORT_GPU |
21 #include "GrContext.h" | 22 #include "GrContext.h" |
22 #include "GrTexture.h" | 23 #include "GrTexture.h" |
23 #include "GrFragmentProcessor.h" | 24 #include "GrFragmentProcessor.h" |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
251 canvas.drawPath(path, paint); | 252 canvas.drawPath(path, paint); |
252 } | 253 } |
253 return true; | 254 return true; |
254 } | 255 } |
255 | 256 |
256 static bool rect_exceeds(const SkRect& r, SkScalar v) { | 257 static bool rect_exceeds(const SkRect& r, SkScalar v) { |
257 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || | 258 return r.fLeft < -v || r.fTop < -v || r.fRight > v || r.fBottom > v || |
258 r.width() > v || r.height() > v; | 259 r.width() > v || r.height() > v; |
259 } | 260 } |
260 | 261 |
261 #include "SkMaskCache.h" | |
262 | |
263 static bool copy_cacheddata_to_mask(SkCachedData* data, SkMask* mask) { | |
264 const size_t size = data->size(); | |
265 SkASSERT(mask->computeTotalImageSize() <= size); | |
266 | |
267 mask->fImage = SkMask::AllocImage(size); | |
268 if (mask->fImage) { | |
269 memcpy(mask->fImage, data->data(), size); | |
270 return true; | |
271 } | |
272 return false; | |
273 } | |
274 | |
275 static SkCachedData* copy_mask_to_cacheddata(const SkMask& mask) { | |
276 const size_t size = mask.computeTotalImageSize(); | |
277 SkCachedData* data = SkResourceCache::NewCachedData(size); | |
278 if (data) { | |
279 memcpy(data->writable_data(), mask.fImage, size); | |
280 return data; | |
281 } | |
282 return NULL; | |
283 } | |
284 | |
285 static bool find_cached_rrect(SkMask* mask, SkScalar sigma, SkBlurStyle style, | |
286 SkBlurQuality quality, const SkRRect& rrect) { | |
287 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit
y, rrect, mask)); | |
288 return data.get() && copy_cacheddata_to_mask(data, mask); | |
289 } | |
290 | |
291 static void add_cached_rrect(const SkMask& mask, SkScalar sigma, SkBlurStyle sty
le, | |
292 SkBlurQuality quality, const SkRRect& rrect) { | |
293 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); | |
294 if (data.get()) { | |
295 SkMaskCache::Add(sigma, style, quality, rrect, mask, data); | |
296 } | |
297 } | |
298 | |
299 static bool find_cached_rects(SkMask* mask, SkScalar sigma, SkBlurStyle style, | |
300 SkBlurQuality quality, const SkRect rects[], int c
ount) { | |
301 SkAutoTUnref<SkCachedData> data(SkMaskCache::FindAndRef(sigma, style, qualit
y, rects, count, mask)); | |
302 return data.get() && copy_cacheddata_to_mask(data, mask); | |
303 } | |
304 | |
305 static void add_cached_rects(const SkMask& mask, SkScalar sigma, SkBlurStyle sty
le, | |
306 SkBlurQuality quality, const SkRect rects[], int co
unt) { | |
307 SkAutoTUnref<SkCachedData> data(copy_mask_to_cacheddata(mask)); | |
308 if (data.get()) { | |
309 SkMaskCache::Add(sigma, style, quality, rects, count, mask, data); | |
310 } | |
311 } | |
312 | |
313 #ifdef SK_IGNORE_FAST_RRECT_BLUR | 262 #ifdef SK_IGNORE_FAST_RRECT_BLUR |
314 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); | 263 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, false, "Use the faster analytic blur approach for ninepatch rects" ); |
315 #else | 264 #else |
316 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); | 265 SK_CONF_DECLARE( bool, c_analyticBlurRRect, "mask.filter.blur.analyticblurrrect"
, true, "Use the faster analytic blur approach for ninepatch round rects" ); |
317 #endif | 266 #endif |
318 | 267 |
319 SkMaskFilter::FilterReturn | 268 SkMaskFilter::FilterReturn |
320 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, | 269 SkBlurMaskFilterImpl::filterRRectToNine(const SkRRect& rrect, const SkMatrix& ma
trix, |
321 const SkIRect& clipBounds, | 270 const SkIRect& clipBounds, |
322 NinePatch* patch) const { | 271 NinePatch* patch) const { |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 364 |
416 SkRRect smallRR; | 365 SkRRect smallRR; |
417 SkVector radii[4]; | 366 SkVector radii[4]; |
418 radii[SkRRect::kUpperLeft_Corner] = UL; | 367 radii[SkRRect::kUpperLeft_Corner] = UL; |
419 radii[SkRRect::kUpperRight_Corner] = UR; | 368 radii[SkRRect::kUpperRight_Corner] = UR; |
420 radii[SkRRect::kLowerRight_Corner] = LR; | 369 radii[SkRRect::kLowerRight_Corner] = LR; |
421 radii[SkRRect::kLowerLeft_Corner] = LL; | 370 radii[SkRRect::kLowerLeft_Corner] = LL; |
422 smallRR.setRectRadii(smallR, radii); | 371 smallRR.setRectRadii(smallR, radii); |
423 | 372 |
424 const SkScalar sigma = this->computeXformedSigma(matrix); | 373 const SkScalar sigma = this->computeXformedSigma(matrix); |
425 if (!find_cached_rrect(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallRR)) { | 374 if (!SkMaskCache::FindCachedRRect(&patch->fMask, sigma, fBlurStyle, this->ge
tQuality(), smallRR)) { |
426 bool analyticBlurWorked = false; | 375 bool analyticBlurWorked = false; |
427 if (c_analyticBlurRRect) { | 376 if (c_analyticBlurRRect) { |
428 analyticBlurWorked = | 377 analyticBlurWorked = |
429 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, | 378 this->filterRRectMask(&patch->fMask, smallRR, matrix, &margin, |
430 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); | 379 SkMask::kComputeBoundsAndRenderImage_Creat
eMode); |
431 } | 380 } |
432 | 381 |
433 if (!analyticBlurWorked) { | 382 if (!analyticBlurWorked) { |
434 if (!draw_rrect_into_mask(smallRR, &srcM)) { | 383 if (!draw_rrect_into_mask(smallRR, &srcM)) { |
435 return kFalse_FilterReturn; | 384 return kFalse_FilterReturn; |
436 } | 385 } |
437 | 386 |
438 SkAutoMaskFreeImage amf(srcM.fImage); | 387 SkAutoMaskFreeImage amf(srcM.fImage); |
439 | 388 |
440 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 389 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
441 return kFalse_FilterReturn; | 390 return kFalse_FilterReturn; |
442 } | 391 } |
443 } | 392 } |
444 add_cached_rrect(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allRR); | 393 SkMaskCache::AddCachedRRect(patch->fMask, sigma, fBlurStyle, this->getQu
ality(), smallRR); |
445 } | 394 } |
446 | 395 |
447 patch->fMask.fBounds.offsetTo(0, 0); | 396 patch->fMask.fBounds.offsetTo(0, 0); |
448 patch->fOuterRect = dstM.fBounds; | 397 patch->fOuterRect = dstM.fBounds; |
449 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; | 398 patch->fCenter.fX = SkScalarCeilToInt(leftUnstretched) + 1; |
450 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; | 399 patch->fCenter.fY = SkScalarCeilToInt(topUnstretched) + 1; |
451 return kTrue_FilterReturn; | 400 return kTrue_FilterReturn; |
452 } | 401 } |
453 | 402 |
454 SK_CONF_DECLARE( bool, c_analyticBlurNinepatch, "mask.filter.analyticNinePatch",
true, "Use the faster analytic blur approach for ninepatch rects" ); | 403 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... |
545 if (smallR[0].width() < 2 || smallR[0].height() < 2) { | 494 if (smallR[0].width() < 2 || smallR[0].height() < 2) { |
546 return kUnimplemented_FilterReturn; | 495 return kUnimplemented_FilterReturn; |
547 } | 496 } |
548 if (2 == count) { | 497 if (2 == count) { |
549 smallR[1].set(rects[1].left(), rects[1].top(), | 498 smallR[1].set(rects[1].left(), rects[1].top(), |
550 rects[1].right() - dx, rects[1].bottom() - dy); | 499 rects[1].right() - dx, rects[1].bottom() - dy); |
551 SkASSERT(!smallR[1].isEmpty()); | 500 SkASSERT(!smallR[1].isEmpty()); |
552 } | 501 } |
553 | 502 |
554 const SkScalar sigma = this->computeXformedSigma(matrix); | 503 const SkScalar sigma = this->computeXformedSigma(matrix); |
555 if (!find_cached_rects(&patch->fMask, sigma, fBlurStyle, this->getQuality(),
smallR, count)) { | 504 if (!SkMaskCache::FindCachedRects(&patch->fMask, sigma, fBlurStyle, this->ge
tQuality(), smallR, count)) { |
556 if (count > 1 || !c_analyticBlurNinepatch) { | 505 if (count > 1 || !c_analyticBlurNinepatch) { |
557 if (!draw_rects_into_mask(smallR, count, &srcM)) { | 506 if (!draw_rects_into_mask(smallR, count, &srcM)) { |
558 return kFalse_FilterReturn; | 507 return kFalse_FilterReturn; |
559 } | 508 } |
560 | 509 |
561 SkAutoMaskFreeImage amf(srcM.fImage); | 510 SkAutoMaskFreeImage amf(srcM.fImage); |
562 | 511 |
563 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { | 512 if (!this->filterMask(&patch->fMask, srcM, matrix, &margin)) { |
564 return kFalse_FilterReturn; | 513 return kFalse_FilterReturn; |
565 } | 514 } |
566 } else { | 515 } else { |
567 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, | 516 if (!this->filterRectMask(&patch->fMask, smallR[0], matrix, &margin, |
568 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { | 517 SkMask::kComputeBoundsAndRenderImage_Creat
eMode)) { |
569 return kFalse_FilterReturn; | 518 return kFalse_FilterReturn; |
570 } | 519 } |
571 } | 520 } |
572 add_cached_rects(patch->fMask, sigma, fBlurStyle, this->getQuality(), sm
allR, count); | 521 SkMaskCache::AddCachedRects(patch->fMask, sigma, fBlurStyle, this->getQu
ality(), smallR, count); |
573 } | 522 } |
574 patch->fMask.fBounds.offsetTo(0, 0); | 523 patch->fMask.fBounds.offsetTo(0, 0); |
575 patch->fOuterRect = dstM.fBounds; | 524 patch->fOuterRect = dstM.fBounds; |
576 patch->fCenter = center; | 525 patch->fCenter = center; |
577 return kTrue_FilterReturn; | 526 return kTrue_FilterReturn; |
578 } | 527 } |
579 | 528 |
580 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, | 529 void SkBlurMaskFilterImpl::computeFastBounds(const SkRect& src, |
581 SkRect* dst) const { | 530 SkRect* dst) const { |
582 SkScalar pad = 3.0f * fSigma; | 531 SkScalar pad = 3.0f * fSigma; |
(...skipping 685 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 } else { | 1217 } else { |
1269 str->append("None"); | 1218 str->append("None"); |
1270 } | 1219 } |
1271 str->append("))"); | 1220 str->append("))"); |
1272 } | 1221 } |
1273 #endif | 1222 #endif |
1274 | 1223 |
1275 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) | 1224 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkBlurMaskFilter) |
1276 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) | 1225 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkBlurMaskFilterImpl) |
1277 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 1226 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |