Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: src/effects/gradients/SkGradientShader.cpp

Issue 395603002: Simplify flattening to just write enough to call the factory (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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;
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
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[0], 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 static uint32_t pack_mode_flags(SkShader::TileMode mode, uint32_t flags) {
129 SkASSERT(0 == (flags >> 28)); 202 SkASSERT(0 == (flags >> 28));
130 SkASSERT(0 == ((uint32_t)mode >> 4)); 203 SkASSERT(0 == ((uint32_t)mode >> 4));
131 return (flags << 4) | mode; 204 return (flags << 4) | mode;
132 } 205 }
133 206
207 #ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING
134 static SkShader::TileMode unpack_mode(uint32_t packed) { 208 static SkShader::TileMode unpack_mode(uint32_t packed) {
135 return (SkShader::TileMode)(packed & 0xF); 209 return (SkShader::TileMode)(packed & 0xF);
136 } 210 }
137 211
138 static uint32_t unpack_flags(uint32_t packed) { 212 static uint32_t unpack_flags(uint32_t packed) {
139 return packed >> 4; 213 return packed >> 4;
140 } 214 }
141 215
142 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) { 216 SkGradientShaderBase::SkGradientShaderBase(SkReadBuffer& buffer) : INHERITED(buf fer) {
143 if (buffer.isVersionLT(SkReadBuffer::kNoUnitMappers_Version)) { 217 if (buffer.isVersionLT(SkReadBuffer::kNoUnitMappers_Version)) {
(...skipping 26 matching lines...) Expand all
170 Rec* recs = fRecs; 244 Rec* recs = fRecs;
171 recs[0].fPos = 0; 245 recs[0].fPos = 0;
172 for (int i = 1; i < colorCount; i++) { 246 for (int i = 1; i < colorCount; i++) {
173 recs[i].fPos = buffer.readInt(); 247 recs[i].fPos = buffer.readInt();
174 recs[i].fScale = buffer.readUInt(); 248 recs[i].fScale = buffer.readUInt();
175 } 249 }
176 } 250 }
177 buffer.readMatrix(&fPtsToUnit); 251 buffer.readMatrix(&fPtsToUnit);
178 this->initCommon(); 252 this->initCommon();
179 } 253 }
254 #endif
180 255
181 SkGradientShaderBase::~SkGradientShaderBase() { 256 SkGradientShaderBase::~SkGradientShaderBase() {
182 if (fOrigColors != fStorage) { 257 if (fOrigColors != fStorage) {
183 sk_free(fOrigColors); 258 sk_free(fOrigColors);
184 } 259 }
185 } 260 }
186 261
187 void SkGradientShaderBase::initCommon() { 262 void SkGradientShaderBase::initCommon() {
188 unsigned colorAlpha = 0xFF; 263 unsigned colorAlpha = 0xFF;
189 for (int i = 0; i < fColorCount; i++) { 264 for (int i = 0; i < fColorCount; i++) {
190 colorAlpha &= SkColorGetA(fOrigColors[i]); 265 colorAlpha &= SkColorGetA(fOrigColors[i]);
191 } 266 }
192 fColorsAreOpaque = colorAlpha == 0xFF; 267 fColorsAreOpaque = colorAlpha == 0xFF;
193 } 268 }
194 269
195 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const { 270 void SkGradientShaderBase::flatten(SkWriteBuffer& buffer) const {
196 this->INHERITED::flatten(buffer); 271 Descriptor desc;
197 buffer.writeColorArray(fOrigColors, fColorCount); 272 desc.fColors = fOrigColors;
198 buffer.writeUInt(pack_mode_flags(fTileMode, fGradFlags)); 273 desc.fPos = fOrigPos;
199 if (fColorCount > 2) { 274 desc.fCount = fColorCount;
200 Rec* recs = fRecs; 275 desc.fTileMode = fTileMode;
201 for (int i = 1; i < fColorCount; i++) { 276 desc.fGradFlags = fGradFlags;
202 buffer.writeInt(recs[i].fPos); 277
203 buffer.writeUInt(recs[i].fScale); 278 const SkMatrix& m = this->getLocalMatrix();
204 } 279 desc.fLocalMatrix = m.isIdentity() ? NULL : &m;
205 } 280 desc.flatten(buffer);
206 buffer.writeMatrix(fPtsToUnit);
207 } 281 }
208 282
209 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const { 283 SkGradientShaderBase::GpuColorType SkGradientShaderBase::getGpuColorType(SkColor colors[3]) const {
210 if (fColorCount <= 3) { 284 if (fColorCount <= 3) {
211 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor)); 285 memcpy(colors, fOrigColors, fColorCount * sizeof(SkColor));
212 } 286 }
213 287
214 if (SkShader::kClamp_TileMode == fTileMode) { 288 if (SkShader::kClamp_TileMode == fTileMode) {
215 if (2 == fColorCount) { 289 if (2 == fColorCount) {
216 return kTwo_GpuColorType; 290 return kTwo_GpuColorType;
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
1148 (*stops)[i] = stop; 1222 (*stops)[i] = stop;
1149 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f; 1223 stop = i < outColors - 1 ? stop + random->nextUScalar1() * (1.f - st op) : 1.f;
1150 } 1224 }
1151 } 1225 }
1152 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount)); 1226 *tm = static_cast<SkShader::TileMode>(random->nextULessThan(SkShader::kTileM odeCount));
1153 1227
1154 return outColors; 1228 return outColors;
1155 } 1229 }
1156 1230
1157 #endif 1231 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698