reduce SkDisplacementImageFilter size.
    
Saves ~8K on mac laptop
    
    - remove templates
    - check for 0 0r 0xFF in alpha
    
    Before: (using modified bench w/o caching)
    
      23/23  MB     2       134µs   151µs   146µs   156µs   6%      █▇▆▆▆▆▄▁▁▁      8888    displacement_full_large
      23/23  MB     2       253µs   254µs   255µs   260µs   1%      █▄▄▅▂▁▂▁▁▁      8888    displacement_alpha_large
      24/24  MB     1       410µs   410µs   415µs   445µs   3%      █▃▁▂▁▁▁▁▁▁      8888    displacement_zero_large
      24/24  MB     151     840ns   841ns   853ns   938ns   4%      █▁▁▁▁▁▁▂▁▁      8888    displacement_full_small
      24/24  MB     180     832ns   835ns   836ns   851ns   1%      █▂▁▂▂▁▂▂▂▂      8888    displacement_alpha_small
      24/24  MB     9       60µs    60.9µs  69.9µs  101µs   19%     █▄▄▄▁▁▁▁▁▁      8888    displacement_zero_small
    
    After:
    
      23/23  MB     3       47.4µs  48µs    48.2µs  51.4µs  2%      █▂▂▃▃▁▁▁▂▁      8888    displacement_full_large
      23/23  MB     2       140µs   141µs   145µs   166µs   7%      ▂▁▁▁▁▁▁▁▇█      8888    displacement_alpha_large
      24/24  MB     2       189µs   196µs   197µs   225µs   5%      █▃▂▂▂▂▃▂▁▁      8888    displacement_zero_large
      24/24  MB     134     588ns   594ns   597ns   616ns   1%      ▂▁▁█▂▆▂▂▃▄      8888    displacement_full_small
      24/24  MB     168     590ns   592ns   592ns   599ns   0%      ▃▂▁▁▁▁▁█▂▂      8888    displacement_alpha_small
      24/24  MB     9       8.39µs  8.41µs  8.42µs  8.53µs  0%      █▄▃▂▁▁▃▂▁▂      8888    displacement_zero_small

This reverts commit 3f93b7265f558c414d0f33a7771be52b1fd1ce61.

fix: use PMColor shifts, not RGBA shifts

Bug: skia:
Change-Id: I044ef323b56d842f00cc50a828e14374aea8bb9e
Reviewed-on: https://skia-review.googlesource.com/20204
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/src/effects/SkDisplacementMapEffect.cpp b/src/effects/SkDisplacementMapEffect.cpp
index 82c2b59..900efcb 100644
--- a/src/effects/SkDisplacementMapEffect.cpp
+++ b/src/effects/SkDisplacementMapEffect.cpp
@@ -33,35 +33,41 @@
 
 #define kChannelSelectorKeyBits 3; // Max value is 4, so 3 bits are required at most
 
-template<SkDisplacementMapEffect::ChannelSelectorType type>
-uint32_t getValue(SkColor, const SkUnPreMultiply::Scale*) {
-    SkDEBUGFAIL("Unknown channel selector");
-    return 0;
+const uint8_t gChannelTypeToShift[] = {
+     0,  // unknown
+    SK_R32_SHIFT,
+    SK_G32_SHIFT,
+    SK_B32_SHIFT,
+    SK_A32_SHIFT,
+};
+struct Extractor {
+    Extractor(SkDisplacementMapEffect::ChannelSelectorType typeX,
+              SkDisplacementMapEffect::ChannelSelectorType typeY)
+        : fShiftX(gChannelTypeToShift[typeX])
+        , fShiftY(gChannelTypeToShift[typeY])
+    {}
+
+    unsigned fShiftX, fShiftY;
+
+    unsigned getX(SkPMColor c) const { return (c >> fShiftX) & 0xFF; }
+    unsigned getY(SkPMColor c) const { return (c >> fShiftY) & 0xFF; }
+};
+
+static SkPMColor unpremul_pm(SkPMColor c) {
+    const U8CPU a = SkGetPackedA32(c);
+    if (0 == a) {
+        return 0;
+    } else if (0xFF == a) {
+        return c;
+    }
+    const unsigned scale = SkUnPreMultiply::GetScale(a);
+    return SkPackARGB32NoCheck(a,
+                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedR32(c)),
+                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedG32(c)),
+                               SkUnPreMultiply::ApplyScale(scale, SkGetPackedB32(c)));
 }
 
