blob: 2b9675fd94824d1b4047a0e8a41075a8f0f2d2b9 [file] [log] [blame]
Ethan Nicholas420f1562017-07-14 13:11:38 -04001/*
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 GrEllipseEffect.fp; do not modify.
10 */
11#include "GrEllipseEffect.h"
12#if SK_SUPPORT_GPU
13#include "glsl/GrGLSLColorSpaceXformHelper.h"
14#include "glsl/GrGLSLFragmentProcessor.h"
15#include "glsl/GrGLSLFragmentShaderBuilder.h"
16#include "glsl/GrGLSLProgramBuilder.h"
17#include "SkSLCPP.h"
18#include "SkSLUtil.h"
19class GrGLSLEllipseEffect : public GrGLSLFragmentProcessor {
20public:
21 GrGLSLEllipseEffect() {}
22 void emitCode(EmitArgs& args) override {
23 GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
24 const GrEllipseEffect& _outer = args.fFp.cast<GrEllipseEffect>();
25 (void) _outer;
26prevRadii = vec2(-1.0);
27useScale = sk_Caps.floatPrecisionVaries;
28 fEllipseVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec4f_GrSLType, kHigh_GrSLPrecision, "ellipse");
29 if (useScale) {
30 fScaleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kVec2f_GrSLType, kDefault_GrSLPrecision, "scale");
31 }
32 fragBuilder->codeAppendf("vec2 prevCenter;\nvec2 prevRadii = vec2(%f, %f);\nbool useScale = %s;\nvec2 d = sk_FragCoord.xy - %s.xy;\n@if (useScale) {\n d *= %s.y;\n}\nvec2 Z = d * %s.zw;\nfloat implicit = dot(Z, d) - 1.0;\nfloat grad_dot = 4.0 * dot(Z, Z);\ngrad_dot = max(grad_dot, 0.0001);\nfloat approx_dist = implicit * inversesqrt(grad_dot);\n@if (useScale) {\n approx_dist *= %s.x;\n}\nfloat alpha;\n@switch (%d) {\n case 0:\n alpha = approx_dist > 0.0 ? 0.0 : 1.0;\n break;\n case 1:\n alpha = clamp(0.5 - approx_dist, 0.0, 1.0);\n break;\n case 2:\n alpha = approx_dist > 0.0 ? 1.0 : 0.0;\n break;\n case 3:\n alpha = clamp(0.5 + approx_dist, 0.0, 1.0);\n break;\n default:\n discard;\n}\n%s = %s * alpha;\n", prevRadii.fX, prevRadii.fY, (useScale ? "true" : "false"), args.fUniformHandler->getUniformCStr(fEllipseVar), fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "vec2(0.0)", args.fUniformHandler->getUniformCStr(fEllipseVar), fScaleVar.isValid() ? args.fUniformHandler->getUniformCStr(fScaleVar) : "vec2(0.0)", _outer.edgeType(), args.fOutputColor, args.fInputColor ? args.fInputColor : "vec4(1)");
33 }
34private:
35 void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& _proc) override {
36 const GrEllipseEffect& _outer = _proc.cast<GrEllipseEffect>();
37 auto edgeType = _outer.edgeType();
38 (void) edgeType;
39 auto center = _outer.center();
40 (void) center;
41 auto radii = _outer.radii();
42 (void) radii;
43 UniformHandle& ellipse = fEllipseVar;
44 (void) ellipse;
45 UniformHandle& scale = fScaleVar;
46 (void) scale;
47
48 if (radii != prevRadii || center != prevCenter) {
49 float invRXSqd;
50 float invRYSqd;
51
52
53 if (scale.isValid()) {
54 if (radii.fX > radii.fY) {
55 invRXSqd = 1.f;
56 invRYSqd = (radii.fX * radii.fX) /
57 (radii.fY * radii.fY);
58 pdman.set2f(scale, radii.fX, 1.f / radii.fX);
59 } else {
60 invRXSqd = (radii.fY * radii.fY) /
61 (radii.fX * radii.fX);
62 invRYSqd = 1.f;
63 pdman.set2f(scale, radii.fY, 1.f / radii.fY);
64 }
65 } else {
66 invRXSqd = 1.f / (radii.fX * radii.fX);
67 invRYSqd = 1.f / (radii.fY * radii.fY);
68 }
69 pdman.set4f(ellipse, center.fX, center.fY, invRXSqd, invRYSqd);
70 prevCenter = center;
71 prevRadii = radii;
72 }
73 }
74SkPoint prevCenter;
75SkPoint prevRadii;
76bool useScale;
77 UniformHandle fEllipseVar;
78 UniformHandle fScaleVar;
79};
80GrGLSLFragmentProcessor* GrEllipseEffect::onCreateGLSLInstance() const {
81 return new GrGLSLEllipseEffect();
82}
83void GrEllipseEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const {
84 b->add32(fEdgeType);
85}
86bool GrEllipseEffect::onIsEqual(const GrFragmentProcessor& other) const {
87 const GrEllipseEffect& that = other.cast<GrEllipseEffect>();
88 (void) that;
89 if (fEdgeType != that.fEdgeType) return false;
90 if (fCenter != that.fCenter) return false;
91 if (fRadii != that.fRadii) return false;
92 return true;
93}
94GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrEllipseEffect);
95#if GR_TEST_UTILS
96sk_sp<GrFragmentProcessor> GrEllipseEffect::TestCreate(GrProcessorTestData* testData) {
97
98 SkPoint center;
99 center.fX = testData->fRandom->nextRangeScalar(0.f, 1000.f);
100 center.fY = testData->fRandom->nextRangeScalar(0.f, 1000.f);
101 SkScalar rx = testData->fRandom->nextRangeF(0.f, 1000.f);
102 SkScalar ry = testData->fRandom->nextRangeF(0.f, 1000.f);
103 GrPrimitiveEdgeType et;
104 do {
105 et = (GrPrimitiveEdgeType) testData->fRandom->nextULessThan(kGrProcessorEdgeTypeCnt);
106 } while (kHairlineAA_GrProcessorEdgeType == et);
107 return GrEllipseEffect::Make(et, center, SkPoint::Make(rx, ry));
108}
109#endif
110#endif