diff options
Diffstat (limited to 'src/gpu/effects/GrMagnifierEffect.fp')
-rw-r--r-- | src/gpu/effects/GrMagnifierEffect.fp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/src/gpu/effects/GrMagnifierEffect.fp b/src/gpu/effects/GrMagnifierEffect.fp new file mode 100644 index 0000000000..962c1a0160 --- /dev/null +++ b/src/gpu/effects/GrMagnifierEffect.fp @@ -0,0 +1,85 @@ +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; +} |