From 84f0e745839a0cb5ff5055f5ea0726bdd83b920b Mon Sep 17 00:00:00 2001 From: senorblanco Date: Tue, 16 Feb 2016 13:26:56 -0800 Subject: [PATCH] Remove 6-param applyCropRect() from lighting filters (raster path). BUG=skia:4502 GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1701133002 Review URL: https://codereview.chromium.org/1701133002 --- gm/imagefilterscropexpand.cpp | 29 ++++--- src/effects/SkLightingImageFilter.cpp | 107 +++++++++++++++++--------- 2 files changed, 90 insertions(+), 46 deletions(-) diff --git a/gm/imagefilterscropexpand.cpp b/gm/imagefilterscropexpand.cpp index 4fa9b0084e..9ceab2036a 100644 --- a/gm/imagefilterscropexpand.cpp +++ b/gm/imagefilterscropexpand.cpp @@ -19,8 +19,10 @@ #include "SkImageSource.h" #include "SkMorphologyImageFilter.h" #include "SkColorFilterImageFilter.h" +#include "SkLightingImageFilter.h" #include "SkMergeImageFilter.h" #include "SkOffsetImageFilter.h" +#include "SkPoint3.h" #include "SkSurface.h" /////////////////////////////////////////////////////////////////////////////// @@ -35,7 +37,7 @@ protected: return SkString("imagefilterscropexpand"); } - SkISize onISize() override { return SkISize::Make(650, 650); } + SkISize onISize() override { return SkISize::Make(730, 650); } void onDraw(SkCanvas* canvas) override { SkAutoTUnref cf( @@ -62,6 +64,9 @@ protected: SkRect r = SkRect::MakeWH(SkIntToScalar(64), SkIntToScalar(64)); SkScalar MARGIN = SkIntToScalar(12); + SkPoint3 pointLocation = SkPoint3::Make(0, 0, SkIntToScalar(10)); + SkScalar kd = SkIntToScalar(2); + SkScalar surfaceScale = SkIntToScalar(1); SkIRect bounds; r.roundOut(&bounds); @@ -72,27 +77,27 @@ protected: SkRect rect = cropRect.rect(); rect.outset(SkIntToScalar(outset), SkIntToScalar(outset)); - SkImageFilter::CropRect big_rect(rect, SkImageFilter::CropRect::kHasAll_CropEdge); + SkImageFilter::CropRect bigRect(rect, SkImageFilter::CropRect::kHasAll_CropEdge); Draw(canvas, checkerboard, rect, SkColorFilterImageFilter::Create( - cfAlphaTrans, noopCropped.get(), &big_rect)); + cfAlphaTrans, noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create( - 0.3f, 0.3f, noopCropped.get(), &big_rect)); + 0.3f, 0.3f, noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkBlurImageFilter::Create( - 8.0f, 8.0f, noopCropped.get(), &big_rect)); + 8.0f, 8.0f, noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkDilateImageFilter::Create( - 2, 2, noopCropped.get(), &big_rect)); + 2, 2, noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkErodeImageFilter::Create( - 2, 2, noopCropped.get(), &big_rect)); + 2, 2, noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkDropShadowImageFilter::Create( SkIntToScalar(10), SkIntToScalar(10), SkIntToScalar(3), SkIntToScalar(3), SK_ColorBLUE, SkDropShadowImageFilter::kDrawShadowAndForeground_ShadowMode, - noopCropped.get(), &big_rect)); + noopCropped.get(), &bigRect)); Draw(canvas, checkerboard, rect, SkDisplacementMapEffect::Create( SkDisplacementMapEffect::kR_ChannelSelectorType, @@ -100,10 +105,14 @@ protected: SkIntToScalar(12), gradientCircleSource.get(), noopCropped.get(), - &big_rect)); + &bigRect)); Draw(canvas, checkerboard, rect, SkOffsetImageFilter::Create( - SkIntToScalar(-8), SkIntToScalar(16), noopCropped.get(), &big_rect)); + SkIntToScalar(-8), SkIntToScalar(16), noopCropped.get(), &bigRect)); + + Draw(canvas, checkerboard, rect, + SkLightingImageFilter::CreatePointLitDiffuse(pointLocation, SK_ColorWHITE, + surfaceScale, kd, noopCropped.get(), &bigRect)); canvas->restore(); canvas->translate(0, SkIntToScalar(80)); diff --git a/src/effects/SkLightingImageFilter.cpp b/src/effects/SkLightingImageFilter.cpp index 19da3ed5e8..4be9f17db5 100644 --- a/src/effects/SkLightingImageFilter.cpp +++ b/src/effects/SkLightingImageFilter.cpp @@ -185,35 +185,55 @@ inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) { surfaceScale); } -template void lightBitmap(const LightingType& lightingType, - const SkImageFilterLight* light, - const SkBitmap& src, - SkBitmap* dst, - SkScalar surfaceScale, - const SkIRect& bounds) { + +class UncheckedPixelFetcher { +public: + static inline uint32_t Fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { + return SkGetPackedA32(*src.getAddr32(x, y)); + } +}; + +// The DecalPixelFetcher is used when the destination crop rect exceeds the input bitmap bounds. +class DecalPixelFetcher { +public: + static inline uint32_t Fetch(const SkBitmap& src, int x, int y, const SkIRect& bounds) { + if (x < bounds.fLeft || x >= bounds.fRight || y < bounds.fTop || y >= bounds.fBottom) { + return 0; + } else { + return SkGetPackedA32(*src.getAddr32(x, y)); + } + } +}; + +template +void lightBitmap(const LightingType& lightingType, + const SkImageFilterLight* light, + const SkBitmap& src, + SkBitmap* dst, + SkScalar surfaceScale, + const SkIRect& bounds) { SkASSERT(dst->width() == bounds.width() && dst->height() == bounds.height()); const LightType* l = static_cast(light); int left = bounds.left(), right = bounds.right(); int bottom = bounds.bottom(); int y = bounds.top(); + SkIRect srcBounds = src.bounds(); SkPMColor* dptr = dst->getAddr32(0, 0); { int x = left; - const SkPMColor* row1 = src.getAddr32(x, y); - const SkPMColor* row2 = src.getAddr32(x, y + 1); int m[9]; - m[4] = SkGetPackedA32(*row1++); - m[5] = SkGetPackedA32(*row1++); - m[7] = SkGetPackedA32(*row2++); - m[8] = SkGetPackedA32(*row2++); + m[4] = PixelFetcher::Fetch(src, x, y, srcBounds); + m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); + m[7] = PixelFetcher::Fetch(src, x, y + 1, srcBounds); + m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(topLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); for (++x; x < right - 1; ++x) { shiftMatrixLeft(m); - m[5] = SkGetPackedA32(*row1++); - m[8] = SkGetPackedA32(*row2++); + m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); + m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(topNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); @@ -226,24 +246,21 @@ template void lightBitmap(const LightingTy for (++y; y < bottom - 1; ++y) { int x = left; - const SkPMColor* row0 = src.getAddr32(x, y - 1); - const SkPMColor* row1 = src.getAddr32(x, y); - const SkPMColor* row2 = src.getAddr32(x, y + 1); int m[9]; - m[1] = SkGetPackedA32(*row0++); - m[2] = SkGetPackedA32(*row0++); - m[4] = SkGetPackedA32(*row1++); - m[5] = SkGetPackedA32(*row1++); - m[7] = SkGetPackedA32(*row2++); - m[8] = SkGetPackedA32(*row2++); + m[1] = PixelFetcher::Fetch(src, x, y - 1, srcBounds); + m[2] = PixelFetcher::Fetch(src, x + 1, y - 1, srcBounds); + m[4] = PixelFetcher::Fetch(src, x, y, srcBounds); + m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); + m[7] = PixelFetcher::Fetch(src, x, y + 1, srcBounds); + m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(leftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); for (++x; x < right - 1; ++x) { shiftMatrixLeft(m); - m[2] = SkGetPackedA32(*row0++); - m[5] = SkGetPackedA32(*row1++); - m[8] = SkGetPackedA32(*row2++); + m[2] = PixelFetcher::Fetch(src, x + 1, y - 1, srcBounds); + m[5] = PixelFetcher::Fetch(src, x + 1, y, srcBounds); + m[8] = PixelFetcher::Fetch(src, x + 1, y + 1, srcBounds); surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(interiorNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); @@ -256,21 +273,19 @@ template void lightBitmap(const LightingTy { int x = left; - const SkPMColor* row0 = src.getAddr32(x, bottom - 2); - const SkPMColor* row1 = src.getAddr32(x, bottom - 1); int m[9]; - m[1] = SkGetPackedA32(*row0++); - m[2] = SkGetPackedA32(*row0++); - m[4] = SkGetPackedA32(*row1++); - m[5] = SkGetPackedA32(*row1++); + m[1] = PixelFetcher::Fetch(src, x, bottom - 2, srcBounds); + m[2] = PixelFetcher::Fetch(src, x + 1, bottom - 2, srcBounds); + m[4] = PixelFetcher::Fetch(src, x, bottom - 1, srcBounds); + m[5] = PixelFetcher::Fetch(src, x + 1, bottom - 1, srcBounds); SkPoint3 surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(bottomLeftNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); for (++x; x < right - 1; ++x) { shiftMatrixLeft(m); - m[2] = SkGetPackedA32(*row0++); - m[5] = SkGetPackedA32(*row1++); + m[2] = PixelFetcher::Fetch(src, x + 1, bottom - 2, srcBounds); + m[5] = PixelFetcher::Fetch(src, x + 1, bottom - 1, srcBounds); surfaceToLight = l->surfaceToLight(x, y, m[4], surfaceScale); *dptr++ = lightingType.light(bottomNormal(m, surfaceScale), surfaceToLight, l->lightColor(surfaceToLight)); @@ -282,6 +297,22 @@ template void lightBitmap(const LightingTy } } +template +void lightBitmap(const LightingType& lightingType, + const SkImageFilterLight* light, + const SkBitmap& src, + SkBitmap* dst, + SkScalar surfaceScale, + const SkIRect& bounds) { + if (src.bounds().contains(bounds)) { + lightBitmap( + lightingType, light, src, dst, surfaceScale, bounds); + } else { + lightBitmap( + lightingType, light, src, dst, surfaceScale, bounds); + } +} + SkPoint3 readPoint3(SkReadBuffer& buffer) { SkPoint3 point; point.fX = buffer.readScalar(); @@ -1187,8 +1218,10 @@ bool SkDiffuseLightingImageFilter::onFilterImage(Proxy* proxy, if (src.colorType() != kN32_SkColorType) { return false; } + SkIRect srcBounds = src.bounds(); + srcBounds.offset(srcOffset); SkIRect bounds; - if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { + if (!this->applyCropRect(ctx, srcBounds, &bounds)) { return false; } @@ -1331,8 +1364,10 @@ bool SkSpecularLightingImageFilter::onFilterImage(Proxy* proxy, return false; } + SkIRect srcBounds = src.bounds(); + srcBounds.offset(srcOffset); SkIRect bounds; - if (!this->applyCropRect(ctx, proxy, src, &srcOffset, &bounds, &src)) { + if (!this->applyCropRect(ctx, srcBounds, &bounds)) { return false; }