1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
|
From 1ab13a923399aa638388231baca784ba89f2c82b Mon Sep 17 00:00:00 2001
From: George Wright <gw@gwright.org.uk>
Date: Wed, 12 Sep 2012 12:30:29 -0400
Subject: [PATCH 5/9] Bug 777614 - Re-apply bug 687188 - Expand the gradient
cache by 2 to store 0/1 colour stop values for
clamping. r=nrc
---
.../src/effects/gradients/SkGradientShader.cpp | 22 +++++++++++----
.../src/effects/gradients/SkGradientShaderPriv.h | 5 +++-
.../src/effects/gradients/SkLinearGradient.cpp | 32 ++++++++++++++++------
.../gradients/SkTwoPointConicalGradient.cpp | 11 ++++++--
.../effects/gradients/SkTwoPointRadialGradient.cpp | 11 ++++++--
5 files changed, 61 insertions(+), 20 deletions(-)
diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
index f0dac4d..79e7202 100644
--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
@@ -426,15 +426,15 @@ static void complete_32bit_cache(SkPMColor* cache, int stride) {
const SkPMColor* SkGradientShaderBase::getCache32() const {
if (fCache32 == NULL) {
- // double the count for dither entries
- const int entryCount = kCache32Count * 2;
+ // double the count for dither entries, and have an extra two entries for clamp values
+ const int entryCount = kCache32Count * 2 + 2;
const size_t allocSize = sizeof(SkPMColor) * entryCount;
if (NULL == fCache32PixelRef) {
fCache32PixelRef = SkNEW_ARGS(SkMallocPixelRef,
(NULL, allocSize, NULL));
}
- fCache32 = (SkPMColor*)fCache32PixelRef->getAddr();
+ fCache32 = (SkPMColor*)fCache32PixelRef->getAddr() + 1;
if (fColorCount == 2) {
Build32bitCache(fCache32, fOrigColors[0], fOrigColors[1],
kGradient32Length, fCacheAlpha);
@@ -458,7 +458,7 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
SkMallocPixelRef* newPR = SkNEW_ARGS(SkMallocPixelRef,
(NULL, allocSize, NULL));
SkPMColor* linear = fCache32; // just computed linear data
- SkPMColor* mapped = (SkPMColor*)newPR->getAddr(); // storage for mapped data
+ SkPMColor* mapped = (SkPMColor*)newPR->getAddr() + 1; // storage for mapped data
SkUnitMapper* map = fMapper;
for (int i = 0; i < kGradient32Length; i++) {
int index = map->mapUnit16((i << 8) | i) >> 8;
@@ -467,10 +467,22 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
}
fCache32PixelRef->unref();
fCache32PixelRef = newPR;
- fCache32 = (SkPMColor*)newPR->getAddr();
+ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
}
complete_32bit_cache(fCache32, kCache32Count);
}
+
+ // Write the clamp colours into the first and last entries of fCache32
+ fCache32[kCache32ClampLower] = SkPackARGB32(fCacheAlpha,
+ SkColorGetR(fOrigColors[0]),
+ SkColorGetG(fOrigColors[0]),
+ SkColorGetB(fOrigColors[0]));
+
+ fCache32[kCache32ClampUpper] = SkPackARGB32(fCacheAlpha,
+ SkColorGetR(fOrigColors[fColorCount - 1]),
+ SkColorGetG(fOrigColors[fColorCount - 1]),
+ SkColorGetB(fOrigColors[fColorCount - 1]));
+
return fCache32;
}
diff --git a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
index 0e7c2fc..7427935 100644
--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
@@ -133,7 +133,10 @@ public:
kDitherStride32 = 0,
#endif
kDitherStride16 = kCache16Count,
- kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1
+ kLerpRemainderMask32 = (1 << (16 - kCache32Bits)) - 1,
+
+ kCache32ClampLower = -1,
+ kCache32ClampUpper = kCache32Count * 2
};
diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
index bcebc26..d400b4d 100644
--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
@@ -126,6 +126,17 @@ void shadeSpan_linear_vertical(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
+ if (proc == clamp_tileproc) {
+ // No need to lerp or dither for clamp values
+ if (fx < 0) {
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
+ return;
+ } else if (fx > 0xffff) {
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
+ return;
+ }
+ }
+
// We're a vertical gradient, so no change in a span.
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
@@ -144,6 +155,17 @@ void shadeSpan_linear_vertical_lerp(TileProc proc, SkFixed dx, SkFixed fx,
SkPMColor* SK_RESTRICT dstC,
const SkPMColor* SK_RESTRICT cache,
int toggle, int count) {
+ if (proc == clamp_tileproc) {
+ // No need to lerp or dither for clamp values
+ if (fx < 0) {
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
+ return;
+ } else if (fx > 0xffff) {
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
+ return;
+ }
+ }
+
// We're a vertical gradient, so no change in a span.
// If colors change sharply across the gradient, dithering is
// insufficient (it subsamples the color space) and we need to lerp.
@@ -169,10 +191,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
range.init(fx, dx, count, 0, SkGradientShaderBase::kGradient32Length);
if ((count = range.fCount0) > 0) {
- sk_memset32_dither(dstC,
- cache[toggle + range.fV0],
- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV0],
- count);
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
dstC += count;
}
if ((count = range.fCount1) > 0) {
@@ -191,10 +210,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
}
}
if ((count = range.fCount2) > 0) {
- sk_memset32_dither(dstC,
- cache[toggle + range.fV1],
- cache[(toggle ^ SkGradientShaderBase::kDitherStride32) + range.fV1],
- count);
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampUpper], count);
}
}
diff --git a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
index 3466d2c..764a444 100644
--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -123,9 +123,14 @@ static void twopoint_clamp(TwoPtRadial* rec, SkPMColor* SK_RESTRICT dstC,
if (TwoPtRadial::DontDrawT(t)) {
*dstC++ = 0;
} else {
- SkFixed index = SkClampMax(t, 0xFFFF);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
+ if (t < 0) {
+ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
+ } else if (t > 0xFFFF) {
+ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
+ } else {
+ SkASSERT(t <= 0xFFFF);
+ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
+ }
}
}
}
diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
index 9362ded..22b028e 100644
--- a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
+++ b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
@@ -120,9 +120,14 @@ void shadeSpan_twopoint_clamp(SkScalar fx, SkScalar dx,
for (; count > 0; --count) {
SkFixed t = two_point_radial(b, fx, fy, fSr2D2, foura,
fOneOverTwoA, posRoot);
- SkFixed index = SkClampMax(t, 0xFFFF);
- SkASSERT(index <= 0xFFFF);
- *dstC++ = cache[index >> SkGradientShaderBase::kCache32Shift];
+ if (t < 0) {
+ *dstC++ = cache[SkGradientShaderBase::kCache32ClampLower];
+ } else if (t > 0xFFFF) {
+ *dstC++ = cache[SkGradientShaderBase::kCache32ClampUpper];
+ } else {
+ SkASSERT(t <= 0xFFFF);
+ *dstC++ = cache[t >> SkGradientShaderBase::kCache32Shift];
+ }
fx += dx;
fy += dy;
b += db;
--
1.7.11.4
|