GrMagnifierEffect.cpp revision 5f9836edb0de062a6e30ba74f94803fae4f311ed
1/*
2 * Copyright 2017 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
8/*
9 * This file was autogenerated from GrMagnifierEffect.fp; do not modify.
10 */
11#include "GrMagnifierEffect.h"
12#if SK_SUPPORT_GPU
13#include "glsl/GrGLSLFragmentProcessor.h"
14#include "glsl/GrGLSLFragmentShaderBuilder.h"
15#include "glsl/GrGLSLProgramBuilder.h"
16#include "GrTexture.h"
17#include "SkSLCPP.h"
18#include "SkSLUtil.h"
19class GrGLSLMagnifierEffect : public GrGLSLFragmentProcessor {
20public:
21    GrGLSLMagnifierEffect() {}
22    void emitCode(EmitArgs& args) override {
23        GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24        const GrMagnifierEffect& _outer = args.fFp.cast<GrMagnifierEffect>();
25        (void)_outer;
26        auto bounds = _outer.bounds();
27        (void)bounds;
28        auto srcRect = _outer.srcRect();
29        (void)srcRect;
30        auto xInvZoom = _outer.xInvZoom();
31        (void)xInvZoom;
32        auto yInvZoom = _outer.yInvZoom();
33        (void)yInvZoom;
34        auto xInvInset = _outer.xInvInset();
35        (void)xInvInset;
36        auto yInvInset = _outer.yInvInset();
37        (void)yInvInset;
38        fBoundsUniformVar = args.fUniformHandler->addUniform(
39                kFragment_GrShaderFlag, kFloat4_GrSLType, kDefault_GrSLPrecision, "boundsUniform");
40        fXInvZoomVar = args.fUniformHandler->addUniform(
41                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvZoom");
42        fYInvZoomVar = args.fUniformHandler->addUniform(
43                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvZoom");
44        fXInvInsetVar = args.fUniformHandler->addUniform(
45                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "xInvInset");
46        fYInvInsetVar = args.fUniformHandler->addUniform(
47                kFragment_GrShaderFlag, kFloat_GrSLType, kDefault_GrSLPrecision, "yInvInset");
48        fOffsetVar = args.fUniformHandler->addUniform(
49                kFragment_GrShaderFlag, kHalf2_GrSLType, kDefault_GrSLPrecision, "offset");
50        SkString sk_TransformedCoords2D_0 = fragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
51        fragBuilder->codeAppendf(
52                "float2 coord = %s;\nfloat2 zoom_coord = float2(%s + half2(coord * "
53                "float2(half2(half(%s), half(%s)))));\nfloat2 delta = (coord - %s.xy) * "
54                "%s.zw;\ndelta = min(delta, float2(half2(1.0, 1.0) - half2(delta)));\ndelta *= "
55                "float2(half2(half(%s), half(%s)));\nhalf weight = 0.0;\nif (delta.x < 2.0 && "
56                "delta.y < 2.0) {\n    delta = float2(half2(2.0, 2.0) - half2(delta));\n    half "
57                "dist = half(length(delta));\n    dist = half(max(2.0 - float(dist), 0.0));\n    "
58                "weight = half(min(float(dist * dist), 1.0));\n} else {\n    ",
59                sk_TransformedCoords2D_0.c_str(),
60                args.fUniformHandler->getUniformCStr(fOffsetVar),
61                args.fUniformHandler->getUniformCStr(fXInvZoomVar),
62                args.fUniformHandler->getUniformCStr(fYInvZoomVar),
63                args.fUniformHandler->getUniformCStr(fBoundsUniformVar),
64                args.fUniformHandler->getUniformCStr(fBoundsUniformVar),
65                args.fUniformHandler->getUniformCStr(fXInvInsetVar),
66                args.fUniformHandler->getUniformCStr(fYInvInsetVar));
67        fragBuilder->codeAppendf(
68                "float2 delta_squared = delta * delta;\n    weight = half(min(min(delta_squared.x, "
69                "delta_squared.y), 1.0));\n}\n%s = texture(%s, mix(coord, zoom_coord, "
70                "float(weight))).%s;\n",
71                args.fOutputColor,
72                fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]).c_str(),
73                fragBuilder->getProgramBuilder()->samplerSwizzle(args.fTexSamplers[0]).c_str());
74    }
75
76private:
77    void onSetData(const GrGLSLProgramDataManager& pdman,
78                   const GrFragmentProcessor& _proc) override {
79        const GrMagnifierEffect& _outer = _proc.cast<GrMagnifierEffect>();
80        {
81            pdman.set1f(fXInvZoomVar, _outer.xInvZoom());
82            pdman.set1f(fYInvZoomVar, _outer.yInvZoom());
83            pdman.set1f(fXInvInsetVar, _outer.xInvInset());
84            pdman.set1f(fYInvInsetVar, _outer.yInvInset());
85        }
86        GrSurfaceProxy& srcProxy = *_outer.textureSampler(0).proxy();
87        GrTexture& src = *srcProxy.priv().peekTexture();
88        (void)src;
89        auto bounds = _outer.bounds();
90        (void)bounds;
91        UniformHandle& boundsUniform = fBoundsUniformVar;
92        (void)boundsUniform;
93        auto srcRect = _outer.srcRect();
94        (void)srcRect;
95        UniformHandle& xInvZoom = fXInvZoomVar;
96        (void)xInvZoom;
97        UniformHandle& yInvZoom = fYInvZoomVar;
98        (void)yInvZoom;
99        UniformHandle& xInvInset = fXInvInsetVar;
100        (void)xInvInset;
101        UniformHandle& yInvInset = fYInvInsetVar;
102        (void)yInvInset;
103        UniformHandle& offset = fOffsetVar;
104        (void)offset;
105
106        SkScalar invW = 1.0f / src.width();
107        SkScalar invH = 1.0f / src.height();
108
109        {
110            SkScalar y = srcRect.y() * invH;
111            if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
112                y = 1.0f - (srcRect.height() / bounds.height()) - y;
113            }
114
115            pdman.set2f(offset, srcRect.x() * invW, y);
116        }
117
118        {
119            SkScalar y = bounds.y() * invH;
120            if (srcProxy.origin() != kTopLeft_GrSurfaceOrigin) {
121                y = 1.0f - bounds.height() * invH;
122            }
123
124            pdman.set4f(boundsUniform,
125                        bounds.x() * invW,
126                        y,
127                        SkIntToScalar(src.width()) / bounds.width(),
128                        SkIntToScalar(src.height()) / bounds.height());
129        }
130    }
131    UniformHandle fBoundsUniformVar;
132    UniformHandle fOffsetVar;
133    UniformHandle fXInvZoomVar;
134    UniformHandle fYInvZoomVar;
135    UniformHandle fXInvInsetVar;
136    UniformHandle fYInvInsetVar;
137};
138GrGLSLFragmentProcessor* GrMagnifierEffect::onCreateGLSLInstance() const {
139    return new GrGLSLMagnifierEffect();
140}
141void GrMagnifierEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
142                                              GrProcessorKeyBuilder* b) const {}
143bool GrMagnifierEffect::onIsEqual(const GrFragmentProcessor& other) const {
144    const GrMagnifierEffect& that = other.cast<GrMagnifierEffect>();
145    (void)that;
146    if (fSrc != that.fSrc) return false;
147    if (fBounds != that.fBounds) return false;
148    if (fSrcRect != that.fSrcRect) return false;
149    if (fXInvZoom != that.fXInvZoom) return false;
150    if (fYInvZoom != that.fYInvZoom) return false;
151    if (fXInvInset != that.fXInvInset) return false;
152    if (fYInvInset != that.fYInvInset) return false;
153    return true;
154}
155GrMagnifierEffect::GrMagnifierEffect(const GrMagnifierEffect& src)
156        : INHERITED(kGrMagnifierEffect_ClassID, src.optimizationFlags())
157        , fSrc(src.fSrc)
158        , fBounds(src.fBounds)
159        , fSrcRect(src.fSrcRect)
160        , fXInvZoom(src.fXInvZoom)
161        , fYInvZoom(src.fYInvZoom)
162        , fXInvInset(src.fXInvInset)
163        , fYInvInset(src.fYInvInset)
164        , fSrcCoordTransform(src.fSrcCoordTransform) {
165    this->addTextureSampler(&fSrc);
166    this->addCoordTransform(&fSrcCoordTransform);
167}
168std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::clone() const {
169    return std::unique_ptr<GrFragmentProcessor>(new GrMagnifierEffect(*this));
170}
171GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrMagnifierEffect);
172#if GR_TEST_UTILS
173std::unique_ptr<GrFragmentProcessor> GrMagnifierEffect::TestCreate(GrProcessorTestData* d) {
174    sk_sp<GrTextureProxy> proxy = d->textureProxy(0);
175    const int kMaxWidth = 200;
176    const int kMaxHeight = 200;
177    const SkScalar kMaxInset = 20.0f;
178    uint32_t width = d->fRandom->nextULessThan(kMaxWidth);
179    uint32_t height = d->fRandom->nextULessThan(kMaxHeight);
180    SkScalar inset = d->fRandom->nextRangeScalar(1.0f, kMaxInset);
181
182    SkIRect bounds = SkIRect::MakeWH(SkIntToScalar(kMaxWidth), SkIntToScalar(kMaxHeight));
183    SkRect srcRect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
184
185    auto effect = GrMagnifierEffect::Make(std::move(proxy),
186                                          bounds,
187                                          srcRect,
188                                          srcRect.width() / bounds.width(),
189                                          srcRect.height() / bounds.height(),
190                                          bounds.width() / inset,
191                                          bounds.height() / inset);
192    SkASSERT(effect);
193    return effect;
194}
195#endif
196#endif
197