Chromium Code Reviews| 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) { | |
|
Mark Kilgard
2014/08/04 17:08:53
good, I like this
| |
| 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 |