| 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 |