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
|
From: George Wright <gw@gwright.org.uk>
Date: Thu, 25 Apr 2013 20:47:06 -0400
Subject: Bug 848491 - Re-apply bug 687188 - Expand the gradient cache by 2 to store 0/1 colour stop values for clamping.
diff --git a/gfx/skia/src/effects/gradients/SkGradientShader.cpp b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
index 684355d..27a9c46 100644
--- a/gfx/skia/src/effects/gradients/SkGradientShader.cpp
+++ b/gfx/skia/src/effects/gradients/SkGradientShader.cpp
@@ -453,15 +453,15 @@ const uint16_t* SkGradientShaderBase::getCache16() const {
const SkPMColor* SkGradientShaderBase::getCache32() const {
if (fCache32 == NULL) {
- // double the count for dither entries
- const int entryCount = kCache32Count * 4;
+ // double the count for dither entries, and have an extra two entries for clamp values
+ const int entryCount = kCache32Count * 4 + 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],
kCache32Count, fCacheAlpha);
@@ -484,7 +484,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 < kCache32Count; i++) {
int index = map->mapUnit16((i << 8) | i) >> 8;
@@ -495,9 +495,21 @@ const SkPMColor* SkGradientShaderBase::getCache32() const {
}
fCache32PixelRef->unref();
fCache32PixelRef = newPR;
- fCache32 = (SkPMColor*)newPR->getAddr();
+ fCache32 = (SkPMColor*)newPR->getAddr() + 1;
}
}
+
+ // 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 729ce4e..2cb6a9d 100644
--- a/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
+++ b/gfx/skia/src/effects/gradients/SkGradientShaderPriv.h
@@ -86,6 +86,9 @@ public:
/// if dithering is disabled.
kDitherStride32 = kCache32Count,
kDitherStride16 = kCache16Count,
+
+ kCache32ClampLower = -1,
+ kCache32ClampUpper = kCache32Count * 4
};
diff --git a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
index e0f216c..40ab918 100644
--- a/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
+++ b/gfx/skia/src/effects/gradients/SkLinearGradient.cpp
@@ -127,6 +127,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.
@@ -154,10 +165,7 @@ void shadeSpan_linear_clamp(TileProc proc, SkFixed dx, SkFixed fx,
range.init(fx, dx, count, 0, SkGradientShaderBase::kCache32Count - 1);
if ((count = range.fCount0) > 0) {
- sk_memset32_dither(dstC,
- cache[toggle + range.fV0],
- cache[next_dither_toggle(toggle) + range.fV0],
- count);
+ sk_memset32(dstC, cache[SkGradientShaderBase::kCache32ClampLower], count);
dstC += count;
}
if ((count = range.fCount1) > 0) {
@@ -176,10 +184,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[next_dither_toggle(toggle) + 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 abd974b..601fff4 100644
--- a/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
+++ b/gfx/skia/src/effects/gradients/SkTwoPointConicalGradient.cpp
@@ -124,10 +124,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[toggle +
- (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];
+ }
}
toggle = next_dither_toggle(toggle);
}
diff --git a/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp b/gfx/skia/src/effects/gradients/SkTwoPointRadialGradient.cpp
index f70b67d..ec2ae75 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.7
|