converted GrMagnifierEffect to SkSL

Bug: skia:
Change-Id: I6dc14ac66d5b911117e71fa23fef49a897082781
Reviewed-on: https://skia-review.googlesource.com/71342
Commit-Queue: Ethan Nicholas <ethannicholas@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/effects/GrMagnifierEffect.fp b/src/gpu/effects/GrMagnifierEffect.fp
new file mode 100644
index 0000000..962c1a0
--- /dev/null
+++ b/src/gpu/effects/GrMagnifierEffect.fp
@@ -0,0 +1,85 @@
+in uniform sampler2D src;
+layout(ctype=SkIRect) in int4 bounds;
+uniform float4 boundsUniform;
+layout(ctype=SkRect) in float4 srcRect;
+in uniform float xInvZoom;
+in uniform float yInvZoom;
+in uniform float xInvInset;
+in uniform float yInvInset;
+
+uniform half2 offset;
+
+@coordTransform(src) {
+    SkMatrix::I()
+}
+
+void main() {
+    float2 coord = sk_TransformedCoords2D[0];
+    float2 zoom_coord = offset + coord * half2(xInvZoom, yInvZoom);
+    float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw;
+    delta = min(delta, half2(1.0, 1.0) - delta);
+    delta *= half2(xInvInset, yInvInset);
+
+    half weight = 0.0;
+    if (delta.s < 2.0 && delta.t < 2.0) {
+        delta = half2(2.0, 2.0) - delta;
+        half dist = length(delta);
+        dist = max(2.0 - dist, 0.0);
+        weight = min(dist * dist, 1.0);
+    } else {
+        float2 delta_squared = delta * delta;
+        weight = min(min(delta_squared.x, delta_squared.y), 1.0);
+    }
+
+    sk_OutColor = texture(src, mix(coord, zoom_coord, weight));
+}
+
+@setData(pdman) {
+    SkScalar invW = 1.0f / src.width();
+    SkScalar invH = 1.0f / src.height();
+
+    {
+        SkScalar y = srcRect.y() * invH;
+        if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
+            y = 1.0f - (srcRect.height() / bounds.height()) - y;
+        }
+
+        pdman.set2f(offset, srcRect.x() * invW, y);
+    }
+
+    {
+        SkScalar y = bounds.y() * invH;
+        if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
+            y = 1.0f - bounds.height() * invH;
+        }
+
+        pdman.set4f(boundsUniform,
+                    bounds.x() * invW,
+                    y,
+                    SkIntToScalar(src.width()) / bounds.width(),
+                    SkIntToScalar(src.height()) / bounds.height());
+    }
+}
+
+@test(d) {
+    sk_sp<GrTextureProxy> proxy = d->textureProxy(0);
+    const int kMaxWidth = 200;
+    const int kMaxHeight = 200;
+    const SkScalar kMaxInset = 20.0f;
+    uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
+    uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
+    SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset);
+
+    SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight));
+    SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
+
+    auto effect = GrMagnifierEffect::Make(std::move(proxy),
+                                          bounds,
+                                          srcRect,
+                                          srcRect.width() / bounds.width(),
+                                          srcRect.height() / bounds.height(),
+                                          bounds.width() / inset,
+                                          bounds.height() / inset);
+    SkASSERT(effect);
+    return effect;
+}