OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkGradientShaderPriv.h" | 8 #include "SkGradientShaderPriv.h" |
9 #include "SkLinearGradient.h" | 9 #include "SkLinearGradient.h" |
10 #include "SkRadialGradient.h" | 10 #include "SkRadialGradient.h" |
11 #include "SkTwoPointRadialGradient.h" | 11 #include "SkTwoPointRadialGradient.h" |
12 #include "SkTwoPointConicalGradient.h" | 12 #include "SkTwoPointConicalGradient.h" |
13 #include "SkSweepGradient.h" | 13 #include "SkSweepGradient.h" |
14 | 14 |
15 void SkGradientShaderBase::Descriptor::flatten(SkWriteBuffer& buffer) const { | |
16 buffer.writeColorArray(fColors, fCount); | |
17 if (fPos) { | |
18 buffer.writeBool(true); | |
19 buffer.writeScalarArray(fPos, fCount); | |
20 } else { | |
21 buffer.writeBool(false); | |
22 } | |
23 buffer.write32(fTileMode); | |
24 buffer.write32(fGradFlags); | |
25 if (fLocalMatrix) { | |
26 buffer.writeBool(true); | |
27 buffer.writeMatrix(*fLocalMatrix); | |
28 } else { | |
29 buffer.writeBool(false); | |
30 } | |
31 } | |
32 | |
33 bool SkGradientShaderBase::DescriptorScope::unflatten(SkReadBuffer& buffer) { | |
34 fCount = buffer.getArrayCount(); | |
35 if (fCount > kStorageCount) { | |
36 size_t allocSize = (sizeof(SkColor) + sizeof(SkScalar)) * fCount; | |
37 fDynamicStorage.reset(allocSize); | |
38 fColors = (SkColor*)fDynamicStorage.get(); | |
39 fPos = (SkScalar*)(fColors + fCount); | |
40 } else { | |
41 fColors = fColorStorage; | |
42 fPos = fPosStorage; | |
43 } | |
44 | |
45 if (!buffer.readColorArray(const_cast<SkColor*>(fColors), fCount)) { | |
46 return false; | |
47 } | |
48 if (buffer.readBool()) { | |
49 if (!buffer.readScalarArray(const_cast<SkScalar*>(fPos), fCount)) { | |
50 return false; | |
51 } | |
52 } else { | |
53 fPos = NULL; | |
54 } | |
55 | |
56 fTileMode = (SkShader::TileMode)buffer.read32(); | |
57 fGradFlags = buffer.read32(); | |
58 | |
59 if (buffer.readBool()) { | |
60 fLocalMatrix = &fLocalMatrixStorage; | |
61 buffer.readMatrix(&fLocalMatrixStorage); | |
62 } else { | |
63 fLocalMatrix = NULL; | |
64 } | |
65 return true; | |
sugoi1
2014/08/19 18:46:18
return buffer.isValid() ?
reed1
2014/08/19 19:58:06
Done.
| |
66 } | |
67 | |
68 //////////////////////////////////////////////////////////////////////////////// //////////// | |
69 | |
15 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) | 70 SkGradientShaderBase::SkGradientShaderBase(const Descriptor& desc) |
16 : INHERITED(desc.fLocalMatrix) | 71 : INHERITED(desc.fLocalMatrix) |
17 { | 72 { |
18 SkASSERT(desc.fCount > 1); | 73 SkASSERT(desc.fCount > 1); |
19 | 74 |
20 fGradFlags = SkToU8(desc.fGradFlags); | 75 fGradFlags = SkToU8(desc.fGradFlags); |
21 | 76 |
22 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); | 77 SkASSERT((unsigned)desc.fTileMode < SkShader::kTileModeCount); |
23 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); | 78 SkASSERT(SkShader::kTileModeCount == SK_ARRAY_COUNT(gTileProcs)); |
24 fTileMode = desc.fTileMode; | 79 fTileMode = desc.fTileMode; |
(...skipping 15 matching lines...) Expand all Loading... | |
40 bool dummyFirst = false; | 95 bool dummyFirst = false; |
41 bool dummyLast = false; | 96 bool dummyLast = false; |
42 if (desc.fPos) { | 97 if (desc.fPos) { |
43 dummyFirst = desc.fPos[0] != 0; | 98 dummyFirst = desc.fPos[0] != 0; |
44 dummyLast = desc.fPos[desc.fCount - 1] != SK_Scalar1; | 99 dummyLast = desc.fPos[desc.fCount - 1] != SK_Scalar1; |
45 fColorCount += dummyFirst + dummyLast; | 100 fColorCount += dummyFirst + dummyLast; |
46 } | 101 } |
47 | 102 |
48 if (fColorCount > kColorStorageCount) { | 103 if (fColorCount > kColorStorageCount) { |
49 size_t size = sizeof(SkColor) + sizeof(Rec); | 104 size_t size = sizeof(SkColor) + sizeof(Rec); |
105 if (desc.fPos) { | |
106 size += sizeof(SkScalar); | |
107 } | |
50 fOrigColors = reinterpret_cast<SkColor*>( | 108 fOrigColors = reinterpret_cast<SkColor*>( |
51 sk_malloc_throw(size * fColorCount)); | 109 sk_malloc_throw(size * fColorCount)); |
52 } | 110 } |
53 else { | 111 else { |
54 fOrigColors = fStorage; | 112 fOrigColors = fStorage; |
55 } | 113 } |
56 | 114 |
57 // Now copy over the colors, adding the dummies as needed | 115 // Now copy over the colors, adding the dummies as needed |
58 { | 116 { |
59 SkColor* origColors = fOrigColors; | 117 SkColor* origColors = fOrigColors; |
60 if (dummyFirst) { | 118 if (dummyFirst) { |
61 *origColors++ = desc.fColors[0]; | 119 *origColors++ = desc.fColors[0]; |
62 } | 120 } |
63 memcpy(origColors, desc.fColors, desc.fCount * sizeof(SkColor)); | 121 memcpy(origColors, desc.fColors, desc.fCount * sizeof(SkColor)); |
64 if (dummyLast) { | 122 if (dummyLast) { |
65 origColors += desc.fCount; | 123 origColors += desc.fCount; |
66 *origColors = desc.fColors[desc.fCount - 1]; | 124 *origColors = desc.fColors[desc.fCount - 1]; |
67 } | 125 } |
68 } | 126 } |
69 | 127 |
70 fRecs = (Rec*)(fOrigColors + fColorCount); | 128 if (desc.fPos && fColorCount) { |
129 fOrigPos = (SkScalar*)(fOrigColors + fColorCount); | |
130 fRecs = (Rec*)(fOrigPos + fColorCount); | |
131 } else { | |
132 fOrigPos = NULL; | |
133 fRecs = (Rec*)(fOrigColors + fColorCount); | |
134 } | |
135 | |
71 if (fColorCount > 2) { | 136 if (fColorCount > 2) { |
72 Rec* recs = fRecs; | 137 Rec* recs = fRecs; |
73 recs->fPos = 0; | 138 recs->fPos = 0; |
74 // recs->fScale = 0; // unused; | 139 // recs->fScale = 0; // unused; |
75 recs += 1; | 140 recs += 1; |
76 if (desc.fPos) { | 141 if (desc.fPos) { |
142 SkScalar* origPosPtr = fOrigPos; | |
143 *origPosPtr++ = 0; | |
144 | |
77 /* We need to convert the user's array of relative positions into | 145 /* We need to convert the user's array of relative positions into |
78 fixed-point positions and scale factors. We need these results | 146 fixed-point positions and scale factors. We need these results |
79 to be strictly monotonic (no two values equal or out of order). | 147 to be strictly monotonic (no two values equal or out of order). |
80 Hence this complex loop that just jams a zero for the scale | 148 Hence this complex loop that just jams a zero for the scale |
81 value if it sees a segment out of order, and it assures that | 149 value if it sees a segment out of order, and it assures that |
82 we start at 0 and end at 1.0 | 150 we start at 0 and end at 1.0 |
83 */ | 151 */ |
84 SkFixed prev = 0; | 152 SkScalar prev = 0; |
85 int startIndex = dummyFirst ? 0 : 1; | 153 int startIndex = dummyFirst ? 0 : 1; |
86 int count = desc.fCount + dummyLast; | 154 int count = desc.fCount + dummyLast; |
87 for (int i = startIndex; i < count; i++) { | 155 for (int i = startIndex; i < count; i++) { |
88 // force the last value to be 1.0 | 156 // force the last value to be 1.0 |
89 SkFixed curr; | 157 SkScalar curr; |
90 if (i == desc.fCount) { // we're really at the dummyLast | 158 if (i == desc.fCount) { // we're really at the dummyLast |
91 curr = SK_Fixed1; | 159 curr = 1; |
92 } else { | 160 } else { |
93 curr = SkScalarToFixed(desc.fPos[i]); | 161 curr = SkScalarPin(desc.fPos[i], 0, 1); |
94 } | 162 } |
95 // pin curr withing range | 163 *origPosPtr++ = curr; |
96 if (curr < 0) { | 164 |
97 curr = 0; | 165 recs->fPos = SkScalarToFixed(curr); |
98 } else if (curr > SK_Fixed1) { | |
99 curr = SK_Fixed1; | |
100 } | |
101 recs->fPos = curr; | |
102 if (curr > prev) { | 166 if (curr > prev) { |
103 recs->fScale = (1 << 24) / (curr - prev); | 167 recs->fScale = (1 << 24) / SkScalarToFixed(curr - prev); |
104 } else { | 168 } else { |
105 recs->fScale = 0; // ignore this segment | 169 recs->fScale = 0; // ignore this segment |
106 } | 170 } |
107 // get ready for the next value | 171 // get ready for the next value |
108 prev = curr; | 172 prev = curr; |
109 recs += 1; | 173 recs += 1; |
110 } | 174 } |
111 } else { // assume even distribution | 175 } else { // assume even distribution |
176 fOrigPos = NULL; | |
177 | |
112 SkFixed dp = SK_Fixed1 / (desc.fCount - 1); | 178 SkFixed dp = SK_Fixed1 / (desc.fCount - 1); |
113 SkFixed p = dp; | 179 SkFixed p = dp; |
114 SkFixed scale = (desc.fCount - 1) << 8; // (1 << 24) / dp | 180 SkFixed scale = (desc.fCount - 1) << 8; // (1 << 24) / dp |
115 for (int i = 1; i < desc.fCount - 1; i++) { | 181 for (int i = 1; i < desc.fCount - 1; i++) { |
116 recs->fPos = p; | 182 recs->fPos = p; |
117 recs->fScale = scale; | 183 recs->fScale = scale; |
118 recs += 1; | 184 recs += 1; |
119 p += dp; | 185 p += dp; |
120 } | 186 } |
121 recs->fPos = SK_Fixed1; | 187 recs->fPos = SK_Fixed1; |
122 recs->fScale = scale; | 188 recs->fScale = scale; |
123 } | 189 } |
190 } else if (desc.fPos) { | |
191 SkASSERT(2 == fColorCount); | |
192 fOrigPos[0] = SkScalarPin(desc.fPos[0], 0, 1); | |
193 fOrigPos[1] = SkScalarPin(desc.fPos[1], fOrigPos[0], 1); | |
194 if (0 == fOrigPos[0] && 1 == fOrigPos[1]) { | |
195 fOrigPos = NULL; | |
196 } | |
124 } | 197 } |
125 this->initCommon(); | 198 this->initCommon(); |
126 } | 199 } |
127 | 200 |
128 static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) { | 201 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING |
129 SkASSERT(0 == (flags >> 28)); | |
130 SkASSERT(0 == ((uint32_t)mode >> 4)); | |
131 return (flags << 4) | mode; | |
132 } | |
133 | |
134 static SkShader::TileMode unpack_mode(uint32_t packed) { | 202 static SkShader::TileMode unpack_mode(uint32_t packed) { |
135 return (SkShader::TileMode)(packed & 0xF); | 203 return (SkShader::TileMode)(packed & 0xF); |
136 } | 204 } |
137 | 205 |
138 static uint32_t unpack_flags(uint32_t packed) { | 206 static uint32_t unpack_flags(uint32_t packed) { |
139 return packed >> 4; | 207 return packed >> 4; |
140 } | 208 } |
141 | 209 |
142 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) { | 210 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) { |
143 if (buffer.isVersionLT(SkReadBuffer::kNoUnitMappers_Version)) { | 211 if (buffer.isVersionLT(SkReadBuffer::kNoUnitMappers_Version)) { |
(...skipping 26 matching lines...) Expand all Loading... | |
170 Rec* recs = fRecs; | 238 Rec* recs = fRecs; |
171 recs[0].fPos = 0; | 239 recs[0].fPos = 0; |
172 for (int i = 1; i < colorCount; i++) { | 240 for (int i = 1; i < colorCount; i++) { |
173 recs[i].fPos = buffer.readInt(); | 241 recs[i].fPos = buffer.readInt(); |
174 recs[i].fScale = buffer.readUInt(); | 242 recs[i].fScale = buffer.readUInt(); |
175 } | 243 } |
176 } | 244 } |
177 buffer.readMatrix(&fPtsToUnit); | 245 buffer.readMatrix(&fPtsToUnit); |
178 this->initCommon(); | 246 this->initCommon(); |
179 } | 247 } |
248 #endif | |
180 | 249 |
181 SkGradientShaderBase::~SkGradientShaderBase() { | 250 SkGradientShaderBase::~SkGradientShaderBase() { |
182 if (fOrigColors != fStorage) { | 251 if (fOrigColors != fStorage) { |
183 sk_free(fOrigColors); | 252 sk_free(fOrigColors); |
184 } | 253 } |
185 } | 254 } |
186 | 255 |
187 void SkGradientShaderBase::initCommon() { | 256 void SkGradientShaderBase::initCommon() { |
188 unsigned colorAlpha = 0xFF; | 257 unsigned colorAlpha = 0xFF; |
189 for (int i = 0; i < fColorCount; i++) { | 258 for (int i = 0; i < fColorCount; i++) { |
190 colorAlpha &= SkColorGetA(fOrigColors[i]); | 259 colorAlpha &= SkColorGetA(fOrigColors[i]); |
191 } | 260 } |
192 fColorsAreOpaque = colorAlpha == 0xFF; | 261 fColorsAreOpaque = colorAlpha == 0xFF; |
193 } | 262 } |
194 | 263 |
195 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { | 264 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { |
196 this->INHERITED::flatten(buffer); | 265 Descriptor desc; |
197 buffer.writeColorArray(fOrigColors, fColorCount); | 266 desc.fColors = fOrigColors; |
198 buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags)); | 267 desc.fPos = fOrigPos; |
199 if (fColorCount > 2) { | 268 desc.fCount = fColorCount; |
200 Rec* recs = fRecs; | 269 desc.fTileMode = fTileMode; |
201 for (int i = 1; i < fColorCount; i++) { | 270 desc.fGradFlags = fGradFlags; |
202 buffer.writeInt(recs[i].fPos); | 271 |
203 buffer.writeUInt(recs[i].fScale); | 272 const SkMatrix& m = this->getLocalMatrix(); |
204 } | 273 desc.fLocalMatrix = m.isIdentity() ? NULL : &m; |
205 } | 274 desc.flatten(buffer); |
206 buffer.writeMatrix(fPtsToUnit); | |
207 } | 275 } |
208 | 276 |
209 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const { | 277 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const { |
210 if (fColorCount <= 3) { | 278 if (fColorCount <= 3) { |
211 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); | 279 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); |
212 } | 280 } |
213 | 281 |
214 if (SkShader::kClamp_TileMode == fTileMode) { | 282 if (SkShader::kClamp_TileMode == fTileMode) { |
215 if (2 == fColorCount) { | 283 if (2 == fColorCount) { |
216 return kTwo_GpuColorType; | 284 return kTwo_GpuColorType; |
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1148 (*stops)[i] = stop; | 1216 (*stops)[i] = stop; |
1149 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; | 1217 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; |
1150 } | 1218 } |
1151 } | 1219 } |
1152 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); | 1220 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); |
1153 | 1221 |
1154 return outColors; | 1222 return outColors; |
1155 } | 1223 } |
1156 | 1224 |
1157 #endif | 1225 #endif |
OLD | NEW |