Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 */
8 #ifndef GrBezierEffect_DEFINED
9 #define GrBezierEffect_DEFINED
11 #include "GrDrawTargetCaps.h"
12 #include "GrEffect.h"
13 #include "GrVertexEffect.h"
14 #include "GrTypesPriv.h"
16 /**
17 * Shader is based off of Loop-Blinn Quadratic GPU Rendering
18 * The output of this effect is a hairline edge for conics.
19 * Conics specified by implicit equation K^2 - LM.
20 * K, L, and M, are the first three values of the vertex attribute,
21 * the fourth value is not used. Distance is calculated using a
22 * first order approximation from the taylor series.
23 * Coverage for AA is max(0, 1-distance).
24 *
25 * Test were also run using a second order distance approximation.
26 * There were two versions of the second order approx. The first version
27 * is of roughly the form:
28 * f(q) = |f(p)| - ||f'(p)||*||q-p|| - ||f''(p)||*||q-p||^2.
29 * The second is similar:
30 * f(q) = |f(p)| + ||f'(p)||*||q-p|| + ||f''(p)||*||q-p||^2.
31 * The exact version of the equations can be found in the paper
32 * "Distance Approximations for Rasterizing Implicit Curves" by Gabriel Taubin
33 *
34 * In both versions we solve the quadratic for ||q-p||.
35 * Version 1:
36 * gFM is magnitude of first partials and gFM2 is magnitude of 2nd partials (as derived from paper)
37 * builder->fsCodeAppend("\t\tedgeAlpha = (sqrt(gFM*gFM+4.0*func*gF2M) - gFM)/(2.0*gF2M);\n");
38 * Version 2:
39 * builder->fsCodeAppend("\t\tedgeAlpha = (gFM - sqrt(gFM*gFM-4.0*func*gF2M))/(2.0*gF2M);\n");
40 *
41 * Also note that 2nd partials of k,l,m are zero
42 *
43 * When comparing the two second order approximations to the first order approximations,
44 * the following results were found. Version 1 tends to underestimate the distances, thus it
45 * basically increases all the error that we were already seeing in the first order
46 * approx. So this version is not the one to use. Version 2 has the opposite effect
47 * and tends to overestimate the distances. This is much closer to what we are
48 * looking for. It is able to render ellipses (even thin ones) without the need to chop.
49 * However, it can not handle thin hyperbolas well and thus would still rely on
50 * chopping to tighten the clipping. Another side effect of the overestimating is
51 * that the curves become much thinner and "ropey". If all that was ever rendered
52 * were "not too thin" curves and ellipses then 2nd order may have an advantage since
53 * only one geometry would need to be rendered. However no benches were run comparing
54 * chopped first order and non chopped 2nd order.
55 */
56 class GrGLConicEffect;
58 class GrConicEffect : public GrVertexEffect {
59 public:
60 static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
61 GR_CREATE_STATIC_EFFECT(gConicFillAA, GrConicEffect, (kFillAA_GrEffectEdgeType));
62 GR_CREATE_STATIC_EFFECT(gConicHairAA, GrConicEffect, (kHairlineAA_GrEffectEdgeType));
63 GR_CREATE_STATIC_EFFECT(gConicFillBW, GrConicEffect, (kFillBW_GrEffectEdgeType));
64 switch (edgeType) {
65 case kFillAA_GrEffectEdgeType:
66 if (!caps.shaderDerivativeSupport()) {
67 return NULL;
68 }
69 gConicFillAA->ref();
70 return gConicFillAA;
71 case kHairlineAA_GrEffectEdgeType:
72 if (!caps.shaderDerivativeSupport()) {
73 return NULL;
74 }
75 gConicHairAA->ref();
76 return gConicHairAA;
77 case kFillBW_GrEffectEdgeType:
78 gConicFillBW->ref();
79 return gConicFillBW;
80 default:
81 return NULL;
82 }
83 }
85 virtual ~GrConicEffect();
87 static const char* Name() { return "Conic"; }
89 inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
90 inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
91 inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
93 typedef GrGLConicEffect GLEffect;
95 virtual void getConstantColorComponents(GrColor* color,
96 uint32_t* validFlags) const SK_OVERRIDE {
97 *validFlags = 0;
98 }
100 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
102 private:
103 GrConicEffect(GrEffectEdgeType);
105 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
107 GrEffectEdgeType fEdgeType;
109 GR_DECLARE_EFFECT_TEST;
111 typedef GrVertexEffect INHERITED;
112 };
114 ///////////////////////////////////////////////////////////////////////////////
115 /**
116 * The output of this effect is a hairline edge for quadratics.
117 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first
118 * two components of the vertex attribute. At the three control points that define
119 * the Quadratic, u, v have the values {0,0}, {1/2, 0}, and {1, 1} respectively.
120 * Coverage for AA is min(0, 1-distance). 3rd & 4th cimponent unused.
121 * Requires shader derivative instruction support.
122 */
123 class GrGLQuadEffect;
125 class GrQuadEffect : public GrVertexEffect {
126 public:
127 static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
128 GR_CREATE_STATIC_EFFECT(gQuadFillAA, GrQuadEffect, (kFillAA_GrEffectEdgeType));
129 GR_CREATE_STATIC_EFFECT(gQuadHairAA, GrQuadEffect, (kHairlineAA_GrEffectEdgeType));
130 GR_CREATE_STATIC_EFFECT(gQuadFillBW, GrQuadEffect, (kFillBW_GrEffectEdgeType));
131 switch (edgeType) {
132 case kFillAA_GrEffectEdgeType:
133 if (!caps.shaderDerivativeSupport()) {
134 return NULL;
135 }
136 gQuadFillAA->ref();
137 return gQuadFillAA;
138 case kHairlineAA_GrEffectEdgeType:
139 if (!caps.shaderDerivativeSupport()) {
140 return NULL;
141 }
142 gQuadHairAA->ref();
143 return gQuadHairAA;
144 case kFillBW_GrEffectEdgeType:
145 gQuadFillBW->ref();
146 return gQuadFillBW;
147 default:
148 return NULL;
149 }
150 }
152 virtual ~GrQuadEffect();
154 static const char* Name() { return "Quad"; }
156 inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
157 inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
158 inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
160 typedef GrGLQuadEffect GLEffect;
162 virtual void getConstantColorComponents(GrColor* color,
163 uint32_t* validFlags) const SK_OVERRIDE {
164 *validFlags = 0;
165 }
167 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
169 private:
170 GrQuadEffect(GrEffectEdgeType);
172 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
174 GrEffectEdgeType fEdgeType;
176 GR_DECLARE_EFFECT_TEST;
178 typedef GrVertexEffect INHERITED;
179 };
181 //////////////////////////////////////////////////////////////////////////////
182 /**
183 * Shader is based off of "Resolution Independent Curve Rendering using
184 * Programmable Graphics Hardware" by Loop and Blinn.
185 * The output of this effect is a hairline edge for non rational cubics.
186 * Cubics are specified by implicit equation K^3 - LM.
187 * K, L, and M, are the first three values of the vertex attribute,
188 * the fourth value is not used. Distance is calculated using a
189 * first order approximation from the taylor series.
190 * Coverage for AA is max(0, 1-distance).
191 */
192 class GrGLCubicEffect;
194 class GrCubicEffect : public GrVertexEffect {
195 public:
196 static GrEffectRef* Create(const GrEffectEdgeType edgeType, const GrDrawTargetCaps& caps) {
197 GR_CREATE_STATIC_EFFECT(gCubicFillAA, GrCubicEffect, (kFillAA_GrEffectEdgeType));
198 GR_CREATE_STATIC_EFFECT(gCubicHairAA, GrCubicEffect, (kHairlineAA_GrEffectEdgeType));
199 GR_CREATE_STATIC_EFFECT(gCubicFillBW, GrCubicEffect, (kFillBW_GrEffectEdgeType));
200 switch (edgeType) {
201 case kFillAA_GrEffectEdgeType:
202 if (!caps.shaderDerivativeSupport()) {
203 return NULL;
204 }
205 gCubicFillAA->ref();
206 return gCubicFillAA;
207 case kHairlineAA_GrEffectEdgeType:
208 if (!caps.shaderDerivativeSupport()) {
209 return NULL;
210 }
211 gCubicHairAA->ref();
212 return gCubicHairAA;
213 case kFillBW_GrEffectEdgeType:
214 gCubicFillBW->ref();
215 return gCubicFillBW;
216 default:
217 return NULL;
218 }
219 }
221 virtual ~GrCubicEffect();
223 static const char* Name() { return "Cubic"; }
225 inline bool isAntiAliased() const { return GrEffectEdgeTypeIsAA(fEdgeType); }
226 inline bool isFilled() const { return GrEffectEdgeTypeIsFill(fEdgeType); }
227 inline GrEffectEdgeType getEdgeType() const { return fEdgeType; }
229 typedef GrGLCubicEffect GLEffect;
231 virtual void getConstantColorComponents(GrColor* color,
232 uint32_t* validFlags) const SK_OVERRIDE {
233 *validFlags = 0;
234 }
236 virtual const GrBackendEffectFactory& getFactory() const SK_OVERRIDE;
238 private:
239 GrCubicEffect(GrEffectEdgeType);
241 virtual bool onIsEqual(const GrEffect& other) const SK_OVERRIDE;
243 GrEffectEdgeType fEdgeType;
245 GR_DECLARE_EFFECT_TEST;
247 typedef GrVertexEffect INHERITED;
248 };
250 #endif