OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2014 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 #include "gl/GrGLPathRendering.h" | |
9 #include "gl/GrGLInterface.h" | |
10 #include "gl/GrGLNameAllocator.h" | |
11 #include "gl/GrGLUtil.h" | |
12 | |
13 #define GL_CALL(X) GR_GL_CALL(fGLInterface.get(), X) | |
14 #define GL_CALL_RET(RET, X) GR_GL_CALL_RET(fGLInterface.get(), RET, X) | |
15 | |
16 class GrGLPathRenderingV12 : public GrGLPathRendering { | |
17 public: | |
18 GrGLPathRenderingV12(const GrGLInterface* glInterface) | |
19 : GrGLPathRendering(glInterface) { | |
20 } | |
21 | |
22 virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, | |
23 GrGLuint mask, GrGLenum coverMode)
SK_OVERRIDE; | |
24 virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference
, | |
25 GrGLuint mask, GrGLenum coverMod
e) SK_OVERRIDE; | |
26 virtual GrGLvoid stencilThenCoverFillPathInstanced( | |
27 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
id *paths, | |
28 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, Gr
GLenum coverMode, | |
29 GrGLenum transformType, const GrGLfloat *transformValue
s) SK_OVERRIDE; | |
30 virtual GrGLvoid stencilThenCoverStrokePathInstanced( | |
31 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
id *paths, | |
32 GrGLuint pathBase, GrGLint reference, GrGLuint mask, Gr
GLenum coverMode, | |
33 GrGLenum transformType, const GrGLfloat *transformValue
s) SK_OVERRIDE; | |
34 }; | |
35 | |
36 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 { | |
37 public: | |
38 GrGLPathRenderingV13(const GrGLInterface* glInterface) | |
39 : GrGLPathRenderingV12(glInterface) { | |
40 fCaps.fragmentInputGenSupport = true; | |
41 } | |
42 | |
43 virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint locat
ion, | |
44 GrGLenum genMode, GrGLint compo
nents, | |
45 const GrGLfloat *coeffs) SK_OVE
RRIDE; | |
46 }; | |
47 | |
48 | |
49 GrGLPathRendering* GrGLPathRendering::Create(const GrGLInterface* glInterface) { | |
50 if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath || | |
51 NULL == glInterface->fFunctions.fStencilThenCoverStrokePath || | |
52 NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced || | |
53 NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) { | |
54 return new GrGLPathRendering(glInterface); | |
55 } | |
56 | |
57 if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) { | |
58 return new GrGLPathRenderingV12(glInterface); | |
59 } | |
60 | |
61 return new GrGLPathRenderingV13(glInterface); | |
62 } | |
63 | |
64 GrGLPathRendering::GrGLPathRendering(const GrGLInterface* glInterface) | |
65 : fGLInterface(SkRef(glInterface)) { | |
66 memset(&fCaps, 0, sizeof(fCaps)); | |
67 } | |
68 | |
69 GrGLPathRendering::~GrGLPathRendering() { | |
70 } | |
71 | |
72 void GrGLPathRendering::abandonGpuResources() { | |
73 fPathNameAllocator.reset(NULL); | |
74 } | |
75 | |
76 | |
77 // NV_path_rendering | |
78 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { | |
79 if (range > 1) { | |
80 GrGLuint name; | |
81 GL_CALL_RET(name, GenPaths(range)); | |
82 return name; | |
83 } | |
84 | |
85 if (NULL == fPathNameAllocator.get()) { | |
86 static const int range = 65536; | |
87 GrGLuint firstName; | |
88 GL_CALL_RET(firstName, GenPaths(range)); | |
89 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, first
Name + range))); | |
90 } | |
91 | |
92 // When allocating names one at a time, pull from a client-side pool of | |
93 // available names in order to save a round trip to the GL server. | |
94 GrGLuint name = fPathNameAllocator->allocateName(); | |
95 | |
96 if (0 == name) { | |
97 // Our reserved path names are all in use. Fall back on GenPaths. | |
98 GL_CALL_RET(name, GenPaths(1)); | |
99 } | |
100 | |
101 return name; | |
102 } | |
103 | |
104 GrGLvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { | |
105 if (range > 1) { | |
106 // It is not supported to delete names in ranges that were allocated | |
107 // individually using GrGLPathNameAllocator. | |
108 SkASSERT(NULL == fPathNameAllocator.get() || | |
109 path + range <= fPathNameAllocator->firstName() || | |
110 path >= fPathNameAllocator->endName()); | |
111 GL_CALL(DeletePaths(path, range)); | |
112 return; | |
113 } | |
114 | |
115 if (NULL == fPathNameAllocator.get() || | |
116 path < fPathNameAllocator->firstName() || | |
117 path >= fPathNameAllocator->endName()) { | |
118 // If we aren't inside fPathNameAllocator's range then this name was | |
119 // generated by the GenPaths fallback (or else was never allocated). | |
120 GL_CALL(DeletePaths(path, 1)); | |
121 return; | |
122 } | |
123 | |
124 // Make the path empty to save memory, but don't free the name in the driver
. | |
125 GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); | |
126 fPathNameAllocator->free(path); | |
127 } | |
128 | |
129 GrGLvoid GrGLPathRendering::pathCommands(GrGLuint path, GrGLsizei numCommands, | |
130 const GrGLubyte *commands, GrGLsizei nu
mCoords, | |
131 GrGLenum coordType, const GrGLvoid *coo
rds) { | |
132 GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coor
ds)); | |
133 } | |
134 | |
135 GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords, | |
136 GrGLenum coordType, const GrGLvoid *coord
s) { | |
137 GL_CALL(PathCoords(path, numCoords, coordType, coords)); | |
138 } | |
139 | |
140 GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLin
t value) { | |
141 GL_CALL(PathParameteri(path, pname, value)); | |
142 } | |
143 | |
144 GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfl
oat value) { | |
145 GL_CALL(PathParameterf(path, pname, value)); | |
146 } | |
147 | |
148 GrGLboolean GrGLPathRendering::isPath(GrGLuint path) { | |
149 GrGLboolean ret; | |
150 GL_CALL_RET(ret, IsPath(path)); | |
151 return ret; | |
152 } | |
153 | |
154 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint
mask) { | |
155 GL_CALL(PathStencilFunc(func, ref, mask)); | |
156 } | |
157 | |
158 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, Gr
GLuint mask) { | |
159 GL_CALL(StencilFillPath(path, fillMode, mask)); | |
160 } | |
161 | |
162 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference,
GrGLuint mask) { | |
163 GL_CALL(StencilStrokePath(path, reference, mask)); | |
164 } | |
165 | |
166 GrGLvoid GrGLPathRendering::stencilFillPathInstanced( | |
167 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
168 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, | |
169 GrGLenum transformType, const GrGLfloat *transformValues) { | |
170 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
171 fillMode, mask, transformType, transformVal
ues)); | |
172 } | |
173 | |
174 GrGLvoid GrGLPathRendering::stencilStrokePathInstanced( | |
175 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
176 GrGLuint pathBase, GrGLint reference, GrGLuint mask, | |
177 GrGLenum transformType, const GrGLfloat *transformValues) { | |
178 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
179 reference, mask, transformType, transform
Values)); | |
180 } | |
181 | |
182 GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode, | |
183 GrGLint components, const GrGLfloat *coef
fs) { | |
184 GL_CALL(PathTexGen(texCoordSet, genMode, components, coeffs)); | |
185 } | |
186 | |
187 GrGLvoid GrGLPathRendering::coverFillPath(GrGLuint path, GrGLenum coverMode) { | |
188 GL_CALL(CoverFillPath(path, coverMode)); | |
189 } | |
190 | |
191 GrGLvoid GrGLPathRendering::coverStrokePath(GrGLuint name, GrGLenum coverMode) { | |
192 GL_CALL(CoverStrokePath(name, coverMode)); | |
193 } | |
194 | |
195 GrGLvoid GrGLPathRendering::coverFillPathInstanced( | |
196 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G
rGLuint pathBase, | |
197 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transf
ormValues) { | |
198 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
199 coverMode, transformType, transformValues)); | |
200 } | |
201 | |
202 GrGLvoid GrGLPathRendering::coverStrokePathInstanced( | |
203 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G
rGLuint pathBase, | |
204 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transf
ormValues) { | |
205 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
206 coverMode, transformType, transformValues))
; | |
207 } | |
208 | |
209 GrGLvoid GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fil
lMode, | |
210 GrGLuint mask, GrGLenum cov
erMode) { | |
211 GL_CALL(StencilFillPath(path, fillMode, mask)); | |
212 GL_CALL(CoverFillPath(path, coverMode)); | |
213 } | |
214 | |
215 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint re
ference, | |
216 GrGLuint mask, GrGLenum c
overMode) { | |
217 GL_CALL(StencilStrokePath(path, reference, mask)); | |
218 GL_CALL(CoverStrokePath(path, coverMode)); | |
219 } | |
220 | |
221 GrGLvoid GrGLPathRendering::stencilThenCoverFillPathInstanced( | |
222 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
223 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, | |
224 GrGLenum transformType, const GrGLfloat *transformValues) { | |
225 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
226 fillMode, mask, transformType, transformVal
ues)); | |
227 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
228 coverMode, transformType, transformValues)); | |
229 } | |
230 | |
231 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePathInstanced( | |
232 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
233 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover
Mode, | |
234 GrGLenum transformType, const GrGLfloat *transformValues) { | |
235 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
236 reference, mask, transformType, transform
Values)); | |
237 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
238 coverMode, transformType, transformValues))
; | |
239 } | |
240 | |
241 GrGLvoid GrGLPathRendering::programPathFragmentInputGen( | |
242 GrGLuint program, GrGLint location, GrGLenum genMode, | |
243 GrGLint components, const GrGLfloat *coeffs) { | |
244 SkFAIL("ProgramPathFragmentInputGen not supported in this GL context."); | |
245 } | |
246 | |
247 | |
248 // NV_path_rendering v1.2 | |
249 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPath(GrGLuint path, GrGLenum
fillMode, | |
250 GrGLuint mask, GrGLenum
coverMode) { | |
251 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); | |
252 } | |
253 | |
254 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePath(GrGLuint path, GrGLint
reference, | |
255 GrGLuint mask, GrGLenu
m coverMode) { | |
256 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); | |
257 } | |
258 | |
259 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPathInstanced( | |
260 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
261 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, | |
262 GrGLenum transformType, const GrGLfloat *transformValues) { | |
263 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pat
hBase, fillMode, | |
264 mask, coverMode, transformType, t
ransformValues)); | |
265 } | |
266 | |
267 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePathInstanced( | |
268 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
269 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover
Mode, | |
270 GrGLenum transformType, const GrGLfloat *transformValues) { | |
271 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, p
athBase, reference, | |
272 mask, coverMode, transformType,
transformValues)); | |
273 } | |
274 | |
275 | |
276 // NV_path_rendering v1.3 | |
277 GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen( | |
278 GrGLuint program, GrGLint location, GrGLenum genMode, | |
279 GrGLint components, const GrGLfloat *coeffs) { | |
280 GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components,
coeffs)); | |
281 } | |
OLD | NEW |