blob: 962c1a0160f084b55ec04f16e85604839e274a2e [file] [log] [blame]
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -05001in uniform sampler2D src;
2layout(ctype=SkIRect) in int4 bounds;
3uniform float4 boundsUniform;
4layout(ctype=SkRect) in float4 srcRect;
5in uniform float xInvZoom;
6in uniform float yInvZoom;
7in uniform float xInvInset;
8in uniform float yInvInset;
9
10uniform half2 offset;
11
12@coordTransform(src) {
13 SkMatrix::I()
14}
15
16void main() {
17 float2 coord = sk_TransformedCoords2D[0];
18 float2 zoom_coord = offset + coord * half2(xInvZoom, yInvZoom);
19 float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw;
20 delta = min(delta, half2(1.0, 1.0) - delta);
21 delta *= half2(xInvInset, yInvInset);
22
23 half weight = 0.0;
24 if (delta.s < 2.0 && delta.t < 2.0) {
25 delta = half2(2.0, 2.0) - delta;
26 half dist = length(delta);
27 dist = max(2.0 - dist, 0.0);
28 weight = min(dist * dist, 1.0);
29 } else {
30 float2 delta_squared = delta * delta;
31 weight = min(min(delta_squared.x, delta_squared.y), 1.0);
32 }
33
34 sk_OutColor = texture(src, mix(coord, zoom_coord, weight));
35}
36
37@setData(pdman) {
38 SkScalar invW = 1.0f / src.width();
39 SkScalar invH = 1.0f / src.height();
40
41 {
42 SkScalar y = srcRect.y() * invH;
43 if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
44 y = 1.0f - (srcRect.height() / bounds.height()) - y;
45 }
46
47 pdman.set2f(offset, srcRect.x() * invW, y);
48 }
49
50 {
51 SkScalar y = bounds.y() * invH;
52 if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
53 y = 1.0f - bounds.height() * invH;
54 }
55
56 pdman.set4f(boundsUniform,
57 bounds.x() * invW,
58 y,
59 SkIntToScalar(src.width()) / bounds.width(),
60 SkIntToScalar(src.height()) / bounds.height());
61 }
62}
63
64@test(d) {
65 sk_sp<GrTextureProxy> proxy = d->textureProxy(0);
66 const int kMaxWidth = 200;
67 const int kMaxHeight = 200;
68 const SkScalar kMaxInset = 20.0f;
69 uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
70 uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
71 SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset);
72
73 SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight));
74 SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
75
76 auto effect = GrMagnifierEffect::Make(std::move(proxy),
77 bounds,
78 srcRect,
79 srcRect.width() / bounds.width(),
80 srcRect.height() / bounds.height(),
81 bounds.width() / inset,
82 bounds.height() / inset);
83 SkASSERT(effect);
84 return effect;
85}