1/* 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 8in 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]; 25 float2 zoom_coord = offset + coord * half2(xInvZoom, yInvZoom); 26 float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw; 27 delta = min(delta, half2(1.0, 1.0) - delta); 28 delta *= half2(xInvInset, yInvInset); 29 30 half weight = 0.0; 31 if (delta.s < 2.0 && delta.t < 2.0) { 32 delta = half2(2.0, 2.0) - delta; 33 half dist = length(delta); 34 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 41 sk_OutColor = texture(src, mix(coord, zoom_coord, weight)); 42} 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; 59 if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) { 60 y = 1.0f - bounds.height() * invH; 61 } 62 63 pdman.set4f(boundsUniform, 64 bounds.x() * invW, 65 y, 66 SkIntToScalar(src.width()) / bounds.width(), 67 SkIntToScalar(src.height()) / bounds.height()); 68 } 69} 70 71@test(d) { 72 sk_sp<GrTextureProxy> proxy = d->textureProxy(0); 73 const int kMaxWidth = 200; 74 const int kMaxHeight = 200; 75 const SkScalar kMaxInset = 20.0f; 76 uint32_t width = d->fRandom->nextULessThan(kMaxWidth); 77 uint32_t height = d->fRandom->nextULessThan(kMaxHeight); 78 SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset); 79 80 SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight)); 81 SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)); 82 83 auto effect = GrMagnifierEffect::Make(std::move(proxy), 84 bounds, 85 srcRect, 86 srcRect.width() / bounds.width(), 87 srcRect.height() / bounds.height(), 88 bounds.width() / inset, 89 bounds.height() / inset); 90 SkASSERT(effect); 91 return effect; 92} 93