blob: 7e3245709f4ad5fa03f209737a272da09d7018f1 [file] [log] [blame]
/*
* 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 * float2(xInvZoom, yInvZoom);
float2 delta = (coord - boundsUniform.xy) * boundsUniform.zw;
delta = min(delta, half2(1.0, 1.0) - delta);
delta *= float2(xInvInset, yInvInset);
float weight = 0.0;
if (delta.s < 2.0 && delta.t < 2.0) {
delta = half2(2.0, 2.0) - delta;
float 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;
}