| /* | |
| * Copyright 2018 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| 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; | |
| } |