Chromium Code Reviews| 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 |