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 |