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 "GrGeometryProcessor.h" | 8 #include "GrGeometryProcessor.h" |
9 | 9 |
| 10 #include "GrCoordTransform.h" |
| 11 #include "GrInvariantOutput.h" |
10 #include "gl/GrGLGeometryProcessor.h" | 12 #include "gl/GrGLGeometryProcessor.h" |
11 #include "GrInvariantOutput.h" | |
12 | 13 |
13 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 14 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
14 | 15 |
| 16 /** |
| 17 * The key for an individual coord transform is made up of a matrix type, a prec
ision, and a bit |
| 18 * that indicates the source of the input coords. |
| 19 */ |
| 20 enum { |
| 21 kMatrixTypeKeyBits = 1, |
| 22 kMatrixTypeKeyMask = (1 << kMatrixTypeKeyBits) - 1, |
| 23 |
| 24 kPrecisionBits = 2, |
| 25 kPrecisionShift = kMatrixTypeKeyBits, |
| 26 |
| 27 kPositionCoords_Flag = (1 << (kPrecisionShift + kPrecisionBits)), |
| 28 kDeviceCoords_Flag = kPositionCoords_Flag + kPositionCoords_Flag, |
| 29 |
| 30 kTransformKeyBits = kMatrixTypeKeyBits + kPrecisionBits + 2, |
| 31 }; |
| 32 |
| 33 GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits)); |
| 34 |
| 35 /** |
| 36 * We specialize the vertex code for each of these matrix types. |
| 37 */ |
| 38 enum MatrixType { |
| 39 kNoPersp_MatrixType = 0, |
| 40 kGeneral_MatrixType = 1, |
| 41 }; |
| 42 |
| 43 uint32_t |
| 44 GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, tr
ue>& coords) const { |
| 45 uint32_t totalKey = 0; |
| 46 for (int t = 0; t < coords.count(); ++t) { |
| 47 uint32_t key = 0; |
| 48 const GrCoordTransform* coordTransform = coords[t]; |
| 49 if (coordTransform->getMatrix().hasPerspective()) { |
| 50 key |= kGeneral_MatrixType; |
| 51 } else { |
| 52 key |= kNoPersp_MatrixType; |
| 53 } |
| 54 |
| 55 if (kLocal_GrCoordSet == coordTransform->sourceCoords() && |
| 56 !this->hasExplicitLocalCoords()) { |
| 57 key |= kPositionCoords_Flag; |
| 58 } else if (kDevice_GrCoordSet == coordTransform->sourceCoords()) { |
| 59 key |= kDeviceCoords_Flag; |
| 60 } |
| 61 |
| 62 GR_STATIC_ASSERT(kGrSLPrecisionCount <= (1 << kPrecisionBits)); |
| 63 key |= (coordTransform->precision() << kPrecisionShift); |
| 64 |
| 65 key <<= kTransformKeyBits * t; |
| 66 |
| 67 SkASSERT(0 == (totalKey & key)); // keys for each transform ought not to
overlap |
| 68 totalKey |= key; |
| 69 } |
| 70 return totalKey; |
| 71 } |
| 72 |
| 73 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 74 |
15 void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) co
nst { | 75 void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) co
nst { |
16 if (fHasVertexColor) { | 76 if (fHasVertexColor) { |
17 if (fOpaqueVertexColors) { | 77 if (fOpaqueVertexColors) { |
18 out->setUnknownOpaqueFourComponents(); | 78 out->setUnknownOpaqueFourComponents(); |
19 } else { | 79 } else { |
20 out->setUnknownFourComponents(); | 80 out->setUnknownFourComponents(); |
21 } | 81 } |
22 } else { | 82 } else { |
23 out->setKnownFourComponents(fColor); | 83 out->setKnownFourComponents(fColor); |
24 } | 84 } |
25 this->onGetInvariantOutputColor(out); | 85 this->onGetInvariantOutputColor(out); |
26 } | 86 } |
27 | 87 |
28 void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out)
const { | 88 void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out)
const { |
29 this->onGetInvariantOutputCoverage(out); | 89 this->onGetInvariantOutputCoverage(out); |
30 } | 90 } |
31 | 91 |
32 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 92 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
33 | 93 |
34 #include "gl/builders/GrGLProgramBuilder.h" | 94 #include "gl/builders/GrGLProgramBuilder.h" |
35 | 95 |
36 void GrGLGeometryProcessor::setupColorPassThrough(GrGLGPBuilder* pb, | 96 SkMatrix GrGLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix, |
37 GrGPInput inputType, | 97 const GrCoordTransform& coor
dTransform) { |
38 const char* outputName, | 98 SkMatrix combined; |
39 const GrGeometryProcessor::GrA
ttribute* colorAttr, | 99 // We only apply the localmatrix to localcoords |
40 UniformHandle* colorUniform) { | 100 if (kLocal_GrCoordSet == coordTransform.sourceCoords()) { |
| 101 combined.setConcat(coordTransform.getMatrix(), localMatrix); |
| 102 } else { |
| 103 combined = coordTransform.getMatrix(); |
| 104 } |
| 105 if (coordTransform.reverseY()) { |
| 106 // combined.postScale(1,-1); |
| 107 // combined.postTranslate(0,1); |
| 108 combined.set(SkMatrix::kMSkewY, |
| 109 combined[SkMatrix::kMPersp0] - combined[SkMatrix::kMSkewY]); |
| 110 combined.set(SkMatrix::kMScaleY, |
| 111 combined[SkMatrix::kMPersp1] - combined[SkMatrix::kMScaleY]); |
| 112 combined.set(SkMatrix::kMTransY, |
| 113 combined[SkMatrix::kMPersp2] - combined[SkMatrix::kMTransY]); |
| 114 } |
| 115 return combined; |
| 116 } |
| 117 |
| 118 void |
| 119 GrGLPrimitiveProcessor::setupColorPassThrough(GrGLGPBuilder* pb, |
| 120 GrGPInput inputType, |
| 121 const char* outputName, |
| 122 const GrGeometryProcessor::GrAttri
bute* colorAttr, |
| 123 UniformHandle* colorUniform) { |
41 GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder(); | 124 GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder(); |
42 if (kUniform_GrGPInput == inputType) { | 125 if (kUniform_GrGPInput == inputType) { |
43 SkASSERT(colorUniform); | 126 SkASSERT(colorUniform); |
44 const char* stagedLocalVarName; | 127 const char* stagedLocalVarName; |
45 *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, | 128 *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
46 kVec4f_GrSLType, | 129 kVec4f_GrSLType, |
47 kDefault_GrSLPrecision, | 130 kDefault_GrSLPrecision, |
48 "Color", | 131 "Color", |
49 &stagedLocalVarName); | 132 &stagedLocalVarName); |
50 fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName); | 133 fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName); |
51 } else if (kAttribute_GrGPInput == inputType) { | 134 } else if (kAttribute_GrGPInput == inputType) { |
52 SkASSERT(colorAttr); | 135 SkASSERT(colorAttr); |
53 pb->addPassThroughAttribute(colorAttr, outputName); | 136 pb->addPassThroughAttribute(colorAttr, outputName); |
54 } else if (kAllOnes_GrGPInput == inputType) { | 137 } else if (kAllOnes_GrGPInput == inputType) { |
55 fs->codeAppendf("%s = vec4(1);", outputName); | 138 fs->codeAppendf("%s = vec4(1);", outputName); |
56 } | 139 } |
57 } | 140 } |
58 | 141 |
59 void GrGLGeometryProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) { | 142 void GrGLPrimitiveProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) { |
60 fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, | 143 fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, |
61 kMat33f_GrSLType, kDefault_GrSLPrecision
, | 144 kMat33f_GrSLType, kDefault_GrSLPrecision
, |
62 "uViewM", | 145 "uViewM", |
63 &fViewMatrixName); | 146 &fViewMatrixName); |
64 } | 147 } |
65 | 148 |
66 void GrGLGeometryProcessor::setUniformViewMatrix(const GrGLProgramDataManager& p
dman, | 149 void GrGLPrimitiveProcessor::setUniformViewMatrix(const GrGLProgramDataManager&
pdman, |
67 const SkMatrix& viewMatrix) { | 150 const SkMatrix& viewMatrix) { |
68 if (!fViewMatrix.cheapEqualTo(viewMatrix)) { | 151 if (!fViewMatrix.cheapEqualTo(viewMatrix)) { |
69 SkASSERT(fViewMatrixUniform.isValid()); | 152 SkASSERT(fViewMatrixUniform.isValid()); |
70 fViewMatrix = viewMatrix; | 153 fViewMatrix = viewMatrix; |
71 | 154 |
72 GrGLfloat viewMatrix[3 * 3]; | 155 GrGLfloat viewMatrix[3 * 3]; |
73 GrGLGetMatrix<3>(viewMatrix, fViewMatrix); | 156 GrGLGetMatrix<3>(viewMatrix, fViewMatrix); |
74 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); | 157 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix); |
75 } | 158 } |
76 } | 159 } |
77 | 160 |
78 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 161 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
79 | 162 |
| 163 |
| 164 void GrGLGeometryProcessor::emitCode(EmitArgs& args) { |
| 165 GrGLVertexBuilder* vsBuilder = args.fPB->getVertexShaderBuilder(); |
| 166 vsBuilder->codeAppendf("vec3 %s;", this->position()); |
| 167 this->onEmitCode(args); |
| 168 vsBuilder->transformToNormalizedDeviceSpace(this->position()); |
| 169 } |
| 170 |
| 171 void GrGLGeometryProcessor::emitTransforms(GrGLGPBuilder* pb, |
| 172 const char* position, |
| 173 const char* localCoords, |
| 174 const SkMatrix& localMatrix, |
| 175 const TransformsIn& tin, |
| 176 TransformsOut* tout) { |
| 177 GrGLVertexBuilder* vb = pb->getVertexShaderBuilder(); |
| 178 tout->push_back_n(tin.count()); |
| 179 fInstalledTransforms.push_back_n(tin.count()); |
| 180 for (int i = 0; i < tin.count(); i++) { |
| 181 const ProcCoords& coordTransforms = tin[i]; |
| 182 fInstalledTransforms[i].push_back_n(coordTransforms.count()); |
| 183 for (int t = 0; t < coordTransforms.count(); t++) { |
| 184 SkString strUniName("StageMatrix"); |
| 185 strUniName.appendf("_%i_%i", i, t); |
| 186 GrSLType varyingType; |
| 187 |
| 188 GrCoordSet coordType = coordTransforms[t]->sourceCoords(); |
| 189 uint32_t type = coordTransforms[t]->getMatrix().getType(); |
| 190 if (kLocal_GrCoordSet == coordType) { |
| 191 type |= localMatrix.getType(); |
| 192 } |
| 193 varyingType = SkToBool(SkMatrix::kPerspective_Mask & type) ? kVec3f_
GrSLType : |
| 194 kVec2f_
GrSLType; |
| 195 GrSLPrecision precision = coordTransforms[t]->precision(); |
| 196 |
| 197 const char* uniName; |
| 198 fInstalledTransforms[i][t].fHandle = |
| 199 pb->addUniform(GrGLProgramBuilder::kVertex_Visibility, |
| 200 kMat33f_GrSLType, precision, |
| 201 strUniName.c_str(), |
| 202 &uniName).toShaderBuilderIndex(); |
| 203 |
| 204 SkString strVaryingName("MatrixCoord"); |
| 205 strVaryingName.appendf("_%i_%i", i, t); |
| 206 |
| 207 GrGLVertToFrag v(varyingType); |
| 208 pb->addVarying(strVaryingName.c_str(), &v, precision); |
| 209 |
| 210 SkASSERT(kVec2f_GrSLType == varyingType || kVec3f_GrSLType == varyin
gType); |
| 211 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords
, |
| 212 (SkString(v.fsIn()), varyingType)); |
| 213 |
| 214 // varying = matrix * coords (logically) |
| 215 if (kDevice_GrCoordSet == coordType) { |
| 216 if (kVec2f_GrSLType == varyingType) { |
| 217 vb->codeAppendf("%s = (%s * %s).xy;", v.vsOut(), uniName, po
sition); |
| 218 } else { |
| 219 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, positio
n); |
| 220 } |
| 221 } else { |
| 222 if (kVec2f_GrSLType == varyingType) { |
| 223 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), un
iName, localCoords); |
| 224 } else { |
| 225 vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName
, localCoords); |
| 226 } |
| 227 } |
| 228 } |
| 229 } |
| 230 } |
| 231 |
| 232 |
| 233 void |
| 234 GrGLGeometryProcessor::setTransformData(const GrPrimitiveProcessor* primProc, |
| 235 const GrGLProgramDataManager& pdman, |
| 236 int index, |
| 237 const SkTArray<const GrCoordTransform*,
true>& transforms) { |
| 238 SkSTArray<2, Transform, true>& procTransforms = fInstalledTransforms[index]; |
| 239 int numTransforms = transforms.count(); |
| 240 for (int t = 0; t < numTransforms; ++t) { |
| 241 SkASSERT(procTransforms[t].fHandle.isValid()); |
| 242 const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(),
*transforms[t]); |
| 243 if (!procTransforms[t].fCurrentValue.cheapEqualTo(transform)) { |
| 244 pdman.setSkMatrix(procTransforms[t].fHandle.convertToUniformHandle()
, transform); |
| 245 procTransforms[t].fCurrentValue = transform; |
| 246 } |
| 247 } |
| 248 } |
| 249 |
| 250 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
| 251 |
| 252 #include "gl/GrGLGpu.h" |
| 253 #include "gl/GrGLPathRendering.h" |
| 254 |
80 struct PathBatchTracker { | 255 struct PathBatchTracker { |
81 GrGPInput fInputColorType; | 256 GrGPInput fInputColorType; |
82 GrGPInput fInputCoverageType; | 257 GrGPInput fInputCoverageType; |
83 GrColor fColor; | 258 GrColor fColor; |
84 bool fUsesLocalCoords; | 259 bool fUsesLocalCoords; |
85 }; | 260 }; |
86 | 261 |
87 class GrGLPathProcessor : public GrGLGeometryProcessor { | 262 GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracke
r&) |
| 263 : fColor(GrColor_ILLEGAL) {} |
| 264 |
| 265 void GrGLPathProcessor::emitCode(EmitArgs& args) { |
| 266 GrGLGPBuilder* pb = args.fPB; |
| 267 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); |
| 268 const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>(); |
| 269 |
| 270 // emit transforms |
| 271 this->emitTransforms(args.fPB, args.fTransformsIn, args.fTransformsOut); |
| 272 |
| 273 // Setup uniform color |
| 274 if (kUniform_GrGPInput == local.fInputColorType) { |
| 275 const char* stagedLocalVarName; |
| 276 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility, |
| 277 kVec4f_GrSLType, |
| 278 kDefault_GrSLPrecision, |
| 279 "Color", |
| 280 &stagedLocalVarName); |
| 281 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); |
| 282 } |
| 283 |
| 284 // setup constant solid coverage |
| 285 if (kAllOnes_GrGPInput == local.fInputCoverageType) { |
| 286 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); |
| 287 } |
| 288 } |
| 289 |
| 290 void GrGLPathProcessor::GenKey(const GrPathProcessor&, |
| 291 const GrBatchTracker& bt, |
| 292 const GrGLCaps&, |
| 293 GrProcessorKeyBuilder* b) { |
| 294 const PathBatchTracker& local = bt.cast<PathBatchTracker>(); |
| 295 b->add32(local.fInputColorType | local.fInputCoverageType << 16); |
| 296 } |
| 297 |
| 298 void GrGLPathProcessor::setData(const GrGLProgramDataManager& pdman, |
| 299 const GrPrimitiveProcessor& primProc, |
| 300 const GrBatchTracker& bt) { |
| 301 const PathBatchTracker& local = bt.cast<PathBatchTracker>(); |
| 302 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColor) { |
| 303 GrGLfloat c[4]; |
| 304 GrColorToRGBAFloat(local.fColor, c); |
| 305 pdman.set4fv(fColorUniform, 1, c); |
| 306 fColor = local.fColor; |
| 307 } |
| 308 } |
| 309 |
| 310 class GrGLLegacyPathProcessor : public GrGLPathProcessor { |
88 public: | 311 public: |
89 GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&) | 312 GrGLLegacyPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracke
r& bt, |
90 : fColor(GrColor_ILLEGAL) {} | 313 int maxTexCoords) |
91 | 314 : INHERITED(pathProc, bt) |
92 void emitCode(const EmitArgs& args) SK_OVERRIDE { | 315 , fMaxTexCoords(maxTexCoords) |
93 GrGLGPBuilder* pb = args.fPB; | 316 , fTexCoordSetCnt(0) {} |
94 GrGLGPFragmentBuilder* fs = args.fPB->getFragmentShaderBuilder(); | 317 |
95 const PathBatchTracker& local = args.fBT.cast<PathBatchTracker>(); | 318 int addTexCoordSets(int count) { |
96 | 319 int firstFreeCoordSet = fTexCoordSetCnt; |
97 // Setup uniform color | 320 fTexCoordSetCnt += count; |
98 if (kUniform_GrGPInput == local.fInputColorType) { | 321 SkASSERT(fMaxTexCoords >= fTexCoordSetCnt); |
99 const char* stagedLocalVarName; | 322 return firstFreeCoordSet; |
100 fColorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibil
ity, | 323 } |
101 kVec4f_GrSLType, | 324 |
102 kDefault_GrSLPrecision, | 325 void emitTransforms(GrGLGPBuilder*, const TransformsIn& tin, TransformsOut*
tout) SK_OVERRIDE { |
103 "Color", | 326 tout->push_back_n(tin.count()); |
104 &stagedLocalVarName); | 327 fInstalledTransforms.push_back_n(tin.count()); |
105 fs->codeAppendf("%s = %s;", args.fOutputColor, stagedLocalVarName); | 328 for (int i = 0; i < tin.count(); i++) { |
106 } | 329 const ProcCoords& coordTransforms = tin[i]; |
107 | 330 int texCoordIndex = this->addTexCoordSets(coordTransforms.count()); |
108 // setup constant solid coverage | 331 |
109 if (kAllOnes_GrGPInput == local.fInputCoverageType) { | 332 // Use the first uniform location as the texcoord index. |
110 fs->codeAppendf("%s = vec4(1);", args.fOutputCoverage); | 333 fInstalledTransforms[i].push_back_n(1); |
111 } | 334 fInstalledTransforms[i][0].fHandle = ShaderVarHandle(texCoordIndex); |
112 } | 335 |
113 | 336 SkString name; |
114 static inline void GenKey(const GrPathProcessor&, | 337 for (int t = 0; t < coordTransforms.count(); ++t) { |
115 const GrBatchTracker& bt, | 338 GrSLType type = coordTransforms[t]->getMatrix().hasPerspective()
? kVec3f_GrSLType : |
116 const GrGLCaps&, | 339
kVec2f_GrSLType; |
117 GrProcessorKeyBuilder* b) { | 340 |
118 const PathBatchTracker& local = bt.cast<PathBatchTracker>(); | 341 name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCo
ordIndex++); |
119 b->add32(local.fInputColorType | local.fInputCoverageType << 16); | 342 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCo
ords, (name, type)); |
120 } | 343 } |
121 | 344 } |
122 void setData(const GrGLProgramDataManager& pdman, | 345 } |
123 const GrPrimitiveProcessor& primProc, | 346 |
124 const GrBatchTracker& bt) SK_OVERRIDE { | 347 void setTransformData(const GrPrimitiveProcessor* primProc, |
125 const PathBatchTracker& local = bt.cast<PathBatchTracker>(); | 348 int index, |
126 if (kUniform_GrGPInput == local.fInputColorType && local.fColor != fColo
r) { | 349 const SkTArray<const GrCoordTransform*, true>& transfo
rms, |
127 GrGLfloat c[4]; | 350 GrGLPathRendering* glpr, |
128 GrColorToRGBAFloat(local.fColor, c); | 351 GrGLuint) SK_OVERRIDE { |
129 pdman.set4fv(fColorUniform, 1, c); | 352 // We've hidden the texcoord index in the first entry of the transforms
array for each |
130 fColor = local.fColor; | 353 // effect |
131 } | 354 int texCoordIndex = fInstalledTransforms[index][0].fHandle.handle(); |
| 355 for (int t = 0; t < transforms.count(); ++t) { |
| 356 const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix
(), *transforms[t]); |
| 357 GrGLPathRendering::PathTexGenComponents components = |
| 358 GrGLPathRendering::kST_PathTexGenComponents; |
| 359 if (transform.hasPerspective()) { |
| 360 components = GrGLPathRendering::kSTR_PathTexGenComponents; |
| 361 } |
| 362 glpr->enablePathTexGen(texCoordIndex++, components, transform); |
| 363 } |
| 364 } |
| 365 |
| 366 void didSetData(GrGLPathRendering* glpr) SK_OVERRIDE { |
| 367 glpr->flushPathTexGenSettings(fTexCoordSetCnt); |
132 } | 368 } |
133 | 369 |
134 private: | 370 private: |
135 UniformHandle fColorUniform; | 371 int fMaxTexCoords; |
136 GrColor fColor; | 372 int fTexCoordSetCnt; |
137 | 373 |
138 typedef GrGLGeometryProcessor INHERITED; | 374 typedef GrGLPathProcessor INHERITED; |
139 }; | 375 }; |
140 | 376 |
| 377 class GrGLNormalPathProcessor : public GrGLPathProcessor { |
| 378 public: |
| 379 GrGLNormalPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracke
r& bt) |
| 380 : INHERITED(pathProc, bt) {} |
| 381 |
| 382 void emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin, |
| 383 TransformsOut* tout) SK_OVERRIDE { |
| 384 tout->push_back_n(tin.count()); |
| 385 fInstalledTransforms.push_back_n(tin.count()); |
| 386 for (int i = 0; i < tin.count(); i++) { |
| 387 const ProcCoords& coordTransforms = tin[i]; |
| 388 fInstalledTransforms[i].push_back_n(coordTransforms.count()); |
| 389 for (int t = 0; t < coordTransforms.count(); t++) { |
| 390 GrSLType varyingType = |
| 391 coordTransforms[t]->getMatrix().hasPerspective() ? kVec3
f_GrSLType : |
| 392 kVec2
f_GrSLType; |
| 393 |
| 394 const char* varyingName = "MatrixCoord"; |
| 395 SkString suffixedVaryingName; |
| 396 if (0 != t) { |
| 397 suffixedVaryingName.append(varyingName); |
| 398 suffixedVaryingName.appendf("_%i", t); |
| 399 varyingName = suffixedVaryingName.c_str(); |
| 400 } |
| 401 GrGLVertToFrag v(varyingType); |
| 402 pb->addVarying(varyingName, &v); |
| 403 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_
back(); |
| 404 varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.
back(); |
| 405 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1; |
| 406 varyingInfo.fType = varyingType; |
| 407 fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo
.fLocation); |
| 408 fInstalledTransforms[i][t].fType = varyingType; |
| 409 |
| 410 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCo
ords, |
| 411 (SkString(v.fsIn()), varyingType)); |
| 412 } |
| 413 } |
| 414 } |
| 415 |
| 416 void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) { |
| 417 int count = fSeparableVaryingInfos.count(); |
| 418 for (int i = 0; i < count; ++i) { |
| 419 GrGLint location; |
| 420 GR_GL_CALL_RET(gpu->glInterface(), |
| 421 location, |
| 422 GetProgramResourceLocation(programId, |
| 423 GR_GL_FRAGMENT_INPUT, |
| 424 fSeparableVaryingInfos[i].
fVariable.c_str())); |
| 425 fSeparableVaryingInfos[i].fLocation = location; |
| 426 } |
| 427 } |
| 428 |
| 429 void setTransformData(const GrPrimitiveProcessor* primProc, |
| 430 int index, |
| 431 const SkTArray<const GrCoordTransform*, true>& coordTr
ansforms, |
| 432 GrGLPathRendering* glpr, |
| 433 GrGLuint programID) SK_OVERRIDE { |
| 434 SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index]; |
| 435 int numTransforms = transforms.count(); |
| 436 for (int t = 0; t < numTransforms; ++t) { |
| 437 SkASSERT(transforms[t].fHandle.isValid()); |
| 438 const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix
(), |
| 439 *coordTransforms[t]); |
| 440 if (transforms[t].fCurrentValue.cheapEqualTo(transform)) { |
| 441 continue; |
| 442 } |
| 443 transforms[t].fCurrentValue = transform; |
| 444 const SeparableVaryingInfo& fragmentInput = |
| 445 fSeparableVaryingInfos[transforms[t].fHandle.handle()]; |
| 446 SkASSERT(transforms[t].fType == kVec2f_GrSLType || |
| 447 transforms[t].fType == kVec3f_GrSLType); |
| 448 unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3
; |
| 449 glpr->setProgramPathFragmentInputTransform(programID, |
| 450 fragmentInput.fLocation, |
| 451 GR_GL_OBJECT_LINEAR, |
| 452 components, |
| 453 transform); |
| 454 } |
| 455 } |
| 456 |
| 457 private: |
| 458 struct SeparableVaryingInfo { |
| 459 GrSLType fType; |
| 460 GrGLShaderVar fVariable; |
| 461 GrGLint fLocation; |
| 462 }; |
| 463 |
| 464 |
| 465 typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray; |
| 466 |
| 467 SeparableVaryingInfoArray fSeparableVaryingInfos; |
| 468 |
| 469 typedef GrGLPathProcessor INHERITED; |
| 470 }; |
| 471 |
141 GrPathProcessor::GrPathProcessor(GrColor color, | 472 GrPathProcessor::GrPathProcessor(GrColor color, |
142 const SkMatrix& viewMatrix, | 473 const SkMatrix& viewMatrix, |
143 const SkMatrix& localMatrix) | 474 const SkMatrix& localMatrix) |
144 : INHERITED(viewMatrix, localMatrix) | 475 : INHERITED(viewMatrix, localMatrix) |
145 , fColor(color) { | 476 , fColor(color) { |
146 this->initClassID<GrPathProcessor>(); | 477 this->initClassID<GrPathProcessor>(); |
147 } | 478 } |
148 | 479 |
149 void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const
{ | 480 void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const
{ |
150 out->setKnownFourComponents(fColor); | 481 out->setKnownFourComponents(fColor); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 CanCombineOutput(mine.fInputCoverageType, 0xff, | 520 CanCombineOutput(mine.fInputCoverageType, 0xff, |
190 theirs.fInputCoverageType, 0xff); | 521 theirs.fInputCoverageType, 0xff); |
191 } | 522 } |
192 | 523 |
193 void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt, | 524 void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt, |
194 const GrGLCaps& caps, | 525 const GrGLCaps& caps, |
195 GrProcessorKeyBuilder* b) const { | 526 GrProcessorKeyBuilder* b) const { |
196 GrGLPathProcessor::GenKey(*this, bt, caps, b); | 527 GrGLPathProcessor::GenKey(*this, bt, caps, b); |
197 } | 528 } |
198 | 529 |
199 GrGLGeometryProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& b
t) const { | 530 GrGLPrimitiveProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker&
bt, |
200 return SkNEW_ARGS(GrGLPathProcessor, (*this, bt)); | 531 const GrGLCaps& caps)
const { |
| 532 SkASSERT(caps.nvprSupport() != GrGLCaps::kNone_NvprSupport); |
| 533 if (caps.nvprSupport() == GrGLCaps::kLegacy_NvprSupport) { |
| 534 return SkNEW_ARGS(GrGLLegacyPathProcessor, (*this, bt, |
| 535 caps.maxFixedFunctionTexture
Coords())); |
| 536 } else { |
| 537 return SkNEW_ARGS(GrGLNormalPathProcessor, (*this, bt)); |
| 538 } |
201 } | 539 } |
| 540 |
OLD | NEW |