| 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 27 matching lines...) Expand all Loading... |
| 38 default: | 38 default: |
| 39 SkFAIL("Unexpected path fill."); | 39 SkFAIL("Unexpected path fill."); |
| 40 /* fallthrough */; | 40 /* fallthrough */; |
| 41 case kIncClamp_StencilOp: | 41 case kIncClamp_StencilOp: |
| 42 return GR_GL_COUNT_UP; | 42 return GR_GL_COUNT_UP; |
| 43 case kInvert_StencilOp: | 43 case kInvert_StencilOp: |
| 44 return GR_GL_INVERT; | 44 return GR_GL_INVERT; |
| 45 } | 45 } |
| 46 } | 46 } |
| 47 | 47 |
| 48 class GrGLPathRenderingV12 : public GrGLPathRendering { | |
| 49 public: | |
| 50 GrGLPathRenderingV12(GrGpuGL* gpu) | |
| 51 : GrGLPathRendering(gpu) { | |
| 52 } | |
| 53 | |
| 54 virtual GrGLvoid stencilThenCoverFillPath(GrGLuint path, GrGLenum fillMode, | |
| 55 GrGLuint mask, GrGLenum coverMode)
SK_OVERRIDE; | |
| 56 virtual GrGLvoid stencilThenCoverStrokePath(GrGLuint path, GrGLint reference
, | |
| 57 GrGLuint mask, GrGLenum coverMod
e) SK_OVERRIDE; | |
| 58 virtual GrGLvoid stencilThenCoverFillPathInstanced( | |
| 59 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
id *paths, | |
| 60 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, Gr
GLenum coverMode, | |
| 61 GrGLenum transformType, const GrGLfloat *transformValue
s) SK_OVERRIDE; | |
| 62 virtual GrGLvoid stencilThenCoverStrokePathInstanced( | |
| 63 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvo
id *paths, | |
| 64 GrGLuint pathBase, GrGLint reference, GrGLuint mask, Gr
GLenum coverMode, | |
| 65 GrGLenum transformType, const GrGLfloat *transformValue
s) SK_OVERRIDE; | |
| 66 }; | |
| 67 | |
| 68 class GrGLPathRenderingV13 : public GrGLPathRenderingV12 { | |
| 69 public: | |
| 70 GrGLPathRenderingV13(GrGpuGL* gpu) | |
| 71 : GrGLPathRenderingV12(gpu) { | |
| 72 fCaps.fragmentInputGenSupport = true; | |
| 73 } | |
| 74 | |
| 75 virtual GrGLvoid programPathFragmentInputGen(GrGLuint program, GrGLint locat
ion, | |
| 76 GrGLenum genMode, GrGLint compo
nents, | |
| 77 const GrGLfloat *coeffs) SK_OVE
RRIDE; | |
| 78 }; | |
| 79 | |
| 80 | |
| 81 GrGLPathRendering* GrGLPathRendering::Create(GrGpuGL* gpu) { | |
| 82 const GrGLInterface* glInterface = gpu->glInterface(); | |
| 83 if (NULL == glInterface->fFunctions.fStencilThenCoverFillPath || | |
| 84 NULL == glInterface->fFunctions.fStencilThenCoverStrokePath || | |
| 85 NULL == glInterface->fFunctions.fStencilThenCoverFillPathInstanced || | |
| 86 NULL == glInterface->fFunctions.fStencilThenCoverStrokePathInstanced) { | |
| 87 return new GrGLPathRendering(gpu); | |
| 88 } | |
| 89 | |
| 90 if (NULL == glInterface->fFunctions.fProgramPathFragmentInputGen) { | |
| 91 return new GrGLPathRenderingV12(gpu); | |
| 92 } | |
| 93 | |
| 94 return new GrGLPathRenderingV13(gpu); | |
| 95 } | |
| 96 | |
| 97 GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu) | 48 GrGLPathRendering::GrGLPathRendering(GrGpuGL* gpu) |
| 98 : fGpu(gpu) { | 49 : fGpu(gpu) { |
| 99 memset(&fCaps, 0, sizeof(fCaps)); | 50 const GrGLInterface* glInterface = gpu->glInterface(); |
| 51 fCaps.stencilThenCoverSupport = |
| 52 NULL != glInterface->fFunctions.fStencilThenCoverFillPath && |
| 53 NULL != glInterface->fFunctions.fStencilThenCoverStrokePath && |
| 54 NULL != glInterface->fFunctions.fStencilThenCoverFillPathInstanced && |
| 55 NULL != glInterface->fFunctions.fStencilThenCoverStrokePathInstanced; |
| 56 fCaps.fragmentInputGenSupport = |
| 57 NULL != glInterface->fFunctions.fProgramPathFragmentInputGen; |
| 100 fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords()); | 58 fHWPathTexGenSettings.reset(fGpu->glCaps().maxFixedFunctionTextureCoords()); |
| 101 } | 59 } |
| 102 | 60 |
| 103 GrGLPathRendering::~GrGLPathRendering() { | 61 GrGLPathRendering::~GrGLPathRendering() { |
| 104 } | 62 } |
| 105 | 63 |
| 106 void GrGLPathRendering::abandonGpuResources() { | 64 void GrGLPathRendering::abandonGpuResources() { |
| 107 fPathNameAllocator.reset(NULL); | 65 fPathNameAllocator.reset(NULL); |
| 108 } | 66 } |
| 109 | 67 |
| 110 void GrGLPathRendering::resetContext() { | 68 void GrGLPathRendering::resetContext() { |
| 111 fHWProjectionMatrixState.invalidate(); | 69 fHWProjectionMatrixState.invalidate(); |
| 112 // we don't use the model view matrix. | 70 // we don't use the model view matrix. |
| 113 GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); | 71 GL_CALL(MatrixLoadIdentity(GR_GL_MODELVIEW)); |
| 114 | 72 |
| 115 for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { | 73 for (int i = 0; i < fGpu->glCaps().maxFixedFunctionTextureCoords(); ++i) { |
| 116 this->pathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL); | 74 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); |
| 117 fHWPathTexGenSettings[i].fMode = GR_GL_NONE; | 75 fHWPathTexGenSettings[i].fMode = GR_GL_NONE; |
| 118 fHWPathTexGenSettings[i].fNumComponents = 0; | 76 fHWPathTexGenSettings[i].fNumComponents = 0; |
| 119 } | 77 } |
| 120 fHWActivePathTexGenSets = 0; | 78 fHWActivePathTexGenSets = 0; |
| 121 fHWPathStencilSettings.invalidate(); | 79 fHWPathStencilSettings.invalidate(); |
| 122 } | 80 } |
| 123 | 81 |
| 124 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& s
troke) { | 82 GrPath* GrGLPathRendering::createPath(const SkPath& inPath, const SkStrokeRec& s
troke) { |
| 125 return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke)); | 83 return SkNEW_ARGS(GrGLPath, (fGpu, inPath, stroke)); |
| 126 } | 84 } |
| 127 | 85 |
| 128 GrPathRange* GrGLPathRendering::createPathRange(size_t size, const SkStrokeRec&
stroke) { | 86 GrPathRange* GrGLPathRendering::createPathRange(size_t size, const SkStrokeRec&
stroke) { |
| 129 return SkNEW_ARGS(GrGLPathRange, (fGpu, size, stroke)); | 87 return SkNEW_ARGS(GrGLPathRange, (fGpu, size, stroke)); |
| 130 } | 88 } |
| 131 | 89 |
| 132 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
nents, | |
| 133 const GrGLfloat* coefficients) { | |
| 134 SkASSERT(components >= kS_PathTexGenComponents && | |
| 135 components <= kSTR_PathTexGenComponents); | |
| 136 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx); | |
| 137 | |
| 138 if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode && | |
| 139 components == fHWPathTexGenSettings[unitIdx].fNumComponents && | |
| 140 !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients, | |
| 141 3 * components * sizeof(GrGLfloat))) { | |
| 142 return; | |
| 143 } | |
| 144 | |
| 145 fGpu->setTextureUnit(unitIdx); | |
| 146 | |
| 147 fHWPathTexGenSettings[unitIdx].fNumComponents = components; | |
| 148 this->pathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components,
coefficients); | |
| 149 | |
| 150 memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, | |
| 151 3 * components * sizeof(GrGLfloat)); | |
| 152 } | |
| 153 | |
| 154 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
nents, | |
| 155 const SkMatrix& matrix) { | |
| 156 GrGLfloat coefficients[3 * 3]; | |
| 157 SkASSERT(components >= kS_PathTexGenComponents && | |
| 158 components <= kSTR_PathTexGenComponents); | |
| 159 | |
| 160 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); | |
| 161 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); | |
| 162 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); | |
| 163 | |
| 164 if (components >= kST_PathTexGenComponents) { | |
| 165 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); | |
| 166 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); | |
| 167 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); | |
| 168 } | |
| 169 | |
| 170 if (components >= kSTR_PathTexGenComponents) { | |
| 171 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); | |
| 172 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); | |
| 173 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); | |
| 174 } | |
| 175 | |
| 176 this->enablePathTexGen(unitIdx, components, coefficients); | |
| 177 } | |
| 178 | |
| 179 void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) { | |
| 180 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSe
ts); | |
| 181 | |
| 182 // Only write the inactive path tex gens, since active path tex gens were | |
| 183 // written when they were enabled. | |
| 184 | |
| 185 SkDEBUGCODE( | |
| 186 for (int i = 0; i < numUsedTexCoordSets; i++) { | |
| 187 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); | |
| 188 } | |
| 189 ); | |
| 190 | |
| 191 for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) { | |
| 192 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); | |
| 193 | |
| 194 fGpu->setTextureUnit(i); | |
| 195 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); | |
| 196 fHWPathTexGenSettings[i].fNumComponents = 0; | |
| 197 } | |
| 198 | |
| 199 fHWActivePathTexGenSets = numUsedTexCoordSets; | |
| 200 } | |
| 201 | |
| 202 void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { | 90 void GrGLPathRendering::stencilPath(const GrPath* path, SkPath::FillType fill) { |
| 203 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); | 91 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); |
| 204 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); | 92 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); |
| 205 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); | 93 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); |
| 206 | 94 |
| 207 this->flushPathStencilSettings(fill); | 95 this->flushPathStencilSettings(fill); |
| 208 SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 96 SkASSERT(!fHWPathStencilSettings.isTwoSided()); |
| 209 | 97 |
| 210 GrGLenum fillMode = | 98 GrGLenum fillMode = |
| 211 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
Op(GrStencilSettings::kFront_Face)); | 99 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
Op(GrStencilSettings::kFront_Face)); |
| 212 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); | 100 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); |
| 213 this->stencilFillPath(id, fillMode, writeMask); | 101 GL_CALL(StencilFillPath(id, fillMode, writeMask)); |
| 214 } | 102 } |
| 215 | 103 |
| 216 void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { | 104 void GrGLPathRendering::drawPath(const GrPath* path, SkPath::FillType fill) { |
| 217 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); | 105 GrGLuint id = static_cast<const GrGLPath*>(path)->pathID(); |
| 218 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); | 106 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()); |
| 219 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); | 107 SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer()); |
| 220 SkASSERT(!fGpu->fCurrentProgram->hasVertexShader()); | 108 SkASSERT(!fGpu->fCurrentProgram->hasVertexShader()); |
| 221 | 109 |
| 222 this->flushPathStencilSettings(fill); | 110 this->flushPathStencilSettings(fill); |
| 223 SkASSERT(!fHWPathStencilSettings.isTwoSided()); | 111 SkASSERT(!fHWPathStencilSettings.isTwoSided()); |
| 224 | 112 |
| 225 const SkStrokeRec& stroke = path->getStroke(); | 113 const SkStrokeRec& stroke = path->getStroke(); |
| 226 | 114 |
| 227 SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill)
; | 115 SkPath::FillType nonInvertedFill = SkPath::ConvertToNonInverseFillType(fill)
; |
| 228 | 116 |
| 229 GrGLenum fillMode = | 117 GrGLenum fillMode = |
| 230 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
Op(GrStencilSettings::kFront_Face)); | 118 gr_stencil_op_to_gl_path_rendering_fill_mode(fHWPathStencilSettings.pass
Op(GrStencilSettings::kFront_Face)); |
| 231 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); | 119 GrGLint writeMask = fHWPathStencilSettings.writeMask(GrStencilSettings::kFro
nt_Face); |
| 232 | 120 |
| 233 if (nonInvertedFill == fill) { | 121 if (nonInvertedFill == fill) { |
| 234 if (stroke.needToApply()) { | 122 if (stroke.needToApply()) { |
| 235 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { | 123 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { |
| 236 this->stencilFillPath(id, fillMode, writeMask); | 124 GL_CALL(StencilFillPath(id, fillMode, writeMask)); |
| 237 } | 125 } |
| 238 this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDI
NG_BOX); | 126 this->stencilThenCoverStrokePath(id, 0xffff, writeMask, GR_GL_BOUNDI
NG_BOX); |
| 239 } else { | 127 } else { |
| 240 this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDI
NG_BOX); | 128 this->stencilThenCoverFillPath(id, fillMode, writeMask, GR_GL_BOUNDI
NG_BOX); |
| 241 } | 129 } |
| 242 } else { | 130 } else { |
| 243 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
getStyle()) { | 131 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
getStyle()) { |
| 244 this->stencilFillPath(id, fillMode, writeMask); | 132 GL_CALL(StencilFillPath(id, fillMode, writeMask)); |
| 245 } | 133 } |
| 246 if (stroke.needToApply()) { | 134 if (stroke.needToApply()) { |
| 247 this->stencilStrokePath(id, 0xffff, writeMask); | 135 GL_CALL(StencilStrokePath(id, 0xffff, writeMask)); |
| 248 } | 136 } |
| 249 | 137 |
| 250 GrDrawState* drawState = fGpu->drawState(); | 138 GrDrawState* drawState = fGpu->drawState(); |
| 251 GrDrawState::AutoViewMatrixRestore avmr; | 139 GrDrawState::AutoViewMatrixRestore avmr; |
| 252 SkRect bounds = SkRect::MakeLTRB(0, 0, | 140 SkRect bounds = SkRect::MakeLTRB(0, 0, |
| 253 SkIntToScalar(drawState->getRenderTarge
t()->width()), | 141 SkIntToScalar(drawState->getRenderTarge
t()->width()), |
| 254 SkIntToScalar(drawState->getRenderTarge
t()->height())); | 142 SkIntToScalar(drawState->getRenderTarge
t()->height())); |
| 255 SkMatrix vmi; | 143 SkMatrix vmi; |
| 256 // mapRect through persp matrix may not be correct | 144 // mapRect through persp matrix may not be correct |
| 257 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { | 145 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 288 | 176 |
| 289 GrGLenum fillMode = | 177 GrGLenum fillMode = |
| 290 gr_stencil_op_to_gl_path_rendering_fill_mode( | 178 gr_stencil_op_to_gl_path_rendering_fill_mode( |
| 291 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); | 179 fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face)); |
| 292 GrGLint writeMask = | 180 GrGLint writeMask = |
| 293 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); | 181 fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face); |
| 294 | 182 |
| 295 if (nonInvertedFill == fill) { | 183 if (nonInvertedFill == fill) { |
| 296 if (stroke.needToApply()) { | 184 if (stroke.needToApply()) { |
| 297 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { | 185 if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) { |
| 298 this->stencilFillPathInstanced( | 186 GL_CALL(StencilFillPathInstanced( |
| 299 count, GR_GL_UNSIGNED_INT, indices, baseID,
fillMode, | 187 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
Mode, |
| 300 writeMask, gXformType2GLType[transformsType]
, | 188 writeMask, gXformType2GLType[transformsType], |
| 301 transforms); | 189 transforms)); |
| 302 } | 190 } |
| 303 this->stencilThenCoverStrokePathInstanced( | 191 this->stencilThenCoverStrokePathInstanced( |
| 304 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
ff, writeMask, | 192 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
ff, writeMask, |
| 305 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, | 193 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, |
| 306 gXformType2GLType[transformsType], transforms); | 194 gXformType2GLType[transformsType], transforms); |
| 307 } else { | 195 } else { |
| 308 this->stencilThenCoverFillPathInstanced( | 196 this->stencilThenCoverFillPathInstanced( |
| 309 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
Mode, writeMask, | 197 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
Mode, writeMask, |
| 310 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, | 198 GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES, |
| 311 gXformType2GLType[transformsType], transforms); | 199 gXformType2GLType[transformsType], transforms); |
| 312 } | 200 } |
| 313 } else { | 201 } else { |
| 314 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
getStyle()) { | 202 if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.
getStyle()) { |
| 315 this->stencilFillPathInstanced( | 203 GL_CALL(StencilFillPathInstanced( |
| 316 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
Mode, | 204 count, GR_GL_UNSIGNED_INT, indices, baseID, fill
Mode, |
| 317 writeMask, gXformType2GLType[transformsType], | 205 writeMask, gXformType2GLType[transformsType], |
| 318 transforms); | 206 transforms)); |
| 319 } | 207 } |
| 320 if (stroke.needToApply()) { | 208 if (stroke.needToApply()) { |
| 321 this->stencilStrokePathInstanced( | 209 GL_CALL(StencilStrokePathInstanced( |
| 322 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
ff, | 210 count, GR_GL_UNSIGNED_INT, indices, baseID, 0xff
ff, |
| 323 writeMask, gXformType2GLType[transformsType], | 211 writeMask, gXformType2GLType[transformsType], |
| 324 transforms); | 212 transforms)); |
| 325 } | 213 } |
| 326 | 214 |
| 327 GrDrawState* drawState = fGpu->drawState(); | 215 GrDrawState* drawState = fGpu->drawState(); |
| 328 GrDrawState::AutoViewMatrixRestore avmr; | 216 GrDrawState::AutoViewMatrixRestore avmr; |
| 329 SkRect bounds = SkRect::MakeLTRB(0, 0, | 217 SkRect bounds = SkRect::MakeLTRB(0, 0, |
| 330 SkIntToScalar(drawState->getRenderTarge
t()->width()), | 218 SkIntToScalar(drawState->getRenderTarge
t()->width()), |
| 331 SkIntToScalar(drawState->getRenderTarge
t()->height())); | 219 SkIntToScalar(drawState->getRenderTarge
t()->height())); |
| 332 SkMatrix vmi; | 220 SkMatrix vmi; |
| 333 // mapRect through persp matrix may not be correct | 221 // mapRect through persp matrix may not be correct |
| 334 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { | 222 if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewIn
verse(&vmi)) { |
| 335 vmi.mapRect(&bounds); | 223 vmi.mapRect(&bounds); |
| 336 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion | 224 // theoretically could set bloat = 0, instead leave it because of ma
trix inversion |
| 337 // precision. | 225 // precision. |
| 338 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
rHalf; | 226 SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_Scala
rHalf; |
| 339 bounds.outset(bloat, bloat); | 227 bounds.outset(bloat, bloat); |
| 340 } else { | 228 } else { |
| 341 avmr.setIdentity(drawState); | 229 avmr.setIdentity(drawState); |
| 342 } | 230 } |
| 343 | 231 |
| 344 fGpu->drawSimpleRect(bounds); | 232 fGpu->drawSimpleRect(bounds); |
| 345 } | 233 } |
| 346 } | 234 } |
| 347 | 235 |
| 348 void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { | 236 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
nents, |
| 349 GrStencilSettings pathStencilSettings; | 237 const GrGLfloat* coefficients) { |
| 350 fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); | 238 SkASSERT(components >= kS_PathTexGenComponents && |
| 351 if (fHWPathStencilSettings != pathStencilSettings) { | 239 components <= kSTR_PathTexGenComponents); |
| 352 // Just the func, ref, and mask is set here. The op and write mask are p
arams to the call | 240 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= unitIdx); |
| 353 // that draws the path to the SB (glStencilFillPath) | |
| 354 GrGLenum func = | |
| 355 GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront
_Face)); | |
| 356 this->pathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSetting
s::kFront_Face), | |
| 357 pathStencilSettings.funcMask(GrStencilSettings::kF
ront_Face)); | |
| 358 | 241 |
| 359 fHWPathStencilSettings = pathStencilSettings; | 242 if (GR_GL_OBJECT_LINEAR == fHWPathTexGenSettings[unitIdx].fMode && |
| 243 components == fHWPathTexGenSettings[unitIdx].fNumComponents && |
| 244 !memcmp(coefficients, fHWPathTexGenSettings[unitIdx].fCoefficients, |
| 245 3 * components * sizeof(GrGLfloat))) { |
| 246 return; |
| 360 } | 247 } |
| 248 |
| 249 fGpu->setTextureUnit(unitIdx); |
| 250 |
| 251 fHWPathTexGenSettings[unitIdx].fNumComponents = components; |
| 252 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + unitIdx, GR_GL_OBJECT_LINEAR, components
, coefficients)); |
| 253 |
| 254 memcpy(fHWPathTexGenSettings[unitIdx].fCoefficients, coefficients, |
| 255 3 * components * sizeof(GrGLfloat)); |
| 256 } |
| 257 |
| 258 void GrGLPathRendering::enablePathTexGen(int unitIdx, PathTexGenComponents compo
nents, |
| 259 const SkMatrix& matrix) { |
| 260 GrGLfloat coefficients[3 * 3]; |
| 261 SkASSERT(components >= kS_PathTexGenComponents && |
| 262 components <= kSTR_PathTexGenComponents); |
| 263 |
| 264 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); |
| 265 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); |
| 266 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); |
| 267 |
| 268 if (components >= kST_PathTexGenComponents) { |
| 269 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); |
| 270 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); |
| 271 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); |
| 272 } |
| 273 |
| 274 if (components >= kSTR_PathTexGenComponents) { |
| 275 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); |
| 276 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); |
| 277 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); |
| 278 } |
| 279 |
| 280 this->enablePathTexGen(unitIdx, components, coefficients); |
| 281 } |
| 282 |
| 283 void GrGLPathRendering::flushPathTexGenSettings(int numUsedTexCoordSets) { |
| 284 SkASSERT(fGpu->glCaps().maxFixedFunctionTextureCoords() >= numUsedTexCoordSe
ts); |
| 285 |
| 286 // Only write the inactive path tex gens, since active path tex gens were |
| 287 // written when they were enabled. |
| 288 |
| 289 SkDEBUGCODE( |
| 290 for (int i = 0; i < numUsedTexCoordSets; i++) { |
| 291 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); |
| 292 } |
| 293 ); |
| 294 |
| 295 for (int i = numUsedTexCoordSets; i < fHWActivePathTexGenSets; i++) { |
| 296 SkASSERT(0 != fHWPathTexGenSettings[i].fNumComponents); |
| 297 |
| 298 fGpu->setTextureUnit(i); |
| 299 GL_CALL(PathTexGen(GR_GL_TEXTURE0 + i, GR_GL_NONE, 0, NULL)); |
| 300 fHWPathTexGenSettings[i].fNumComponents = 0; |
| 301 } |
| 302 |
| 303 fHWActivePathTexGenSets = numUsedTexCoordSets; |
| 304 } |
| 305 |
| 306 void GrGLPathRendering::setProgramPathFragmentInputTransform(GrGLuint program, G
rGLint location, |
| 307 GrGLenum genMode, G
rGLint components, |
| 308 const SkMatrix& mat
rix) { |
| 309 SkASSERT(caps().fragmentInputGenSupport); |
| 310 GrGLfloat coefficients[3 * 3]; |
| 311 SkASSERT(components >= 1 && components <= 3); |
| 312 |
| 313 coefficients[0] = SkScalarToFloat(matrix[SkMatrix::kMScaleX]); |
| 314 coefficients[1] = SkScalarToFloat(matrix[SkMatrix::kMSkewX]); |
| 315 coefficients[2] = SkScalarToFloat(matrix[SkMatrix::kMTransX]); |
| 316 |
| 317 if (components >= 2) { |
| 318 coefficients[3] = SkScalarToFloat(matrix[SkMatrix::kMSkewY]); |
| 319 coefficients[4] = SkScalarToFloat(matrix[SkMatrix::kMScaleY]); |
| 320 coefficients[5] = SkScalarToFloat(matrix[SkMatrix::kMTransY]); |
| 321 } |
| 322 |
| 323 if (components >= 3) { |
| 324 coefficients[6] = SkScalarToFloat(matrix[SkMatrix::kMPersp0]); |
| 325 coefficients[7] = SkScalarToFloat(matrix[SkMatrix::kMPersp1]); |
| 326 coefficients[8] = SkScalarToFloat(matrix[SkMatrix::kMPersp2]); |
| 327 } |
| 328 |
| 329 GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components,
coefficients)); |
| 361 } | 330 } |
| 362 | 331 |
| 363 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, | 332 void GrGLPathRendering::setProjectionMatrix(const SkMatrix& matrix, |
| 364 const SkISize& renderTargetSize, | 333 const SkISize& renderTargetSize, |
| 365 GrSurfaceOrigin renderTargetOrigin) { | 334 GrSurfaceOrigin renderTargetOrigin) { |
| 366 | 335 |
| 367 SkASSERT(fGpu->glCaps().pathRenderingSupport()); | 336 SkASSERT(fGpu->glCaps().pathRenderingSupport()); |
| 368 | 337 |
| 369 if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && | 338 if (renderTargetOrigin == fHWProjectionMatrixState.fRenderTargetOrigin && |
| 370 renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && | 339 renderTargetSize == fHWProjectionMatrixState.fRenderTargetSize && |
| 371 matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { | 340 matrix.cheapEqualTo(fHWProjectionMatrixState.fViewMatrix)) { |
| 372 return; | 341 return; |
| 373 } | 342 } |
| 374 | 343 |
| 375 fHWProjectionMatrixState.fViewMatrix = matrix; | 344 fHWProjectionMatrixState.fViewMatrix = matrix; |
| 376 fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; | 345 fHWProjectionMatrixState.fRenderTargetSize = renderTargetSize; |
| 377 fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; | 346 fHWProjectionMatrixState.fRenderTargetOrigin = renderTargetOrigin; |
| 378 | 347 |
| 379 GrGLfloat glMatrix[4 * 4]; | 348 GrGLfloat glMatrix[4 * 4]; |
| 380 fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); | 349 fHWProjectionMatrixState.getRTAdjustedGLMatrix<4>(glMatrix); |
| 381 GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix)); | 350 GL_CALL(MatrixLoadf(GR_GL_PROJECTION, glMatrix)); |
| 382 } | 351 } |
| 383 | 352 |
| 384 | |
| 385 | |
| 386 // NV_path_rendering | |
| 387 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { | 353 GrGLuint GrGLPathRendering::genPaths(GrGLsizei range) { |
| 388 if (range > 1) { | 354 if (range > 1) { |
| 389 GrGLuint name; | 355 GrGLuint name; |
| 390 GL_CALL_RET(name, GenPaths(range)); | 356 GL_CALL_RET(name, GenPaths(range)); |
| 391 return name; | 357 return name; |
| 392 } | 358 } |
| 393 | 359 |
| 394 if (NULL == fPathNameAllocator.get()) { | 360 if (NULL == fPathNameAllocator.get()) { |
| 395 static const int range = 65536; | 361 static const int range = 65536; |
| 396 GrGLuint firstName; | 362 GrGLuint firstName; |
| 397 GL_CALL_RET(firstName, GenPaths(range)); | 363 GL_CALL_RET(firstName, GenPaths(range)); |
| 398 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, first
Name + range))); | 364 fPathNameAllocator.reset(SkNEW_ARGS(GrGLNameAllocator, (firstName, first
Name + range))); |
| 399 } | 365 } |
| 400 | 366 |
| 401 // When allocating names one at a time, pull from a client-side pool of | 367 // When allocating names one at a time, pull from a client-side pool of |
| 402 // available names in order to save a round trip to the GL server. | 368 // available names in order to save a round trip to the GL server. |
| 403 GrGLuint name = fPathNameAllocator->allocateName(); | 369 GrGLuint name = fPathNameAllocator->allocateName(); |
| 404 | 370 |
| 405 if (0 == name) { | 371 if (0 == name) { |
| 406 // Our reserved path names are all in use. Fall back on GenPaths. | 372 // Our reserved path names are all in use. Fall back on GenPaths. |
| 407 GL_CALL_RET(name, GenPaths(1)); | 373 GL_CALL_RET(name, GenPaths(1)); |
| 408 } | 374 } |
| 409 | 375 |
| 410 return name; | 376 return name; |
| 411 } | 377 } |
| 412 | 378 |
| 413 GrGLvoid GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { | 379 void GrGLPathRendering::deletePaths(GrGLuint path, GrGLsizei range) { |
| 414 if (range > 1) { | 380 if (range > 1) { |
| 415 // It is not supported to delete names in ranges that were allocated | 381 // It is not supported to delete names in ranges that were allocated |
| 416 // individually using GrGLPathNameAllocator. | 382 // individually using GrGLPathNameAllocator. |
| 417 SkASSERT(NULL == fPathNameAllocator.get() || | 383 SkASSERT(NULL == fPathNameAllocator.get() || |
| 418 path + range <= fPathNameAllocator->firstName() || | 384 path + range <= fPathNameAllocator->firstName() || |
| 419 path >= fPathNameAllocator->endName()); | 385 path >= fPathNameAllocator->endName()); |
| 420 GL_CALL(DeletePaths(path, range)); | 386 GL_CALL(DeletePaths(path, range)); |
| 421 return; | 387 return; |
| 422 } | 388 } |
| 423 | 389 |
| 424 if (NULL == fPathNameAllocator.get() || | 390 if (NULL == fPathNameAllocator.get() || |
| 425 path < fPathNameAllocator->firstName() || | 391 path < fPathNameAllocator->firstName() || |
| 426 path >= fPathNameAllocator->endName()) { | 392 path >= fPathNameAllocator->endName()) { |
| 427 // If we aren't inside fPathNameAllocator's range then this name was | 393 // If we aren't inside fPathNameAllocator's range then this name was |
| 428 // generated by the GenPaths fallback (or else was never allocated). | 394 // generated by the GenPaths fallback (or else was never allocated). |
| 429 GL_CALL(DeletePaths(path, 1)); | 395 GL_CALL(DeletePaths(path, 1)); |
| 430 return; | 396 return; |
| 431 } | 397 } |
| 432 | 398 |
| 433 // Make the path empty to save memory, but don't free the name in the driver
. | 399 // Make the path empty to save memory, but don't free the name in the driver
. |
| 434 GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); | 400 GL_CALL(PathCommands(path, 0, NULL, 0, GR_GL_FLOAT, NULL)); |
| 435 fPathNameAllocator->free(path); | 401 fPathNameAllocator->free(path); |
| 436 } | 402 } |
| 437 | 403 |
| 438 GrGLvoid GrGLPathRendering::pathCommands(GrGLuint path, GrGLsizei numCommands, | 404 void GrGLPathRendering::flushPathStencilSettings(SkPath::FillType fill) { |
| 439 const GrGLubyte *commands, GrGLsizei nu
mCoords, | 405 GrStencilSettings pathStencilSettings; |
| 440 GrGLenum coordType, const GrGLvoid *coo
rds) { | 406 fGpu->getPathStencilSettingsForFillType(fill, &pathStencilSettings); |
| 441 GL_CALL(PathCommands(path, numCommands, commands, numCoords, coordType, coor
ds)); | 407 if (fHWPathStencilSettings != pathStencilSettings) { |
| 408 // Just the func, ref, and mask is set here. The op and write mask are p
arams to the call |
| 409 // that draws the path to the SB (glStencilFillPath) |
| 410 GrGLenum func = |
| 411 GrToGLStencilFunc(pathStencilSettings.func(GrStencilSettings::kFront
_Face)); |
| 412 GL_CALL(PathStencilFunc(func, pathStencilSettings.funcRef(GrStencilSetti
ngs::kFront_Face), |
| 413 pathStencilSettings.funcMask(GrStencilSettings::
kFront_Face))); |
| 414 |
| 415 fHWPathStencilSettings = pathStencilSettings; |
| 416 } |
| 442 } | 417 } |
| 443 | 418 |
| 444 GrGLvoid GrGLPathRendering::pathCoords(GrGLuint path, GrGLsizei numCoords, | 419 inline void GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum
fillMode, |
| 445 GrGLenum coordType, const GrGLvoid *coord
s) { | |
| 446 GL_CALL(PathCoords(path, numCoords, coordType, coords)); | |
| 447 } | |
| 448 | |
| 449 GrGLvoid GrGLPathRendering::pathParameteri(GrGLuint path, GrGLenum pname, GrGLin
t value) { | |
| 450 GL_CALL(PathParameteri(path, pname, value)); | |
| 451 } | |
| 452 | |
| 453 GrGLvoid GrGLPathRendering::pathParameterf(GrGLuint path, GrGLenum pname, GrGLfl
oat value) { | |
| 454 GL_CALL(PathParameterf(path, pname, value)); | |
| 455 } | |
| 456 | |
| 457 GrGLboolean GrGLPathRendering::isPath(GrGLuint path) { | |
| 458 GrGLboolean ret; | |
| 459 GL_CALL_RET(ret, IsPath(path)); | |
| 460 return ret; | |
| 461 } | |
| 462 | |
| 463 GrGLvoid GrGLPathRendering::pathStencilFunc(GrGLenum func, GrGLint ref, GrGLuint
mask) { | |
| 464 GL_CALL(PathStencilFunc(func, ref, mask)); | |
| 465 } | |
| 466 | |
| 467 GrGLvoid GrGLPathRendering::stencilFillPath(GrGLuint path, GrGLenum fillMode, Gr
GLuint mask) { | |
| 468 // Decide how to manipulate the stencil buffer based on the fill rule. | |
| 469 GL_CALL(StencilFillPath(path, fillMode, mask)); | |
| 470 } | |
| 471 | |
| 472 GrGLvoid GrGLPathRendering::stencilStrokePath(GrGLuint path, GrGLint reference,
GrGLuint mask) { | |
| 473 GL_CALL(StencilStrokePath(path, reference, mask)); | |
| 474 } | |
| 475 | |
| 476 GrGLvoid GrGLPathRendering::stencilFillPathInstanced( | |
| 477 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
| 478 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, | |
| 479 GrGLenum transformType, const GrGLfloat *transformValues) { | |
| 480 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
| 481 fillMode, mask, transformType, transformVal
ues)); | |
| 482 } | |
| 483 | |
| 484 GrGLvoid GrGLPathRendering::stencilStrokePathInstanced( | |
| 485 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
| 486 GrGLuint pathBase, GrGLint reference, GrGLuint mask, | |
| 487 GrGLenum transformType, const GrGLfloat *transformValues) { | |
| 488 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
| 489 reference, mask, transformType, transform
Values)); | |
| 490 } | |
| 491 | |
| 492 GrGLvoid GrGLPathRendering::pathTexGen(GrGLenum texCoordSet, GrGLenum genMode, | |
| 493 GrGLint components, const GrGLfloat *coef
fs) { | |
| 494 GL_CALL(PathTexGen(texCoordSet, genMode, components, coeffs)); | |
| 495 } | |
| 496 | |
| 497 GrGLvoid GrGLPathRendering::coverFillPath(GrGLuint path, GrGLenum coverMode) { | |
| 498 GL_CALL(CoverFillPath(path, coverMode)); | |
| 499 } | |
| 500 | |
| 501 GrGLvoid GrGLPathRendering::coverStrokePath(GrGLuint name, GrGLenum coverMode) { | |
| 502 GL_CALL(CoverStrokePath(name, coverMode)); | |
| 503 } | |
| 504 | |
| 505 GrGLvoid GrGLPathRendering::coverFillPathInstanced( | |
| 506 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G
rGLuint pathBase, | |
| 507 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat *transf
ormValues) { | |
| 508 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, | |
| 509 coverMode, transformType, transformValues)); | |
| 510 } | |
| 511 | |
| 512 GrGLvoid GrGLPathRendering::coverStrokePathInstanced( | |
| 513 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, G
rGLuint pathBase, | |
| 514 GrGLenum coverMode, GrGLenum transformType, const GrGLfloat* transf
ormValues) { | |
| 515 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | |
| 516 coverMode, transformType, transformValues))
; | |
| 517 } | |
| 518 | |
| 519 GrGLvoid GrGLPathRendering::stencilThenCoverFillPath(GrGLuint path, GrGLenum fil
lMode, | |
| 520 GrGLuint mask, GrGLenum cov
erMode) { | 420 GrGLuint mask, GrGLenum cov
erMode) { |
| 421 if (caps().stencilThenCoverSupport) { |
| 422 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); |
| 423 return; |
| 424 } |
| 521 GL_CALL(StencilFillPath(path, fillMode, mask)); | 425 GL_CALL(StencilFillPath(path, fillMode, mask)); |
| 522 GL_CALL(CoverFillPath(path, coverMode)); | 426 GL_CALL(CoverFillPath(path, coverMode)); |
| 523 } | 427 } |
| 524 | 428 |
| 525 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint re
ference, | 429 inline void GrGLPathRendering::stencilThenCoverStrokePath(GrGLuint path, GrGLint
reference, |
| 526 GrGLuint mask, GrGLenum c
overMode) { | 430 GrGLuint mask, GrGLenum c
overMode) { |
| 431 if (caps().stencilThenCoverSupport) { |
| 432 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); |
| 433 return; |
| 434 } |
| 527 GL_CALL(StencilStrokePath(path, reference, mask)); | 435 GL_CALL(StencilStrokePath(path, reference, mask)); |
| 528 GL_CALL(CoverStrokePath(path, coverMode)); | 436 GL_CALL(CoverStrokePath(path, coverMode)); |
| 529 } | 437 } |
| 530 | 438 |
| 531 GrGLvoid GrGLPathRendering::stencilThenCoverFillPathInstanced( | 439 inline void GrGLPathRendering::stencilThenCoverFillPathInstanced( |
| 532 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | 440 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, |
| 533 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, | 441 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, |
| 534 GrGLenum transformType, const GrGLfloat *transformValues) { | 442 GrGLenum transformType, const GrGLfloat *transformValues) { |
| 443 if (caps().stencilThenCoverSupport) { |
| 444 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths,
pathBase, fillMode, |
| 445 mask, coverMode, transformType
, transformValues)); |
| 446 return; |
| 447 } |
| 535 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, | 448 GL_CALL(StencilFillPathInstanced(numPaths, pathNameType, paths, pathBase, |
| 536 fillMode, mask, transformType, transformVal
ues)); | 449 fillMode, mask, transformType, transformVal
ues)); |
| 537 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, | 450 GL_CALL(CoverFillPathInstanced(numPaths, pathNameType, paths, pathBase, |
| 538 coverMode, transformType, transformValues)); | 451 coverMode, transformType, transformValues)); |
| 539 } | 452 } |
| 540 | 453 |
| 541 GrGLvoid GrGLPathRendering::stencilThenCoverStrokePathInstanced( | 454 inline void GrGLPathRendering::stencilThenCoverStrokePathInstanced( |
| 542 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | 455 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, |
| 543 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover
Mode, | 456 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum coverMode, |
| 544 GrGLenum transformType, const GrGLfloat *transformValues) { | 457 GrGLenum transformType, const GrGLfloat *transformValues) { |
| 458 if (caps().stencilThenCoverSupport) { |
| 459 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, path
s, pathBase, |
| 460 reference, mask, coverMode,
transformType, |
| 461 transformValues)); |
| 462 return; |
| 463 } |
| 464 |
| 545 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | 465 GL_CALL(StencilStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
| 546 reference, mask, transformType, transform
Values)); | 466 reference, mask, transformType, transform
Values)); |
| 547 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, | 467 GL_CALL(CoverStrokePathInstanced(numPaths, pathNameType, paths, pathBase, |
| 548 coverMode, transformType, transformValues))
; | 468 coverMode, transformType, transformValues))
; |
| 549 } | 469 } |
| 550 | |
| 551 GrGLvoid GrGLPathRendering::programPathFragmentInputGen( | |
| 552 GrGLuint program, GrGLint location, GrGLenum genMode, | |
| 553 GrGLint components, const GrGLfloat *coeffs) { | |
| 554 SkFAIL("ProgramPathFragmentInputGen not supported in this GL context."); | |
| 555 } | |
| 556 | |
| 557 | |
| 558 // NV_path_rendering v1.2 | |
| 559 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPath(GrGLuint path, GrGLenum
fillMode, | |
| 560 GrGLuint mask, GrGLenum
coverMode) { | |
| 561 GL_CALL(StencilThenCoverFillPath(path, fillMode, mask, coverMode)); | |
| 562 } | |
| 563 | |
| 564 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePath(GrGLuint path, GrGLint
reference, | |
| 565 GrGLuint mask, GrGLenu
m coverMode) { | |
| 566 GL_CALL(StencilThenCoverStrokePath(path, reference, mask, coverMode)); | |
| 567 } | |
| 568 | |
| 569 GrGLvoid GrGLPathRenderingV12::stencilThenCoverFillPathInstanced( | |
| 570 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
| 571 GrGLuint pathBase, GrGLenum fillMode, GrGLuint mask, GrGLenum cover
Mode, | |
| 572 GrGLenum transformType, const GrGLfloat *transformValues) { | |
| 573 GL_CALL(StencilThenCoverFillPathInstanced(numPaths, pathNameType, paths, pat
hBase, fillMode, | |
| 574 mask, coverMode, transformType, t
ransformValues)); | |
| 575 } | |
| 576 | |
| 577 GrGLvoid GrGLPathRenderingV12::stencilThenCoverStrokePathInstanced( | |
| 578 GrGLsizei numPaths, GrGLenum pathNameType, const GrGLvoid *paths, | |
| 579 GrGLuint pathBase, GrGLint reference, GrGLuint mask, GrGLenum cover
Mode, | |
| 580 GrGLenum transformType, const GrGLfloat *transformValues) { | |
| 581 GL_CALL(StencilThenCoverStrokePathInstanced(numPaths, pathNameType, paths, p
athBase, reference, | |
| 582 mask, coverMode, transformType,
transformValues)); | |
| 583 } | |
| 584 | |
| 585 | |
| 586 // NV_path_rendering v1.3 | |
| 587 GrGLvoid GrGLPathRenderingV13::programPathFragmentInputGen( | |
| 588 GrGLuint program, GrGLint location, GrGLenum genMode, | |
| 589 GrGLint components, const GrGLfloat *coeffs) { | |
| 590 GL_CALL(ProgramPathFragmentInputGen(program, location, genMode, components,
coeffs)); | |
| 591 } | |
| OLD | NEW |