aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrMagnifierEffect.fp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/effects/GrMagnifierEffect.fp')
-rw-r--r--src/gpu/effects/GrMagnifierEffect.fp85
1 files changed, 85 insertions, 0 deletions
diff --git a/src/gpu/effects/GrMagnifierEffect.fp b/src/gpu/effects/GrMagnifierEffect.fp
new file mode 100644
index 0000000000..962c1a0160
--- /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;
+}