OLD | NEW |
| (Empty) |
1 /* libs/graphics/sgl/SkShader.cpp | |
2 ** | |
3 ** Copyright 2006, The Android Open Source Project | |
4 ** | |
5 ** Licensed under the Apache License, Version 2.0 (the "License"); | |
6 ** you may not use this file except in compliance with the License. | |
7 ** You may obtain a copy of the License at | |
8 ** | |
9 ** http://www.apache.org/licenses/LICENSE-2.0 | |
10 ** | |
11 ** Unless required by applicable law or agreed to in writing, software | |
12 ** distributed under the License is distributed on an "AS IS" BASIS, | |
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 ** See the License for the specific language governing permissions and | |
15 ** limitations under the License. | |
16 */ | |
17 | |
18 #include "SkShader.h" | |
19 #include "SkPaint.h" | |
20 | |
21 SkShader::SkShader() : fLocalMatrix(NULL) { | |
22 SkDEBUGCODE(fInSession = false;) | |
23 } | |
24 | |
25 SkShader::SkShader(SkFlattenableReadBuffer& buffer) | |
26 : INHERITED(buffer), fLocalMatrix(NULL) { | |
27 if (buffer.readBool()) { | |
28 SkMatrix matrix; | |
29 buffer.read(&matrix, sizeof(matrix)); | |
30 setLocalMatrix(matrix); | |
31 } | |
32 SkDEBUGCODE(fInSession = false;) | |
33 } | |
34 | |
35 SkShader::~SkShader() { | |
36 SkASSERT(!fInSession); | |
37 sk_free(fLocalMatrix); | |
38 } | |
39 | |
40 void SkShader::beginSession() { | |
41 SkASSERT(!fInSession); | |
42 SkDEBUGCODE(fInSession = true;) | |
43 } | |
44 | |
45 void SkShader::endSession() { | |
46 SkASSERT(fInSession); | |
47 SkDEBUGCODE(fInSession = false;) | |
48 } | |
49 | |
50 void SkShader::flatten(SkFlattenableWriteBuffer& buffer) { | |
51 this->INHERITED::flatten(buffer); | |
52 buffer.writeBool(fLocalMatrix != NULL); | |
53 if (fLocalMatrix) { | |
54 buffer.writeMul4(fLocalMatrix, sizeof(SkMatrix)); | |
55 } | |
56 } | |
57 | |
58 bool SkShader::getLocalMatrix(SkMatrix* localM) const { | |
59 if (fLocalMatrix) { | |
60 if (localM) { | |
61 *localM = *fLocalMatrix; | |
62 } | |
63 return true; | |
64 } else { | |
65 if (localM) { | |
66 localM->reset(); | |
67 } | |
68 return false; | |
69 } | |
70 } | |
71 | |
72 void SkShader::setLocalMatrix(const SkMatrix& localM) { | |
73 if (localM.isIdentity()) { | |
74 this->resetLocalMatrix(); | |
75 } else { | |
76 if (fLocalMatrix == NULL) { | |
77 fLocalMatrix = (SkMatrix*)sk_malloc_throw(sizeof(SkMatrix)); | |
78 } | |
79 *fLocalMatrix = localM; | |
80 } | |
81 } | |
82 | |
83 void SkShader::resetLocalMatrix() { | |
84 if (fLocalMatrix) { | |
85 sk_free(fLocalMatrix); | |
86 fLocalMatrix = NULL; | |
87 } | |
88 } | |
89 | |
90 bool SkShader::setContext(const SkBitmap& device, | |
91 const SkPaint& paint, | |
92 const SkMatrix& matrix) { | |
93 const SkMatrix* m = &matrix; | |
94 SkMatrix total; | |
95 | |
96 fDeviceConfig = SkToU8(device.getConfig()); | |
97 fPaintAlpha = paint.getAlpha(); | |
98 if (fLocalMatrix) { | |
99 total.setConcat(matrix, *fLocalMatrix); | |
100 m = &total; | |
101 } | |
102 if (m->invert(&fTotalInverse)) { | |
103 fTotalInverseClass = (uint8_t)ComputeMatrixClass(fTotalInverse); | |
104 return true; | |
105 } | |
106 return false; | |
107 } | |
108 | |
109 #include "SkColorPriv.h" | |
110 | |
111 void SkShader::shadeSpan16(int x, int y, uint16_t span16[], int count) { | |
112 SkASSERT(span16); | |
113 SkASSERT(count > 0); | |
114 SkASSERT(this->canCallShadeSpan16()); | |
115 | |
116 // basically, if we get here, the subclass screwed up | |
117 SkASSERT(!"kHasSpan16 flag is set, but shadeSpan16() not implemented"); | |
118 } | |
119 | |
120 #define kTempColorQuadCount 6 // balance between speed (larger) and saving sta
ck-space | |
121 #define kTempColorCount (kTempColorQuadCount << 2) | |
122 | |
123 #ifdef SK_CPU_BENDIAN | |
124 #define SkU32BitShiftToByteOffset(shift) (3 - ((shift) >> 3)) | |
125 #else | |
126 #define SkU32BitShiftToByteOffset(shift) ((shift) >> 3) | |
127 #endif | |
128 | |
129 void SkShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { | |
130 SkASSERT(count > 0); | |
131 | |
132 SkPMColor colors[kTempColorCount]; | |
133 | |
134 while ((count -= kTempColorCount) >= 0) { | |
135 this->shadeSpan(x, y, colors, kTempColorCount); | |
136 x += kTempColorCount; | |
137 | |
138 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset
(SK_A32_SHIFT); | |
139 int quads = kTempColorQuadCount; | |
140 do { | |
141 U8CPU a0 = srcA[0]; | |
142 U8CPU a1 = srcA[4]; | |
143 U8CPU a2 = srcA[8]; | |
144 U8CPU a3 = srcA[12]; | |
145 srcA += 4*4; | |
146 *alpha++ = SkToU8(a0); | |
147 *alpha++ = SkToU8(a1); | |
148 *alpha++ = SkToU8(a2); | |
149 *alpha++ = SkToU8(a3); | |
150 } while (--quads != 0); | |
151 } | |
152 SkASSERT(count < 0); | |
153 SkASSERT(count + kTempColorCount >= 0); | |
154 if (count += kTempColorCount) { | |
155 this->shadeSpan(x, y, colors, count); | |
156 | |
157 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset
(SK_A32_SHIFT); | |
158 do { | |
159 *alpha++ = *srcA; | |
160 srcA += 4; | |
161 } while (--count != 0); | |
162 } | |
163 #if 0 | |
164 do { | |
165 int n = count; | |
166 if (n > kTempColorCount) | |
167 n = kTempColorCount; | |
168 SkASSERT(n > 0); | |
169 | |
170 this->shadeSpan(x, y, colors, n); | |
171 x += n; | |
172 count -= n; | |
173 | |
174 const uint8_t* srcA = (const uint8_t*)colors + SkU32BitShiftToByteOffset
(SK_A32_SHIFT); | |
175 do { | |
176 *alpha++ = *srcA; | |
177 srcA += 4; | |
178 } while (--n != 0); | |
179 } while (count > 0); | |
180 #endif | |
181 } | |
182 | |
183 SkShader::MatrixClass SkShader::ComputeMatrixClass(const SkMatrix& mat) { | |
184 MatrixClass mc = kLinear_MatrixClass; | |
185 | |
186 if (mat.getType() & SkMatrix::kPerspective_Mask) { | |
187 if (mat.fixedStepInX(0, NULL, NULL)) { | |
188 mc = kFixedStepInX_MatrixClass; | |
189 } else { | |
190 mc = kPerspective_MatrixClass; | |
191 } | |
192 } | |
193 return mc; | |
194 } | |
195 | |
196 ////////////////////////////////////////////////////////////////////////////// | |
197 | |
198 bool SkShader::asABitmap(SkBitmap*, SkMatrix*, TileMode*) { | |
199 return false; | |
200 } | |
201 | |
202 SkShader* SkShader::CreateBitmapShader(const SkBitmap& src, | |
203 TileMode tmx, TileMode tmy) { | |
204 return SkShader::CreateBitmapShader(src, tmx, tmy, NULL, 0); | |
205 } | |
206 | |
207 ////////////////////////////////////////////////////////////////////////////// | |
208 | |
209 #include "SkColorShader.h" | |
210 #include "SkUtils.h" | |
211 | |
212 SkColorShader::SkColorShader(SkFlattenableReadBuffer& b) : INHERITED(b) { | |
213 fInheritColor = b.readU8(); | |
214 if (fInheritColor) { | |
215 return; | |
216 } | |
217 fColor = b.readU32(); | |
218 } | |
219 | |
220 void SkColorShader::flatten(SkFlattenableWriteBuffer& buffer) { | |
221 this->INHERITED::flatten(buffer); | |
222 buffer.write8(fInheritColor); | |
223 if (fInheritColor) { | |
224 return; | |
225 } | |
226 buffer.write32(fColor); | |
227 } | |
228 | |
229 uint32_t SkColorShader::getFlags() { | |
230 return (SkGetPackedA32(fPMColor) == 255 ? kOpaqueAlpha_Flag : 0) | | |
231 kHasSpan16_Flag; | |
232 } | |
233 | |
234 uint8_t SkColorShader::getSpan16Alpha() const { | |
235 return SkGetPackedA32(fPMColor); | |
236 } | |
237 | |
238 bool SkColorShader::setContext(const SkBitmap& device, const SkPaint& paint, | |
239 const SkMatrix& matrix) { | |
240 if (!this->INHERITED::setContext(device, paint, matrix)) { | |
241 return false; | |
242 } | |
243 | |
244 SkColor c; | |
245 unsigned a; | |
246 | |
247 if (fInheritColor) { | |
248 c = paint.getColor(); | |
249 a = SkColorGetA(c); | |
250 } else { | |
251 c = fColor; | |
252 a = SkAlphaMul(SkColorGetA(c), SkAlpha255To256(paint.getAlpha())); | |
253 } | |
254 | |
255 unsigned r = SkColorGetR(c); | |
256 unsigned g = SkColorGetG(c); | |
257 unsigned b = SkColorGetB(c); | |
258 | |
259 // we want this before we apply any alpha | |
260 fColor16 = SkPack888ToRGB16(r, g, b); | |
261 | |
262 if (a != 255) { | |
263 a = SkAlpha255To256(a); | |
264 r = SkAlphaMul(r, a); | |
265 g = SkAlphaMul(g, a); | |
266 b = SkAlphaMul(b, a); | |
267 } | |
268 fPMColor = SkPackARGB32(a, r, g, b); | |
269 | |
270 return true; | |
271 } | |
272 | |
273 void SkColorShader::shadeSpan(int x, int y, SkPMColor span[], int count) { | |
274 sk_memset32(span, fPMColor, count); | |
275 } | |
276 | |
277 void SkColorShader::shadeSpan16(int x, int y, uint16_t span[], int count) { | |
278 sk_memset16(span, fColor16, count); | |
279 } | |
280 | |
281 void SkColorShader::shadeSpanAlpha(int x, int y, uint8_t alpha[], int count) { | |
282 memset(alpha, SkGetPackedA32(fPMColor), count); | |
283 } | |
284 | |
OLD | NEW |