blob: eebe42a5cde80d41c7346bfd5240997124d2daa4 [file] [log] [blame]
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +00001/*
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
skia.committer@gmail.com44a77c82013-08-23 07:01:29 +00009#define GrBezierEffect_DEFINED
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000010
bsalomoneb1cb5c2015-05-22 08:01:09 -070011#include "GrCaps.h"
joshualittb0a8a372014-09-23 09:50:21 -070012#include "GrProcessor.h"
joshualitt249af152014-09-15 11:41:13 -070013#include "GrGeometryProcessor.h"
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000014#include "GrTypesPriv.h"
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000015
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 */
56class GrGLConicEffect;
57
joshualitt249af152014-09-15 11:41:13 -070058class GrConicEffect : public GrGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000059public:
bungeman06ca8ec2016-06-09 08:01:03 -070060 static sk_sp<GrGeometryProcessor> Make(GrColor color,
61 const SkMatrix& viewMatrix,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -050062 const GrClipEdgeType edgeType,
bungeman06ca8ec2016-06-09 08:01:03 -070063 const GrCaps& caps,
64 const SkMatrix& localMatrix,
65 bool usesLocalCoords,
66 uint8_t coverage = 0xff) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000067 switch (edgeType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -050068 case GrClipEdgeType::kFillAA:
jvanverthe9c0fc62015-04-29 11:18:05 -070069 if (!caps.shaderCaps()->shaderDerivativeSupport()) {
halcanary96fcdcc2015-08-27 07:41:13 -070070 return nullptr;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000071 }
bungeman06ca8ec2016-06-09 08:01:03 -070072 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -050073 new GrConicEffect(color, viewMatrix, coverage, GrClipEdgeType::kFillAA,
bungeman06ca8ec2016-06-09 08:01:03 -070074 localMatrix, usesLocalCoords));
Ethan Nicholas1706f842017-11-10 11:58:19 -050075 case GrClipEdgeType::kHairlineAA:
jvanverthe9c0fc62015-04-29 11:18:05 -070076 if (!caps.shaderCaps()->shaderDerivativeSupport()) {
halcanary96fcdcc2015-08-27 07:41:13 -070077 return nullptr;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000078 }
bungeman06ca8ec2016-06-09 08:01:03 -070079 return sk_sp<GrGeometryProcessor>(
80 new GrConicEffect(color, viewMatrix, coverage,
Ethan Nicholas1706f842017-11-10 11:58:19 -050081 GrClipEdgeType::kHairlineAA, localMatrix,
bungeman06ca8ec2016-06-09 08:01:03 -070082 usesLocalCoords));
Ethan Nicholas1706f842017-11-10 11:58:19 -050083 case GrClipEdgeType::kFillBW:
bungeman06ca8ec2016-06-09 08:01:03 -070084 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -050085 new GrConicEffect(color, viewMatrix, coverage, GrClipEdgeType::kFillBW,
bungeman06ca8ec2016-06-09 08:01:03 -070086 localMatrix, usesLocalCoords));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +000087 default:
halcanary96fcdcc2015-08-27 07:41:13 -070088 return nullptr;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000089 }
90 }
91
Brian Salomond3b65972017-03-22 12:05:03 -040092 ~GrConicEffect() override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000093
mtklein36352bf2015-03-25 18:17:31 -070094 const char* name() const override { return "Conic"; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +000095
Brian Salomon92be2f72018-06-19 14:33:47 -040096 inline const Attribute& inPosition() const { return kAttributes[0]; }
97 inline const Attribute& inConicCoeffs() const { return kAttributes[1]; }
joshualittb0a8a372014-09-23 09:50:21 -070098 inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
99 inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500100 inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
joshualitt88c23fc2015-05-13 14:18:07 -0700101 GrColor color() const { return fColor; }
joshualitte578a952015-05-14 10:09:13 -0700102 const SkMatrix& viewMatrix() const { return fViewMatrix; }
joshualitte3ababe2015-05-15 07:56:07 -0700103 const SkMatrix& localMatrix() const { return fLocalMatrix; }
joshualittb8c241a2015-05-19 08:23:30 -0700104 bool usesLocalCoords() const { return fUsesLocalCoords; }
105 uint8_t coverageScale() const { return fCoverageScale; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000106
Brian Salomon94efbf52016-11-29 13:43:05 -0500107 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000108
Brian Salomon94efbf52016-11-29 13:43:05 -0500109 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000110
111private:
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500112 GrConicEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
joshualittb8c241a2015-05-19 08:23:30 -0700113 const SkMatrix& localMatrix, bool usesLocalCoords);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000114
Brian Salomon92be2f72018-06-19 14:33:47 -0400115 const Attribute& onVertexAttribute(int i) const override { return kAttributes[i]; }
116
joshualitt88c23fc2015-05-13 14:18:07 -0700117 GrColor fColor;
joshualitte578a952015-05-14 10:09:13 -0700118 SkMatrix fViewMatrix;
joshualitte3ababe2015-05-15 07:56:07 -0700119 SkMatrix fLocalMatrix;
joshualittb8c241a2015-05-19 08:23:30 -0700120 bool fUsesLocalCoords;
joshualitt88c23fc2015-05-13 14:18:07 -0700121 uint8_t fCoverageScale;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500122 GrClipEdgeType fEdgeType;
Brian Salomon92be2f72018-06-19 14:33:47 -0400123 static constexpr Attribute kAttributes[] = {{"inPosition", kFloat2_GrVertexAttribType},
124 {"inConicCoeffs", kHalf4_GrVertexAttribType}};
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000125
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400126 GR_DECLARE_GEOMETRY_PROCESSOR_TEST
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000127
joshualitt249af152014-09-15 11:41:13 -0700128 typedef GrGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000129};
130
131///////////////////////////////////////////////////////////////////////////////
132/**
133 * The output of this effect is a hairline edge for quadratics.
134 * Quadratic specified by 0=u^2-v canonical coords. u and v are the first
135 * two components of the vertex attribute. At the three control points that define
136 * the Quadratic, u, v have the values {0,0}, {1/2, 0}, and {1, 1} respectively.
137 * Coverage for AA is min(0, 1-distance). 3rd & 4th cimponent unused.
138 * Requires shader derivative instruction support.
139 */
140class GrGLQuadEffect;
141
joshualitt249af152014-09-15 11:41:13 -0700142class GrQuadEffect : public GrGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000143public:
bungeman06ca8ec2016-06-09 08:01:03 -0700144 static sk_sp<GrGeometryProcessor> Make(GrColor color,
145 const SkMatrix& viewMatrix,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500146 const GrClipEdgeType edgeType,
bungeman06ca8ec2016-06-09 08:01:03 -0700147 const GrCaps& caps,
148 const SkMatrix& localMatrix,
149 bool usesLocalCoords,
150 uint8_t coverage = 0xff) {
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000151 switch (edgeType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500152 case GrClipEdgeType::kFillAA:
jvanverthe9c0fc62015-04-29 11:18:05 -0700153 if (!caps.shaderCaps()->shaderDerivativeSupport()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700154 return nullptr;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000155 }
bungeman06ca8ec2016-06-09 08:01:03 -0700156 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500157 new GrQuadEffect(color, viewMatrix, coverage, GrClipEdgeType::kFillAA,
bungeman06ca8ec2016-06-09 08:01:03 -0700158 localMatrix, usesLocalCoords));
Ethan Nicholas1706f842017-11-10 11:58:19 -0500159 case GrClipEdgeType::kHairlineAA:
jvanverthe9c0fc62015-04-29 11:18:05 -0700160 if (!caps.shaderCaps()->shaderDerivativeSupport()) {
halcanary96fcdcc2015-08-27 07:41:13 -0700161 return nullptr;
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000162 }
bungeman06ca8ec2016-06-09 08:01:03 -0700163 return sk_sp<GrGeometryProcessor>(
164 new GrQuadEffect(color, viewMatrix, coverage,
Ethan Nicholas1706f842017-11-10 11:58:19 -0500165 GrClipEdgeType::kHairlineAA, localMatrix,
bungeman06ca8ec2016-06-09 08:01:03 -0700166 usesLocalCoords));
Ethan Nicholas1706f842017-11-10 11:58:19 -0500167 case GrClipEdgeType::kFillBW:
bungeman06ca8ec2016-06-09 08:01:03 -0700168 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500169 new GrQuadEffect(color, viewMatrix, coverage, GrClipEdgeType::kFillBW,
bungeman06ca8ec2016-06-09 08:01:03 -0700170 localMatrix, usesLocalCoords));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000171 default:
halcanary96fcdcc2015-08-27 07:41:13 -0700172 return nullptr;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000173 }
174 }
175
Brian Salomond3b65972017-03-22 12:05:03 -0400176 ~GrQuadEffect() override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000177
mtklein36352bf2015-03-25 18:17:31 -0700178 const char* name() const override { return "Quad"; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000179
Brian Salomon92be2f72018-06-19 14:33:47 -0400180 inline const Attribute& inPosition() const { return kAttributes[0]; }
181 inline const Attribute& inHairQuadEdge() const { return kAttributes[1]; }
joshualittb0a8a372014-09-23 09:50:21 -0700182 inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
183 inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500184 inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
joshualitt88c23fc2015-05-13 14:18:07 -0700185 GrColor color() const { return fColor; }
joshualitte578a952015-05-14 10:09:13 -0700186 const SkMatrix& viewMatrix() const { return fViewMatrix; }
joshualitte3ababe2015-05-15 07:56:07 -0700187 const SkMatrix& localMatrix() const { return fLocalMatrix; }
joshualittb8c241a2015-05-19 08:23:30 -0700188 bool usesLocalCoords() const { return fUsesLocalCoords; }
189 uint8_t coverageScale() const { return fCoverageScale; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000190
Brian Salomon94efbf52016-11-29 13:43:05 -0500191 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000192
Brian Salomon94efbf52016-11-29 13:43:05 -0500193 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000194
195private:
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500196 GrQuadEffect(GrColor, const SkMatrix& viewMatrix, uint8_t coverage, GrClipEdgeType,
joshualittb8c241a2015-05-19 08:23:30 -0700197 const SkMatrix& localMatrix, bool usesLocalCoords);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000198
Brian Salomon92be2f72018-06-19 14:33:47 -0400199 const Attribute& onVertexAttribute(int i) const override { return kAttributes[i]; }
200
201 GrColor fColor;
202 SkMatrix fViewMatrix;
203 SkMatrix fLocalMatrix;
204 bool fUsesLocalCoords;
205 uint8_t fCoverageScale;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500206 GrClipEdgeType fEdgeType;
Brian Salomon92be2f72018-06-19 14:33:47 -0400207
208 static constexpr Attribute kAttributes[] = {{"inPosition", kFloat2_GrVertexAttribType},
209 {"inHairQuadEdge", kHalf4_GrVertexAttribType}};
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000210
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400211 GR_DECLARE_GEOMETRY_PROCESSOR_TEST
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000212
joshualitt249af152014-09-15 11:41:13 -0700213 typedef GrGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000214};
215
216//////////////////////////////////////////////////////////////////////////////
217/**
218 * Shader is based off of "Resolution Independent Curve Rendering using
219 * Programmable Graphics Hardware" by Loop and Blinn.
220 * The output of this effect is a hairline edge for non rational cubics.
221 * Cubics are specified by implicit equation K^3 - LM.
222 * K, L, and M, are the first three values of the vertex attribute,
223 * the fourth value is not used. Distance is calculated using a
224 * first order approximation from the taylor series.
225 * Coverage for AA is max(0, 1-distance).
226 */
227class GrGLCubicEffect;
228
joshualitt249af152014-09-15 11:41:13 -0700229class GrCubicEffect : public GrGeometryProcessor {
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000230public:
bungeman06ca8ec2016-06-09 08:01:03 -0700231 static sk_sp<GrGeometryProcessor> Make(GrColor color,
232 const SkMatrix& viewMatrix,
Chris Daltonfebbffa2017-06-08 13:12:02 -0600233 const SkMatrix& klm,
234 bool flipKL,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500235 const GrClipEdgeType edgeType,
bungeman06ca8ec2016-06-09 08:01:03 -0700236 const GrCaps& caps) {
Chris Dalton1d4af542018-04-16 14:23:00 -0600237 if (!caps.shaderCaps()->floatIs32Bits()) {
238 // Cubic math will be too unstable if the hardware doesn't support full fp32.
239 return nullptr;
240 }
241
Chris Daltonfebbffa2017-06-08 13:12:02 -0600242 // Map KLM to something that operates in device space.
243 SkMatrix devKLM;
244 if (!viewMatrix.invert(&devKLM)) {
245 return nullptr;
246 }
247 devKLM.postConcat(klm);
248 if (flipKL) {
249 devKLM.postScale(-1, -1);
250 }
251
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000252 switch (edgeType) {
Ethan Nicholas1706f842017-11-10 11:58:19 -0500253 case GrClipEdgeType::kFillAA:
bungeman06ca8ec2016-06-09 08:01:03 -0700254 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500255 new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kFillAA));
256 case GrClipEdgeType::kHairlineAA:
bungeman06ca8ec2016-06-09 08:01:03 -0700257 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500258 new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kHairlineAA));
259 case GrClipEdgeType::kFillBW:
bungeman06ca8ec2016-06-09 08:01:03 -0700260 return sk_sp<GrGeometryProcessor>(
Ethan Nicholas1706f842017-11-10 11:58:19 -0500261 new GrCubicEffect(color, viewMatrix, devKLM, GrClipEdgeType::kFillBW));
commit-bot@chromium.orgcabf4b22014-03-05 18:27:43 +0000262 default:
halcanary96fcdcc2015-08-27 07:41:13 -0700263 return nullptr;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000264 }
265 }
266
Brian Salomond3b65972017-03-22 12:05:03 -0400267 ~GrCubicEffect() override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000268
mtklein36352bf2015-03-25 18:17:31 -0700269 const char* name() const override { return "Cubic"; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000270
Brian Salomon92be2f72018-06-19 14:33:47 -0400271 inline const Attribute& inPosition() const { return kInPosition; }
joshualittb0a8a372014-09-23 09:50:21 -0700272 inline bool isAntiAliased() const { return GrProcessorEdgeTypeIsAA(fEdgeType); }
273 inline bool isFilled() const { return GrProcessorEdgeTypeIsFill(fEdgeType); }
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500274 inline GrClipEdgeType getEdgeType() const { return fEdgeType; }
joshualitt88c23fc2015-05-13 14:18:07 -0700275 GrColor color() const { return fColor; }
joshualittb8c241a2015-05-19 08:23:30 -0700276 bool colorIgnored() const { return GrColor_ILLEGAL == fColor; }
joshualitte578a952015-05-14 10:09:13 -0700277 const SkMatrix& viewMatrix() const { return fViewMatrix; }
Chris Daltonfebbffa2017-06-08 13:12:02 -0600278 const SkMatrix& devKLMMatrix() const { return fDevKLMMatrix; }
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000279
Brian Salomon94efbf52016-11-29 13:43:05 -0500280 void getGLSLProcessorKey(const GrShaderCaps& caps, GrProcessorKeyBuilder* b) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000281
Brian Salomon94efbf52016-11-29 13:43:05 -0500282 GrGLSLPrimitiveProcessor* createGLSLInstance(const GrShaderCaps&) const override;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000283
284private:
Chris Daltonfebbffa2017-06-08 13:12:02 -0600285 GrCubicEffect(GrColor, const SkMatrix& viewMatrix, const SkMatrix& devKLMMatrix,
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500286 GrClipEdgeType);
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000287
Brian Salomon92be2f72018-06-19 14:33:47 -0400288 const Attribute& onVertexAttribute(int) const override { return kInPosition; }
289
290 GrColor fColor;
291 SkMatrix fViewMatrix;
292 SkMatrix fDevKLMMatrix;
Ethan Nicholas0f3c7322017-11-09 14:51:17 -0500293 GrClipEdgeType fEdgeType;
Brian Salomon92be2f72018-06-19 14:33:47 -0400294
295 static constexpr Attribute kInPosition = {"inPosition", kFloat2_GrVertexAttribType};
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000296
Brian Salomon0c26a9d2017-07-06 10:09:38 -0400297 GR_DECLARE_GEOMETRY_PROCESSOR_TEST
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000298
joshualitt249af152014-09-15 11:41:13 -0700299 typedef GrGeometryProcessor INHERITED;
commit-bot@chromium.org07e1c3f2013-08-22 20:41:15 +0000300};
301
302#endif