OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright 2013 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 #ifndef GrBezierEffect_DEFINED | |
9 #define GrBezierEffect_DEFINED | |
10 | |
11 #include "GrEffect.h" | |
12 | |
13 enum BezierEffectType { | |
bsalomon
2013/08/21 20:04:39
I'm wondering if there is something more specific
egdaniel
2013/08/21 20:18:06
I say either GrBezierEdgeType or Style...wish ther
| |
14 kFillAA_BezierEffectType, | |
15 kHairAA_BezierEffectType, | |
16 kFillNoAA_BezierEffectType, | |
17 }; | |
18 | |
19 /** | |
20 * Shader is based off of Loop-Blinn Quadratic GPU Rendering | |
bsalomon
2013/08/21 20:04:39
Should we merge this comment block with the next o
egdaniel
2013/08/21 20:18:06
Yeah, I just left them separate at first since the
| |
21 * The output of this effect is a hairline edge for conics. | |
22 * Conics specified by implicit equation K^2 - LM. | |
23 * K, L, and M, are the first three values of the vertex attribute, | |
24 * the fourth value is not used. Distance is calculated using a | |
25 * first order approximation from the taylor series. | |
26 * Coverage is max(0, 1-distance). | |
27 */ | |
28 | |
29 /** | |
30 * Test were also run using a second order distance approximation. | |
31 * There were two versions of the second order approx. The first version | |
32 * is of roughly the form: | |
33 * f(q) = |f(p)| - ||f'(p)||*||q-p|| - ||f''(p)||*||q-p||^2. | |
34 * The second is similar: | |
35 * f(q) = |f(p)| + ||f'(p)||*||q-p|| + ||f''(p)||*||q-p||^2. | |
36 * The exact version of the equations can be found in the paper | |
37 * "Distance Approximations for Rasterizing Implicit Curves" by Gabriel Taubin | |
38 * | |
39 * In both versions we solve the quadratic for ||q-p||. | |
40 * Version 1: | |
41 * gFM is magnitude of first partials and gFM2 is magnitude of 2nd partials (as derived from paper) | |
42 * builder->fsCodeAppend("\t\tedgeAlpha = (sqrt(gFM*gFM+4.0*func*gF2M) - gFM)/(2 .0*gF2M);\n"); | |
43 * Version 2: | |
44 * builder->fsCodeAppend("\t\tedgeAlpha = (gFM - sqrt(gFM*gFM-4.0*func*gF2M))/(2 .0*gF2M);\n"); | |
45 * | |
46 * Also note that 2nd partials of k,l,m are zero | |
47 * | |
48 * When comparing the two second order approximations to the first order approxi mations, | |
49 * the following results were found. Version 1 tends to underestimate the distan ces, thus it | |
50 * basically increases all the error that we were already seeing in the first or der | |
51 * approx. So this version is not the one to use. Version 2 has the opposite eff ect | |
52 * and tends to overestimate the distances. This is much closer to what we are | |
53 * looking for. It is able to render ellipses (even thin ones) without the need to chop. | |
54 * However, it can not handle thin hyperbolas well and thus would still rely on | |
55 * chopping to tighten the clipping. Another side effect of the overestimating i s | |
56 * that the curves become much thinner and "ropey". If all that was ever rendere d | |
57 * were "not too thin" curves and ellipses then 2nd order may have an advantage since | |
58 * only one geometry would need to be rendered. However no benches were run comp aring | |
59 * chopped first order and non chopped 2nd order. | |
60 */ | |
61 class GrGLConicEffect; | |
62 | |
63 class GrConicEffect : public GrEffect { | |
64 public: | |
65 static GrEffectRef* Create(BezierEffectType effectType) { | |
bsalomon
2013/08/21 20:11:29
Do we need to check or assert that we have derivat
egdaniel
2013/08/21 20:18:06
I suppose we should. Before we relied on the PathR
| |
66 GR_CREATE_STATIC_EFFECT(gConicFillNoAA, GrConicEffect, (false, true)); | |
bsalomon
2013/08/21 20:04:39
It seems like we should just plumb the enum value
egdaniel
2013/08/21 20:18:06
Will do
On 2013/08/21 20:04:39, bsalomon wrote:
| |
67 GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (true, true)); | |
68 GR_CREATE_STATIC_EFFECT(gConicHairAA, GrConicEffect, (true, false)); | |
69 if (kFillAA_BezierEffectType == effectType) { | |
70 gConicFillAA->ref(); | |
71 return gConicFillAA; | |
72 } else if (kHairAA_BezierEffectType == effectType) { | |
73 gConicHairAA->ref(); | |
74 return gConicHairAA; | |
75 } else { | |
76 gConicFillNoAA->ref(); | |
77 return gConicFillNoAA; | |
78 } | |
79 } | |
80 | |
81 virtual ~GrConicEffect(); | |
82 | |
83 static const char* Name() { return "Conic"; } | |
84 | |
85 inline bool isAntiAliased() const { return fAntiAlias; } | |
86 inline bool isFilled() const { return fFill; } | |
87 | |
88 typedef GrGLConicEffect GLEffect; | |
89 | |
90 virtual void getConstantColorComponents(GrColor* color, | |
91 uint32_t* validFlags) const SK_OVERR IDE { | |
92 *validFlags = 0; | |
93 } | |
94 | |
95 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
96 | |
97 private: | |
98 GrConicEffect(bool antiAlias, bool fill); | |
99 | |
100 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | |
101 | |
102 bool fAntiAlias; | |
103 bool fFill; | |
104 | |
105 GR_DECLARE_EFFECT_TEST; | |
106 | |
107 typedef GrEffect INHERITED; | |
108 }; | |
109 | |
110 /////////////////////////////////////////////////////////////////////////////// | |
111 /** | |
112 * The output of this effect is a hairline edge for quadratics. | |
113 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first | |
114 * two components of the vertex attribute. Uses unsigned distance. | |
115 * Coverage is min(0, 1-distance). 3rd & 4th component unused. | |
bsalomon
2013/08/21 20:04:39
maybe we should say somewhere in here that uv is {
egdaniel
2013/08/21 20:18:06
Adding it.
On 2013/08/21 20:04:39, bsalomon wrote
| |
116 * Requires shader derivative instruction support. | |
117 */ | |
118 class GrGLQuadEffect; | |
119 | |
120 class GrQuadEffect : public GrEffect { | |
121 public: | |
122 static GrEffectRef* Create(BezierEffectType effectType) { | |
123 GR_CREATE_STATIC_EFFECT(gQuadFillNoAA, GrQuadEffect, (false, true)); | |
124 GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (true, true)); | |
125 GR_CREATE_STATIC_EFFECT(gQuadHairAA, GrQuadEffect, (true, false)); | |
126 if (kFillAA_BezierEffectType == effectType) { | |
127 gQuadFillAA->ref(); | |
128 return gQuadFillAA; | |
129 } else if (kHairAA_BezierEffectType == effectType) { | |
130 gQuadHairAA->ref(); | |
131 return gQuadHairAA; | |
132 } else { | |
133 gQuadFillNoAA->ref(); | |
134 return gQuadFillNoAA; | |
135 } | |
136 } | |
137 | |
138 virtual ~GrQuadEffect(); | |
139 | |
140 static const char* Name() { return "Quad"; } | |
141 | |
142 inline bool isAntiAliased() const { return fAntiAlias; } | |
143 inline bool isFilled() const { return fFill; } | |
144 | |
145 typedef GrGLQuadEffect GLEffect; | |
146 | |
147 virtual void getConstantColorComponents(GrColor* color, | |
148 uint32_t* validFlags) const SK_OVERR IDE { | |
149 *validFlags = 0; | |
150 } | |
151 | |
152 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
153 | |
154 private: | |
155 GrQuadEffect(bool antiAlias, bool fill); | |
156 | |
157 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | |
158 | |
159 bool fAntiAlias; | |
160 bool fFill; | |
161 | |
162 GR_DECLARE_EFFECT_TEST; | |
163 | |
164 typedef GrEffect INHERITED; | |
165 }; | |
166 | |
167 ////////////////////////////////////////////////////////////////////////////// | |
168 /** | |
169 * Shader is based off of "Resolution Independent Curve Rendering using | |
170 * Programmable Graphics Hardware" by Loop and Blinn. | |
171 * The output of this effect is a hairline edge for non rational cubics. | |
172 * Cubics are specified by implicit equation K^3 - LM. | |
173 * K, L, and M, are the first three values of the vertex attribute, | |
174 * the fourth value is not used. Distance is calculated using a | |
175 * first order approximation from the taylor series. | |
176 * Coverage is max(0, 1-distance). | |
177 */ | |
178 class GrGLCubicEffect; | |
179 | |
180 class GrCubicEffect : public GrEffect { | |
181 public: | |
182 static GrEffectRef* Create(BezierEffectType effectType) { | |
183 GR_CREATE_STATIC_EFFECT(gCubicFillNoAA, GrCubicEffect, (false, true)); | |
184 GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (true, true)); | |
185 GR_CREATE_STATIC_EFFECT(gCubicHairAA, GrCubicEffect, (true, false)); | |
186 if (kFillAA_BezierEffectType == effectType) { | |
187 gCubicFillAA->ref(); | |
188 return gCubicFillAA; | |
189 } else if (kHairAA_BezierEffectType == effectType) { | |
190 gCubicHairAA->ref(); | |
191 return gCubicHairAA; | |
192 } else { | |
193 gCubicFillNoAA->ref(); | |
194 return gCubicFillNoAA; | |
195 } | |
196 } | |
197 | |
198 virtual ~GrCubicEffect(); | |
199 | |
200 static const char* Name() { return "Cubic"; } | |
201 | |
202 inline bool isAntiAliased() const { return fAntiAlias; } | |
203 inline bool isFilled() const { return fFill; } | |
204 | |
205 typedef GrGLCubicEffect GLEffect; | |
206 | |
207 virtual void getConstantColorComponents(GrColor* color, | |
208 uint32_t* validFlags) const SK_OVERR IDE { | |
209 *validFlags = 0; | |
210 } | |
211 | |
212 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE; | |
213 | |
214 private: | |
215 GrCubicEffect(bool antiAlias, bool fill); | |
216 | |
217 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE; | |
218 | |
219 bool fAntiAlias; | |
220 bool fFill; | |
221 | |
222 GR_DECLARE_EFFECT_TEST; | |
223 | |
224 typedef GrEffect INHERITED; | |
225 }; | |
226 | |
227 #endif | |
OLD | NEW |