-template<> uint32_t getValue<SkDisplacementMapEffect::kR_ChannelSelectorType>(
-    SkColor l, const SkUnPreMultiply::Scale* table) {
-    return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedR32(l));
-}
-
-template<> uint32_t getValue<SkDisplacementMapEffect::kG_ChannelSelectorType>(
-    SkColor l, const SkUnPreMultiply::Scale* table) {
-    return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedG32(l));
-}
-
-template<> uint32_t getValue<SkDisplacementMapEffect::kB_ChannelSelectorType>(
-    SkColor l, const SkUnPreMultiply::Scale* table) {
-    return SkUnPreMultiply::ApplyScale(table[SkGetPackedA32(l)], SkGetPackedB32(l));
-}
-
-template<> uint32_t getValue<SkDisplacementMapEffect::kA_ChannelSelectorType>(
-    SkColor l, const SkUnPreMultiply::Scale*) {
-    return SkGetPackedA32(l);
-}
-
-template<SkDisplacementMapEffect::ChannelSelectorType typeX,
-         SkDisplacementMapEffect::ChannelSelectorType typeY>
-void computeDisplacement(const SkVector& scale, SkBitmap* dst,
+void computeDisplacement(Extractor ex, const SkVector& scale, SkBitmap* dst,
                          const SkBitmap& displ, const SkIPoint& offset,
                          const SkBitmap& src,
                          const SkIRect& bounds) {
@@ -71,13 +77,14 @@
     const SkVector scaleForColor = SkVector::Make(scale.fX * Inv8bit, scale.fY * Inv8bit);
     const SkVector scaleAdj = SkVector::Make(SK_ScalarHalf - scale.fX * SK_ScalarHalf,
                                              SK_ScalarHalf - scale.fY * SK_ScalarHalf);
-    const SkUnPreMultiply::Scale* table = SkUnPreMultiply::GetScaleTable();
     SkPMColor* dstPtr = dst->getAddr32(0, 0);
     for (int y = bounds.top(); y < bounds.bottom(); ++y) {
         const SkPMColor* displPtr = displ.getAddr32(bounds.left() + offset.fX, y + offset.fY);
         for (int x = bounds.left(); x < bounds.right(); ++x, ++displPtr) {
-            SkScalar displX = scaleForColor.fX * getValue<typeX>(*displPtr, table) + scaleAdj.fX;
-            SkScalar displY = scaleForColor.fY * getValue<typeY>(*displPtr, table) + scaleAdj.fY;
+            SkPMColor c = unpremul_pm(*displPtr);
+
+            SkScalar displX = scaleForColor.fX * ex.getX(c) + scaleAdj.fX;
+            SkScalar displY = scaleForColor.fY * ex.getY(c) + scaleAdj.fY;
             // Truncate the displacement values
             const int srcX = x + SkScalarTruncToInt(displX);
             const int srcY = y + SkScalarTruncToInt(displY);
@@ -87,64 +94,6 @@
     }
 }
 
-template<SkDisplacementMapEffect::ChannelSelectorType typeX>
-void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
-                         const SkVector& scale, SkBitmap* dst,
-                         const SkBitmap& displ, const SkIPoint& offset,
-                         const SkBitmap& src,
-                         const SkIRect& bounds) {
-    switch (yChannelSelector) {
-      case SkDisplacementMapEffect::kR_ChannelSelectorType:
-        computeDisplacement<typeX, SkDisplacementMapEffect::kR_ChannelSelectorType>(
-            scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kG_ChannelSelectorType:
-        computeDisplacement<typeX, SkDisplacementMapEffect::kG_ChannelSelectorType>(
-            scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kB_ChannelSelectorType:
-        computeDisplacement<typeX, SkDisplacementMapEffect::kB_ChannelSelectorType>(
-            scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kA_ChannelSelectorType:
-        computeDisplacement<typeX, SkDisplacementMapEffect::kA_ChannelSelectorType>(
-            scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
-      default:
-        SkDEBUGFAIL("Unknown Y channel selector");
-    }
-}
-
-void computeDisplacement(SkDisplacementMapEffect::ChannelSelectorType xChannelSelector,
-                         SkDisplacementMapEffect::ChannelSelectorType yChannelSelector,
-                         const SkVector& scale, SkBitmap* dst,
-                         const SkBitmap& displ, const SkIPoint& offset,
-                         const SkBitmap& src,
-                         const SkIRect& bounds) {
-    switch (xChannelSelector) {
-      case SkDisplacementMapEffect::kR_ChannelSelectorType:
-        computeDisplacement<SkDisplacementMapEffect::kR_ChannelSelectorType>(
-            yChannelSelector, scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kG_ChannelSelectorType:
-        computeDisplacement<SkDisplacementMapEffect::kG_ChannelSelectorType>(
-            yChannelSelector, scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kB_ChannelSelectorType:
-        computeDisplacement<SkDisplacementMapEffect::kB_ChannelSelectorType>(
-            yChannelSelector, scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kA_ChannelSelectorType:
-        computeDisplacement<SkDisplacementMapEffect::kA_ChannelSelectorType>(
-            yChannelSelector, scale, dst, displ, offset, src, bounds);
-        break;
-      case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
-      default:
-        SkDEBUGFAIL("Unknown X channel selector");
-    }
-}
-
 bool channel_selector_type_is_valid(SkDisplacementMapEffect::ChannelSelectorType cst) {
     switch (cst) {
     case SkDisplacementMapEffect::kUnknown_ChannelSelectorType:
@@ -398,7 +347,7 @@
         return nullptr;
     }
 
-    computeDisplacement(fXChannelSelector, fYChannelSelector, scale, &dst,
+    computeDisplacement(Extractor(fXChannelSelector, fYChannelSelector), scale, &dst,
                         displBM, colorOffset - displOffset, colorBM, colorBounds);
 
     offset->fX = bounds.left();