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 | 9 |
10 #include "SkBlurMask.h" | 10 #include "SkBlurMask.h" |
11 #include "SkMath.h" | 11 #include "SkMath.h" |
12 #include "SkTemplates.h" | 12 #include "SkTemplates.h" |
13 #include "SkEndian.h" | 13 #include "SkEndian.h" |
14 | 14 #include "SkBlurMaskFilter.h" |
15 // scale factor for the blur radius to match the behavior of the all existing bl
ur | |
16 // code (both on the CPU and the GPU). This magic constant is 1/sqrt(3). | |
17 | |
18 // TODO: get rid of this fudge factor and move any required fudging up into | |
19 // the calling library | |
20 | |
21 #define kBlurRadiusFudgeFactor SkFloatToScalar( .57735f ) | |
22 | 15 |
23 #define UNROLL_SEPARABLE_LOOPS | 16 #define UNROLL_SEPARABLE_LOOPS |
24 | 17 |
25 /** | 18 /** |
26 * This function performs a box blur in X, of the given radius. If the | 19 * This function performs a box blur in X, of the given radius. If the |
27 * "transpose" parameter is true, it will transpose the pixels on write, | 20 * "transpose" parameter is true, it will transpose the pixels on write, |
28 * such that X and Y are swapped. Reads are always performed from contiguous | 21 * such that X and Y are swapped. Reads are always performed from contiguous |
29 * memory in X, for speed. The destination buffer (dst) must be at least | 22 * memory in X, for speed. The destination buffer (dst) must be at least |
30 * (width + leftRadius + rightRadius) * height bytes in size. | 23 * (width + leftRadius + rightRadius) * height bytes in size. |
31 * | 24 * |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 | 481 |
489 // Force high quality off for small radii (performance) | 482 // Force high quality off for small radii (performance) |
490 if (radius < SkIntToScalar(3)) { | 483 if (radius < SkIntToScalar(3)) { |
491 quality = kLow_Quality; | 484 quality = kLow_Quality; |
492 } | 485 } |
493 | 486 |
494 // highQuality: use three box blur passes as a cheap way | 487 // highQuality: use three box blur passes as a cheap way |
495 // to approximate a Gaussian blur | 488 // to approximate a Gaussian blur |
496 int passCount = (kHigh_Quality == quality) ? 3 : 1; | 489 int passCount = (kHigh_Quality == quality) ? 3 : 1; |
497 SkScalar passRadius = (kHigh_Quality == quality) ? | 490 SkScalar passRadius = (kHigh_Quality == quality) ? |
498 SkScalarMul( radius, kBlurRadiusFudgeFactor): | 491 SkScalarMul( radius, SkBlurMaskFilter::kBlurRadiusFudg
eFactor): |
499 radius; | 492 radius; |
500 | 493 |
501 int rx = SkScalarCeil(passRadius); | 494 int rx = SkScalarCeil(passRadius); |
502 int outerWeight = 255 - SkScalarRound((SkIntToScalar(rx) - passRadius) * 255
); | 495 int outerWeight = 255 - SkScalarRound((SkIntToScalar(rx) - passRadius) * 255
); |
503 | 496 |
504 SkASSERT(rx >= 0); | 497 SkASSERT(rx >= 0); |
505 SkASSERT((unsigned)outerWeight <= 255); | 498 SkASSERT((unsigned)outerWeight <= 255); |
506 if (rx <= 0) { | 499 if (rx <= 0) { |
507 return false; | 500 return false; |
508 } | 501 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 } | 701 } |
709 | 702 |
710 return profile[ox]; | 703 return profile[ox]; |
711 } | 704 } |
712 | 705 |
713 bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, | 706 bool SkBlurMask::BlurRect(SkMask *dst, const SkRect &src, |
714 SkScalar provided_radius, Style style, | 707 SkScalar provided_radius, Style style, |
715 SkIPoint *margin, SkMask::CreateMode createMode) { | 708 SkIPoint *margin, SkMask::CreateMode createMode) { |
716 int profile_size; | 709 int profile_size; |
717 | 710 |
718 float radius = SkScalarToFloat(SkScalarMul(provided_radius, kBlurRadiusFudge
Factor)); | 711 float radius = SkScalarToFloat(SkScalarMul(provided_radius, SkBlurMaskFilter
::kBlurRadiusFudgeFactor)); |
719 | 712 |
720 // adjust blur radius to match interpretation from boxfilter code | 713 // adjust blur radius to match interpretation from boxfilter code |
721 radius = (radius + .5f) * 2.f; | 714 radius = (radius + .5f) * 2.f; |
722 | 715 |
723 profile_size = compute_profile_size(radius); | 716 profile_size = compute_profile_size(radius); |
724 | 717 |
725 int pad = profile_size/2; | 718 int pad = profile_size/2; |
726 if (margin) { | 719 if (margin) { |
727 margin->set( pad, pad ); | 720 margin->set( pad, pad ); |
728 } | 721 } |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
844 // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but ve
ry | 837 // gaussian kernel. It's "ground truth" in a sense; too slow to be used, but ve
ry |
845 // useful for correctness comparisons. | 838 // useful for correctness comparisons. |
846 | 839 |
847 bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar provid
ed_radius, | 840 bool SkBlurMask::BlurGroundTruth(SkMask* dst, const SkMask& src, SkScalar provid
ed_radius, |
848 Style style, SkIPoint* margin) { | 841 Style style, SkIPoint* margin) { |
849 | 842 |
850 if (src.fFormat != SkMask::kA8_Format) { | 843 if (src.fFormat != SkMask::kA8_Format) { |
851 return false; | 844 return false; |
852 } | 845 } |
853 | 846 |
854 float radius = SkScalarToFloat(SkScalarMul(provided_radius, kBlurRadiusFudge
Factor)); | 847 float radius = SkScalarToFloat(SkScalarMul(provided_radius, SkBlurMaskFilter
::kBlurRadiusFudgeFactor)); |
855 float stddev = SkScalarToFloat(radius) /2.0f; | 848 float stddev = SkScalarToFloat(radius) /2.0f; |
856 float variance = stddev * stddev; | 849 float variance = stddev * stddev; |
857 | 850 |
858 int windowSize = SkScalarCeil(stddev*4); | 851 int windowSize = SkScalarCeil(stddev*4); |
859 // round window size up to nearest odd number | 852 // round window size up to nearest odd number |
860 windowSize |= 1; | 853 windowSize |= 1; |
861 | 854 |
862 SkAutoTMalloc<float> gaussWindow(windowSize); | 855 SkAutoTMalloc<float> gaussWindow(windowSize); |
863 | 856 |
864 int halfWindow = windowSize >> 1; | 857 int halfWindow = windowSize >> 1; |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
982 (void)autoCall.detach(); | 975 (void)autoCall.detach(); |
983 } | 976 } |
984 | 977 |
985 if (style == kInner_Style) { | 978 if (style == kInner_Style) { |
986 dst->fBounds = src.fBounds; // restore trimmed bounds | 979 dst->fBounds = src.fBounds; // restore trimmed bounds |
987 dst->fRowBytes = src.fRowBytes; | 980 dst->fRowBytes = src.fRowBytes; |
988 } | 981 } |
989 | 982 |
990 return true; | 983 return true; |
991 } | 984 } |
OLD | NEW |