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

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: rebase 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
« no previous file with comments | « src/effects/SkXfermodeImageFilter.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 buffer.isValid();
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[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
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
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
OLDNEW
« no previous file with comments | « src/effects/SkXfermodeImageFilter.cpp ('k') | src/effects/gradients/SkGradientShaderPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698