blob: 344dccc731861f7e71b32562eb8b18ced4884049 [file] [log] [blame]
joshualitt9b989322014-12-15 14:16:27 -08001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "GrGeometryProcessor.h"
9
joshualittabb52a12015-01-13 15:02:10 -080010#include "GrCoordTransform.h"
joshualitt9b989322014-12-15 14:16:27 -080011#include "GrInvariantOutput.h"
joshualittabb52a12015-01-13 15:02:10 -080012#include "gl/GrGLGeometryProcessor.h"
13
14///////////////////////////////////////////////////////////////////////////////////////////////////
15
16/**
17 * The key for an individual coord transform is made up of a matrix type, a precision, and a bit
18 * that indicates the source of the input coords.
19 */
20enum {
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
33GR_STATIC_ASSERT(kHigh_GrSLPrecision < (1 << kPrecisionBits));
34
35/**
36 * We specialize the vertex code for each of these matrix types.
37 */
38enum MatrixType {
39 kNoPersp_MatrixType = 0,
40 kGeneral_MatrixType = 1,
41};
42
43uint32_t
44GrPrimitiveProcessor::getTransformKey(const SkTArray<const GrCoordTransform*, true>& 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}
joshualitt9b989322014-12-15 14:16:27 -080072
73///////////////////////////////////////////////////////////////////////////////////////////////////
74
75void GrGeometryProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
76 if (fHasVertexColor) {
77 if (fOpaqueVertexColors) {
78 out->setUnknownOpaqueFourComponents();
79 } else {
80 out->setUnknownFourComponents();
81 }
82 } else {
83 out->setKnownFourComponents(fColor);
84 }
85 this->onGetInvariantOutputColor(out);
86}
87
88void GrGeometryProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
89 this->onGetInvariantOutputCoverage(out);
90}
91
92///////////////////////////////////////////////////////////////////////////////////////////////////
93
94#include "gl/builders/GrGLProgramBuilder.h"
95
joshualittabb52a12015-01-13 15:02:10 -080096SkMatrix GrGLPrimitiveProcessor::GetTransformMatrix(const SkMatrix& localMatrix,
97 const GrCoordTransform& coordTransform) {
98 SkMatrix combined;
99 // We only apply the localmatrix to localcoords
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
118void
119GrGLPrimitiveProcessor::setupColorPassThrough(GrGLGPBuilder* pb,
120 GrGPInput inputType,
121 const char* outputName,
joshualitt71c92602015-01-14 08:12:47 -0800122 const GrGeometryProcessor::Attribute* colorAttr,
joshualittabb52a12015-01-13 15:02:10 -0800123 UniformHandle* colorUniform) {
joshualitt9b989322014-12-15 14:16:27 -0800124 GrGLGPFragmentBuilder* fs = pb->getFragmentShaderBuilder();
125 if (kUniform_GrGPInput == inputType) {
126 SkASSERT(colorUniform);
127 const char* stagedLocalVarName;
128 *colorUniform = pb->addUniform(GrGLProgramBuilder::kFragment_Visibility,
129 kVec4f_GrSLType,
130 kDefault_GrSLPrecision,
131 "Color",
132 &stagedLocalVarName);
133 fs->codeAppendf("%s = %s;", outputName, stagedLocalVarName);
134 } else if (kAttribute_GrGPInput == inputType) {
135 SkASSERT(colorAttr);
136 pb->addPassThroughAttribute(colorAttr, outputName);
137 } else if (kAllOnes_GrGPInput == inputType) {
138 fs->codeAppendf("%s = vec4(1);", outputName);
139 }
140}
141
joshualittabb52a12015-01-13 15:02:10 -0800142void GrGLPrimitiveProcessor::addUniformViewMatrix(GrGLGPBuilder* pb) {
joshualittee2af952014-12-30 09:04:15 -0800143 fViewMatrixUniform = pb->addUniform(GrGLProgramBuilder::kVertex_Visibility,
144 kMat33f_GrSLType, kDefault_GrSLPrecision,
145 "uViewM",
146 &fViewMatrixName);
147}
148
joshualittabb52a12015-01-13 15:02:10 -0800149void GrGLPrimitiveProcessor::setUniformViewMatrix(const GrGLProgramDataManager& pdman,
150 const SkMatrix& viewMatrix) {
joshualittee2af952014-12-30 09:04:15 -0800151 if (!fViewMatrix.cheapEqualTo(viewMatrix)) {
152 SkASSERT(fViewMatrixUniform.isValid());
153 fViewMatrix = viewMatrix;
154
155 GrGLfloat viewMatrix[3 * 3];
156 GrGLGetMatrix<3>(viewMatrix, fViewMatrix);
157 pdman.setMatrix3f(fViewMatrixUniform, viewMatrix);
158 }
159}
160
joshualitt9b989322014-12-15 14:16:27 -0800161///////////////////////////////////////////////////////////////////////////////////////////////////
162
joshualittabb52a12015-01-13 15:02:10 -0800163
164void 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
171void 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 == varyingType);
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, position);
218 } else {
219 vb->codeAppendf("%s = %s * %s;", v.vsOut(), uniName, position);
220 }
221 } else {
222 if (kVec2f_GrSLType == varyingType) {
223 vb->codeAppendf("%s = (%s * vec3(%s, 1)).xy;", v.vsOut(), uniName, localCoords);
224 } else {
225 vb->codeAppendf("%s = %s * vec3(%s, 1);", v.vsOut(), uniName, localCoords);
226 }
227 }
228 }
229 }
230}
231
232
233void
234GrGLGeometryProcessor::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
joshualitt9b989322014-12-15 14:16:27 -0800255struct PathBatchTracker {
256 GrGPInput fInputColorType;
257 GrGPInput fInputCoverageType;
258 GrColor fColor;
joshualitt290c09b2014-12-19 13:45:20 -0800259 bool fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800260};
261
joshualittabb52a12015-01-13 15:02:10 -0800262GrGLPathProcessor::GrGLPathProcessor(const GrPathProcessor&, const GrBatchTracker&)
263 : fColor(GrColor_ILLEGAL) {}
264
265void 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
290void 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
298void 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
310class GrGLLegacyPathProcessor : public GrGLPathProcessor {
joshualitt9b989322014-12-15 14:16:27 -0800311public:
joshualittabb52a12015-01-13 15:02:10 -0800312 GrGLLegacyPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt,
313 int maxTexCoords)
314 : INHERITED(pathProc, bt)
mtkleinb54fe402015-01-14 14:18:54 -0800315 , fTexCoordSetCnt(0) {
316 SkDEBUGCODE(fMaxTexCoords = maxTexCoords;)
317 }
joshualitt9b989322014-12-15 14:16:27 -0800318
joshualittabb52a12015-01-13 15:02:10 -0800319 int addTexCoordSets(int count) {
320 int firstFreeCoordSet = fTexCoordSetCnt;
321 fTexCoordSetCnt += count;
322 SkASSERT(fMaxTexCoords >= fTexCoordSetCnt);
323 return firstFreeCoordSet;
324 }
joshualitt9b989322014-12-15 14:16:27 -0800325
joshualittabb52a12015-01-13 15:02:10 -0800326 void emitTransforms(GrGLGPBuilder*, const TransformsIn& tin, TransformsOut* tout) SK_OVERRIDE {
327 tout->push_back_n(tin.count());
328 fInstalledTransforms.push_back_n(tin.count());
329 for (int i = 0; i < tin.count(); i++) {
330 const ProcCoords& coordTransforms = tin[i];
331 int texCoordIndex = this->addTexCoordSets(coordTransforms.count());
joshualitt9b989322014-12-15 14:16:27 -0800332
joshualittabb52a12015-01-13 15:02:10 -0800333 // Use the first uniform location as the texcoord index.
334 fInstalledTransforms[i].push_back_n(1);
335 fInstalledTransforms[i][0].fHandle = ShaderVarHandle(texCoordIndex);
336
337 SkString name;
338 for (int t = 0; t < coordTransforms.count(); ++t) {
339 GrSLType type = coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
340 kVec2f_GrSLType;
341
342 name.printf("%s(gl_TexCoord[%i])", GrGLSLTypeString(type), texCoordIndex++);
343 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords, (name, type));
344 }
joshualitt9b989322014-12-15 14:16:27 -0800345 }
346 }
347
joshualittabb52a12015-01-13 15:02:10 -0800348 void setTransformData(const GrPrimitiveProcessor* primProc,
349 int index,
350 const SkTArray<const GrCoordTransform*, true>& transforms,
351 GrGLPathRendering* glpr,
352 GrGLuint) SK_OVERRIDE {
353 // We've hidden the texcoord index in the first entry of the transforms array for each
354 // effect
355 int texCoordIndex = fInstalledTransforms[index][0].fHandle.handle();
356 for (int t = 0; t < transforms.count(); ++t) {
357 const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(), *transforms[t]);
358 GrGLPathRendering::PathTexGenComponents components =
359 GrGLPathRendering::kST_PathTexGenComponents;
360 if (transform.hasPerspective()) {
361 components = GrGLPathRendering::kSTR_PathTexGenComponents;
362 }
363 glpr->enablePathTexGen(texCoordIndex++, components, transform);
364 }
joshualitt9b989322014-12-15 14:16:27 -0800365 }
366
joshualittabb52a12015-01-13 15:02:10 -0800367 void didSetData(GrGLPathRendering* glpr) SK_OVERRIDE {
368 glpr->flushPathTexGenSettings(fTexCoordSetCnt);
369 }
370
371private:
mtkleinb54fe402015-01-14 14:18:54 -0800372 SkDEBUGCODE(int fMaxTexCoords;)
joshualittabb52a12015-01-13 15:02:10 -0800373 int fTexCoordSetCnt;
374
375 typedef GrGLPathProcessor INHERITED;
376};
377
378class GrGLNormalPathProcessor : public GrGLPathProcessor {
379public:
380 GrGLNormalPathProcessor(const GrPathProcessor& pathProc, const GrBatchTracker& bt)
381 : INHERITED(pathProc, bt) {}
382
383 void emitTransforms(GrGLGPBuilder* pb, const TransformsIn& tin,
384 TransformsOut* tout) SK_OVERRIDE {
385 tout->push_back_n(tin.count());
386 fInstalledTransforms.push_back_n(tin.count());
387 for (int i = 0; i < tin.count(); i++) {
388 const ProcCoords& coordTransforms = tin[i];
389 fInstalledTransforms[i].push_back_n(coordTransforms.count());
390 for (int t = 0; t < coordTransforms.count(); t++) {
391 GrSLType varyingType =
392 coordTransforms[t]->getMatrix().hasPerspective() ? kVec3f_GrSLType :
393 kVec2f_GrSLType;
394
joshualitt31b52b72015-01-13 17:05:03 -0800395
396 SkString strVaryingName("MatrixCoord");
397 strVaryingName.appendf("_%i_%i", i, t);
joshualittabb52a12015-01-13 15:02:10 -0800398 GrGLVertToFrag v(varyingType);
joshualitt31b52b72015-01-13 17:05:03 -0800399 pb->addVarying(strVaryingName.c_str(), &v);
joshualittabb52a12015-01-13 15:02:10 -0800400 SeparableVaryingInfo& varyingInfo = fSeparableVaryingInfos.push_back();
401 varyingInfo.fVariable = pb->getFragmentShaderBuilder()->fInputs.back();
402 varyingInfo.fLocation = fSeparableVaryingInfos.count() - 1;
403 varyingInfo.fType = varyingType;
404 fInstalledTransforms[i][t].fHandle = ShaderVarHandle(varyingInfo.fLocation);
405 fInstalledTransforms[i][t].fType = varyingType;
406
407 SkNEW_APPEND_TO_TARRAY(&(*tout)[i], GrGLProcessor::TransformedCoords,
408 (SkString(v.fsIn()), varyingType));
409 }
410 }
411 }
412
413 void resolveSeparableVaryings(GrGLGpu* gpu, GrGLuint programId) {
414 int count = fSeparableVaryingInfos.count();
415 for (int i = 0; i < count; ++i) {
416 GrGLint location;
417 GR_GL_CALL_RET(gpu->glInterface(),
418 location,
419 GetProgramResourceLocation(programId,
420 GR_GL_FRAGMENT_INPUT,
421 fSeparableVaryingInfos[i].fVariable.c_str()));
422 fSeparableVaryingInfos[i].fLocation = location;
423 }
424 }
425
426 void setTransformData(const GrPrimitiveProcessor* primProc,
427 int index,
428 const SkTArray<const GrCoordTransform*, true>& coordTransforms,
429 GrGLPathRendering* glpr,
430 GrGLuint programID) SK_OVERRIDE {
431 SkSTArray<2, Transform, true>& transforms = fInstalledTransforms[index];
432 int numTransforms = transforms.count();
433 for (int t = 0; t < numTransforms; ++t) {
434 SkASSERT(transforms[t].fHandle.isValid());
435 const SkMatrix& transform = GetTransformMatrix(primProc->localMatrix(),
436 *coordTransforms[t]);
437 if (transforms[t].fCurrentValue.cheapEqualTo(transform)) {
438 continue;
439 }
440 transforms[t].fCurrentValue = transform;
441 const SeparableVaryingInfo& fragmentInput =
442 fSeparableVaryingInfos[transforms[t].fHandle.handle()];
443 SkASSERT(transforms[t].fType == kVec2f_GrSLType ||
444 transforms[t].fType == kVec3f_GrSLType);
445 unsigned components = transforms[t].fType == kVec2f_GrSLType ? 2 : 3;
446 glpr->setProgramPathFragmentInputTransform(programID,
447 fragmentInput.fLocation,
448 GR_GL_OBJECT_LINEAR,
449 components,
450 transform);
joshualitt9b989322014-12-15 14:16:27 -0800451 }
452 }
453
454private:
joshualittabb52a12015-01-13 15:02:10 -0800455 struct SeparableVaryingInfo {
456 GrSLType fType;
457 GrGLShaderVar fVariable;
458 GrGLint fLocation;
459 };
joshualitt9b989322014-12-15 14:16:27 -0800460
joshualittabb52a12015-01-13 15:02:10 -0800461
462 typedef SkSTArray<8, SeparableVaryingInfo, true> SeparableVaryingInfoArray;
463
464 SeparableVaryingInfoArray fSeparableVaryingInfos;
465
466 typedef GrGLPathProcessor INHERITED;
joshualitt9b989322014-12-15 14:16:27 -0800467};
468
joshualitt8059eb92014-12-29 15:10:07 -0800469GrPathProcessor::GrPathProcessor(GrColor color,
470 const SkMatrix& viewMatrix,
471 const SkMatrix& localMatrix)
472 : INHERITED(viewMatrix, localMatrix)
joshualitt290c09b2014-12-19 13:45:20 -0800473 , fColor(color) {
joshualitt9b989322014-12-15 14:16:27 -0800474 this->initClassID<GrPathProcessor>();
475}
476
477void GrPathProcessor::getInvariantOutputColor(GrInitInvariantOutput* out) const {
478 out->setKnownFourComponents(fColor);
479}
480
481void GrPathProcessor::getInvariantOutputCoverage(GrInitInvariantOutput* out) const {
482 out->setKnownSingleComponent(0xff);
483}
484
485void GrPathProcessor::initBatchTracker(GrBatchTracker* bt, const InitBT& init) const {
486 PathBatchTracker* local = bt->cast<PathBatchTracker>();
487 if (init.fColorIgnored) {
488 local->fInputColorType = kIgnored_GrGPInput;
489 local->fColor = GrColor_ILLEGAL;
490 } else {
491 local->fInputColorType = kUniform_GrGPInput;
492 local->fColor = GrColor_ILLEGAL == init.fOverrideColor ? this->color() :
493 init.fOverrideColor;
494 }
495
496 local->fInputCoverageType = init.fCoverageIgnored ? kIgnored_GrGPInput : kAllOnes_GrGPInput;
joshualitt290c09b2014-12-19 13:45:20 -0800497 local->fUsesLocalCoords = init.fUsesLocalCoords;
joshualitt9b989322014-12-15 14:16:27 -0800498}
499
500bool GrPathProcessor::canMakeEqual(const GrBatchTracker& m,
501 const GrPrimitiveProcessor& that,
502 const GrBatchTracker& t) const {
503 if (this->classID() != that.classID() || !this->hasSameTextureAccesses(that)) {
504 return false;
505 }
506
joshualitt8059eb92014-12-29 15:10:07 -0800507 if (!this->viewMatrix().cheapEqualTo(that.viewMatrix())) {
508 return false;
509 }
510
joshualitt9b989322014-12-15 14:16:27 -0800511 const PathBatchTracker& mine = m.cast<PathBatchTracker>();
512 const PathBatchTracker& theirs = t.cast<PathBatchTracker>();
joshualitt290c09b2014-12-19 13:45:20 -0800513 return CanCombineLocalMatrices(*this, mine.fUsesLocalCoords,
514 that, theirs.fUsesLocalCoords) &&
515 CanCombineOutput(mine.fInputColorType, mine.fColor,
joshualitt9b989322014-12-15 14:16:27 -0800516 theirs.fInputColorType, theirs.fColor) &&
517 CanCombineOutput(mine.fInputCoverageType, 0xff,
518 theirs.fInputCoverageType, 0xff);
519}
520
521void GrPathProcessor::getGLProcessorKey(const GrBatchTracker& bt,
522 const GrGLCaps& caps,
523 GrProcessorKeyBuilder* b) const {
524 GrGLPathProcessor::GenKey(*this, bt, caps, b);
525}
526
joshualittabb52a12015-01-13 15:02:10 -0800527GrGLPrimitiveProcessor* GrPathProcessor::createGLInstance(const GrBatchTracker& bt,
528 const GrGLCaps& caps) const {
529 SkASSERT(caps.nvprSupport() != GrGLCaps::kNone_NvprSupport);
530 if (caps.nvprSupport() == GrGLCaps::kLegacy_NvprSupport) {
531 return SkNEW_ARGS(GrGLLegacyPathProcessor, (*this, bt,
532 caps.maxFixedFunctionTextureCoords()));
533 } else {
534 return SkNEW_ARGS(GrGLNormalPathProcessor, (*this, bt));
535 }
joshualitt9b989322014-12-15 14:16:27 -0800536}
joshualittabb52a12015-01-13 15:02:10 -0800537