blob: e6a9aa257a8c4ddb52f33124a0e3f07a33f284f7 [file] [log] [blame]
Ethan Nicholas130fb3f2018-02-01 12:14:34 -05001/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -05008in uniform sampler2D src;
9layout(ctype=SkIRect) in int4 bounds;
10uniform float4 boundsUniform;
11layout(ctype=SkRect) in float4 srcRect;
12in uniform float xInvZoom;
13in uniform float yInvZoom;
14in uniform float xInvInset;
15in uniform float yInvInset;
16
17uniform half2 offset;
18
19@coordTransform(src) {
20 SkMatrix::I()
21}
22
23void main() {
24 float2 coord = sk_TransformedCoords2D[0];
Ethan Nicholase1f55022019-02-05 17:17:40 -050025 float2 zoom_coord = offset + coord * float2(xInvZoom, yInvZoom);
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050026 float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw;
27 delta = min(delta, half2(1.0, 1.0) - delta);
Ethan Nicholase1f55022019-02-05 17:17:40 -050028 delta *= float2(xInvInset, yInvInset);
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050029
Ethan Nicholase1f55022019-02-05 17:17:40 -050030 float weight = 0.0;
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050031 if (delta.s < 2.0 && delta.t < 2.0) {
32 delta = half2(2.0, 2.0) - delta;
Ethan Nicholase1f55022019-02-05 17:17:40 -050033 float dist = length(delta);
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050034 dist = max(2.0 - dist, 0.0);
35 weight = min(dist * dist, 1.0);
36 } else {
37 float2 delta_squared = delta * delta;
38 weight = min(min(delta_squared.x, delta_squared.y), 1.0);
39 }
40
Ethan Nicholas13863662019-07-29 13:05:15 -040041 sk_OutColor = sample(src, mix(coord, zoom_coord, weight));
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050042}
43
44@setData(pdman) {
45 SkScalar invW = 1.0f / src.width();
46 SkScalar invH = 1.0f / src.height();
47
48 {
49 SkScalar y = srcRect.y() * invH;
50 if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
51 y = 1.0f - (srcRect.height() / bounds.height()) - y;
52 }
53
54 pdman.set2f(offset, srcRect.x() * invW, y);
55 }
56
57 {
58 SkScalar y = bounds.y() * invH;
Michael Ludwig9c853fa2019-08-28 14:21:08 -040059 SkScalar hSign = 1.f;
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050060 if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
Michael Ludwig9c853fa2019-08-28 14:21:08 -040061 y = 1.0f - bounds.y() * invH;
62 hSign = -1.f;
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050063 }
64
65 pdman.set4f(boundsUniform,
66 bounds.x() * invW,
67 y,
68 SkIntToScalar(src.width()) / bounds.width(),
Michael Ludwig9c853fa2019-08-28 14:21:08 -040069 hSign * SkIntToScalar(src.height()) / bounds.height());
Ethan Nicholas2d5f9b32017-12-13 14:36:14 -050070 }
71}
72
73@test(d) {
74 sk_sp<GrTextureProxy> proxy = d->textureProxy(0);
75 const int kMaxWidth = 200;
76 const int kMaxHeight = 200;
77 const SkScalar kMaxInset = 20.0f;
78 uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
79 uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
80 SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset);
81
82 SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight));
83 SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
84
85 auto effect = GrMagnifierEffect::Make(std::move(proxy),
86 bounds,
87 srcRect,
88 srcRect.width() / bounds.width(),
89 srcRect.height() / bounds.height(),
90 bounds.width() / inset,
91 bounds.height() / inset);
92 SkASSERT(effect);
93 return effect;
94}