| 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 |