1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/patches/0007-Bug-848491-Re-apply-bug-687188-Expand-the-gradient-c.patch Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,168 @@ 1.4 +From: George Wright <gw@gwright.org.uk> 1.5 +Date: Thu, 25 Apr 2013 20:47:06 -0400 1.6 +Subject: Bug 848491 - Re-apply bug 687188 - Expand the gradient cache by 2 to store 0/1 colour stop values for clamping. 1.7 + 1.8 + 1.9 +diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp 1.10 +index 684355d..27a9c46 100644 1.11 +--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp 1.12 ++++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp 1.13 +@@ -453,15 +453,15 @@ const uint16_t* SkGradientShaderBase::getCache16() const { 1.14 + 1.15 + const SkPMColor* SkGradientShaderBase::getCache32() const { 1.16 + if (fCache32 == NULL) { 1.17 +- // double the count for dither entries 1.18 +- const int entryCount = kCache32Count * 4; 1.19 ++ // double the count for dither entries, and have an extra two entries for clamp values 1.20 ++ const int entryCount = kCache32Count * 4 + 2; 1.21 + const size_t allocSize = sizeof(SkPMColor) * entryCount; 1.22 + 1.23 + if (NULL == fCache32PixelRef) { 1.24 + fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef, 1.25 + (NULL, allocSize, NULL)); 1.26 + } 1.27 +- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr(); 1.28 ++ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1; 1.29 + if (fColorCount == 2) { 1.30 + Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1], 1.31 + kCache32Count, fCacheAlpha); 1.32 +@@ -484,7 +484,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { 1.33 + SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef, 1.34 + (NULL, allocSize, NULL)); 1.35 + SkPMColor* linear = fCache32; // just computed linear data 1.36 +- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data 1.37 ++ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data 1.38 + SkUnitMapper* map = fMapper; 1.39 + for (int i = 0; i < kCache32Count; i++) { 1.40 + int index = map->mapUnit16((i << 8) | i) >> 8; 1.41 +@@ -495,9 +495,21 @@ const SkPMColor* SkGradientShaderBase::getCache32() const { 1.42 + } 1.43 + fCache32PixelRef->unref(); 1.44 + fCache32PixelRef = newPR; 1.45 +- fCache32 = (SkPMColor*)newPR->getAddr(); 1.46 ++ fCache32 = (SkPMColor*)newPR->getAddr() + 1; 1.47 + } 1.48 + } 1.49 ++ 1.50 ++ // Write the clamp colours into the first and last entries of fCache32 1.51 ++ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha, 1.52 ++ SkColorGetR(fOrigColors[0]), 1.53 ++ SkColorGetG(fOrigColors[0]), 1.54 ++ SkColorGetB(fOrigColors[0])); 1.55 ++ 1.56 ++ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha, 1.57 ++ SkColorGetR(fOrigColors[fColorCount - 1]), 1.58 ++ SkColorGetG(fOrigColors[fColorCount - 1]), 1.59 ++ SkColorGetB(fOrigColors[fColorCount - 1])); 1.60 ++ 1.61 + return fCache32; 1.62 + } 1.63 + 1.64 +diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h 1.65 +index 729ce4e..2cb6a9d 100644 1.66 +--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h 1.67 ++++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h 1.68 +@@ -86,6 +86,9 @@ public: 1.69 + /// if dithering is disabled. 1.70 + kDitherStride32 = kCache32Count, 1.71 + kDitherStride16 = kCache16Count, 1.72 ++ 1.73 ++ kCache32ClampLower = -1, 1.74 ++ kCache32ClampUpper = kCache32Count * 4 1.75 + }; 1.76 + 1.77 + 1.78 +diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp 1.79 +index e0f216c..40ab918 100644 1.80 +--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp 1.81 ++++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp 1.82 +@@ -127,6 +127,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx, 1.83 + SkPMColor* SK_RESTRICT dstC, 1.84 + const SkPMColor* SK_RESTRICT cache, 1.85 + int toggle, int count) { 1.86 ++ if (proc == clamp_tileproc) { 1.87 ++ // No need to lerp or dither for clamp values 1.88 ++ if (fx < 0) { 1.89 ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); 1.90 ++ return; 1.91 ++ } else if (fx > 0xffff) { 1.92 ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); 1.93 ++ return; 1.94 ++ } 1.95 ++ } 1.96 ++ 1.97 + // We're a vertical gradient, so no change in a span. 1.98 + // If colors change sharply across the gradient, dithering is 1.99 + // insufficient (it subsamples the color space) and we need to lerp. 1.100 +@@ -154,10 +165,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, 1.101 + range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1); 1.102 + 1.103 + if ((count = range.fCount0) > 0) { 1.104 +- sk_memset32_dither(dstC, 1.105 +- cache[toggle + range.fV0], 1.106 +- cache[next_dither_toggle(toggle) + range.fV0], 1.107 +- count); 1.108 ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count); 1.109 + dstC += count; 1.110 + } 1.111 + if ((count = range.fCount1) > 0) { 1.112 +@@ -176,10 +184,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx, 1.113 + } 1.114 + } 1.115 + if ((count = range.fCount2) > 0) { 1.116 +- sk_memset32_dither(dstC, 1.117 +- cache[toggle + range.fV1], 1.118 +- cache[next_dither_toggle(toggle) + range.fV1], 1.119 +- count); 1.120 ++ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count); 1.121 + } 1.122 + } 1.123 + 1.124 +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp 1.125 +index abd974b..601fff4 100644 1.126 +--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp 1.127 ++++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp 1.128 +@@ -124,10 +124,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC, 1.129 + if (TwoPtRadial::DontDrawT(t)) { 1.130 + *dstC++ = 0; 1.131 + } else { 1.132 +- SkFixed index = SkClampMax(t, 0xFFFF); 1.133 +- SkASSERT(index <= 0xFFFF); 1.134 +- *dstC++ = cache[toggle + 1.135 +- (index >> SkGradientShaderBase::kCache32Shift)]; 1.136 ++ if (t < 0) { 1.137 ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; 1.138 ++ } else if (t > 0xFFFF) { 1.139 ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; 1.140 ++ } else { 1.141 ++ SkASSERT(t <= 0xFFFF); 1.142 ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; 1.143 ++ } 1.144 + } 1.145 + toggle = next_dither_toggle(toggle); 1.146 + } 1.147 +diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp 1.148 +index f70b67d..ec2ae75 100644 1.149 +--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp 1.150 ++++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp 1.151 +@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx, 1.152 + for (; count > 0; --count) { 1.153 + SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura, 1.154 + fOneOverTwoA, posRoot); 1.155 +- SkFixed index = SkClampMax(t, 0xFFFF); 1.156 +- SkASSERT(index <= 0xFFFF); 1.157 +- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift]; 1.158 ++ if (t < 0) { 1.159 ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower]; 1.160 ++ } else if (t > 0xFFFF) { 1.161 ++ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper]; 1.162 ++ } else { 1.163 ++ SkASSERT(t <= 0xFFFF); 1.164 ++ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift]; 1.165 ++ } 1.166 + fx += dx; 1.167 + fy += dy; 1.168 + b += db; 1.169 +-- 1.170 +1.7.11.7 1.171 +