Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / gl / GrGLPathRendering.cpp
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 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;
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 location,
44                                                  GrGLenum genMode, GrGLint components,
45                                                  const GrGLfloat *coeffs) SK_OVERRIDE;
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, firstName + 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 numCoords,
131                                          GrGLenum coordType, const GrGLvoid *coords) {
132     GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coords));
133 }
134
135 GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords,
136                                        GrGLenum coordType, const GrGLvoid *coords) {
137     GL_CALL(PathCoords(path, numCoords, coordType, coords));
138 }
139
140 GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLint value) {
141     GL_CALL(PathParameteri(path, pname, value));
142 }
143
144 GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfloat 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, GrGLuint 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, transformValues));
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, transformValues));
180 }
181
182 GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode,
183                                        GrGLint components, const GrGLfloat *coeffs) {
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, GrGLuint pathBase,
197              GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transformValues) {
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, GrGLuint pathBase,
204              GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transformValues) {
205     GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase,
206                                      coverMode, transformType, transformValues));
207 }
208
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));
213 }
214
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));
219 }
220
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));
229 }
230
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));
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, GrGLenum 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 coverMode,
262              GrGLenum transformType, const GrGLfloat *transformValues) {
263     GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, fillMode,
264                                                mask, coverMode, transformType, transformValues));
265 }
266
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));
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 }