OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2012 The Android Open Source Project | 2 * Copyright 2012 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 "SkLightingImageFilter.h" | 8 #include "SkLightingImageFilter.h" |
9 #include "SkBitmap.h" | 9 #include "SkBitmap.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
178 sobel(m[0], m[3], m[1], m[4], m[2], m[5], gOneHalf), | 178 sobel(m[0], m[3], m[1], m[4], m[2], m[5], gOneHalf), |
179 surfaceScale); | 179 surfaceScale); |
180 } | 180 } |
181 | 181 |
182 inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) { | 182 inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) { |
183 return pointToNormal(sobel(m[0], m[1], m[3], m[4], 0, 0, gTwoThirds), | 183 return pointToNormal(sobel(m[0], m[1], m[3], m[4], 0, 0, gTwoThirds), |
184 sobel(m[0], m[3], m[1], m[4], 0, 0, gTwoThirds), | 184 sobel(m[0], m[3], m[1], m[4], 0, 0, gTwoThirds), |
185 surfaceScale); | 185 surfaceScale); |
186 } | 186 } |
187 | 187 |
188 template <class LightingType, class LightType> void lightBitmap(const LightingTy pe& lightingType, | 188 |
189 const SkImageFil terLight* light, | 189 class UncheckedPixelFetcher { |
190 const SkBitmap& src, | 190 public: |
robertphillips
2016/02/16 20:19:46
Fetch ?
Stephen White
2016/02/16 20:54:08
Done.
| |
191 SkBitmap* dst, | 191 static inline uint32_t fetch(const SkBitmap& src, int x, int y, const SkIRec t& bounds) { |
192 SkScalar surface Scale, | 192 return SkGetPackedA32(*src.getAddr32(x, y)); |
193 const SkIRect& b ounds) { | 193 } |
194 }; | |
195 | |
robertphillips
2016/02/16 20:19:46
// The DecalPixelFetcher is used to implement the
Stephen White
2016/02/16 20:54:08
Almost; done. :)
| |
196 class DecalPixelFetcher { | |
197 public: | |
robertphillips
2016/02/16 20:19:46
Fetch ?
Stephen White
2016/02/16 20:54:08
Done.
| |
198 static inline uint32_t fetch(const SkBitmap& src, int x, int y, const SkIRec t& bounds) { | |
199 if (x < bounds.fLeft || x >= bounds.fRight || y < bounds.fTop || y >= bo unds.fBottom) { | |
200 return 0; | |
201 } else { | |
202 return SkGetPackedA32(*src.getAddr32(x, y)); | |
203 } | |
204 } | |
205 }; | |
206 | |
207 template <class LightingType, class LightType, class PixelFetcher> | |
208 void lightBitmap(const LightingType& lightingType, | |
209 const SkImageFilterLight* light, | |
210 const SkBitmap& src, | |
211 SkBitmap* dst, | |
212 SkScalar surfaceScale, | |
213 const SkIRect& bounds) { | |
194 SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height()) ; | 214 SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height()) ; |
195 const LightType* l = static_cast<const LightType*>(light); | 215 const LightType* l = static_cast<const LightType*>(light); |
196 int left = bounds.left(), right = bounds.right(); | 216 int left = bounds.left(), right = bounds.right(); |
197 int bottom = bounds.bottom(); | 217 int bottom = bounds.bottom(); |
198 int y = bounds.top(); | 218 int y = bounds.top(); |
219 SkIRect srcBounds = src.bounds(); | |
199 SkPMColor* dptr = dst->getAddr32(0, 0); | 220 SkPMColor* dptr = dst->getAddr32(0, 0); |
200 { | 221 { |
201 int x = left; | 222 int x = left; |
202 const SkPMColor* row1 = src.getAddr32(x, y); | |
203 const SkPMColor* row2 = src.getAddr32(x, y + 1); | |
204 int m[9]; | 223 int m[9]; |
205 m[4] = SkGetPackedA32(*row1++); | 224 m[4] = PixelFetcher::fetch(src, x, y, srcBounds); |
206 m[5] = SkGetPackedA32(*row1++); | 225 m[5] = PixelFetcher::fetch(src, x + 1, y, srcBounds); |
207 m[7] = SkGetPackedA32(*row2++); | 226 m[7] = PixelFetcher::fetch(src, x, y + 1, srcBounds); |
208 m[8] = SkGetPackedA32(*row2++); | 227 m[8] = PixelFetcher::fetch(src, x + 1, y + 1, srcBounds); |
209 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 228 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
210 *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLi ght, | 229 *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLi ght, |
211 l->lightColor(surfaceToLight)); | 230 l->lightColor(surfaceToLight)); |
212 for (++x; x < right - 1; ++x) | 231 for (++x; x < right - 1; ++x) |
213 { | 232 { |
214 shiftMatrixLeft(m); | 233 shiftMatrixLeft(m); |
215 m[5] = SkGetPackedA32(*row1++); | 234 m[5] = PixelFetcher::fetch(src, x + 1, y, srcBounds); |
216 m[8] = SkGetPackedA32(*row2++); | 235 m[8] = PixelFetcher::fetch(src, x + 1, y + 1, srcBounds); |
217 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 236 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
218 *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLi ght, | 237 *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLi ght, |
219 l->lightColor(surfaceToLight)); | 238 l->lightColor(surfaceToLight)); |
220 } | 239 } |
221 shiftMatrixLeft(m); | 240 shiftMatrixLeft(m); |
222 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 241 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
223 *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToL ight, | 242 *dptr++ = lightingType.light(topRightNormal(m, surfaceScale), surfaceToL ight, |
224 l->lightColor(surfaceToLight)); | 243 l->lightColor(surfaceToLight)); |
225 } | 244 } |
226 | 245 |
227 for (++y; y < bottom - 1; ++y) { | 246 for (++y; y < bottom - 1; ++y) { |
228 int x = left; | 247 int x = left; |
229 const SkPMColor* row0 = src.getAddr32(x, y - 1); | |
230 const SkPMColor* row1 = src.getAddr32(x, y); | |
231 const SkPMColor* row2 = src.getAddr32(x, y + 1); | |
232 int m[9]; | 248 int m[9]; |
233 m[1] = SkGetPackedA32(*row0++); | 249 m[1] = PixelFetcher::fetch(src, x, y - 1, srcBounds); |
234 m[2] = SkGetPackedA32(*row0++); | 250 m[2] = PixelFetcher::fetch(src, x + 1, y - 1, srcBounds); |
235 m[4] = SkGetPackedA32(*row1++); | 251 m[4] = PixelFetcher::fetch(src, x, y, srcBounds); |
236 m[5] = SkGetPackedA32(*row1++); | 252 m[5] = PixelFetcher::fetch(src, x + 1, y, srcBounds); |
237 m[7] = SkGetPackedA32(*row2++); | 253 m[7] = PixelFetcher::fetch(src, x, y + 1, srcBounds); |
238 m[8] = SkGetPackedA32(*row2++); | 254 m[8] = PixelFetcher::fetch(src, x + 1, y + 1, srcBounds); |
239 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 255 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
240 *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight , | 256 *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight , |
241 l->lightColor(surfaceToLight)); | 257 l->lightColor(surfaceToLight)); |
242 for (++x; x < right - 1; ++x) { | 258 for (++x; x < right - 1; ++x) { |
243 shiftMatrixLeft(m); | 259 shiftMatrixLeft(m); |
244 m[2] = SkGetPackedA32(*row0++); | 260 m[2] = PixelFetcher::fetch(src, x + 1, y - 1, srcBounds); |
245 m[5] = SkGetPackedA32(*row1++); | 261 m[5] = PixelFetcher::fetch(src, x + 1, y, srcBounds); |
246 m[8] = SkGetPackedA32(*row2++); | 262 m[8] = PixelFetcher::fetch(src, x + 1, y + 1, srcBounds); |
247 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 263 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
248 *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfac eToLight, | 264 *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfac eToLight, |
249 l->lightColor(surfaceToLight)); | 265 l->lightColor(surfaceToLight)); |
250 } | 266 } |
251 shiftMatrixLeft(m); | 267 shiftMatrixLeft(m); |
252 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 268 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
253 *dptr++ = lightingType.light(rightNormal(m, surfaceScale), surfaceToLigh t, | 269 *dptr++ = lightingType.light(rightNormal(m, surfaceScale), surfaceToLigh t, |
254 l->lightColor(surfaceToLight)); | 270 l->lightColor(surfaceToLight)); |
255 } | 271 } |
256 | 272 |
257 { | 273 { |
258 int x = left; | 274 int x = left; |
259 const SkPMColor* row0 = src.getAddr32(x, bottom - 2); | |
260 const SkPMColor* row1 = src.getAddr32(x, bottom - 1); | |
261 int m[9]; | 275 int m[9]; |
262 m[1] = SkGetPackedA32(*row0++); | 276 m[1] = PixelFetcher::fetch(src, x, bottom - 2, srcBounds); |
263 m[2] = SkGetPackedA32(*row0++); | 277 m[2] = PixelFetcher::fetch(src, x + 1, bottom - 2, srcBounds); |
264 m[4] = SkGetPackedA32(*row1++); | 278 m[4] = PixelFetcher::fetch(src, x, bottom - 1, srcBounds); |
265 m[5] = SkGetPackedA32(*row1++); | 279 m[5] = PixelFetcher::fetch(src, x + 1, bottom - 1, srcBounds); |
266 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 280 SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
267 *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceT oLight, | 281 *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceT oLight, |
268 l->lightColor(surfaceToLight)); | 282 l->lightColor(surfaceToLight)); |
269 for (++x; x < right - 1; ++x) | 283 for (++x; x < right - 1; ++x) |
270 { | 284 { |
271 shiftMatrixLeft(m); | 285 shiftMatrixLeft(m); |
272 m[2] = SkGetPackedA32(*row0++); | 286 m[2] = PixelFetcher::fetch(src, x + 1, bottom - 2, srcBounds); |
273 m[5] = SkGetPackedA32(*row1++); | 287 m[5] = PixelFetcher::fetch(src, x + 1, bottom - 1, srcBounds); |
274 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 288 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
275 *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceT oLight, | 289 *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceT oLight, |
276 l->lightColor(surfaceToLight)); | 290 l->lightColor(surfaceToLight)); |
277 } | 291 } |
278 shiftMatrixLeft(m); | 292 shiftMatrixLeft(m); |
279 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); | 293 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); |
280 *dptr++ = lightingType.light(bottomRightNormal(m, surfaceScale), surface ToLight, | 294 *dptr++ = lightingType.light(bottomRightNormal(m, surfaceScale), surface ToLight, |
281 l->lightColor(surfaceToLight)); | 295 l->lightColor(surfaceToLight)); |
282 } | 296 } |
283 } | 297 } |
284 | 298 |
299 template <class LightingType, class LightType> | |
300 void lightBitmap(const LightingType& lightingType, | |
301 const SkImageFilterLight* light, | |
302 const SkBitmap& src, | |
303 SkBitmap* dst, | |
304 SkScalar surfaceScale, | |
305 const SkIRect& bounds) { | |
306 if (src.bounds().contains(bounds)) { | |
307 lightBitmap<LightingType, LightType, UncheckedPixelFetcher>( | |
308 lightingType, light, src, dst, surfaceScale, bounds); | |
309 } else { | |
310 lightBitmap<LightingType, LightType, DecalPixelFetcher>( | |
311 lightingType, light, src, dst, surfaceScale, bounds); | |
312 } | |
313 } | |
314 | |
285 SkPoint3 readPoint3(SkReadBuffer& buffer) { | 315 SkPoint3 readPoint3(SkReadBuffer& buffer) { |
286 SkPoint3 point; | 316 SkPoint3 point; |
287 point.fX = buffer.readScalar(); | 317 point.fX = buffer.readScalar(); |
288 point.fY = buffer.readScalar(); | 318 point.fY = buffer.readScalar(); |
289 point.fZ = buffer.readScalar(); | 319 point.fZ = buffer.readScalar(); |
290 buffer.validate(SkScalarIsFinite(point.fX) && | 320 buffer.validate(SkScalarIsFinite(point.fX) && |
291 SkScalarIsFinite(point.fY) && | 321 SkScalarIsFinite(point.fY) && |
292 SkScalarIsFinite(point.fZ)); | 322 SkScalarIsFinite(point.fZ)); |
293 return point; | 323 return point; |
294 }; | 324 }; |
(...skipping 885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1180 SkIPoint* offset) const { | 1210 SkIPoint* offset) const { |
1181 SkBitmap src = source; | 1211 SkBitmap src = source; |
1182 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 1212 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
1183 if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) { | 1213 if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) { |
1184 return false; | 1214 return false; |
1185 } | 1215 } |
1186 | 1216 |
1187 if (src.colorType() != kN32_SkColorType) { | 1217 if (src.colorType() != kN32_SkColorType) { |
1188 return false; | 1218 return false; |
1189 } | 1219 } |
1220 SkIRect srcBounds = src.bounds(); | |
1221 srcBounds.offset(srcOffset); | |
1190 SkIRect bounds; | 1222 SkIRect bounds; |
1191 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { | 1223 if (!this->applyCropRect(ctx, srcBounds, &bounds)) { |
1192 return false; | 1224 return false; |
1193 } | 1225 } |
1194 | 1226 |
1195 if (bounds.width() < 2 || bounds.height() < 2) { | 1227 if (bounds.width() < 2 || bounds.height() < 2) { |
1196 return false; | 1228 return false; |
1197 } | 1229 } |
1198 | 1230 |
1199 SkAutoLockPixels alp(src); | 1231 SkAutoLockPixels alp(src); |
1200 if (!src.getPixels()) { | 1232 if (!src.getPixels()) { |
1201 return false; | 1233 return false; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1324 SkBitmap src = source; | 1356 SkBitmap src = source; |
1325 SkIPoint srcOffset = SkIPoint::Make(0, 0); | 1357 SkIPoint srcOffset = SkIPoint::Make(0, 0); |
1326 if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) { | 1358 if (!this->filterInput(0, proxy, source, ctx, &src, &srcOffset)) { |
1327 return false; | 1359 return false; |
1328 } | 1360 } |
1329 | 1361 |
1330 if (src.colorType() != kN32_SkColorType) { | 1362 if (src.colorType() != kN32_SkColorType) { |
1331 return false; | 1363 return false; |
1332 } | 1364 } |
1333 | 1365 |
1366 SkIRect srcBounds = src.bounds(); | |
1367 srcBounds.offset(srcOffset); | |
1334 SkIRect bounds; | 1368 SkIRect bounds; |
1335 if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { | 1369 if (!this->applyCropRect(ctx, srcBounds, &bounds)) { |
1336 return false; | 1370 return false; |
1337 } | 1371 } |
1338 | 1372 |
1339 if (bounds.width() < 2 || bounds.height() < 2) { | 1373 if (bounds.width() < 2 || bounds.height() < 2) { |
1340 return false; | 1374 return false; |
1341 } | 1375 } |
1342 | 1376 |
1343 SkAutoLockPixels alp(src); | 1377 SkAutoLockPixels alp(src); |
1344 if (!src.getPixels()) { | 1378 if (!src.getPixels()) { |
1345 return false; | 1379 return false; |
(...skipping 675 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2021 | 2055 |
2022 fragBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); | 2056 fragBuilder->codeAppendf("%s(%s)", fLightColorFunc.c_str(), surfaceToLight); |
2023 } | 2057 } |
2024 | 2058 |
2025 #endif | 2059 #endif |
2026 | 2060 |
2027 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) | 2061 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkLightingImageFilter) |
2028 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) | 2062 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkDiffuseLightingImageFilter) |
2029 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) | 2063 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSpecularLightingImageFilter) |
2030 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END | 2064 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END |
OLD | NEW |