Remove 6-param applyCropRect() from lighting filters (raster path).
authorsenorblanco <senorblanco@chromium.org>
Tue, 16 Feb 2016 21:26:56 +0000 (13:26 -0800)
committerCommit bot <commit-bot@chromium.org>
Tue, 16 Feb 2016 21:26:56 +0000 (13:26 -0800)
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
src/effects/SkLightingImageFilter.cpp

index 4fa9b0084e96e7a5a3b7702b647bc1a4f09588bd..9ceab2036a6e667ec282e8dc68eebb2b226eab00 100644 (file)
 #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<SkColorFilter> 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));
index 19da3ed5e8fa2389e6760ae67ba45ec9bec850d3..4be9f17db5f2be984ecc889fe81c8ff2cb6510ba 100644 (file)
@@ -185,35 +185,55 @@ inline SkPoint3 bottomRightNormal(int m[9], SkScalar surfaceScale) {
                          surfaceScale);
 }
 
-template <class LightingType, class LightType> 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 <class LightingType, class LightType, class PixelFetcher>
+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<const LightType*>(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 <class LightingType, class LightType> 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 <class LightingType, class LightType> 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 <class LightingType, class LightType> void lightBitmap(const LightingTy
     }
 }
 
+template <class LightingType, class LightType>
+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, LightType, UncheckedPixelFetcher>(
+            lightingType, light, src, dst, surfaceScale, bounds);
+    } else {
+        lightBitmap<LightingType, LightType, DecalPixelFetcher>(
+            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;
     }