/* * 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; }