OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "gl/GrGLPathRendering.h" | 8 #include "gl/GrGLPathRendering.h" |
9 #include "gl/GrGLNameAllocator.h" | 9 #include "gl/GrGLNameAllocator.h" |
10 #include "gl/GrGLUtil.h" | 10 #include "gl/GrGLUtil.h" |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
54 /* fallthrough */; | 54 /* fallthrough */; |
55 case kIncClamp_StencilOp: | 55 case kIncClamp_StencilOp: |
56 return GR_GL_COUNT_UP; | 56 return GR_GL_COUNT_UP; |
57 case kInvert_StencilOp: | 57 case kInvert_StencilOp: |
58 return GR_GL_INVERT; | 58 return GR_GL_INVERT; |
59 } | 59 } |
60 } | 60 } |
61 | 61 |
62 GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu) | 62 GrGLPathRendering::GrGLPathRendering(GrGLGpu* gpu) |
63 : GrPathRendering(gpu) { | 63 : GrPathRendering(gpu) { |
| 64 const GrGLInterface* glInterface = gpu->glInterface(); |
| 65 fCaps.stencilThenCoverSupport = |
| 66 NULL != glInterface->fFunctions.fStencilThenCoverFillPath && |
| 67 NULL != glInterface->fFunctions.fStencilThenCoverStrokePath && |
| 68 NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced && |
| 69 NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced; |
| 70 fCaps.fragmentInputGenSupport = |
| 71 NULL != glInterface->fFunctions.fProgramPathFragmentInputGen; |
| 72 |
| 73 SkASSERT(fCaps.fragmentInputGenSupport); |
64 } | 74 } |
65 | 75 |
66 GrGLPathRendering::~GrGLPathRendering() { | 76 GrGLPathRendering::~GrGLPathRendering() { |
67 } | 77 } |
68 | 78 |
69 void GrGLPathRendering::abandonGpuResources() { | 79 void GrGLPathRendering::abandonGpuResources() { |
70 fPathNameAllocator.reset(NULL); | 80 fPathNameAllocator.reset(NULL); |
71 } | 81 } |
72 | 82 |
73 void GrGLPathRendering::resetContext() { | 83 void GrGLPathRendering::resetContext() { |
74 fHWProjectionMatrixState.invalidate(); | 84 fHWProjectionMatrixState.invalidate(); |
75 // we don't use the model view matrix. | 85 // we don't use the model view matrix. |
76 GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW)); | 86 GL_CALL(MatrixLoadIdentity(GR_GL_PATH_MODELVIEW)); |
77 | 87 |
| 88 SkASSERT(fCaps.fragmentInputGenSupport); |
78 fHWPathStencilSettings.invalidate(); | 89 fHWPathStencilSettings.invalidate(); |
79 } | 90 } |
80 | 91 |
81 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo&
stroke) { | 92 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const GrStrokeInfo&
stroke) { |
82 return SkNEW_ARGS(GrGLPath, (this->gpu(), inPath, stroke)); | 93 return SkNEW_ARGS(GrGLPath, (this->gpu(), inPath, stroke)); |
83 } | 94 } |
84 | 95 |
85 GrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* path
Generator, | 96 GrPathRange* GrGLPathRendering::createPathRange(GrPathRange::PathGenerator* path
Generator, |
86 const GrStrokeInfo& stroke) { | 97 const GrStrokeInfo& stroke) { |
87 return SkNEW_ARGS(GrGLPathRange, (this->gpu(), pathGenerator, stroke)); | 98 return SkNEW_ARGS(GrGLPathRange, (this->gpu(), pathGenerator, stroke)); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 138 SkASSERT(!fHWPathStencilSettings.isTwoSided()); |
128 | 139 |
129 GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode( | 140 GrGLenum fillMode = gr_stencil_op_to_gl_path_rendering_fill_mode( |
130 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); | 141 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); |
131 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); | 142 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); |
132 | 143 |
133 if (glPath->shouldStroke()) { | 144 if (glPath->shouldStroke()) { |
134 if (glPath->shouldFill()) { | 145 if (glPath->shouldFill()) { |
135 GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask)); | 146 GL_CALL(StencilFillPath(glPath->pathID(), fillMode, writeMask)); |
136 } | 147 } |
137 GL_CALL(StencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask, | 148 this->stencilThenCoverStrokePath(glPath->pathID(), 0xffff, writeMask, GR
_GL_BOUNDING_BOX); |
138 GR_GL_BOUNDING_BOX)); | |
139 } else { | 149 } else { |
140 GL_CALL(StencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask, | 150 this->stencilThenCoverFillPath(glPath->pathID(), fillMode, writeMask, GR
_GL_BOUNDING_BOX); |
141 GR_GL_BOUNDING_BOX)); | |
142 } | 151 } |
143 } | 152 } |
144 | 153 |
145 void GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange*
pathRange, | 154 void GrGLPathRendering::onDrawPaths(const DrawPathArgs& args, const GrPathRange*
pathRange, |
146 const void* indices, PathIndexType indexType
, | 155 const void* indices, PathIndexType indexType
, |
147 const float transformValues[], PathTransform
Type transformType, | 156 const float transformValues[], PathTransform
Type transformType, |
148 int count) { | 157 int count) { |
149 if (!this->gpu()->flushGLState(args)) { | 158 if (!this->gpu()->flushGLState(args)) { |
150 return; | 159 return; |
151 } | 160 } |
152 this->flushPathStencilSettings(*args.fStencil); | 161 this->flushPathStencilSettings(*args.fStencil); |
153 SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 162 SkASSERT(!fHWPathStencilSettings.isTwoSided()); |
154 | 163 |
155 | 164 |
156 const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRan
ge); | 165 const GrGLPathRange* glPathRange = static_cast<const GrGLPathRange*>(pathRan
ge); |
157 | 166 |
158 GrGLenum fillMode = | 167 GrGLenum fillMode = |
159 gr_stencil_op_to_gl_path_rendering_fill_mode( | 168 gr_stencil_op_to_gl_path_rendering_fill_mode( |
160 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); | 169 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); |
161 GrGLint writeMask = | 170 GrGLint writeMask = |
162 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); | 171 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); |
163 | 172 |
164 if (glPathRange->shouldStroke()) { | 173 if (glPathRange->shouldStroke()) { |
165 if (glPathRange->shouldFill()) { | 174 if (glPathRange->shouldFill()) { |
166 GL_CALL(StencilFillPathInstanced( | 175 GL_CALL(StencilFillPathInstanced( |
167 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), | 176 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), |
168 fillMode, writeMask, gXformType2GLType[transformType
], | 177 fillMode, writeMask, gXformType2GLType[transformType
], |
169 transformValues)); | 178 transformValues)); |
170 } | 179 } |
171 GL_CALL(StencilThenCoverStrokePathInstanced( | 180 this->stencilThenCoverStrokePathInstanced( |
172 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), | 181 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), |
173 0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BO
XES, | 182 0xffff, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_BO
XES, |
174 gXformType2GLType[transformType], transformValues)); | 183 gXformType2GLType[transformType], transformValues); |
175 } else { | 184 } else { |
176 GL_CALL(StencilThenCoverFillPathInstanced( | 185 this->stencilThenCoverFillPathInstanced( |
177 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), | 186 count, gIndexType2GLType[indexType], indices, glPath
Range->basePathID(), |
178 fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_
BOXES, | 187 fillMode, writeMask, GR_GL_BOUNDING_BOX_OF_BOUNDING_
BOXES, |
179 gXformType2GLType[transformType], transformValues)); | 188 gXformType2GLType[transformType], transformValues); |
180 } | 189 } |
181 } | 190 } |
182 | 191 |
183 void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, G
rGLint location, | 192 void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, G
rGLint location, |
184 GrGLenum genMode, G
rGLint components, | 193 GrGLenum genMode, G
rGLint components, |
185 const SkMatrix& mat
rix) { | 194 const SkMatrix& mat
rix) { |
| 195 SkASSERT(caps().fragmentInputGenSupport); |
186 GrGLfloat coefficients[3 * 3]; | 196 GrGLfloat coefficients[3 * 3]; |
187 SkASSERT(components >= 1 && components <= 3); | 197 SkASSERT(components >= 1 && components <= 3); |
188 | 198 |
189 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); | 199 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); |
190 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); | 200 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); |
191 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); | 201 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); |
192 | 202 |
193 if (components >= 2) { | 203 if (components >= 2) { |
194 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); | 204 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); |
195 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); | 205 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 // that draws the path to the SB (glStencilFillPath) | 293 // that draws the path to the SB (glStencilFillPath) |
284 GrGLenum func = | 294 GrGLenum func = |
285 GrToGLStencilFunc(stencilSettings.func(GrStencilSettings::kFront_Fac
e)); | 295 GrToGLStencilFunc(stencilSettings.func(GrStencilSettings::kFront_Fac
e)); |
286 GL_CALL(PathStencilFunc(func, stencilSettings.funcRef(GrStencilSettings:
:kFront_Face), | 296 GL_CALL(PathStencilFunc(func, stencilSettings.funcRef(GrStencilSettings:
:kFront_Face), |
287 stencilSettings.funcMask(GrStencilSettings::kFro
nt_Face))); | 297 stencilSettings.funcMask(GrStencilSettings::kFro
nt_Face))); |
288 | 298 |
289 fHWPathStencilSettings = stencilSettings; | 299 fHWPathStencilSettings = stencilSettings; |
290 } | 300 } |
291 } | 301 } |
292 | 302 |
| 303 inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum
fillMode, |
| 304 GrGLuint mask, GrGLenum cov
erMode) { |
| 305 if (caps().stencilThenCoverSupport) { |
| 306 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); |
| 307 return; |
| 308 } |
| 309 GL_CALL(StencilFillPath(path, fillMode, mask)); |
| 310 GL_CALL(CoverFillPath(path, coverMode)); |
| 311 } |
| 312 |
| 313 inline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint
reference, |
| 314 GrGLuint mask, GrGLenum c
overMode) { |
| 315 if (caps().stencilThenCoverSupport) { |
| 316 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); |
| 317 return; |
| 318 } |
| 319 GL_CALL(StencilStrokePath(path, reference, mask)); |
| 320 GL_CALL(CoverStrokePath(path, coverMode)); |
| 321 } |
| 322 |
| 323 inline void GrGLPathRendering::stencilThenCoverFillPathInstanced( |
| 324 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, |
| 325 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, |
| 326 GrGLenum transformType, const GrGLfloat *transformValues) { |
| 327 if (caps().stencilThenCoverSupport) { |
| 328 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths,
pathBase, fillMode, |
| 329 mask, coverMode, transformType
, transformValues)); |
| 330 return; |
| 331 } |
| 332 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, |
| 333 fillMode, mask, transformType, transformVal
ues)); |
| 334 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, |
| 335 coverMode, transformType, transformValues)); |
| 336 } |
| 337 |
| 338 inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced( |
| 339 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, |
| 340 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, |
| 341 GrGLenum transformType, const GrGLfloat *transformValues) { |
| 342 if (caps().stencilThenCoverSupport) { |
| 343 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, path
s, pathBase, |
| 344 reference, mask, coverMode,
transformType, |
| 345 transformValues)); |
| 346 return; |
| 347 } |
| 348 |
| 349 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
| 350 reference, mask, transformType, transform
Values)); |
| 351 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
| 352 coverMode, transformType, transformValues))
; |
| 353 } |
| 354 |
293 inline GrGLGpu* GrGLPathRendering::gpu() { | 355 inline GrGLGpu* GrGLPathRendering::gpu() { |
294 return static_cast<GrGLGpu*>(fGpu); | 356 return static_cast<GrGLGpu*>(fGpu); |
295 } | 357 } |
OLD | NEW |