2 * Copyright 2014 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "gl/GrGLPathRendering.h"
9 #include "gl/GrGLInterface.h"
10 #include "gl/GrGLNameAllocator.h"
11 #include "gl/GrGLUtil.h"
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)
16 class GrGLPathRenderingV12 : public GrGLPathRendering {
18 GrGLPathRenderingV12(const GrGLInterface* glInterface)
19 : GrGLPathRendering(glInterface) {
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 coverMode) SK_OVERRIDE;
26 virtual GrGLvoid stencilThenCoverFillPathInstanced(
27 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
28 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
29 GrGLenum transformType, const GrGLfloat *transformValues) SK_OVERRIDE;
30 virtual GrGLvoid stencilThenCoverStrokePathInstanced(
31 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
32 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
33 GrGLenum transformType, const GrGLfloat *transformValues) SK_OVERRIDE;
36 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 {
38 GrGLPathRenderingV13(const GrGLInterface* glInterface)
39 : GrGLPathRenderingV12(glInterface) {
40 fCaps.fragmentInputGenSupport = true;
43 virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint location,
44 GrGLenum genMode, GrGLint components,
45 const GrGLfloat *coeffs) SK_OVERRIDE;
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);
57 if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) {
58 return new GrGLPathRenderingV12(glInterface);
61 return new GrGLPathRenderingV13(glInterface);
64 GrGLPathRendering::GrGLPathRendering(const GrGLInterface* glInterface)
65 : fGLInterface(SkRef(glInterface)) {
66 memset(&fCaps, 0, sizeof(fCaps));
69 GrGLPathRendering::~GrGLPathRendering() {
72 void GrGLPathRendering::abandonGpuResources() {
73 fPathNameAllocator.reset(NULL);
78 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) {
81 GL_CALL_RET(name, GenPaths(range));
85 if (NULL == fPathNameAllocator.get()) {
86 static const int range = 65536;
88 GL_CALL_RET(firstName, GenPaths(range));
89 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, firstName + range)));
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();
97 // Our reserved path names are all in use. Fall back on GenPaths.
98 GL_CALL_RET(name, GenPaths(1));
104 GrGLvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) {
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));
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));
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);
129 GrGLvoid GrGLPathRendering::pathCommands(GrGLuint path, GrGLsizei numCommands,
130 const GrGLubyte *commands, GrGLsizei numCoords,
131 GrGLenum coordType, const GrGLvoid *coords) {
132 GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coords));
135 GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords,
136 GrGLenum coordType, const GrGLvoid *coords) {
137 GL_CALL(PathCoords(path, numCoords, coordType, coords));
140 GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLint value) {
141 GL_CALL(PathParameteri(path, pname, value));
144 GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfloat value) {
145 GL_CALL(PathParameterf(path, pname, value));
148 GrGLboolean GrGLPathRendering::isPath(GrGLuint path) {
150 GL_CALL_RET(ret, IsPath(path));
154 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint mask) {
155 GL_CALL(PathStencilFunc(func, ref, mask));
158 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, GrGLuint mask) {
159 GL_CALL(StencilFillPath(path, fillMode, mask));
162 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference, GrGLuint mask) {
163 GL_CALL(StencilStrokePath(path, reference, mask));
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, transformValues));
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, transformValues));
182 GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode,
183 GrGLint components, const GrGLfloat *coeffs) {
184 GL_CALL(PathTexGen(texCoordSet, genMode, components, coeffs));
187 GrGLvoid GrGLPathRendering::coverFillPath(GrGLuint path, GrGLenum coverMode) {
188 GL_CALL(CoverFillPath(path, coverMode));
191 GrGLvoid GrGLPathRendering::coverStrokePath(GrGLuint name, GrGLenum coverMode) {
192 GL_CALL(CoverStrokePath(name, coverMode));
195 GrGLvoid GrGLPathRendering::coverFillPathInstanced(
196 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase,
197 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) {
198 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
199 coverMode, transformType, transformValues));
202 GrGLvoid GrGLPathRendering::coverStrokePathInstanced(
203 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, GrGLuint pathBase,
204 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues) {
205 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
206 coverMode, transformType, transformValues));
209 GrGLvoid GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode,
210 GrGLuint mask, GrGLenum coverMode) {
211 GL_CALL(StencilFillPath(path, fillMode, mask));
212 GL_CALL(CoverFillPath(path, coverMode));
215 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
216 GrGLuint mask, GrGLenum coverMode) {
217 GL_CALL(StencilStrokePath(path, reference, mask));
218 GL_CALL(CoverStrokePath(path, coverMode));
221 GrGLvoid GrGLPathRendering::stencilThenCoverFillPathInstanced(
222 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
223 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
224 GrGLenum transformType, const GrGLfloat *transformValues) {
225 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase,
226 fillMode, mask, transformType, transformValues));
227 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase,
228 coverMode, transformType, transformValues));
231 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePathInstanced(
232 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
233 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
234 GrGLenum transformType, const GrGLfloat *transformValues) {
235 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
236 reference, mask, transformType, transformValues));
237 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
238 coverMode, transformType, transformValues));
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.");
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));
254 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePath(GrGLuint path, GrGLint reference,
255 GrGLuint mask, GrGLenum coverMode) {
256 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode));
259 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPathInstanced(
260 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
261 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum coverMode,
262 GrGLenum transformType, const GrGLfloat *transformValues) {
263 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
264 mask, coverMode, transformType, transformValues));
267 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePathInstanced(
268 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths,
269 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode,
270 GrGLenum transformType, const GrGLfloat *transformValues) {
271 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, reference,
272 mask, coverMode, transformType, transformValues));
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));